Spark配置参数调优

1.配置多个executor

       在项目中,由于数据量为几百万甚至千万级别,如果一个executor装载的对象过多,会导致GC很慢。项目中,我们使一个worker节点执行app时启动多个executor,从而加大并发度,解决full GC慢的问题。同时,由于启动了多个exeucute,在内存与核数不变的情况下,需要调整分配给每个execute的内存数及核数。

2.配置数据序列化

       Spark默认序列化方式为Java的ObjectOutputStream序列化一个对象,速度较慢,序列化产生的结果有时也比较大。所以项目中我们使用kryo序列化方式,通过kryo序列化,使产生的结果更为紧凑,减少内存的占用空间,同时减少了对象本身的元数据信息与基本数据类型的开销,从而更好地提高了性能。

3.优化缓存大小

    Spark默认用于缓存RDD的空间为一个executor的60%,项目中由于考虑到标签数量为成百个,使用同样规则与数量的标签进行客户群探索及客户群生成的概率很小。所以修改spark.storage.memoryFaction=0.4,这样使百分之60%的内存空间可以在task执行过程中缓存创建新对象,从而加大task的任务执行效率。

4.控制并行度

       项目中,由于标签的周期性有两种,分别是日标签与月标签,分别对应hdfs上的日宽表与月宽表。同时选中多个日与月标签进行客户群探索时,SQL会出现多个join的情况。在spark中join操作属于宽依赖,RDD在计算的时候需要进行类似于MapReduce的shuffle操作。Spark官网推荐为每个cpu Core分配2到3个任务,所以在32个core的服务器上,我们通过配置spark.default.parallelise=64,设置cpu的并行数量,从而防止并行度太高导致的任务启动与切换的开销。

 

5.  参数spark.shuffle.memoryFraction spark应用程序在所申请的内存资源中可用于shuffle的比例


SQL级别的优化:

1.优化sql结构

       传统的行式存储数据库在经过where条件筛选后,依旧会将整行的数据提到内存中进行数据处理,所以使用select * from table与select 字段 from table运行效率是一样的。但HDFS上我们通过hive的接口创建的为列式存储的parquet格式表结构,列式存储表结构只是将涉及到的字段加载到内存中,从而降低了IO,至此将代码中所有的sql拼接统一改为了条件字段。极大地提高了查询效率。

2.表关联方式的改变

       sparkSQL的查询优化是基于Scala语言开发的Catalyst,在最后的执行阶段,会在Spark内部将执行计划转化为有向无环图DAG进行执行。在逻辑优化阶段,Catalyst将SQL进行谓词下压,优先执行where条件后的筛选,过滤了大部分数据之后,通过属性之间的合并只做一次最后的投影,从而极大地提高查询效率。但在使用时发现,执行两表left join时,并未按照Catalyst的解析优先执行where条件的筛选,但使用inner join时发现执行了Catalyt解析如图5-12 sql解析过程图所示,至此我们将spark中的left join改为了inner join.

 

图5-12 SQL解析过程图

3.修改表数据类型

后台通过spark-shell执行编写好的scala代码的jar包,由于现有版本的spark的parquet存储格式无法更好的支持decimal数据类型,只能生成json格式的标签宽表。至此,将从数据仓库中挖掘出的数据源表中的浮点型数据类型统一改为double数据类型,最终生成的parquet格式的宽表在hdfs上节省的空间为json格式的3倍,前台对标签宽表的关联查询也提高了4倍。

posted on 2015-10-10 15:47  松伯  阅读(1383)  评论(0编辑  收藏  举报