学习笔记:Twitter核心数据类库团队的Hadoop优化经验
一、来源
Streaming Hadoop Performance Optimization at Scale, Lessons Learned at Twitter
(Data platform @Twitter)
二、观后感
2.1 概要
此稿介绍了Twitter的核心数据类库团队,在使用Hadoop处理离线任务时,使用的性能分析方法,及由此发现的问题和优化手段,对如何使用JVM/HotSpot profile(-Xprof)分析Hadoop Job的方法调用开销、Hadoop配置对象的高开销、MapReduce阶段的排序中对象序列化/反序列的高开销问题及优化等给出了实际可操作的方案。
其介绍了Apache Parquet这一面向列的存储格式,并成功应用于列投影(column project),配合predicated push-down技术,过滤不需要的列,极大提高了数据压缩比和序列化/反序列化的性能。
纯干货。
32个赞!
2.2 优化总结
1) Profile!(-Xprofile)性能优化不能靠猜,而应靠分析!
2) 序列化开销很大,但是Hadoop里有许多序列化(操作)!
3) 根据特定(数据)访问模式,选择不同的存储格式(面向行还是面向列)!
4) 使用column projection。
5) 在Hadoop的MR阶段,排序开销很大,使用Raw Comparators以降低开销。
注:此排序针对如Comparator,其会引发序列化/反序列化操作。
6) I/O并不一定就是瓶颈。必要的时候要多I/O换取更少的CPU计算。
JVM/HotSpot原生profile能力(-Xprof),其优点如下:
1) 低开销(使用Stack sampling)。
2) 能揭示开销最大的方法调用。
3) 使用标准输出(Stdout)将结果直接写入Task Logs。
2.3 Hadoop的配置对象
1) Hadoop的Configuration Object开销出人意料的高。
2) Conf的操作看起来就像一个HashMap的操作。
3) 构造函数:读取+解压+分析一个来自磁盘的XML文件
4) get()调用引起正则表达式计算,变量替换。
5) 如果在循环中对上述等方法进行调用,或者每秒一次调用,开销很高.某些(Hadoop)Jobs有30%的时间花在配置相关的方法上!(的确是出人意料的高开销)
总之,没有profile(-Xprof)技术,不可能获取以上洞察,也不可能轻易找到优化的契机和方向,需要使用profile技术来获知I/O和CPU谁才是真正的瓶颈。
2.4 中间结果的压缩
- Xprof揭示了spill线程中的压缩和解压缩操作消耗了大量时间。
- 中间结果是临时的。
- 使用lz4方法取代lzo level 3,减少了30%多的中间数据,使其能被更快地读取。
- 并使得某些大型Jobs提速150%。
2.5 对记录的序列化和反序列,会成为Hadoop Job中开销最高的操作!
2.6 对记录的序列化是CPU敏感的,相对比之下,I/O都不算什么了!
2.7 如何消除或者减小序列化/反序列化引起的(CPU)开销?
2.7.1 使用Hadoop的Raw Comparator API(来比较元素大小)
开销分析:如下图所示,Hadoop的MR在map和reduce阶段,会反序列化map结果的keys以在此阶段进行排序。
(反序列化操作)开销很大,特别是对于复杂的、非原语的keys,而这些keys又很常用。
Hadoop提供了一个RawComparator API,用于对已序列化的(原始的)数据(字节级)进行比较:
不幸的是,需要亲手实现一个自定义的Comparator。
现在,假设数据已序列化后的字节流,本身是易于比较的:
Scala有个很拉风的API,Scala还有一些宏可以产生这些API,以用于:
Tuples , case classes , thrift objects , primitives , Strings,等等数据结构。
怎么拉风法呢?首先,定义一个密集且易于比较的数据序列化(字节)格式:
其次,生成一个用于比较的方法,以利用这种数据格式的优势:
下图是采用上述优化手段后的比较开销对比:
提速到150%!
接着优化!
2.7.2 使用column projection
不要读取不需要的列:
1) 可使用Apache Parquet(列式文件格式)。
2) 使用特别的反序列化手段可以在面向行的存储中跳过一些不需要的字段。
面向列的存储中,一整列按顺序存储(而不是向面向行的存储那样,列是分开存储的):
可以看到,面向列的存储,使得同类型的字段被顺序排在一起(易于压缩):
采用Lzo + Parquet,文件小了2倍多!
2.7.3 Apache Parquet
1) 按列存储,可以有效地进行列投影(column projection)。
2) 可按需从磁盘上读取列。
3) 更重要的是:可以只反序列化需要的列!
看下效果:
可以看到,列数越少,Parquet的威力越大,到40列时,其效率反而不如Lzo Thrift。
- 在读取所有列的情况下,Parquet一般比面向行的存储慢。
- Parquet是种密集格式,其读性能和模式中列的数目相关,空值读取也消耗时间。
- 而面向行的格式(thrift)是稀疏的,所以其读性能和数据的列数相关,空值读取是不消耗时间的。
跳过不需要的字段,如下所示:
- 虽然,没有降低I/O开销
- 但是,可以仅将感兴趣的字段编码进对象中
- 相对于从磁盘读取 + 略过编码后字节的开销,在解码字符串时所花的CPU时间要高的多!
看下各种列映射方案的对比:
Parquet Thrift还有很多优化空间;Parquet在选取的列数小于13列之前,是更快的;此模式相对平坦,且大多数列都被生成了。
- 还可以采用Predicate Push-Down策略,使得Parquet可以跳过一些不满足过滤条件的数据记录。
- Parquet存储了一些统计信息,比如记录的chunks,所以在某些场景下,可以通过对这些统计信息进行读取分析,以跳过整个数据块(chunk)。
注:左图为column projection,中图为predicate push-down过滤,右图为组合效果。可以看到很多字段被跳过了,那绝壁可以优化序列化/反序列化的效率。
下图则展示了push-down过滤 + parquet的优化成效:
2.8 结语
感叹:Twitter真是一家伟大的公司!
上述优化手段,集群越大、Hadoop Job越多,效果越明显!
学习笔记:Twitter核心数据类库团队的Hadoop优化经验的更多相关文章
- 微信小程序开发:学习笔记[9]——本地数据缓存
微信小程序开发:学习笔记[9]——本地数据缓存 快速开始 说明 本地数据缓存是小程序存储在当前设备上硬盘上的数据,本地数据缓存有非常多的用途,我们可以利用本地数据缓存来存储用户在小程序上产生的操作,在 ...
- springmvc学习笔记(18)-json数据交互
springmvc学习笔记(18)-json数据交互 标签: springmvc springmvc学习笔记18-json数据交互 springmvc进行json交互 环境准备 加入json转换的依赖 ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- MyCat 学习笔记 第九篇.数据分片 之 数值分布
1 应用场景 Mycat 自带了多套数据分片的机制,其实根据数值分片也是比较简单,其实这个和数据取摸是类似的实现. 优.缺点同上一篇 2 环境说明 参考 <MyCat 学习笔记>第六篇. ...
- 《C#并发编程经典实例》学习笔记—3.1 数据的并行处理
问题 有一批数据,需要对每个元素进行相同的操作.该操作是计算密集型的,需要耗费一定的时间. 解决方案 常见的操作可以粗略分为 计算密集型操作 和 IO密集型操作.计算密集型操作主要是依赖于CPU计算, ...
- Hadoop学习笔记1-如何简单布署hadoop
企业机型配置: 选型标准:普通的,廉价的,标准的(容易替换的),工业化大规模生产的 CPU:支持多核CPU,如2个4核CPU 内存:16G以上,内存越大,常用数据都缓存在内存,提高速度 硬盘:不需RA ...
- 【学习笔记】大数据技术原理与应用(MOOC视频、厦门大学林子雨)
1 大数据概述 大数据特性:4v volume velocity variety value 即大量化.快速化.多样化.价值密度低 数据量大:大数据摩尔定律 快速化:从数据的生成到消耗,时间窗口小,可 ...
- NodeJS学习笔记 (15)二进制数据-buffer(ok)
模块概览 Buffer是node的核心模块,开发者可以利用它来处理二进制数据,比如文件流的读写.网络请求数据的处理等. Buffer的API非常多,本文仅挑选 比较常用/容易理解 的API进行讲解,包 ...
- Guava学习笔记:Google Guava 类库简介
http://www.cnblogs.com/peida/tag/Guava/ Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, cachin ...
随机推荐
- 一个自定义 HBase Filter -“通过RowKeys来高性能获取数据”
摘要: 大家在使用HBase和Solr搭建系统中经常遇到的一个问题就是:“我通过SOLR得到了RowKeys后,该怎样去HBase上取数据”.使用现有的Filter性能差劲,网上也没有现成的自定义Fi ...
- java PKCS7Padding 加密Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
在java中用aes256进行加密,但是发现java里面不能使用PKCS7Padding,而java中自带的是PKCS5Padding填充,那解决办法是,通过BouncyCastle组件来让java里 ...
- 如何做好presentation
1.全心投入 要么不做,要做就做好 承诺自己会花时间好好准备自己的演讲,投入专注的精力. 人们可以通过练习使自己成为很好的演讲者. 2分析你的观众 他们想听什么? 3.组织你的想法 让语言简单 让观众 ...
- [转]Oracle分页之二:自定义web分页控件的封装
本文转自:http://www.cnblogs.com/scy251147/archive/2011/04/16/2018326.html 上节中,讲述的就是Oracle存储过程分页的使用方式,但是如 ...
- 教你一招 - Misc类型插件的妙用(附带插件源码)
熟悉nopcommerce插件的朋友应该知道里面有一种Misc类型的插件,比如Nop.Plugin.Misc.WebServices和 Nop.Plugin.Misc.FacebookShop,继承自 ...
- common-pool2对象池(连接池)的介绍及使用
我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...
- NOIP2008 普及组T1 ISBN号码 解题报告-S.B.S.
题目描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”就是分隔符(键盘上的减号),最后一 ...
- cni 添加网络 流程分析
cnitool: Add or remove network interfaces from a network namespace cnitool add <net> <netns ...
- 深入理解UIApplication和ios程序启动过程
在深入理解UIApplication前我们先了解ios程序的启动过程: UIApplication类在ios里面为app的管理和协调提供一个集中的点,每一个app有一个UIApplication的实例 ...
- Git版本控制工具(一)----git的安装及创建版本库
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...