ByConity 是字节跳动基于 ClickHouse 发展出的存算分离的云原生数仓引擎,2023年1月正式发布开源 Beta 版本,今年7月,ByConity 正式发布1.0版本。
开源一周年之际,ByConity 已经获得了2100+的 Star 数,issue 数480+,用户60+,贡献者80+。2024年5月25日,ByConity 一周年线下 meetup 在北京召开。本期主题是《云原生数仓创新之路》,多位重磅嘉宾出席并分享了 ByConity 的最佳实践。
来自 MetaApp 的张少谦分享了 ByConity 在可观测性方面的应用。
2023 上半年,MetaApp 就开始使用 ByConity 替代 ClickHouse 做行为分析。目前,正在将 ByConity 引入到可观测平台相关的服务中。主要包括:容器日志、应用日志收集(客户端)和应用性能数据分析(客户端)。
整体的系统架构如下:
数据来源分两个部分,一部分是客户端埋点,另外一部分是容器日志:
- 客户端埋点是由 SDK 主动上报到日志服务,并且由日志服务写入 Kafka;
- 容器日志由 FluentBit 采集后写入 Kafka。
Kafka 内的日志由 ByConity 提供的 Kafka 引擎消费到 ByConity,最后各个平台查询 ByConity 的数据。
技术选型思路如下:
在技术选型时,MetaApp 一开始是用的 ElasticSearch,后在2021年转到了 ClickHouse,2024年才用上 ByConity。这3款都是业界比较常用的分析引擎:
- ES 是一款开源的分布式搜索和分析引擎,它是基于 Apache Lucene 搜索引擎构建而成,在搜索和分析领域被广泛使用
- ClickHouse 是一款在线分析处理的OLAP引擎,专门用于处理大规模数据集,由俄罗斯的 Yandex 开发。主要是用于处理大量数据并支持复杂的分析查询。它被广泛应用于需要实时分析海量数据的领域,如日志分析、数据仓库、实时报表等
- ByConity 是新一代的开源的云原生数据仓库,它采用计算-存储分离的架构,在满足数仓用户对资源弹性扩缩容,读写分离,资源隔离,数据强一致性等多种需求的同时,并提供优异的查询、写入性能。
但项目最后选择了 ByConity,则是因为它有独特的优势:
- 读写分离
读写完全隔离,在业务高峰期不会互相影响。
由于业务特性,在某些时候整体写入流量会比较高,同时在这个时候也是查询高峰期,在使用 ClickHouse 的时候写入和查询会影响,导致写入堆积并且查的很慢。ByConity 比较好的解决了这一点,读取 VW 和写入 VW 完全隔离开,互相不会造成影响。
- 存算分离
- 计算节点无状态,可根据使用情况进行扩缩容,保证稳定提供查询。
由于 Clickhouse 数据落在本地,对 Clickhouse 进行扩容时候,针对历史数据需要 resharding 或者等之前的数据过期,扩容成本非常高,ByConity 实现了存算分离,计算资源可以进行分钟级扩缩容,在某些查询高峰期可以随时多拉起一些 Pod,满足查询需求。
2. 多租户隔离,避免抢夺计算资源。
在实际场景中,不同功能可能有不同优先级,之前在使用 ClickHouse 的时候,可能会出现部分功能的查询直接把整个集群资源吃满,导致一些优先级高的查询无法执行。ByConity 可以针对不同表设置使用不同的查询资源组,甚至可以在查询的时候指定查询资源组,可以很好帮助我们保证高优先级业务正常运行。
3. 云上弹性伸缩,节省成本。
这两年 serverless 很火,各大云厂商都有对应的产品,比如阿里的 SAE 和火山的 VCI 等,ByConity 可以在云上部署通过和这些产品结合做到业务高峰期扩容,业务低峰期缩容。
- Kafka 引擎 low level 消费
支持 low level 模型消费,失败后数据不会重复。
ByConity 提供了开箱即用的写入连接器,相对于传统的 Flink、Spark 或自己开发的程序,会主动保存每个 partition 的消费信息,写入失败也不会出现重复等问题。
张少谦介绍,从 ClickHouse 更换至 ByConity,k8s 部署,运维更加方便了。同时,ByConity 支持分钟级扩容,方便业务高峰期随时拉起资源,稳定性大大提高。另外,在云上运行,MetaApp 采用了定时扩缩容的方案,节省下了40%的成本。
MetaApp 使用的服务运维主要有:
- 堆积监控
使用 Kafka Export 到处数据到 prometheus,然后使用 Grafana Alter 对接 IM 进行堆积报警规则,以及做成堆积看板。
- 消费错误监控
通过使用定时脚本查询 cnch_system.cnch_kafka_log 表,来发现消费过程中产生的错误,并将错误发送到 IM。
- 服务监控
通过 pod 监控报警等服务来发现服务出现崩溃、重启等情况。
最后,张少谦给大家分享了使用中遇到的一些常见问题和解决方式。
- 对象存储 QPS 和带宽使用很高
最开始测试 ByConity 时遇到一个问题,平常对象存储 QPS 非常高,最后发现是测试过程中开启了预加载并且开启最高级别预加载,这块可以根据实际情况来测试需要开启的预加载级别。
- 查询时出现 Reached timeout=30000ms @xxx.xxx.xxx.xx: While executing Remote 错误
由于服务资源是定时扩缩容并且 max_execution_time 设置太短,有时候业务流量超出预期可能导致合并来不及;还有表的 part 太多,可能导致查询超时,可以增加 part 发送时间。
同时,查询 system.cnch_parts 确认当前表的 part 个数,如果 part 个数很多(根据经验,超过5000已经算多),尝试提高合并速度或者尝试修改 brpc_data_parts_timeout_ms 参数大小。
- 合并过慢问题
如果遇到合并过慢,可以设置 enable_addition_bg_task=1 这个参数允许更多 merge 任务和调整,设置参数max_addition_bg_task_num 调整最大允许任务个数。这块如果有任务优先级建议可以对合并资源进行分组使用。
- 消费过慢问题
- 首先可以查看一下 cnch_kafka_log 表中是否存在消费异常,比如内存溢出之类的,根据具体情况调整.
- 可以尝试调大消费者个数,消费者个数最好能被 partition 个数整除。
- 还可以查看机器监控,看一下 kafka 引擎资源组的使用资源是否均匀,是否存在有的使用很高有的使用很低,可以通过设置 kafka_cnch_schedule_mode 来调整 consumer 分配模式,这里推荐设置为 least_consumers, 保证尽可能均匀。当前使用这个模式也可能存在一个问题,如果多个表使用一个资源组,并且节点个数不能被 consumer 个数整除,由于循环分配特性,那么可能有一个节点上运行的 consumer 远远超过其它节点。排查消费异常,如果在 exception 中发现经常出现 memory limit 则可以适当调小 kafka_max_block_size 参数值。
- k8s 部署如何外部访问 server
如果项目是在 k8s 部署,可能会遇到外部访问 server 的需求。
这里有两种情况:
如果是在云厂商部署,可以直接给 server 挂载一个 LB 并且指定9000/8123端口即可;
如果在机房部署,则可以采用 NodePort 方式允许外部访问。
张少谦表示,未来,MetaApp 将把可观测平台融合在一起,实现统一 TraceID,使客户端日志和服务端日志能够关联起来。同时,MetaApp 也会继续探索 ByConity 在监控指标方面以及其他方面的应用。
更多直播精彩内容,请点击链接观看:
https://www.bilibili.com/video/BV1w14212714/?spm_id_from=333.999.0.0&vd_source=71f3be2102fec1a0171b49a530cefad0