在 1 月 4 号 ECUG 技术大会的分享中,Kyligence 的 CEO Luke Han 为大家带来了主题为《Apache Kylin 云原生架构的思考及规划》的精彩演讲,分享了 Kylin 如何拥抱云原生这一趋势。欢迎希望参与打造云原生 Kylin 的同学踊跃联系我们 [email protected],邮箱主题请备注「参与 Kylin 云原生开发」,下一代 Kylin 等着你~
以下为演讲实录。
各位同学,大家下午好!非常高兴今天来到这个场合,给大家介绍一下 Apache Kylin 在接下来云原生方面的变化和思考,以及我们在这方面最近的工作。
01 关于 Apache Kylin
首先介绍一下 Apache Kylin 这个项目,Kylin 是我们五六年前在 eBay 中国研发中心孵化,完全由中国人设计、研发、贡献出来的第一个 Apache 顶级项目,我们在这方面的确踩了一条路出来。今天我们看到 Apache 软件基金会里有十几个来自中国的项目,包括华为、百度、阿里等等,我们看到在全球的开源社区里有越来越多中国人的声音和力量。
Apache Kylin 是做什么的?它是一个分布式引擎,为 Hadoop 等大型分布式数据平台之上的超大规模数据集通过标准 SQL 查询及多维分析(OLAP)功能,提供亚秒级的交互式分析能力。也就是数据集很大的情况下,业务人员需要快速分析的时候,需要这么一个数据集市的解决方案,把数据汇总好,能够让你的业务人员用起来很快很爽,而不是让他再跑一个脚本。
我们看一下 Kylin 的基础架构。Kylin 是基于 Hadoop的,使用 MapReduce/Spark 进行预计算,并且使用 HBase 保存预计算的中间结果。通过 Calcite 来将 SQL 解析为执行计划,并且将最复杂的现场计算工作省去,直接利用预计算准备好的中间结果,达到加速查询的目的。
在当年的时候其实做得还挺好,但是这几年遇到了巨大的挑战。
02 挑战来临
第一个挑战叫云原生, Hadoop 的架构在云原生上是非常大的痛苦,而且是反云原生的,需要去解决的还有很多。我们 Apache Kylin 项目最原始的一些人出来创业,我们的创业公司叫 Kyligence ,在上海。我们成立之后,自己做了一个项目叫“逃离动物园”,因为整个 Hadoop 都是动物,猪、蛇还有蚂蚁、蜜蜂等等。
今天云计算在吞噬所有的世界,所以你如果不去做,你就被人吃掉了,赶紧去做。这张图背后的故事今天就不讲了,这两年发生的故事太多了。
回过头,来分析下我们想干的这件事情好在哪里,不好在哪里。可以看到整个 Hadoop 的曲线,对于整体私有部署还不错,还很便宜。但是你会发现整个学习曲线、计算存储、版本管理之类的相当令人痛苦。和 Hadoop 相关的项目有两三百个,你要去把这个事情玩得溜,要把版本弄清楚,要把牌打清楚,非常复杂。让这个东西上云的时候,你会发现更痛苦。
如果你有 PB 以上的数据量放在 Hadoop 里,我相信你靠一个人是摆不平的。如果你上面老板还想要做复杂点的东西,你发现养 10 个人的团队是必然的,而且还要天天晚上起来,因为跑 batch 的时候往往在晚上。
当时,我们发现 Kylin 的存储 HBase 也有巨大的挑战。它的挑战在于不是一个真正的列存,它可以很好地写优化,但是整个索引等等都有很大的挑战,而且运维相当困难。当然现在已经很好了,我们最早用 v0.98,那时候整个挂掉都是很正常的。另外一个是它缺乏二级索引,HBase 今天的版本里面依然没有很好的二级索引。我如果做查询,只做一个维度上的高查询,是可以做到的,但是业务用户永远不是这么想的。包括无数据类型等等,都有很大的挑战。而且放在云上面的挑战更大,日积月累以后数据占用的资源就很大了。我不是说它不好,它还是相当不错的。
当时我们看到了这些问题,但当时我们严重依赖 Hadoop ,今天我们要做的是想要怎么样逃出去,又不能完全从头写一个,外面那么多用户在用。所以我们想的第一件事情是云上有哪些好的东西,云上的特点在哪里。讲到云上的时候对象存储,云上对象存储很便宜,可以放很多的数据,但它不是一个 native 的存储,也就是说它比 HBase 直接访问磁盘要慢不少,今天我们在云上一定要加速,一定要在这方面做很多工作。好处是放在云上很便宜。
另外一个是在整个资源管理上,一般来说云上现在更多的是用 Kubernetes ,你在 Hadoop 里还得去做选型,很复杂。还有其他一些问题,其中最重要的一点叫存储与计算分离,不能说老是往云上方放数据,如果老板已经让你买了几千台机器,放在机房里不用,是沉没成本,但是放在云上就不一样了。
03 Apache Kylin 如何适应这一趋势?
回过头来,我们希望在整个云上面做几样东西,第一个是希望能够做到从整个持续集成,从容器编排到微服务和敏捷开发,都可以在新一代架构里面做出来,来看看我们是怎么去做的。
我们第一步是做重构,这件事情大概发生在 2014、2015 年的样子,我们创业前后的样子。这是最早的麒麟架构,其实我们最早设计的时候比较好的一点,我们完全是面向接口编程的,所以每个模块做得非常好,从源数据到执行引擎到存储到访问到 Server ,全部都是放开的。但还不够,所以我们做了一件事情叫可插拔的架构,我在某一年的 ECUG 讲过这个概念。也就是说我们把每一块都抽象出来,把 Cube Builder 这块全部变掉,这个好处也就是我们有能力去随时随地换掉某一个引擎。理想是很好的,但是现实确实很骨感。比如你想换个存储引擎,换换挺快的,让它成熟我们至少花了两年,这是一个过程。这是第一步,好几年前就做完了。
我们干完这件事情之后,各个地方都可以变成一个所谓的 Adaptor 的结构,我们最早只能支持 Hive source ,也就是说我们只能从 Hive 读数据,今天我们已经可以从 Kafka 等等,甚至前段时间做了一个阿里的接口,都做出来了,很容易,因为可插拔的架构在这儿了。
第二件事情是非常重的改变。最早的时候我们完全用 MapReduce 去做整个底下的计算,那个时候 MapReduce 做得确实好,坦率讲今天我的大量客户还在用 MapReduce ,原因是稳定,慢是很慢,但是真的稳定。但有的时候 MapReduce 并不 work,尤其我们想要扔到云上去,尤其是我们想要逃出这个动物园的话。所以我们第一个决定是用 Spark。
Spark 有几个好处,我们之前的计算是一层一层算的,简单地说,每一层是一个 Mapreduce Job,我这个 Job 做完才能做下一个,下一个做完才能做下一个。但是这里最大的问题是两个:一个在于数据会落盘,每一层计算完了以后都会 flush 到 HDFS 之上,下一个层才能去读;第二个问题在于,每一层都是一个 MapReduce Job ,所以会带来一个巨大的 job 的 overhead,因为你起一个 job 和关一个 job 是有时间差的,整个构建有很多层,时间就很长很长。所以我们当时就整个换成了 Spark,用 RDD 的方式,好处在于整个过程,一个 Spark Job 就过去了。
坦率讲,在这个场景下我们碰到了若干的坑,尤其是内存相关的,因为数据量太大,所以那时候 Spark 经常会爆,现在比较稳定了,我们有比较好的方式。这是整个 Spark 当时的改变。这个版本大概是在 2015 、2016 年的时候出来的,我们花了很多力气去做稳定性。
这是整个实现,以前每个 MapReduce Job 都是一个 for 循环,计算复杂度是非常大的。你想想看去加载几百 TB 数据计算的时候,是几个小时甚至十几个小时的过程,十几个小时的 for 循环。现在一个 Spark Job 提交上去之后就结束了,所有的东西在一个 Job 处理。这里最重要的是内存配置,不要把数据爆掉,这块 Kylin 社区有相当多的经验和实践可以给大家看。
不仅是 build ,整个过程都用 Spark 去做,这个时候你完全不需要依赖于 Hadoop 的东西了。这是一个对比,在 2017 年的 Spark 会议上介绍了,当时对比了一些相应的 MapReduce 的性能对比,一个非常粗的结论是我们可以节省一半的时间,当然这跟数据有关,有些数据集上反而会慢,这是肯定的,需要调优。
干完这件事情之后,我们另外一个事情是要运维了,因为云原生的东西一定要想办法更好地去运维它,所以 Docker 化是我们的第一步。我们在 2016 年 Docker 很火的时候就做了一个版本出来,这个东西一直在,然后整个查询服务是完全可以无状态化的,完全可以容器化了,当时我们就全部解决掉了,一个 Docker 下载下来就好了。现在查询服务本身无状态,都可以做到,这个很简单。
Docker 有了后还缺一样东西——天下大火的东西 Kubernetes 。你有了 Docker 已经去多中心了,耦合性也没有了,怎么去编排它,这块社区在开发中,快结束了。
怎么用 Kubernetes 去管理所有跟 Kylin 相关的东西,这是非常重要的。尤其在云上的时候,我们自己的云版本已经做到自动伸缩了,也就是说我可以在数据量进来之后,通过规则对资源的使用去做伸缩。这个得益于整个 Docker 化和 Kubernetes 化,可以做自动化的编排。
第二点,Kubernetes 化之后,给我们带来一个最大的变化,就是我们之前要依赖云上的 Hadoop ,你要做一整套东西的时候,要先去弄一堆东西出来,然后再培育出我们的东西出来,前前后后加在一起最乐观的情况下,EMR 的资源足够的情况下都需要 30 分钟,这不是我们的问题,是 Hadoop 集群初始化太慢了。今天我们的云版本已经完全拿掉 Hadoop 的情况下,现在最快大概 2 到 3 分钟就可以把一个集群完全性地跑出来,几行命令出来就可以了,这才应该是云上应该有的方式。
这是怎么使用 Kubernetes,我们现在有很多开源用户,他们在生产,已经把这块东西注册到他们内部上去了,用得还蛮好的,看到很多不错的方式,可以做到无人值守、无人运维。
这还不够,我们现在准备改动最深的一块:存储。之前提到了 Kylin on HBase 方案的诸多局限性,所以我们在商业版里用 Parquet 代替了 HBase。这个方案正在贡献回开源社区,目标是在今年上半年做出来,在下一代Kylin里面就没有 HBase 了,这套东西很复杂,因为存储改变带来的各种调优,确实相当复杂。而且有太多的东西进来以后,你要去做各种妥协,甚至有些场景之间是互斥的,你怎么去做,我们花了蛮多的力气,无所不用其极,压榨最后一分能力。
社区已有 Kylin on Parquet 分支。我们 2018 年底做的简单测试,证明我们把同样的东西放在 Parquet 上和放在 HBase 上,性能上差不多,甚至有些东西 Parquet 好一点,有些东西 Parquet 差一点,但是那时候没有做调优。也就是存储换成 Parquet 能够跑通我所有的测试,可以全部接得住。所以现在我们在紧锣密鼓地做这个事情,这还是蛮有挑战的。
最后一块,前面的五步做完了之后,扔到云上去就可以了,还差一块,也就是查询引擎。其实做到这个地方,作为一个分析的工具,SQL 的查询引擎是最难的,SQL 的查询引擎我们最早用的是 Apache Calcite, Calcite 应该是现在业界用得最多的 SQL 引擎。
当时我们用起来挺好的,但我们发现在大数据场景下就不行了。SQL 进来,plan 出来,优化好,从存储层将数据拿出来就好了,很快的。但是返回结果集的数据量非常大的场景下,尤其在咱们中国人多,在我们这里,返回来几百万条太正常了。所有的场景,我要把数据取回来,你会发现没有任何办法去缩小最终的数据集。Calcite 是一个单线程的设计,所以这个时候麻烦就大了,底下的存储引擎的计算速度很快,可能十几二十个毫秒就把数据取回来了,结果到Calcite这里是单线程,就只能等 Query 节点的 CPU 资源了,所以还是不合适的。
我们现在花了巨大的力气把它改成了 Spark 的方式,完全变成分布式的。变成这个以后,你会发现以前 cube 是因为存在 HBase 上,它是分布式的,所以我能够在各个节点把数据拉回来。收集完各个节点数据进行 Filter 开始就慢了,因为是单线程的。所以我们改变了一个方式,现在完全是用分布式了,所以你可以看打在上面的 sort 都是分布式的,你不需要在一个进程进行大量数据的 sort。这个情况,今天很多客户说在 Kylin 的节点上会去做优化,但是有时候不能解决性能瓶颈,只有这种分布式方式去做才能根本上解决性问题。但是这块的坑更大,因为这里面太复杂了。我们现在花很多力气,现在也在开发和测试,我们在看是不是可以和社区一起去做,我们把大部分的东西已经做完了。
2019 年 12 月发布了Kylin 3.0,3.0 是纯实时的架构。我们今年的目标是去做 Apache Kylin 4.0,希望 4.0 能变成真云原生,真实时的一整套。而且我们希望做到更好的一点,叫批流一体化,也就是说一个数据模型不用管数据到底是历史进来还是流式进来,对于业务用户,不应该切换不同的平台,只要去查就好了,只要去用就好了,不需要维护两套。如果我们可以做到前面讲的计划,完全是在云的整个场景下,会大大地降低整个运维难度和使用门槛。
欢迎希望参与打造云原生 Kylin 的同学踊跃联系我们 [email protected],邮箱主题请备注「参与 Kylin 云原生开发」,下一代 Kylin 等着你~
我们的整体目标,第一是轻量级的架构,在云上我们基本上只会依赖两三样东西:一个是 Spark,这是肯定要的;第二个是 Kubernetes;还有一个是云存储。第二个目标是在云上自动伸缩起停,根据负载来伸缩,而不是一直放在那里。最终就是 TCO ,整个成本要降低下去。
以上是我们对 Kylin 往云原生这个方向转型的思考以及做法,我们非常谨慎,原因在于数据是用户的核心资产,我们非常敬畏这件事情。在转换的过程中,还是需要巨大的工作要去把它做得更加好、更加完善。谢谢各位!
了解更多大数据资讯,点击进入Kyligence官网