当前位置: 首页 > news >正文

spark读取数据性能提升

1. 背景

spark默认的jdbc只会用单task读取数据,读取大数据量时,效率低。

2. 解决方案

根据分区字段,如日期进行划分,增加task数量提升效率。

  /*** 返回每个task按时间段划分的过滤语句* @param startDate* @param endDate* @param threadCount* @return*/def getPredicateDates(startDate: String, endDate: String, threadCount: Int): Array[String] = {getPredicates(startDate, endDate, threadCount).map(x=>s"recordDate>='${x._1}' and recordDate <='${x._2}'")}/*** 将startDate到endDate间的日期,根据给定的threadCount参数,做时间段划分,例如:* getPredicates("2017-01-01", "2017-01-31", 10)* 返回:* 2017-01-01 -> 2017-01-04* 2017-01-05 -> 2017-01-08* 2017-01-09 -> 2017-01-12* 2017-01-13 -> 2017-01-16* 2017-01-17 -> 2017-01-20* 2017-01-21 -> 2017-01-24* 2017-01-25 -> 2017-01-28* 2017-01-29 -> 2017-01-31** @param startDate   开始日期* @param endDate     结束日期* @param threadCount 线程数* @return 包含各个连续时段的数组*/def getPredicates(startDate: String, endDate: String, threadCount: Int): Array[(String, String)] = {val dayDiff = DateTimeUtils.rangeDay(startDate, endDate)val buff = new ArrayBuffer[(String, String)]()if (dayDiff <= threadCount) {//天数差小于期望的线程数,则按照每天一个线程处理var tempDate = startDatewhile (tempDate <= endDate) {buff += (tempDate -> tempDate)tempDate = DateTimeUtils.dateAddOne(tempDate)}} else {//天数差大于期望的线程数,则按照线程数对时间段切分val offset = (dayDiff / threadCount).toIntvar tempDate = startDatewhile (DateTimeUtils.dateAddN(tempDate, offset) <= endDate) {buff += (tempDate -> DateTimeUtils.dateAddN(tempDate, offset))tempDate = DateTimeUtils.dateAddOne(DateTimeUtils.dateAddN(tempDate, offset))}if (tempDate != endDate) {buff += (tempDate -> endDate)}}buff.toArray}
DateTimeUtils工具类
import java.text.SimpleDateFormat
import java.util.{Calendar, Date, Locale}object DateTimeUtils {def rangeDay(startDateStr: String, endDateStr: String): Long = {val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")val startDate: Date = dateFormat.parse(startDateStr)val endDate: Date = dateFormat.parse(endDateStr)(endDate.getTime() - startDate.getTime()) / 1000 / 60 / 60 / 24}def dateAddOne(dateStr: String): String = {var dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")var dateInfo: Date = dateFormat.parse(dateStr)var cal: Calendar = Calendar.getInstance()cal.setTime(dateInfo)cal.add(Calendar.DATE, 1)dateFormat.format(cal.getTime)}def dateAddN(dateStr: String, value: Int): String = {var dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")var dateInfo: Date = dateFormat.parse(dateStr)var cal: Calendar = Calendar.getInstance()cal.setTime(dateInfo)cal.add(Calendar.DATE, value)dateFormat.format(cal.getTime)}
}

举例

    val startDate = DateTimeUtils.dateAddN(calcDate,-365) //获取计算日期一年前的日期作为开始时间val predicates= getPredicateDates(startDate,calcDate,12) //分12个task读取,提高性能val url = PropUtils.getProxyJdbc() //jdbc连接的代理(需按自己的项目实现)val res = spark.read.jdbc(url, tableName, predicates,PropUtils.getProperties()) 

3. 实验及结论

使用1个节点 8核16G的Clickhouse数据库,spark从clickhouse读取近4亿行数据。

单Task运行时间:14min

按日期划分成12个Task,运行时间:1.6min

结论:性能提升88.6%

相关文章:

  • 【YashanDB知识库】客户端字符集与数据库字符集兼容问题
  • node的控制流,异步,以及异常处理
  • 【机器学习】---神经架构搜索(NAS)
  • react crash course 2024(7) react router dom
  • langchain 记忆力(memory),让语言大模型拥有记忆
  • SQL_over_partition_by_order_by
  • Java数据库连接jdbc
  • 广东高校建设AIGC实验室时需要注意哪几个关键点?
  • [JavaEE] 网络编程----UDP / TCP 回显服务器
  • neo4j:ubuntu环境下的安装与使用
  • Spring Boot 点餐系统:餐饮界的技术革新
  • 【mac开发入坑指南】能让你的终端好用一万倍的神仙组合iTerm2 + oh-my-zsh
  • 【Rust练习】16.方法和关联函数
  • 解决远程连接AlpineLinux Mysql/MariaDB 无法连接的问题
  • Nginx反向代理配置支持websocket
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • ES10 特性的完整指南
  • ES6 ...操作符
  • ESLint简单操作
  • es的写入过程
  • IOS评论框不贴底(ios12新bug)
  • Js基础知识(一) - 变量
  • JS数组方法汇总
  • MySQL主从复制读写分离及奇怪的问题
  • Python实现BT种子转化为磁力链接【实战】
  • SQLServer之创建显式事务
  • vue 配置sass、scss全局变量
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 二维平面内的碰撞检测【一】
  • 构建工具 - 收藏集 - 掘金
  • 回顾 Swift 多平台移植进度 #2
  • 技术:超级实用的电脑小技巧
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 如何使用 JavaScript 解析 URL
  • 想写好前端,先练好内功
  • 消息队列系列二(IOT中消息队列的应用)
  • 移动端唤起键盘时取消position:fixed定位
  • 优化 Vue 项目编译文件大小
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #Z0458. 树的中心2
  • #知识分享#笔记#学习方法
  • (poj1.3.2)1791(构造法模拟)
  • (八)Flink Join 连接
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二)测试工具
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (九)信息融合方式简介
  • (离散数学)逻辑连接词
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (四)Controller接口控制器详解(三)
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一