目录
原文大佬的这篇存算分离实践是有借鉴意义的,摘抄下来用作沉淀学习。如有侵权,请告知~
背景
云览科技公司倾力打造了凤凰浏览器,专注于为海外用户提供服务,作为数据驱动的高科技公司,从数据中挖掘价值一直是公司核心任务,公司以前选用了众多组件来提升内部大数据分析效率,如 Trino 作为即席查询的工具、用 ClickHouse 和 StarRocks 来加速报表业务查询,但经过长期实践,最终决定将所有内部数据分析平台统一至 StarRocks。并且社区在 3.0.0 版本中发布的存算分离能力,与公司内部大数据平台部门正在推动的降本增效理念非常契合,部门也在第一时间测试验证,确定评测各方面满足业务需求后,已经开始逐步在线上业务中替换现有系统,未来也会作为公司大数据平台部门统一数据架构的重点发展方向。
一、平台现状&痛点
作为公司内部大数据平台部门,主要负责公司海量数据处理、数据质量保证及指标体系维护的工作,服务公司四大业务场景:用户画像,报表,实验系统以及业务服务。公司大数据平台经过上云及几次云平台迁移,当前结合某云 EMR、对象存储建设存算分离的架构,主要架构如下图所示:
如图所示,原始数据存储在 Kafka中,通过 Flink 消费写入到OSS,然后通过Hive和 Spark 进行数据进一步加工,最后再将数据导入不同的 OLAP 组件中供业务查询。后期统一了计算引擎,使用 Spark on K8s 的架构,使用 Spark SQL和自定义了UDF/UDAF对数据进行统一处理。
在发展过程中不断采用新技术来满足不同业务需求,日积月累各种数据处理与分析组件越来越多,面临着巨大的压力与挑战,主要表现在以下几点:
1.1 使用组件多,维护成本高
公司的业务近几年飞速增长,伴随着业务扩张带来了数据量指数式增长。我们的分析平台规模也相应增长,使用的规模变大,平台维护成本也成倍增长。例如,仅OLAP 引擎就使用了 Trino、ClickHouse、StarRocks。其中Trino 给业务同学提供即席查询用途,ClickHouse 负责应用与用户洞察、实验系统和报表,StarRocks 对接业务报表。维护成本高体现在:
- 学习成本高,不同的系统实现不同,语法兼容性不同,对开发人员提出了很高要求。
- 定位问题复杂,三种组件对应三套监控系统,定位排查问题需要查看不同的监控系统,搜索各自的日志,排查链路很长。
1.2 链路冗长,数据时效性难以保证
数据由客户端上报,通过统一的转发服务,进入到不同的 Kafka 实例中,再经由 Flink 消费,sink 到数仓的 ODS 层,最后通过 tez 和 Spark SQL 对数据进行处理,构建数仓分层。而这其中 ODS 层的数据统一处理,整体时间就需要3小时左右,偶尔中间任务数据产出有误,需重跑整条链路,数据延时会被进一步拉长。
1.3 服务稳定性不足
当并发量大,大查询多时,Trino很容易出现内存溢出,稳定性不足,目前统计线上查询失败的情况约有10%左右由内存溢出导致。ClickHouse则无法处理高并发场景,很容易因CPU打满导致服务重启。
二、StarRocks 存算分离调研
StarRocks社区在3.0.0 版本推出了存算分离版本,与内部追求降本增效的目标不谋而合,也第一时间进行了调研测评。在调研时特别关注这几个方面:
- 查询效率,相比存算一体,用户不能感觉到较为明显的查询变慢
- 显著的成本降低,这也是我们尝试存算分离新架构的初衷
- 能够无缝替换我们正在使用的各个组件,为未来统一分析打好基础
- 运维简单,减轻开发运维同学的日常工作复杂度
以下是针对各个维度的一些调研结果。
2.1 性能对比
针对单表和多表 Join两种真实线上场景进行了具体测试,采用两个相同规模的集群,对同一数据量的表,进行相同的查询,多次查询,取平均值的方式进行对比。ClickHouse 集群规模:单节点 96C * 384G , StarRocks 集群 6 * 16C * 64G。单表查询的数据量大小为 200G,数据行数为1.3亿行,对表进行 count 计数查询。Join 查询为表进行自 Join,然后进行 count 计数查询。
测试表明,在 ClickHouse 最拿手的单表查询场景中, StarRocks存算分离性能可以保持一致,在多表Join场景中,StarRocks 能快3倍左右。
2.2 易用性
了解到 StarRocks也推出了Operator 支持 K8s 集群部署。利用 K8s 本身的容灾恢复机制以及强大的 StarRocks Operator 显著降低了集群部署运维复杂性。另外,StarRocks还提供了较为丰富的监控和诊断工具,便于在第一时间观察系统运行情况。
2.3 存储成本
对比了存算一体和存算分离的成本情况。在存算一体中数据量 1T 的表通过 export 到 OSS,再通过 Broker Load 到存算分离集群中,由标准磁盘存储转换为对象存储,后期还可以在对象存储内将数据进行冷热归档,进一步节省成本,存储费用降为原来的1/15。
三、StarRocks 存算分离实践
3.1 查询优化
3.1.1 物化视图
在一些实时查询的场景,发现通过物化视图进行预聚合的方式,能达到查询事半功倍的效果。例如我们的实时分析场景,通过 Flink 直接将明细数据写入到 StarRocks,最初直接对原始明细数据复杂查询,耗时约30秒左右,后来看社区力推物化视图,也为该表创建异步物化视图,对明细数据进行预聚合,结果显示,查询延迟降低为3秒左右,带来了10倍性能提升。
3.1.2 数据分桶
初次接触StarRocks 存算分离时,简单认为数据存储在对象存储中,建表时没有关注分桶数设置,分桶数设置过多,结果在使用时发现随着系统 Tablet 数量越来越多,发现FE的内存被被打满。后来在社区同学帮助下定位发现是由于 Tablet 过多导致 FE 节点一直在 GC。最后通过增加 FE 内存,再按数据量合理分配不同表的分桶数便彻底解决了该问题。
根据实际使用的经验来看,一般为每个分桶差不多容纳 1 ~ 3G 数据容量比较合理。过多的数据分桶会产生大量的小文件,且降低了I/O效率,而分桶数不足可能会影响查询的并发效果。
3.1.3 聚合查询模型
最初公司大部分报表都是参照 Kylin 模型,使用 Hive、Spark 将数据预聚合处理,再将处理结果数据导入到StarRocks中进行查询,依靠StarRocks强大的查询能力降低查询延迟。这种方式虽然提升了查询速度,但会导致数仓中结果表的数据量膨胀,且部分报表增加维度后会存在数据兼容性问题。后来将部分预聚合查询转换为 StarRocks 的聚合模型,通过测试和提前预聚合的查询效率几乎相同,同时也解决了数据膨胀和历史数据兼容问题。
3.1.4 Cache
对于线上所有的表在创建时都开启了 Data Cache。目前线上计算节点规模为6个,每个计算节点配置了 2 块 200G 容量大小的 SSD,通过该配置,基本上能将业务访问的热点数据都缓存在 Local Disk 上。
3.2 降本
使用StarRocks存算分离替换现有架构后,能在以下几个方面给成本带来较大的降低:
将OLAP组件替换成StarRocks,首先是通过聚合模型替代在数仓中的结果表预聚合,不必对所有维度进行排列组合,计算各个组合的结果数据。省去这一步骤后,存储对比之前减少了20%左右。
通过使用StarRocks 存算分离,数据被存储在对象存储,通过将存算一体集群中 5T 左右的数据导入到对象存储中,一个月能节省 1000$ 左右,未来随着数据量的不断增长,成本降低会愈发明显。 使用 K8s 部署,方便部署的同时也省去了一笔不菲的云平台服务费。
通过以上几点综合测算,相比原来使用 Spark 离线计算出结果,再将结果导入ClickHouse 的方式,使用StarRocks 存算分离,将成本降低了 46%。
3.3 运维监控
StarRocks的监控可以无缝对接Prometheus 和 Grafana,使用 StarRocks 存算分离版本后,我们根据建议首先配置了较为完善的监控,在存算一体基础上增加了不少对于系统 I/O 等指标,通过这些监控我们可以直观查看当前的各种指标。
- FE、BE相关监控
- StarRocks I/O 相关监控
另外,我们使用过程中比较关注查询性能问题,也出现过由于版本太多导致了查询时读取文件数较多的问题,在社区的提醒下,可以利用SQL监控当前集群的Compaction情况:
有了这种监控,我们也能看出当前是否出现 Compaction 慢等情况并考虑是否资源不足,需要扩容。
另外从使用来看,相比于存算一体,存算分离版本有一个极大的简化就是:无需关注多副本的数据一致性,存算分离数据位于OSS之上,本地缓存单副本,再也无需关注副本的数据均衡迁移、数据恢复等问题,这是一个不小的解放。
我们使用存算分离集群,上线初期遇到了一些 bug导致集群运行不稳定,但是在社区帮助下,快速定位并修复后,现在集群已经稳定运行了3月有余。
3.4 数据迁移
由于目前社区尚未提供一键式迁移工具将数据从存算一体集群迁移至存算分离集群,咨询过社区后,决定采用 export 到对象储存再使用 Broker Load 到新集群的方式进行数据迁移。
另外,在进行Broker Load时,导入任务和线上查询任务会对磁盘的 I/O 资源产生争用,这可能会导致 K8s 将 BE 节点驱逐,进而导致短时间 StarRocks 查询变慢,对此建议降低 Broker Load 并发度,通过分批导入的方式来减少 I/O 争抢。
通过 Export + Broker Load 配合上文提到的优化手段,目前已经将线上 80% 的业务数据迁移到存算分离集群中,并做到用户在使用上体验感更佳。
四、未来规划
4.1 数据湖 + StarRocks缩短计算链路
数据入仓后,ODS层的统一处理需要2-3个小时,这对数据及时产出有不小的影响,且计算成本较高。通过对数据湖的调研,计划将 ODS 层的处理提前到 Flink 当中,省去这几个小时的计算时间和计算资源,将 Flink 处理的数据直接落入数据湖中。利用 StarRocks 和数据湖的结合,实现对数据的实时查询,解决离线数仓中的数据不方便实时查询的问题。
4.2 StarRocks构建数据湖仓一体新架构
公司现在使用了三种 OLAP 组件服务不同场景,每种组件都需要将 Spark 加工好的数据导入至对应系统,运维复杂,难以保证数据时效性同时数据的多方存储也进一步提升了成本。引出一个问题,能否做到 Spark不参与计算加工,只用 StarRocks 搭建数仓呢?经过我们调研推导,发现还是有可能实现这一步的。
具体而言,Flink 消费 Kafka的流式数据后,直接入湖(Hudi、Iceberg 等),接下来利用 StarRocks作为计算引擎直接查询湖上数据,利用强大的湖查询能力可以直接进行查询,对于某些查询效率较低的查询,我们直接为其构建物化视图。
之前的测试表明,利用物化视图能带来 10 倍以上的加速效果。构建数仓的过程中,涉及到简单的 ETL 也能够通过逻辑视图结合物化视图的方式来完成。通过这样一套 Lakehouse 新架构,我们理想中能够达到以下几点目的:
- 去掉当前多套 OLAP 服务,只保留 StarRocks 作为计算引擎,节约大量计算资源
- 数据无需多处存储,降低数据延迟时效性。同时使用存算分离架构,数据单一存储能节约大量存储成本(尤其原来存算一体架构下数据依靠云盘多副本存储,云盘价格过于昂贵) 利用 StarRocks 存算分离带来的弹性和数据共享能力,我们可以做到:
(1)为不同的业务实现资源硬隔离
(2)业务峰谷期间可以轻松实现快速弹性,业务高峰期快速扩容以应对突发流量,业务低峰期可以快速缩容以削减成本
参考文章: