作者: 康凯森
日期: 2017-09-08
分类: OLAP
历经20天准备,30天逐个Project迁移,Kylin跨机房迁移终于完成,本次迁移累计迁移Project 20+,Cube 200 +, 其中8个Project以对用户零影响的方式完成迁移。本文对整个迁移过程进行回顾,总结。 (下文的S指迁移的源机房和集群,D指迁移的目标机房和集群)
方案的整体思路是我们在D新部署1套1.2.4版本的HBase服务,部署1套Kylin的线上JobServer服务和QueryServer服务,部署1套Staging环境的服务。然后将Kylin的部分业务线从S迁移到D。在实际迁移过程中,我们实际采用了两个方案,方案一主要是采用迁移HBase数据的思路,方案二主要是采用重新Build Kylin Cube的思路。前期我采用了方案一,后来我发现方案一过程较为繁琐,后改用方案二,效率有较大提升。 无论采用哪种迁移方案,我们的准备工作都是一样的:
方案一最大的痛点是Kylin的每张HBase表都有Coprocessor,而HBase有个很大的bug:如果一张HBase表的Coprocessor无法正确加载,不仅是对应的Region无法正确加载,而是这台RegionServer会挂掉,更进一步,这些Region会不断尝试重新加载,然后整个HBase集群就会挂掉。 我感觉HBase这个处理逻辑简直奇葩!
为了防止出现这个问题,我们在迁移完HBase表数据后,需要删除掉旧的tabledesc文件,再用HBCK生成新的tabledesc文件,然后迁移Kylin元数据时将hostname,segment,SPLIT_POLICY等信息写入HTableDescriptor,最后再更新HBase表的Coprocessor。所以整个过程比较繁琐,当然我们可以开发个工具直接更新tabledesc二进制文件,也可以通过让D的HBase集群可以访问S的HBase集群的HDFS来解决这个问题。 这个方案最不好的地方是HBase HBCK耗时很长,而且还可能失败,失败后当然可以修,但是比较麻烦。
方案一还有一个问题,正常Copy Cube元数据还需要copy Cube的Cuboid文件,但是Cuboid文件的大小一般是比HBase表大,如果Copy Cuboid数据,1个project 元数据迁移的时间估计得一整天, 所以我没有Copy Cuboid文件,但是不Copy Cuboid文件会导致迁移后的Cube auto merge时失败,这个问题我简单的改了下Kylin代码,就是merge的输入文件不存在时,则不merge。
正因为方案一有着以上的痛点,我换到了方案二。可以看到方案二的操作步骤很少,效率比方案一高很多。 那为什么我一开始没有采用方案二呢? 因为开始觉得所有Cube完全从头构建会消耗大量的集群资源,而且耗时较长。 但是后来发现D集群资源在白天比较空闲,所以资源不是问题。 耗时长的问题可以通过并发Segment构建来解决,我在具体实施的过程中将Segment的并发调到了20,迁移过程中同时Running的Job达到了500左右。 这同时也体现了我之前开发的全局字典MR构建的意义,现在Kylin JobServer的并发瓶颈已经不再是字典构建,而是Hive客户端和Spark客户端的内存占用。
整个跨机房迁移的细节很多,我就不就一一细说,只介绍几个关键点:
Kylin默认的元数据迁移工具CubeMigrationCLI要求必须是同一个HDFS集群,同一个HBase集群,不支持跨HBase集群元数据Copy。Kylin用CubeMetaExtractor和CubeMetaIngester支持跨HBase集群的元数据Copy,原理是从A集群将元数据从HBase Copy到本地,然后需要手动将本地的元数据Copy到目标节点,最后在目标节点Load进HBase。显然,现有的工具都不能用,我们需要一个可以一键跨HBase集群迁移元数据的工具。
这个实现的难点在于1个Kylin服务只能有1个KylinConfig,并且所有的元数据管理类都是基于KylinConfig的单列,1个Kylin服务中也只能有1个HBaseConfiguration和1个HBaseConnection。 所以实现的关键点是:
为了保证可以及时回滚,我们决定调度脚本支持双机房双跑。实现的基本思路是用一个Python主进程启动两个Python子进程的方式进行处理,发现Cube在哪个集群就启动一个子进程执行之前的调度脚本,将JobServer的hostname作为参数传给子进程。这样的好处是实现简单,能保证对用户透明,未迁移的Cube不受影响,Cube迁移到D后就自动进行双跑,S下线后自动变成D单跑。双跑另外一个好处是可以将迁移的粒度降至Cube,不必要求整个Project1次性迁移完成。
我们知道跨机房带宽是很宝贵的资源,我们应该尽量避免跨机房读写。所以我们迁移Project的原则是HDFS数据迁移到D,我们肯定也会迁移到D;每天上游Hive新增数据很大的Project我们不迁移。
我们知道,Kylin的Cube构建是一系列MR或Spark作业,Cube构建时的跨机房读取可以发生在两处:
最终我们选择的是1,在读取上游Hive表时跨机房。
我们的规范是所有的Cube Schema变更都需要在staging环境进行,测试没问题后再切到线上环境,所以在迁移期间我们只需要禁止用户的一键上线即可(为了提高运维效率,释放我自己,我将CubeMigrationCLI封装到Web UI上并和公司内部IM工具整合,让用户自己可以在Web页面上一键上线),只要保证了线上数据在迁移期间是没有变化的,我们就可以确保S集群和D集群的数据一致性。当然,在迁移完成后,肯定还需要在对数据正确性进行校验,主要就是写个脚本对于Project下所有Cube进行count。
在整个跨机房迁移过程中,由于我们是第一个迁移到D,并在D正式投入生产的应用,踩到了很多坑,有底层依赖的坑,有基础服务的坑,有运维操作上的坑。这里就不详细讲了,仅仅简单提一下:
开始确定采用方案一的原因是,之前和HBase同学协商,HBase的数据迁移是由HBase同学或者SRE同学来完成的,也就是说方案一中的3,4,5是不用我操心的,而且HBase同学也有了迁移其他HBase集群的先例。但是当我让SRE同学迁移HBase数据时,发现处理时间很慢,于是确认了下HBase数据迁移的步骤,发现竟然有6步,而且是在多个节点上执行。执行步骤很多的原因就是由于Kylin的HBase表中有Coprocessor,后来我把这个操作步骤优化到2步,并且由我来执行HBase的数据迁移,但是由于前面提到的原因,我放弃这种了这种方案,采用了方案二。
出现方案更换的原因是我和HBase同学都忽略了Kylin HBase表有Coprocessor的特殊性,而在一开始有小伙伴提出方案二时,被我直接否决了,当时顾虑的原因是前面提到的两点:资源消耗和迁移时间消耗,关键是我当时内心已经倾向了方案一这种正统的HBase数据迁移思路,所以没有对方案二认真考虑和调研。其实这也是我们大多数人决策时常犯的一个错误,一旦我们已经倾向于一个方案,我们就会一心想着这个方案的优点,对于其他方案,我们就会一心挑缺点。这就和"情人眼里出西施"一样。所以我们在确定方案时,一定要放下心中的感性偏见,用理性,逻辑,事实,调研来确定合理的方案。
那么我们如何制定出靠谱的方案呢?
其实可以分四步走:第一步是明确需求,确定我们的目标是什么,我们最在乎的是什么,只有明确了我们最在乎的是什么后,在确定具体方案时,我们才能进行tradeoff,因为没有最好的方案,只有最合适的方案;第二步是调研,可以参考业界已有的成熟系统,可以参考学术界的理论,确定出方案的主体内容和思路;第三步是设计方案,此时只需要确定方案最核心的部分,不要求面面俱到,确定出最有可能的一个或两个方案;第四步是POC,快速验证备选方案的核心部分,确定方案的可行性,剔除不可行的备选方案,明确最终方案,完善方案细节。 这次我出现变更方案的情况就是在调研阶段出了问题。
这次跨机房迁移,我深刻感受到团队的重要性,准确的说,一个强大的,靠谱的团队的重要性。在大公司中,大家的分工都比较明确,即使你再牛逼,甚至你自己也可以做这件事,但是由于权限,由于流程,由于规范,你不可能自己去操作,必须让对应系统负责的同学去处理。 在这次跨机房迁移中,我需要为D机房的Kylin查询设置负载均衡,之前搞的时候,我只是给我们的SRE说了一声,然后过了几十分钟就好了,我没有花费任何精力。 但在这次申请域名负载均衡的时候,竟然专门拉了个群,5,6个人撕了大半天才搞好,你说我内心TM是多郁闷,之所以如此费劲,是因为现在的流程不清晰,对应操作的负责人不明确。不过庆幸的是我所在的离线大数据团队还是十分强大和靠谱的。
其实这也是我们选择工作的标准,选择工作最重要是我们能不能做一些有挑战的,有难度的,有价值的,能帮助我们快速成长的事情,其次是我们所在的团队的水准怎么样,直属leader怎么样,碰上一个水货团队或者水货leader,你个人成长的速度就会大幅降低,最后就是整个公司的技术实力,这一点肯定有影响,但是对个人的影响远没有前两者大。
这次跨机房迁移中遇到了很多基础环境的问题,比如,操作系统相关的,JDK相关的,Hadoop各个系统配置相关的,Jar包冲突的,kerberos问题,兼容性问题等等,基础环境的问题一般追查起来都比较麻烦,耗时费力也没啥价值。 所以公司内部我们必须把各种基础环境统一,一切严格按照流程规范来。
感谢我们团队HBase,HDFS,SRE,Hive,Yarn,Spark同学在迁移期间的给力支持!
本次跨机房迁移在技术上没有什么挑战,Kylin主要是开发了跨HBase集群元数据Copy工具,此外就是写了十几个Python和Shell脚本。本次跨机房迁移重点的是如何保证对用户影响最小,如何设计一个高效的迁移方案,如何保证迁移过程数据的一致性和正确性,如何保证整个迁移过程是平稳的,如何和用户高效沟通并推动用户迁移。
本次跨机房迁移成果如下: