【PPT 下载】最佳实践|揭秘 eBay 如何将 Kylin 迁移至 K8s

Author
潘俍颀
eBay 高级软件工程师,Apache Kylin Committer
2020年 8月 13日


本文是不久前 Kylin on Kubernetes 在 eBay 的实践的进阶篇!

在「718 Apache Kylin Meetup」直播上,eBay 的高级软件工程师和 Apache Kylin Committer 潘俍颀 (Julian) 为大家带来了精彩的分享:他介绍了主要讲述了当前 Kylin 在 eBay 的架构,以及迁移到 Kubernetes 后的使用情况,同时详细讲解了 Kylin 迁移到 Kubernetes 的完整方案和实践的技术细节。

以下是 Meetup 回顾,想要看现场录播的同学们可以点击此链接观看学习~


Kylin 在 eBay 内部概况和架构

目前 eBay 内部有 36 个业务部门在使用 Kylin,主要概况如下:

  • 共有 258 个 Cube,使用了 410TB 存储空间;
  • 每天大约有 400 个 Job 被构建;
  • 日查询量达到 1 百万;
  • 查询的平均时间在 1.15s 左右。

eBay 将 Kylin 迁移到 Kubernetes 之后有以下 4 个优点:

1. Available Time Increment

可以利用 Kubernetes 的 livenessProbe 和 readinessProbe 探针特性实现 Kylin 自动恢复,不需要人工干预,从而提高可用性,在迁移到 Kubernetes 之后我们的可用性几乎达到 100%;

2. Expansibility

在 Kubernetes 上可以很方便地实现扩展和收缩;


3. Maintainability

维护起来更方便:在 Kubernetes 上,使用 ConfigMap 和 Secret 就可以轻松完成机器上一些配置的改变,它们可以自动发布到相应的 Pod 上;


4. Cost Saving

将 Kylin 迁移到 Kubernetes 之后,原本一些需要自己维护的监控就不需要了,Kubernetes 可以帮你监控各个 Pod 的资源使用。当清楚明了资源的使用率之后,可以对资源进行更灵活的更改或调配,就可以避免造成不必要的浪费,从而达到精准的效能。


上图是 eBay 内部的 Kylin on k8s 架构图,分为以下几部分:

  • 顶部是 BI 工具和 webapp 流量入口;
  • 左边是数据源,包括 Hive 和 Kafka 数据源;
  • 左下方是构建引擎,由 Map Reduce Engine 和 Spark Engine 组成;
  • 右上方是 Kylin 的存储,现在主要是 HBase,但在升级到 v3.1 之后,会尝试用 Parquet 来作为存储;
  • 右下角是依赖的一些服务,比如 elasticsearch 和 kibana 等。


本文主要讲解架构图中间的部分,即 Kylin 本身,分为左右两部分。左侧是 Kylin 本身的 Pod 和服务。在这部分中,上方是 Kylin 的 Pod,分为三种类型:

kylin-all既能构建又能查询
kylin-query只用于查询
kylin-job只用于构建


这部分服务主要暴露出的是能够支持查询的 Pod。而下方是用于支持 Kylin 实时功能的 kylin-receiver 的 Pod。

右侧则是一些 Ecosystem 组件:

  • 上方的 memcached 主要用于 Kylin 查询缓存,其次也用于存放用户登陆后的 session id;
  • 下方则是用来管理 memcached 的工具:memcached-admin。这部分还包括了另外两个 Pod,一个是 cronjob,主要做一些清理和备份的工作;另一个是集成的查询性能分析系统 jaeger tracing,它提供了友好的界面,当在代码中注入片段时,可以方地看到各个阶段的用时,因此更容易去定位问题。同时,这里还使用了 Filebeat 作为 Kylin Pod 里的一个 side-car container,它可以把 Kylin 的 Log 发到 elasticsearch 做持久化,方便我们集中查看所有 Kylin Pod 的 Log。


Kylin on K8s 实践

Kylin on K8s 所需镜像

在迁移到 Kubernetes 之前需要构建所需镜像,我们现在主要把镜像拆成两部分,分别是 hadoop-client 和 Kylin 本身。


I. hadoop-client 镜像文件


上图是 hadoop-client 的镜像文件。从左边的目录结构中可以看到,其中包括 conf,hdp-clients 以及 Dockerfile。


conf 目录

此目录底下是配置文件,由于 hadoop-client 的配置文件比较稳定,基本没有改动的需求,因此我们直接将配置文件打包在镜像里面。如果是经常需要改动的配置文件,建议把配置文件放在 Config Map 或者 Secrets 里,与镜像分离会更好一些。


hdp-clients 目录

此目录中是我们事先下载好的 hdp-client 的包。这样构建镜像会更快,如果对这种事先下载的方式有顾虑,可以采用在 Dockerfile 里通过 wget 下载的方式。


Dockerfile 文件

文件具体内容如上图右半部分所示。它是基于 centos 的镜像来构建的,会安装一些 Kylin 需要的 Hadoop 组件,包括 Hadoop, HBase, Hive, Spark 和 Zookeeper。     


II. Kylin 镜像文件


上图展示的是 Kylin 的镜像文件。Kylin 镜像文件的目录分为 Kylin 源码,脚本目录和 Dockerfile。

将 Kylin 源码事先放在目录下面可以使镜像构建得更快,并且这样构建得到的镜像会比在线拉取源代码再解压后构建得到的镜像更小。

bin 目录下的脚本分别是:启动程序 bootstrap.sh, Kubernetes 探针检查脚本 check-liveness 和 check-readiness,定时清理日志的脚本 clean-log。

经过我们的测试,这样构建得到的 Kylin 镜像上传到 Docker Hub 后,大小大约是 1.2G。为了能够更快地下载镜像,我们会尽量把改动不频繁的部分放在前面,这样在 pull 镜像的时候,只需要下载最上层改动过 layer 而不需要下载之前相同的 layer,可以更快让镜像被 pull 下来。

除了以上的两个主要的镜像之外,其他用到的 ecosystem 的 Docker image 地址为以下:

  • memcached
    https://hub.docker.com/_/memcached
  • memcached-admin
    https://hub.docker.com/r/jacksoncage/phpmemcachedadmin
  • jaeger-tracing
    https://hub.docker.com/r/jaegertracing/jaeger-collector
    https://hub.docker.com/r/jaegertracing/jaeger-query
  • filebeat
    https://hub.docker.com/_/filebeat

有了以上的镜像文件,就可以通过 docker build 命令来构建本地镜像,然后通过 docker push 把相应的镜像上传到 docker hub 上。建议创建一个 jenkins 任务来处理制作和上传镜像的工作。


Build docker image with tag:

docker build -t {url}/{folder}/{image-name}:{image-version}


Push docker images:

docker login
docker push {url}/{folder}/{image-name}:{image-version}


下图为 eBay 内部的 docker hub 上 Kylin 相关的所有镜像,包括 ecosystem 的镜像,Kylin 以及 hadoop-client 镜像。


部署 Kylin on K8s 服务

准备好所需镜像,就可以开始在 Kubernetes 上搭建 Kylin 服务了。下方列举了 Kubernetes 的一些概念,在之后创建 Kylin 的服务时候会用到。


创建完 Namespace 后,就可以在相应的 Namespace 下创建 Kylin 的 Service。Kubernetes 中 Service 的作用就是把一组相同功能的 Pod 暴露出来,组成一个服务。这里的 kylin-service 会把所有带有 App 为 Kylin 且 Query 为 True 标签的 Pod 组成一个负载均衡的整体服务,并通过 Port 和 TargetPort 配置端口转发。Receiver-service 的作用是通过和 statefulset 结合,为每一个带有 kylin-receiver 标签的 Pod 暴露出固定的域名。


Kubernetes Objects:

  • Namespace
  • Service
  • Pod
  • Volumes
  • Deployment
  • StatefulSet
  • ConfigMaps
  • Secrets


首先可以通过下图两种方式来创建所需的 Namespace,它代表一个虚拟的 Cluster。如果以环境作为区分,我们可以将 kylin-prod 作为一个 Namespace 来表示生产环境,kylin-qa 和 kylin-dev 来表示测试和开发环境。

创建完 Namespace 后,就可以在相应的 Namespace 下创建 Kylin 的 Service。Kubernetes 中 Service 的作用就是把一组相同功能的 Pod 暴露出来,组成一个服务。这里的 kylin-service 会把所有带有 App 为 Kylin 且 Query 为 True 标签的 Pod 组成一个负载均衡的整体服务,并通过 Port 和 TargetPort 配置端口转发。Receiver-service 的作用是通过和 statefulset 结合,为每一个带有 kylin-receiver 标签的 Pod 暴露出固定的域名。

在 Kubernetes 中常用的配置文件通过创建 ConfigMap 和 Secrets 以 Volume 的形式挂载到 Pod 的 Container 中。而 ConfigMap 与 Secret 的区别在于,后者在前者基础上做了一层加密,在一定程度上更安全一些。一般含有密码等敏感信息的配置文件都会使用 Secret 作为配置文件的形式,因此 Kylin 的配置文件几乎都是以 Secret 的形式存储在 eBay 的 Kubernetes 上。

kylin-all.yaml 和 kylin-receiver.yaml 部署文件和分析注释,以及关于 Ecosystem 服务的详细信息,包括配置文件和部署文件都可以在 Apache Kylin Wiki 中查看。


小贴士

以下是一些关于我们对某些服务的配置文件改动的 tips,供大家参考。

下图是关于 Tomcat 配置文件的改动,包括 context.xml 和 server.xml 两个文件。context.xml 中配置 memcached 作为 Tomcat 的 Session 存储。server.xml 里主要配置了 https 所用到的证书和日志的格式以及 rotate 策略。


下方两张图是关于日志收集服务中一些配置文件的修改,在 Filebeat 的配置中添加了多行日志合并的功能,比如可以将多行的 error trace 合并为一行,方便查看。除此之外,为了更好的分析日志,我们在 Elasticsearch 端也做了 Pipeline 来根据 Pattern 解析日志,为之后更详细的分析日志提供了可能性。


展望

下面是我们对 Kylin on k8s 未来的展望以及希望做出的改进:

  • 加强自动化故障切换机制
    例如当时考虑到性能,我们在 kylin-receiver 中挂载了本地磁盘,但在 Kubernetes 的节点的磁盘出现故障时,需要人工干预去删除本地磁盘后,才能避免 Pod 被再次分配到原来出故障的节点;

  • 更好地压缩镜像大小
    镜像越小,上传和下载的速度越快,使用轻量化的 Linux 镜像(例如 alpine, busybox 等)作为基础镜像也许是更好的选择;

  • 统一部署实现资源隔离
    把需要的服务,部署文件和配置整合成一个 Kubernetes 的 List 来统一部署,从而创建各个团队自己的 Kylin Cluster来实现资源隔离;

  • 自动伸缩
    繁忙时自动扩展,闲暇时自动收缩 Kylin 的资源。


关于作者

潘俍颀 (Julian),eBay 高级软件工程师,Apache Kylin Committer。在 eBay 担任 Kylin 的开发以及运维。不会 Kylin 的运维不是一个好全栈 🙂



想第一时间获得 Apache Kylin 资讯,请扫二维码,关注 Apache Kylin 官方微信公众号。