2011年小规模试水
这一阶段的主要工作是建立了一个小的集,并导入了少量用户进行测试。为了满足用户的需求,我们还调研了任务调度系统和数据交换系统。
我们使用的版本是当时最新的稳定版,Hadoop 0.20.203和Hive 0.7.1。此后经历过多次升级与Bugfix。现在使用的是Hadoop 1.0.3+自有Patch与Hive 0.9+自有Patch。考虑到人手不足及自己的Patch不多等问题,我们采取的策略是,以Apache的稳定版本为基础,尽量将自己的修改提交到社区,并且应用这些还没有被接受的 Patch。因为现在Hadoop生态圈中还没有出现一个类似Red Hat地位的公司,我们也不希望被锁定在某个特定的发行版上,更重要的是Apache Jira与Maillist依然是获取Hadoop相关知识、解决Hadoop相关问题最好的地方(Cloudera为CDH建立了私有的Jira,但人气不足),所以没有采用Cloudera或者Hortonworks的发行版。目前我们正对Hadoop 2.1.0进行测试。
在前期,我们团队的主要工作是ops+solution,现在DBA已接手了很大一部分ops的工作,我们正在转向solution+dev的工作。
我们使用Puppet管理整个集,用Ganglia和Zabbix做监控与报警。
集搭建好,用户便开始使用,面临的第一个问题是需要任务级别的调度、报警和工作流服务。当用户的任务出现异常或其他情况时,需要以邮件或者短信的方式通知用户。而且用户的任务间可能有复杂的依赖关系,需要工作流系统来描述任务间的依赖关系。我们首先将目光投向开源项目Apache Oozie。Oozie是Apache开发的工作流引擎,以XML的方式描述任务及任务间的依赖,功能强大。但在测试后,发现Oozie并不是一个很好的选择。
Oozie采用XML作为任务的配置,特别是对于MapReduce Job,需要在XML里配置Map、Reduce类、输入输出路径、Distributed Cache和各种参数。在运行时,先由Oozie提交一个Map only的Job,在这个Job的Map里,再拼装用户的Job,通过JobClient提交给JobTracker。相对于Java编写的Job Runner,这种XML的方式缺乏灵活性,而且难以调试和维 护。先提交一个Job,再由这个Job提交真正Job的设计,我个人认为相当不优雅。
另一个问题在于,公司内的很多用户,希望调度系统不仅可以调度Hadoop任务,也可以调度单机任务,甚至Spring容器里的任务,而Oozie并不支持Hadoop集之外的任务。
所以我们转而自行开发调度系统Taurus(github/dianping/taurus)。Taurus是一个调度系统, 通过时间依赖与任务依赖,触发任务的执行,并通过任务间的依赖管理将任务组织成工作流;支持Hadoop/Hive Job、Spring容器里的任务及一般性任务的调度/监控。
图1 Taurus的结构图
图1是Taurus的结构图,Taurus的主节点称为Master,Web 界面与Master在一起。用户在Web界面上创建任务后,写入MySQL做持久化存储,当Master判断任务触发的条件满足时,
则从MySQL中读出 任务信息,写入ZooKeeper;Agent部署在用户的机器上,观察ZooKeeper上的变化,获得任务信息,启动任务。Taurus在2012年 中上线。
另一个迫切需求是数据交换系统。用户需要将MySQL、MongoDB甚至文件中的数据导入到HDFS上进行分析。另外一些用户要将HDFS中生成的数据再导入MySQL作为报表展现或者供在线系统使用。
我们首先调研了Apache Sqoop,它主要用于HDFS与关系型数据库间的数据传输。经过测试,发现Sqoop的主要问题在于数据的一致性。Sqoop采用 MapReduce Job进行数据库的插入,而Hadoop自带Task的重试机制,当一个Task失败,会自动重启这个xml技术的主要应用Task。这是一个很好的特性,大大提高了Hadoop的容错能力,但对于数据库插入操作,却带来了麻烦。
考虑有10个Map,每个Map插入十分之一的数据,如果有一个Map插入到一半时failed,再通过Task rerun执行成功,那么fail那次插入的一半数据就重复了,这在很多应用场景下是不可接受的。 而且Sqoop不支持MongoDB和MySQL之间的数据交换,但公司内却有这需求。最终我们参考淘宝的DataX,于2011年底开始设计并开发了Wormhole。之所以采用自行开发而没有直接使用DataX主要出于维护上的考虑,而且DataX并未形成良好的社区。
2012年大规模应用
2012年,出于成本、稳定性与源码级别维护性的考虑,公司的Data Warehouse系统由商业的OLAP数据库转向Hadoop/Hive。2012年初,Wormhole开发完成;之后Taurus也上线部署;大量应用接入到Hadoop平台上。为了保证数据的安全性,我们开启了Hadoop的Security特性。为了提高数据的压缩率,我们将默认存储格式替换为RCFile,并开发了Hive Web供公司内部使用。2012年底,我们开始调研HBase。
图2 Wormhole的结构图
Wormhole(github /dianping/wormhole)是一个结构化数据传输工具,用于解决多种异构数据源间的数据交换,具有高效、易扩展等特点,由Reader、 Storage、Writer三部分组成(如图2所示)。Reader是个线程池,可以启动多个Reader线程从数据源读出数据,写入Storage。 Writer也是线程池,多线程的Writer不仅用于提高吞吐量,还用于写入多个目的地。Storage是个双缓冲队列,如果使用一读多写,则每个目的地都拥有自己的Storage。
当写入过程出错时,将自动执行用户配置的Rollback方法,消除错误状态,从而保证数据的完整性。通过开发不同的Reader和Writer插件,如MySQL、MongoDB、Hive、HDFS、SFTP和Salesforce,我们就可以支持多种数据源间的数据交换。Wormhole在大众点评内部得到了大量使用,获得了广泛好评。
随着越来越多的部门接入Hadoop,特别是数据仓库(DW)部门接入后,我们对数据的安全性需求变得更为迫切。而Hadoop默认采用Simple的用户认证模式,具有很大的安全风险。
默认的Simple认证模式,会在Hadoop的客户端执行whoami命令,并以whoami命令的形式返回结果,作为访问Hadoop的用户名(准确地说,是以whoami的形式返回结果,作为Hadoop RPC的userGroupInformation参数发起RPC Call)。这样会产生以下三个问题。
(1)User Authentication。假设有账号A和账号B,分别在Host1和Host2上。如果恶意用户在Host2上建立了一个同名的账号A,那么通过RPC Call获得的UGI就和真正的账号A相同,伪造了账号A的身份。用这种方式,恶意用户可以访问/修改其他用户的数据。
(2)Service Authentication。Hadoop采用主从结构,如NameNode-DataNode、JobTracker-Tasktracker。Slave节点启动时,主动连接Master节点。Slave到Master的连接过程,没有经过认证。假设某个用户在某台非Hadoop机器上,错误地启动了一个Slave实例,那么也会连接到Master;Master会为它分配任务/数据,可能会影响任务的执行。
(3)可管理性。任何可以连到Master节点的机器,都可以请求集的服务,访问HDFS,运行Hadoop Job,无法对用户的访问进行控制。
从Hadoop 0.20.203开始,社区开发了Hadoop Security,实现了基于Kerberos的Authentic
ation。任何访问Hadoop的用户,都必须持有KDC(Key Distribution Center)发布的Ticket或者Keytab File(准确地说,是Ticket Granting Ticket),才能调用Hadoop的服务。用户通过密码,获取Ticket,Hadoop Client在发起RPC Call时读取Ticket的内容,使用其中的Principal字段,作为RPC Call的UserGroupInformation参数,解决了问题(1)。Hadoop的任何Daemon进程在启动时,都需要使用Keytab File做Authentication。因为Keytab File的分发是由管理员控制的,所以解决了问题(2)。最后,不论是Ticket,还是Keytab File,都由KDC管理/生成,而KDC由管理员控制,解决了问题(3)。
在使用了Hadoop Security之后,只有通过了身份认证的用户才能访问Hadoop,大大增强了数据的安全性和集的可管理性。之后我们基于Hadoop Secuirty,与DW部门一起开发了ACL系统,用户可以自助申请Hive上表的权限。在申请通过审批工作流之后,就可以访问了。
JDBC是一种很常用的数据访问接口,Hive自带了Hive Server,可以接受Hive JDBC Driver的连接。实际 上,Hive JDBC Driver是将JDBC的请求转化为Thrift Call发给Hive Server,再由Hive Server将Job 启动起来。但Hive自带的Hive Server并不支持Security,默认会使
用启动Hive Server的用户作为Job的owner提交到 Hadoop,造成安全漏洞。因此,我们自己开发了Hive Server的Security,解决了这个问题。
但在Hive Server的使用过程中,我们发现Hive Server并不稳定,而且存在内存泄漏。更严重的是由于Hive Server自身的设计缺陷,不能很好地应对并发访问的情况,所以我们现在并不推荐使用Hive JDBC的访问方式。
社区后来重新开发了Hive Server 2,解决了并发的问题,我们正在对Hive Server 2进行测试。
有一些同事,特别是BI的同事,不熟悉以CLI的方式使用Hive,希望Hive可以有个GUI界面。在上线Hive Server之后,我们调研了开源的SQL GUI Client——Squirrel,可惜使用Squirrel访问Hive存在一些问题。
∙ 办公网与线上环境是隔离的,在办公机器上运行的Squirrel无法连到线上环境的Hive Server。
∙ Hive会返回大量的数据,特别是当用户对于Hive返回的数据量没有预估的情况下,Squirr
el会吃掉大量的内存,然后Out of Memory挂掉。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论