共计 1905 个字符,预计需要花费 5 分钟才能阅读完成。
咱们晓得,大部分 Spark 计算都是在内存中实现的,所以 Spark 的瓶颈个别来自于集群 (standalone, yarn, mesos, k8s) 的资源缓和,CPU,网络带宽,内存。Spark 的性能,想要它快,就得充分利用好系统资源,尤其是内存和 CPU。有时候咱们也须要做一些优化调整来缩小内存占用,例如将小文件进行合并的操作。
一、问题景象
咱们有一个 15 万条总数据量 133MB 的表,应用 SELECT * FROM bi.dwd_tbl_conf_info 全表查问耗时 3min,另外一个 500 万条总数据量 6.3G 的表 ods_tbl_conf_detail,查问耗时 23 秒。两张表均为列式存储的表。
大表查问快,而小表反而查问慢了,为什么会产生如此奇怪的景象呢?
二、问题探询
数据量 6.3G 的表查问耗时 23 秒,反而数据量 133MB 的小表查问耗时 3min,这十分奇怪。咱们收集了对应的建表语句,发现两者没有太大的差别,大部分为 String,两表的列数也相差不大。
CREATE TABLE IF NOT EXISTS `bi`.`dwd_tbl_conf_info` (
`corp_id` STRING COMMENT '',
`dept_uuid` STRING COMMENT '',
`user_id` STRING COMMENT '',
`user_name` STRING COMMENT '',
`uuid` STRING COMMENT '',
`dtime` DATE COMMENT '',
`slice_number` INT COMMENT '',
`attendee_count` INT COMMENT '',
`mr_id` STRING COMMENT '',
`mr_pkg_id` STRING COMMENT '',
`mr_parties` INT COMMENT '',
`is_mr` TINYINT COMMENT 'R',
`is_live_conf` TINYINT COMMENT ''
)
CREATE TABLE IF NOT EXISTS `bi`.`ods_tbl_conf_detail` (
`id` string,
`conf_uuid` string,
`conf_id` string,
`name` string,
`number` string,
`device_type` string,
`j_time` bigint,
`l_time` bigint,
`media_type` string,
`dept_name` string,
`UPDATETIME` bigint,
`CREATETIME` bigint,
`user_id` string,
`USERAGENT` string,
`corp_id` string,
`account` string
)
因为两张表均为很简略的 SELECT 查问操作,无任何简单的聚合 join 操作,也无 UDF 相干的操作,所以根本确认查问慢的应该产生的读表的时候,咱们将狐疑的点放到了读表操作上。通过查问两个查问语句的 DAG 和工作散布,咱们发现了不一样的中央。
查问快的表,查问时总共有 68 个工作,任务分配比方平均,均匀 7~9s 左右,而查问慢的表,查问时总共 1160 个工作,均匀也是 9s 左右。如下图所示:
至此,咱们根本发现了猫腻所在。大表 6.3G 但文件个数小,只有 68 个,所以很快跑完了。而小表尽管只有 133MB,但文件个数特地多,导致产生的工作特地多,而因为单个工作自身比拟快,大部分工夫破费在任务调度上,导致工作耗时较长。
那如何能力解决小表查问慢的问题呢?
三、业务调优
那当初摆在咱们背后就存在当初问题:
1、为什么小表会产生这么小文件
2、曾经产生的这么小文件如何合并
带着这两个问题,咱们和业务的开发人员聊了一个发现小表是业务开发人员从原始数据表中,依照不同的工夫切片查问并做数据荡涤后插入到小表中的,而因为工夫切片切的比拟小,导致这样的插入次数特地多,从而产生了大量的小文件。
那么咱们须要解决的问题就是 2 个,如何能力把这些历史的小文件进行合并以及如何能力保障后续的业务流程中不再产生小文件,咱们领导业务开发人员做了以下优化:
1)应用 INSERT OVERWRITE bi.dwd_tbl_conf_info SELECT * FROM bi.dwd_tbl_conf_info 合并下历史的数据。因为 DLI 做了数据一致性爱护,OVERWRITE 期间不影响原有数据的读取和查问,OVERWRITE 之后就会应用新的合并后的数据。合并后全表查问由原来的 3min 缩短到 9s 内实现。
2)原有表批改为分区表,插入时不同工夫放入到不同分区,查问时只查问须要的时间段内的分区数据,进一步减小读取数据量。
点击关注,第一工夫理解华为云陈腐技术~