zoukankan      html  css  js  c++  java
  • 为什么我们选择parquet

    说明:此方案已经我们已经运行1年。

    1、场景描述:

    我们对客户登录日志做了数据仓库,但实际业务使用中有一些个共同点,

    A  需要关联维度表

    B  最终仅取某个产品一段时间内的数据

    C 只关注其中极少的字段

    基于以上业务,我们决定每天定时统一关联维度表,对关联后的数据进行另外存储。各个业务直接使用关联后的数据进行离线计算。

    2、择parquet的外部因素

    在各种列存储中,我们最终选择parquet的原因有许多。除了parquet自身的优点,还有以下因素

    A、公司当时已经上线spark 集群,而spark天然支持parquet,并为其推荐的存储格式(默认存储为parquet)。

    B、hive 支持parquet格式存储,如果以后使用hiveql 进行查询,也完全兼容。

    3、选择parquet的内在原因

    下面通过对比parquet和csv,说说parquet自身都有哪些优势

    csv在hdfs上存储的大小与实际文件大小一样。若考虑副本,则为实际文件大小*副本数目。(若没有压缩)

    3.1 parquet采用不同压缩方式的压缩比

    说明:原始日志大小为214G左右,120+字段

    采用csv(非压缩模式)几乎没有压缩。

    采用parquet 非压缩模式、gzip、snappy格式压缩后分别为17.4G、8.0G、11G,达到的压缩比分别是:12、27、19。

    若我们在hdfs上存储3份,压缩比仍达到4、9、6倍

    3.2 分区过滤与列修剪

    3.2.1分区过滤

    parquet结合spark,可以完美的实现支持分区过滤。如,需要某个产品某段时间的数据,则hdfs只取这个文件夹。

    spark sql、rdd 等的filter、where关键字均能达到分区过滤的效果。

    使用spark的partitionBy 可以实现分区,若传入多个参数,则创建多级分区。第一个字段作为一级分区,第二个字段作为2级分区。。。。。

    3.2.2 列修剪

    列修剪:其实说简单点就是我们要取回的那些列的数据。

    当取得列越少,速度越快。当取所有列的数据时,比如我们的120列数据,这时效率将极低。同时,也就失去了使用parquet的意义。

    3.2.3 分区过滤与列修剪测试如下:


    说明:

    A、task数、input值、耗时均为spark web ui上的真实数据。

    B、之所以没有验证csv进行对比,是因为当200多G,每条记录为120字段时,csv读取一个字段算个count就直接lost excuter了。

    C、注意:为避免自动优化,我们直接打印了每条记录每个字段的值。(以上耗时估计有多部分是耗在这里了)

    D、通过上图对比可以发现:

    • 当我们取出所有记录时,三种压缩方式耗时差别不大。耗时大概7分钟。
    • 当我们仅取出某一天时,parquet的分区过滤优势便显示出来。仅为6分之一左右。貌似当时全量为七八天左右吧。
    • 当我们仅取某一天的一个字段时,时间将再次缩短。这时,硬盘将只扫描该列所在rowgroup的柱面。大大节省IO。如有兴趣,可以参考 深入分析Parquet列式存储格式

    E、测试时请开启filterpushdown功能

    4、结论

    • parquet的gzip的压缩比率最高,若不考虑备份可以达到27倍。可能这也是spar parquet默认采用gzip压缩的原因吧。
    • 分区过滤和列修剪可以帮助我们大幅节省磁盘IO。以减轻对服务器的压力。
    • 如果你的数据字段非常多,但实际应用中,每个业务仅读取其中少量字段,parquet将是一个非常好的选择。
  • 相关阅读:
    [Codeforces Round #498 (Div. 3)] -F. Xor-Paths (折半搜索)
    Best Reward [HDU
    [Educational Codeforces Round 72] A. Creating a Character (简单数学)
    [Codeforces Round #624 (Div. 3)] -E. Construct the Binary Tree (构造二叉树)
    [Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)] -D. Present(异或性质,按位拆分,双指针)
    [Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)] -D. Present(异或性质,按位拆分,树桩数组)
    [Educational Codeforces Round 83 ] E. Array Shrinking
    [AtCoder Beginner Contest 158]
    [CodeCraft-20 (Div. 2)]- E. Team Building (状压DP)
    HDU 3308 LCIS (线段树区间合并)
  • 原文地址:https://www.cnblogs.com/piaolingzxh/p/5469964.html
Copyright © 2011-2022 走看看