Apache Kylin : Analytical Data Warehouse for Big Data
Page History
自动调参的概念和作用
在Kylin 4.0中为了提升构建任务的稳定性,尽量少的出现因为Spark参数没有配置正确导致任务失败的情况,以及尽可能地减少资源的浪费,构建引擎加入了自动调参的功能。在集群上运行的时候,构建引擎会根据此次构建任务的数据量自动调整spark相关的运行参数,提高构建效率。若想启用自动调参功能,需要的注意的地方如下:
- 自动调参功能是默认打开的
- 仅仅会在集群模式生效
- 会影响的spark的配置项如下(当且仅当用户没有在kylin.properties中配置如下属性的时候才会启用本功能)
Code Block # Spark executor kylin.engine.spark-conf.spark.executor.instances kylin.engine.spark-conf.spark.executor.cores kylin.engine.spark-conf.spark.executor.memory kylin.engine.spark-conf.spark.executor.memoryOverhead # Spark driver kylin.engine.spark-conf.spark.driver.memory
实现
Spark driver参数
driver端只会修改spark.driver.memory, 执行逻辑如下; Spark任务会使用如下公式min(kylin.engine.driver-memory-maximum, kylin.engine.driver-memory-base * 档位)
- 默认kylin.engine.driver-memory-maximum=4096
- 默认kylin.engine.driver-memory-base=1024
- 档位根据cuboid个数通过配置项kylin.engine.driver-memory-strategy={2,20,100}得到,例如此时有26个cuboid则为3档,1个cuboid为1档
Spark executor参数
资源探测
资源探测会收集一些必要的信息为后续的自动调参、构建任务准备。构建任务资源探测会将如下三个文件记录到 working-dir/working−dir/project/job_tmp/$jobId/share 目录下: a. count_distinct.json 是否需要构建count distinct measure b. 每个segment会生成 ${seg_id}_resource_paths.json,每个根节点的执行计划的所有文件路径 c. 每个segment会生成 {seg_id}_cubing_detect_items.json,每个根节点的执行计划的分区数总和(如果源表是一个view,会遍历view 下面的所有leafNode的分区数之和) 需要注意的是merge任务资源探测只会生成count_distinct.json和segidcubingdetectitems.json,每个根节点的执行计划的分区数总和(如果源表是一个view,会遍历view下面的所有leafNode的分区数之和)需要注意的是merge任务资源探测只会生成countdistinct.json和{merged_segment_id}_resource_paths.json
各个Spark参数设置规则如下:
spark.executor.memory
- 从*_resource_paths.json中获取读取的文件
- 获取这些文件的大小并选出最大值
- 根据如下规则配置
a. 如果size >= 100G && 存在count distinct 则结果为20G
b. 如果size >= 100G || (size >= 10G && 存在count distinct) 则结果为16G
c. 如果size >= 10G || (size >= 1G && 存在count distinct) 则结果为10G
d. 其他情况结果为4G
spark.executor.cores
- 从*_resource_paths.json中获取读取的文件
- 获取这些文件的大小并选出最大值
- 根据如下规则配置
a. 如果size >= 10G
...
- 或者存在count distinct度量, 则结果为5
b. 其他情况为1
spark.executor.memoryOverhead
- 从*_resource_paths.json中获取读取的文件
- 获取这些文件的大小并选出最大值
- 根据如下规则配置
a. 如果size >= 100G
...
- 并且存在count distinct度量,则结果为6G
b. 如果size >= 100G
...
- 或者 (size >=10G
...
- 并且 存在count distinct) ,则结果为4G
c. 如果size >= 10G
...
- 或者 (size >=1G
...
- 并且 存在count distinct),则结果为2G
d. 如果size >= 1G
...
- 或者 存在count distinct 则结果为1G
e. 其他情况为512M
spark.executor.instances
- 从 *_cubing_detect_items.json 获取最大的task数量 max_tasks,
- 计算总共需要的cores数量为max_tasks / kylin.engine.spark.task-core-factor,kylin.engine.spark.task-core-factor 默认是3
- 根据layout数量计算instance数量 instance_by_layout
a. kylin.engine.base-executor-instance 默认是 5
b. 档位 0 ~ 100 => 1, 100 ~ 500 =>2, 500 ~ 1000 => 3, 1000+ => 4
c. kylin.engine.base-executor-instance * 档位 - 获取队列 available_cores, available_memory
- 计算 available_instances = min(available_cores / (spark.executor.memory + spark.executor.memoryOverhead), available_memory / spark.executor.cores )
- 计算 instance = min(max(instance_by_layout, required_cores / spark.executor.cores), available_instances)
- 最终结果为max(instance, kylin.engine.base-executor-instance), kylin.engine.base-executor-instance 默认是 5