写点什么

一站式全覆盖数据 I/O 平台 - Alluxio 与 Aunalytics 的完美结合

作者:Alluxio
  • 2022-10-26
    北京
  • 本文字数:5248 字

    阅读完需:约 17 分钟

一站式全覆盖数据 I/O 平台 - Alluxio 与 Aunalytics 的完美结合

一、引言

Presto 是开源分布式 SQL 查询引擎,可以对从 GB 到 PB 级大小的数据源进行交互式分析查询。Presto 支持 Hive、Cassandra、关系型数据库甚至专有数据存储等多种数据源,允许跨源查询。(详见参考[1] )

图1 Presto层次架构图(图源Presto官网)


无处不在的 Presto

当今大规模的互联网公司都在使用 Presto。

Uber 将 Presto 用于 SQL 数据湖,每周有超过 7000 名活跃用户,每天在超过 50PB 的 HDFS(Hadoop Distributed File System)数据上运行 50 万次查询。

字节跳动对 Presto 进行了广泛的应用,例如数据仓库、BI 工具、广告等。字节跳动的 Presto 集群拥有上万个计算核心,每天处理约 100 万次查询,涵盖 90% 以上的交互式查询。这极大地减少了查询延迟并节省了大量计算资源。

Meta 公司(Facebook)使用 Presto 对多个内部数据存储进行交互式查询,包括 300PB 数据湖。每天有超过 1,000 名 Facebook 员工使用 Presto 运行 30,000 多个查询,平均每个查询扫描超过 1 PB。

腾讯将 Presto 应用于内部的不同业务场景,包括微信支付、QQ、游戏等关键业务。日均处理数据量 PB 级,P90 查询耗时为 50s,全面提升各业务数据实时分析性能,有效助力业务增长。

阿里数据湖分析集成了 Presto 的联合查询引擎能力,不仅让阿里云众多用户体验了大规模的 Serverless 云服务,也积累了许多成功的业务用例,比如日志数据分析和基因数据分析等,这些案例表明了 Presto 应用广泛,分析能力强大。

图2 各大互联网公司Presto性能展示数据部分来源Presto官网


Presto 系统架构

Presto 集群由一个 Coordinator 和一个或多个 Worker 组成。Coordinator 负责接纳、解析、规划和优化查询以及查询编排,Worker 负责查询处理。Presto 通过 Connector 适应底层不同类型的数据源,以便访问各种数据源中的数据。如图 3 显示了 Presto 架构的简化视图(详见参考[2] )。

图3 Presto 架构图

传统方式部署 Presto 存在的问题

作为一个分布式架构的系统,Presto 为数据查询和处理提供了高效便捷的方法。随着数据量增大,为了保证数据查询处理的效率,Presto 集群规模也要扩大。例如上文提到的 Uber、字节跳动和 Meta 等公司每天查询的数据量是 PB 级别,一个 Presto 集群的节点数量已经上千。当数据量远超单机处理能力时,分布式架构相比于集中式架构的优势就体现出来了,但是对于一个规模庞大的分布式集群,持续高效地处理数据,将会面临一系列的问题:

  1. 对于一个规模庞大、节点数量上千的 Presto 集群,如果没有自动化部署工具,采用传统方式一个一个部署 Presto 节点,耗费的时间是难以想象的。此外对于部署好的 Presto 集群根据业务进行调优,需要不断修改 Presto 节点的配置信息,按照传统方式逐个修改配置信息,耗费的人力和时间成本也是难以忍受的。

2. 传统部署 Presto 集群,当其中某个节点发生故障时,无法做到自动重启或者动态加入新的节点以维持集群数量,此时如果正好发生故障的是 Coordinator 节点,则整个集群将陷入瘫痪,导致服务不可用。

3. Presto 主要应用场景是即席查询,比如 Uber 和滴滴等网约车公司,查询业务高峰时段主要在白天,晚上基本没有查询。如果晚上闲置的资源不能加以回收利用,将会产生很大的资源浪费。此外,当业务高峰期的查询负载超过当前集群的承载能力时,如果不对集群立刻按需扩容,也会对业务产生很大的影响。

使用 Kubernetes 部署 Presto 集群,将云原生与 Presto 相结合,借助 Kubernetes 便捷部署、自动化运维和弹性伸缩等优点,解决上述提到的一系列问题。

二、使用 Kubernetes 部署 Presto

Kubernetes,也被称为 K8s,是一个用于自动化部署、扩展和管理容器化应用程序的开源系统,目前已被业界广泛接受并得到了大规模的应用。Kubernetes 集群由控制平面和 node 组成。其中 node 上运行由 Kubernetes 所管理的容器化应用,也就是 Pod。控制平面管理集群中的 node 和 Pod,为集群提供故障转移和高可用性,而集群也会跨多个主机运行(详见参考[3] )。

图4 Kubernetes部署Presto集群方案


如图 4 所示为本次测试所部署方案,Deployment 负责创建、更新、维护其所管理的所有 Pods。Presto Coordinator 和 Worker 进程分别运行在 Pod 中,针对 Presto 集群内 Coordinator 和 Worker 分别配置不同类型的 Deployment 来进行管理。Deployment 可以保证集群内可用 Pod 的数量,实现弹性伸缩,维持集群可用性和稳定性。

Configmap 用来存储配置文件,Coordinator 和 Worker 的配置信息分别通过 Configmap 进行存储,每次进行配置更改,只需要修改 Configmap 里面的配置信息,Coordinator 和 Worker 就会更新相应的配置信息。

Service 会对同一个服务的多个 Pod 进行聚合,向集群提供一个统一的入口地址,通过访问 Service 的入口地址就能访问到后面的 Pod 服务,实现负载均衡和服务发现。在 Kubernetes 部署的 Presto 集群中,Coordinator 将自己的地址注册到 Service,Worker 通过 Service 中的域名地址与 Coordinator 连接,从而实现 Presto 集群的服务注册与发现。

在 Kubernetes 部署 Presto 方案中,Deployment 负责创建和管理 Pods,Configmap 负责存储配置信息,Service 负责服务注册与发现。Deployment、Configmap 和 Service 三类资源相互配合,保证了 Presto 集群持续高效工作。

Kubernetes 部署方案的优点

通过合理设置 Deployment、Configmap 和 Service 等资源对象,使用 Kubernetes 部署 Presto 集群,将 Kubernetes 的运营优势与 Presto 技术优势相结合:

√ 便捷部署:在 Deployment 中设置 Coordinator 和 Worker 的副本数量,Configmap 设置配置信息,Service 设置 Presto 集群提供服务的入口地址。将上述三类资源对象提交到 Kubernetes 中即可完成 Presto 集群配置,比如设置 Worker 副本数量为 1000,提交之后即可创建 1000 个 Worker Pod,每一个节点的配置信息从 Configmap 文件中读取。只需要编写好资源对象文件,提交到 Kubernetes,即可创建 Presto 集群,后续可以通过修改 Configmap 文件更新各个节点的配置信息。通过 Kubernetes 部署 Presto 集群减轻了配置、部署、管理和监控容器化 Presto 应用程序的负担和复杂性。

√ 自动化运维:可以更方便地和 Prometheus 结合,通过 Prometheus 可以实现对整个集群的监控数据采集、存储、分析以及可视化。有效监控 Presto 集群,当发生故障时可以针对性修复,从而维持集群稳定,保证高可用性。

√ 弹性伸缩:当业务量激增,自动扩容 Presto Worker 节点,满足业务需求;当业务量处于低谷,自动缩容 Presto Worker 节点,节省运行成本。

Kubernetes 部署方案的问题

传统方式部署 Presto 集群是以物理机的方式运行,相比之下,在 Kubernetes 上部署 Presto 集群是以容器的方式运行。尽管 Kubernetes 部署方式带来了很多优点,但是容器方式和物理机方式的性能差异仍然未知,下面的测试将重点对比分析两种不同部署方式的性能差异。

三、对比测试评估

测试介绍

基准测试的目的是比较物理机的 Presto 集群和部署在 Kubernetes 的 Presto 集群的性能差异。因此,测试方案分为物理机方案和 Kubernetes 方案。Presto 物理机集群的结构是 1 个 Coordinator 和 5 个 Worker;Kubernetes 集群是在 6 个 node 之间分配了 1 个 Coordinator 和 5 个 Worker。在物理机集群中,用户直接通过 Presto 客户端向 Coordinator 发起查询请求,Coordinator 将任务分配给 Worker;如图 5 所示,在 Kubernetes 集群中,首先利用 6 个 node 部署 Presto 集群,Presto 客户端向 Kubernetes 中的 Coordinator 发起 SQL 查询,Coordinator 将任务分配给 Worker。

图5 基准测试系统架构图

TPC-DS

沿用目前业内的普遍测评方法,本次测试采用 TPC-DS 作为 benchmark,它在多个普遍适用的商业场景基础上进行了建模,包括查询和数据维护等场景(详见参考[4] ),同时提供了一系列能够代表系统性能的评估指标。简单来说,TPC-DS 使用了一个真实的商品零售业务场景来测试系统性能。它构建了一个大型跨国零售公司的业务模型,模型里不仅包含了多家专卖店,同时还包含了线上销售业务,以及库存管理系统和促销系统(详见参考[5] )。由于 TPC-DS 是以真实场景为原型,在业内能够起到比较好的测评效果,从而成为了当前 SQL 引擎测试最常用的 benchmark(详见参考[6] )。

集群配置

四、测试结果

为了保证本次测试的结果具有更加广泛的意义,分别选取了 TPC-DS 不同的查询类型进行测试,包括即席查询、报告查询和迭代 OLAP 查询三种类型:

即席查询:这类查询主要的应用场景是通过查询来回答即时和特定的业务问题。即席查询和报告查询之间的主要区别在于系统管理员在规划即席查询时可用的预知程度有限。图表中为 q19, q42, q52, q55, q63, q68, q73, q98。

报告查询:定期执行的查询,这类查询主要是定期获取到有关企业财务和运营状况。图表中为 q3, q7, q27, q43, q53, q89。

迭代 OLAP 查询:OLAP 查询通常用于探索和分析业务数据以发现新的和有意义的关联关系和趋势。图表中为 q34, q46, q59, q79, q96, q48。

图6 Kubernetes VS 物理机查询时间对比图


如图 6 所示,纵坐标为查询时间,单位是毫秒;横坐标为查询任务分类,图表中所显示的每个查询任务的时间实际为 4 次查询时间的平均值。可以看出,在不同的查询分类中,Kubernetes 部署的 Presto 集群的平均查询时间稍微短于物理机部署,两者时间差基本保持在几秒之间,考虑到本次测试环境部署在云服务器上,不同时段使用云服务器,性能会有不同程度的偏差,几秒之间的性能波动是可以容忍的。排除本次测试使用的云服务器产生的波动,可以说明 Kubernetes 部署与物理机部署在性能和效率上几乎相差无几。所以针对不同类型的查询,Kubernetes 部署的 Presto 集群相比物理机部署在查询速度上并没有损耗,性能与效率几乎没有损失。

五、结论

Kubernetes 部署 Presto 集群的方案减轻了配置、部署、管理和监控容器化 Presto 应用程序的负担和复杂性。实现了 Presto 集群的自动配置以及工作节点自动扩展,保证了 Presto Coordinator 的高可用,通过与 Prometheus 集成可以更好地实现集群监控。在 Kubernetes 上部署 Presto 集群将这两种技术的架构优势和运维优势结合在一起,相比于传统方案,在没有性能损耗的情况下,实现了对 Presto 集群的动态扩展、便捷部署管理和稳定维护。

六、问题排查

在性能对比测试的过程中,并非一帆风顺,前期测试中出现了一些问题,导致 Kubernetes 部署的 Presto 集群性能无法完全释放,与物理机部署的 Presto 集群性能相差很多。现将测试过程中遇到的一系列问题以及相应的解决方法单开一节进行总结,方便读者在实际部署过程中遇到类似问题时可以得到借鉴与参考。

节点分配不均

Kubernetes 部署 Presto Pod(Master 或 Worker)时,如果使用了 Deployment 而非 DaemonSet 进行部署,会集中在几台物理机上(多个 Presto Pod 会同时运行在一台物理机上),有些物理机没有 Pod 运行。

图7 Presto Pod 分布情况


解决方法:出现这种现象的原因是 Presto Pod 所需的 CPU 和内存远远小于主机的上限,因此可以在一台物理机上运行多个 Presto Pod。造成的影响包括同一主机中的 Pod 互相抢占资源,导致效率下降,以及部分主机(没有 Presto Pod)闲置,造成资源浪费。解决方案是可以通过 resources requests 和 limits 合理设置 Presto Pod 运行所需的资源,使其均匀分布到各个主机上。

资源利用率过低

与物理机相比,Kubernetes 部署的 Presto 无法使用所有 CPU,只使用一个 CPU 核,每个节点的吞吐量有限,导致查询时间明显变慢。

图8 Kubernetes vs 物理机资源利用情况


解决方法:出现这种现象的原因是没有设置 Presto Pod 调用主机资源的最大限制。最大限制可能是默认值,无法达到主机的理想资源配额。影响是 Presto Pod 使用的资源严重受限,导致查询任务执行效率低下。解决的办法是合理设置 Presto Pod 可以调用的宿主机的最大资源限制。

针对上述两个问题,在 Kubernetes 中采用 requests 和 limits 两种限制类型来对资源进行容器粒度的分配。这 2 个参数是通过每个容器 containerSpec 的 resources 字段进行设置的。requests 定义了对应容器需要的最小资源量。limits 定义了这个容器最大可以消耗的资源上限,防止过量消耗资源导致资源短缺甚至宕机。设置为 0 表示对使用的资源不做限制。如下图所示,设置 request 的 cpu 为 3,memory 为 6Gi,这样保证一个 pod 运行在一个节点上,解决了 Pod 在节点上分配不均的问题;设置 limit 的 cpu 为 8,memory 为 8Gi,为节点的最大资源配置,解决了性能受限的问题,同时也避免了使用资源超过节点最大资源引起的 Pod 崩溃重启问题。

图9 资源配置

Presto 性能如何调优

解决方法:对于 Kubernetes 部署集群,需要设置 CpuCoreRequests、CpuCoreLimits、MemoryRequests 和 MemoryLimits。CpuCoreLimits 和 MemoryLimits 需要设置为宿主机配置的最大值,这样在执行任务时就不会受到限制。在此基础上,在 Presto 应用层面还需要设置一个合理的 query.max-memory-per-node。query.max-memory-per-node:查询可以在任何一台机器上使用的最大用户内存量,如果不进行设置,默认值为 jvm * 0.1。在本次测试中,如果单个查询在节点上的使用内存最大值过小,会导致查询无法完成,建议将内存值设置足够大,以避免查询失败的情况。

七、参考

[1] https://prestodb.io/

[2] R. Sethi et al., "Presto: SQL on Everything," 2019 IEEE 35th International Conference on Data Engineering (ICDE), 2019, pp. 1802-1813, doi: 10.1109/ICDE.2019.00196.

[3] https://kubernetes.io/

[4] https://www.tpc.org/tpcds/

[5] https://zhuanlan.zhihu.com/p/466908637

[6] https://bbs.huaweicloud.com/blogs/198087


想要获取更多有趣有料的【活动信息】【技术文章】【大咖观点】,请关注[Alluxio智库]


发布于: 刚刚阅读数: 4
用户头像

Alluxio

关注

还未添加个人签名 2022-01-04 加入

Alluxio是全球首个面向基于云原生数据分析和人工智能的开源的资料编排技术!能够在跨集群、跨区域、跨国家的任何云中将数据更紧密地编排接近数据分析和AI/ML应用程序,从而向上层应用提供内存速度的数据访问。

评论

发布
暂无评论
一站式全覆盖数据 I/O 平台 - Alluxio 与 Aunalytics 的完美结合_分布式_Alluxio_InfoQ写作社区