【CSDN现场报道】中国IT界技术盛会——Hadoop与大数据技术大会(Hadoop&BigData Technology Conference 2012,HBTC 2012)于2012年11月30日-12月1日在北京新云南皇冠假日酒店隆重召开。本次大会以“大数据共享与开放技术”为主题,聚焦于Hadoop与大 数据,力邀数十位国内外Hadoop及大数据技术应用的产学界人士和实践企业,探讨大数据技术生态系统的现状和发展趋势,并围绕Hadoop与大数据热点 技术和应用实践进行深入解析。
赵伟2009年加入腾讯,任职于数据平台部。一直从事海量数据处理平台研发工作,精通Hive、Hadoop、PostgreSQL等技术。今天他演讲的主题是腾讯分布式数据仓库介绍, HIVE在TDW中的实践和TDW HIVE接下来的工作。
腾讯高级工程师赵伟
腾讯分布式数据仓库,简称TDW,基于Hadoop、HIVE、PostgreSQL进行的大量定制和优化。TDW是腾讯最大的分布式系统,是腾讯公司级数据仓库;集中了各个业务中的有价值的数据。为腾讯内部提供离线的海量数据处理和分析的服务。包括数据挖掘、产品报表和经营分析。
解析TDW特性
这是TDW的特性。得益于底层的Hadoop,TDW是在存储和计算方面都具有容灾备份功能及线性扩展性。支持基本的SQL语言,除了SQL语言还支持一些高级的DB特性,比如说窗口函数、数据挖掘的函数,也支持过程语言、多维分析功能,这个是像Oracle这样的商业数据库所具备的。TDW也允许跑Map Reduce,我们有文本和结构化,也支持列存储,也支持ProtoBuf的数据解析,放在其他的DB里面我们可以在TDW里面提取。
TDW提供两种开发工具,一个是集成开发工具TDWIDE,还有一个类似于客户端的工具。TDW还有一个任务调度系统,用户可以在上面用拖拽的方式来配置工作流之间的依赖。TDW也有自己的系统DB,类似于MySQL和Oracle元数据的DB。用户可以通过TDW的SQL访问数据,也可以把元数据和常规TDW中的表进行关联或者是互操作。TDW也支持一些其他的,比如说showprocesslist、select的表达式,这也是对用户高效使用特性的提高;还有insert values,实际上它是不支持单行数据的插入,TDW是支持单行的。还有show create table,还有表格的注释等等。蓝色的部分是Hadoop和HIVE提供给TDW的特性,其余的都是腾讯团队通过研发来实现的。
TDW核心结构
这个是TDW的核心架构。其实TDW全部的架构还包括周边的调度系统和数据流转系统。上图只是最核心的部分,由四个大块组构成。首先是HIVE,它作为腾讯的查询引擎作用是将SQL翻译成MR或者是PGSQL。其次是HDFS和Map Reduce:HDFS主要是分布式存储的功能,而Map Reduce是并行计算。最后,PostgreSQL提供小数据的存储计算的功能。用户提交了数据行以后,HIVE会判断如果是TDW中一个普通的表则会进行Map Reduce的计算把结果返回给用户。如果他发现这张表是DB存储引擎的表会把SQL翻译成PG的SQL。Postgre在这儿主要是作为腾讯的一个配置,作为一个结果表和配置表的存储的地方。因为这些表是需要经常update、delete。另外它需要跟外部进行整合,Postgre也提供了其他语言标准的接口。这是TDW主要的核心架构。
TDW的运营现状,在腾讯TDW机器的设备总量超过了5000台,最大的单集群的节点是超过了2000个节点。TDW覆盖了腾讯内部90%以上的产品。集成开发环境的活跃用户每天有200个以上。每天在系统上提交的分析SQL数量超过5万。这5万条SQL翻译成的Map Reduce Job大概有10万以上。TDW在最近半年服务的可用度是达到了99.99%。每个月服务不可用的时间少于5分钟。
Hive的不足
数据仓库功能不够完善因为腾讯是三年前就使用了HIVE,当时使用HIVE的版本是0.4.1,很多功能是没有的,包括权限管理当时也是没有的。除了这个之外还给HIVE增加了过程语言,还有一些窗口函数多维分析等等。这个是功能上的不完善,其实这是很重要的,在内部推HIVE的时候由于很多的用户之前是熟悉Oracle成熟的DB,很多的业务是跑在这些上面的。他们要迁移到腾讯提供的TDW上面就很有挑战性,主要是腾讯写的分析的SQL在TDW上不支持,当时他们的挑战是很大的。很多功能HIVE是通过改写实现的,很多用户又觉得如果去改写的话本身的SQL就很复杂如果再改写会使得SQL变得更复杂。当面对这个的时候腾讯只能帮他们解决。
- HIVE的使用门槛有一些高
HIVE提供了一个CMI的模式,这个模式其实是比较原始和简陋的,对腾讯这样的开发人员可能会比较OK,但是他们推给用户的时候,用户就会很抱怨。因为他们之前在别的系统上开发的时候,一般都是有一个集成开发环境,这个集成开发环境基本上在Windows下可以做所有的事情,转化到腾讯的系统以后如果要用行的工具会觉得从现代社会回到了原始社会,因为他们可能有一些压力要完成手头的工作,如果换到TDW效率降低的话,其实对他来说压力也是很大的。除了用户界面还有HIVE的运行调试也是很麻烦的,腾讯有很多的业务的SQL其实是很复杂的,如果在一个命令行的工具下调试,可能要在文本编辑器里面把SQL写好,复杂的SQL一般需要有缩进,在文本编辑器里面弄好之后贴到命令行里面,如果出错就又要反复,很麻烦。
- HIVE问题定位很困难
表现变异式的错误,有的时候会提示不准。在一些运行时的错误发生的时候,比如说它读取的数据是一个压缩文件,损坏往往是一个运行式错误,SQL跑了50%突然出错了,这时候爆出的异常信息很不友好,Map Reduce会有一大堆的信息。但如果真的查问题的根源的话往往是要到Map Reduce的页面去看任务的运行日志,特别是失败的Task的日志。因为我们的系统很繁忙,Hadoop前台页面的日志只保存很短的时间,经常在页面上也看不到日志信息了,只能登录机器找日志。这对用户来说要求太高了,而且腾讯的系统是自己维护,但如果他们出问题会找到腾讯的运维人员。对腾讯来说运营的成本会非常高。
- HIVE的查询计划很难做
有一些用户也想把这个东西用好、用得高效。但是原来的HIVE打印出的计划,比如说想优化SQL,这个长期计划是非常难看的,如果这个SQL复杂一些,这个查询计划是好几屏幕的长度是没法儿阅读的,这些导致HIVE的使用门槛太高。
- Hive性能其实是有提升空间
HIVE本身翻译出的Map Reduce的效率有时候比较低,网上也有人对比它跟Pig的效率,其实HIVE在很多情况下的效率是不如Pig的。
- HIVE不够稳定
在生产环境中经常会出现HIVE不明情况的卡死,什么都不做就死在那了。还有是在一些并发的情况下,它的元数据会损坏,这其实有一段时间非常头疼,如果元数据损坏了,要登录到元数据库手工输入,如果是在凌晨,真的是很痛苦的。还有一些情况是HIVE Server的进程会异常退出,什么信息都没有了。
Hive的定制和优化
针对上面的不足,TWD对HIVE进行了大量的定制和优化,主要是在以下这四个方面,一个是功能扩充,一个是易用性的提升,还有一个是HIVE性能的优化,再就是稳定性的优化。
- 功能的扩充
腾讯给HIVE增加了基于角色的管理,因为之前有一些用Oracle的,所以管理员其实是比较擅长Oracle这种机遇角色的权限管理,参考了Oracle还有MySQL设计了TDW的决策管理。主要的做法其实是给它增加几张跟权限相关的元数据表结构,增加了一些权限管理的SQL的语法。这个是基于角色的权限管理,还给HIVE增加了兼容Oracle的分区功能。这里的工作主要是实现了三种分区模式,之后支持最多的是两级分区,可以是一级分区。建分区的语法是跟Oracle兼容的,我们支持了查询优化器,显示的效率是很高的,隐式的分区是指在微软条件中根据对分区的约束查询优化器会只扫描命中的分区的数据而不会扫描所有的数据除此之外还实现了窗口函数,因为之前有很多的业务已有的应用用到了窗口函数,要迁移到TDW的系统之上,他们就要求要提供这样的功能。腾讯制定了HIVE制定了自定义函数框架。这个框架下实现了常见的窗口函数,基本上满足了所有用户的窗口函数的需求。
还有一些用户用到了一些多维分析的功能,TDW支持多维分析的功能支持变换抽象语法数把cube、rollup的操作给它变换。腾讯做了一些优化,支持了公用表达式,像with这样的功能,这里的with是固化成临时表,之后修改后面语句的查询计划,把临时表作为输入去实现。还有一些用户他们的需求其实是不太合理的,他们希望我们支持update delete,而且是行级别的,当时疼腾讯也是评估了很长时间,最后是给他用很难看的方式实现了。实现的方式是delete语句会做一个select,可以看到这个操作其实是很耗资源的,而且在并发的时候是有问题的,所以我们这块给用户说得很明白,说这个东西要少用。实际上用update delete应用的只有几个。
之后还支持了入库的数据校验。原来的是不做校验的,当你做select的时候它会默默地把它置为NO,这个是不太合理的,有一些用户希望在入库的时候就要告诉我这个数据是脏的,可能是因为上游的一些结构变化,其实如果是这样的话整个录的这批都要重录了。他们希望尽早地知道这种情况,现在腾讯的入库支持阶段的合法性检查,腾讯会检查数据是不是符合它定义的表结构类型等等,然后入库完了之后会给它返回入库成功的条 数,这主要是通过Hadoop的counter来实现。
- 易用性提升
腾讯提供了一个命令行工具,上面是可以跑过程语言的,借用了Oracle的工具,很多的命令行跟它都很像。
接下来还做了DB存储引擎,现在TDW支持在建表的时候制定存储引擎,建表的时候DB存储引擎的格式表示的这张表存储在SQL里面。虽然这张表存储在那里,可是它其实是跟TD里面正常的表是没有什么区别的,你可以做select也可以和其他的表做关联,也可以把select的结果放到这个表中。腾讯之前只有TDW默认的存储引擎,它就需要计算完了之后把TDW中的数据导出为文本之后再导到数据库中进行操作。其实用户是觉得这个是很麻烦的,另外效率其实不是很高。最后的解决方案是TDW支持DB的存储引擎,这种存储引擎的数据是直接放在一个传统的DB里面的,可以在计算完了之后直接把结果insert这张表中,可以通过前台的DB的接口来访问这些数据,这样的话数据其实相当于都是在TDW里面的,没有做这种额外的导出或者是导入。
还有一种应用,常见用户有一些表不是很大,比如说维度表和配置表,他们经常有一些update delete的需求,这种实践是很粗暴的,而且在支持那个功能之前,因为TDW是支持分区的,一个用一个分析只存一行数据,因为分区是可以把一个分区drop掉,它通过这个去实现自己的update delete,这会让TDW里面存在很多的小文件,Hadoop处理小文件的时候是有很大的问题,长期会对Namenode产生问题。因为都是一些配置表、小表、结构表,对它的update delete完全可以在DB引擎里面做,所以就把结构表、配置表、存储表都存储成这种存储引擎,所以可以很高效地update delete。访问DB其实是很透明的,用户都可以不用考虑后面的DB。还有一部分用户希望在PG中访问TDW的数据,腾讯开发了一些插件,使它支持TDW Link的功能,可以通过link的功能直接把SQL发给TDW,获得结果。还有一个插件是可以访问外部数据源。通过这些功能可以访问TDW的数据。
应用性有很多SQL细节,用HIVE的都知道类似这种not like的语法是是不支持的。如果用户不知道的话,其实会很头疼,他怎么能想到改写成哪种方式呢?所以这对用户是很不友好的,还有支持了一些insert values,还有select expression,也就是说它后面要跟表达式。我们知道HIVE其实是不支持这个的,可能后面必须要跟一个from,这个from后面的表可能有一条数据,但整个这个语句运行下去就要启动Map Reduce,可能就需要20秒的启动时间。支持了select expression就不需要Map Reduce,腾讯也支持了show create table,一些运维的操作需要它。show processlist, kill query,comment on是支持修改表和注释的。
TDWIDE
应用性提升上有一个里程碑式的东西,就是TDW集成开发环境,它也是腾讯当时为用户实现的一个挑战,当时用户是这样说的,之前用的工具在另外一个系统上开发,一天会开发5、6个函数,在使用TDW的时候,由于这种难用,在命令行下的低效使得一天只能开发一个函数,整个业务迁移,还有应用开发进度严重地受阻。腾讯当时就决心开发一个Windows下的集成开发环境,基于开源的软件来构建。Eclipse提供了基本的IDE的功能,因为我们要让用户能编辑和调试Python这样的过程语言,我们借鉴了PyDev工具,使它支持Python的一些语法。之后还用到了Jython,这是Python和Java粘合的东西,也是很不错的。SQL编辑我们是采用了开源的DB的框架,最后相当于也是自己写了,因为这个插件很复杂。
中间的窗口是SQL的编辑界面,是支持语法高亮自动补全,支持SQL的自动格式化,可以自动缩进。还支持把鼠标放到一个函数上面,这个函数会提示它的用法。右边这块是我们的元数据浏览示图,用户可以在上面一级级地点,直到可以看到字段,也可以看出是不是分区字段。下面的是结果,运行了SQL之后可以直接显示。还有一些功能比如说可以显示查询计划,可以很快地注释一条SQL,还有一些命令是SQL在跑的过程中可以直接在这个界面上打开它的Job跑的页面,有一些高级客户希望看到这些信息。还支持进度的显示,用户提交SQL之后,其实可能会很希望知道SQL运行到什么状态,大概什么时候可以完成,我们也是支持进度的显示的。这个是图形化的查询计划的显示,查询计划右边是HIVE翻译了以后翻译的stage,其实每个Stage就是一个Map Reduce的任务。双击之后可以看出SQL的算法,这个是右边的图可以显示出来的,这个stage里面具体的操作是什么,是不是合理用户可以一眼看到,是先做过滤还是后做过滤,可以做SQL的调优,放到了stage里面可以看到输入是不是合理,特别是有了分区功能之后,希望看到我写的这个SQL的分区优化是不是起作用了,扫描的目录是不是减少了。可以通过这些信息来看到,整个可以很好地帮助用户来调优SQL。
稳定性的优化
在稳定性上的优化确实是有很多的地方。首先是HIVEServer的容灾与负载均衡,腾讯使用用了DNS轮训的方式,这让升级的时候很平滑,可以通过DNS的操作让升级不影响到业务。其次是大结果集获取接口优化,HIVE默认的结果集优化是这样,如果select的数据要获得,会生成一个很大的容器,之后把所有的结果都放到这个容器里面,也就是放到内存里面,遇到的情况是有很多的用户一个select,也不知道这个表有多大,直接把HIVE的内存挤死了。做了一个优化是用FetchN的结果来实现Fetchall,对HIVE的冲击很小。再次,做了一些元数据的优化,做的是让元数据接口尽量少地访问元数据,因为很多操作没有必要调用一个很大的元数据的接口,类似于get table,它完全没有必要说把这个表的所有的元数据都获取。腾讯是在这些地方有一些优化,这让请求量有一些减少。还有一些元数据的问题,在社区其实是没有解决的。HIVE社区里有人提到过,但一直是open的,没有被解决掉。当并发地在HIVE上提交SQL的时候,Datanucleus-core是非线程的,会导致死循环,建议打补丁,腾讯打了两个补丁之后,问题彻底解决了。现在社区的HIVE是没有做这个修改的。大家在用的时候要多去实践和关注。
现在还有一些内存泄漏的问题,HIVE本身在编码的时候没有考虑到一些情况,比如说有一些用户用一些程序拼了一条SQL,最大的这条SQL有40兆,而且还是有这种并发的,40兆并发的SQL过来之后,可能到passer阶段会成为很大的过程,再到语法语义分析阶段,腾讯做了一些优化,先通过剖析工具剖析,之后把它不在使用的量赋值为null。还有HIVE在过载保护上做得不是很好,它的Server是没有做连接数的限制的,有一些情况某个HIVE的连接就是很大,让这个HIVE出现的响应比较慢了,直接影响一些任务。腾讯这儿做的工作主要是限制了HIVE Server的最大连接数,做成了可page的,还限制了SQL长度。还有一个是最近的HIVE的hdfs的接口优化,hdfs的接口中实际上是一个单列,只要有一个接口卡住了,其他的接口都会卡住。所以我们在Hadoop上引用了这个补丁(HADOOP-6231)解决这个问题。
总结
现在总结腾讯在HIVE上的实践,通过上面的一些研发工作使HIVE的功能性的需求降低了80%,基本上大家对HIVE这块觉得功能已经OK了。对易用性方面使HIVE的开发效率提升了3倍。对性能方面做过评测,有一些SQL的性能是涉及到HIVE的两倍,可能HIVE的异常报警量减少了90%,虽然有这些成绩,但HIVE这边还是面临着一些问题要解决,比如说SQL的优化器不够智能,还需要设置一些参数,对用户来说还是不够友好,元数据模块的效率比较低,还有eclipse的运行有时候会比较缓慢,这些都会影响用户的体验。
最后腾讯接下来会在HIVE做的一些工作。首先是SQL优化器,会引入基于cost模型的查询优化,让用户从很多细节的参数设置上解脱出来。会在元数据上进行重构,首先是对表结构进行重构,我们发现HIVE本身的元数据的表结构其实是很不合理的,有很多的操作表其实是没有必要独立出来,完全可以跟其他的表合并。这块已经有一个初步的重构的方案,还会对元数据访问的接口进行重构,会去掉低效的ORM这一层,因为刚才说的表结构不合理其实也是跟ORM层相关的,自动地生成了那些表。最后一点会研发一个web版的IDE,轻量用户可以根据VPN访问,这会有很多的好处。