欢迎来到科技玩吧!
从 ClickHouse 到 ByteHouse:实时数据分析场景下的优化实践
发布日期:2023-02-01 10:24:06 | 来源:ByteHouse | 作者:ByteHouse

  作为国内规模最大的 ClickHouse 用户,目前字节跳动内部的 ClickHouse 节点总数超过 1.8W 个。综合来说,字节跳动广泛的业务增长分析很多都建立在 ClickHouse 为基础的查询引擎上。

  2021年8月,火山引擎基于字节跳动内部实践,正式推出ByteHouse企业版,解决了开源技术上手难、试错成本高等企业数字化转型中遇到的技术痛点。

  在打造ByteHouse的路程中,我们经过了多年的探索与沉淀,本文将分享字节跳动过去使用 ClickHouse 的两个典型应用与优化案例。

  推荐系统实时指标

  在字节跳动内部“A/B 实验”应用非常广泛,特别是在验证推荐算法和功能优化的效果方面。最初,公司内部专门的 A/B 实验平台已经提供了 T+1 的离线实验指标,而推荐系统需要更快地观察算法模型、或者某个功能的上线效果,因此需要一份能够实时反馈的数据作为补充:

  •能同时查询聚合指标和明细数据;

  •能支持多达几百列的维度和指标,且场景灵活变化,会不断增加;

  •可以高效地按 ID 过滤数据;

  •需要支持一些机器学习和统计相关的指标计算(比如 AUC)。

  01 - 技术选型

  字节内部有很多分析引擎,ClickHouse、 Druid、 Elastic Search、 Kylin 等,通过分析用户需求后选择了 ClickHouse:

  •能更快地观察算法模型,没有预计算所导致的高数据时延;

  •ClickHouse 既适合聚合查询,配合跳数索引后,对于明细点查性能也不错;

  •字节自研的 ClickHouse 支持 Map 类型,支持动态变更的维度和指标,更加符合需求;

  •BitSet 的过滤 Bloom Filter 是比较好的解决方案,ClickHouse 原生就有 BF 的支持;

  •字节自研的 ClickHouse 引擎已经通过 UDF 实现了相关的能力,而且有比较好的扩展性。

  每个产品都有自己合适的场景,但是对于当前场景的需求评估下,ClickHouse 更加合适。

  方案对比

  确认技术选型后,在如何实现部分,也有两种方式:

  最终方案及效果

  由于外部写入并不可控和技术栈上的原因,我们最终采用了 Kafka Engine 的方案,也就是 ClickHouse 内置消费者去消费 Kafka。整体的架构如图:

  •数据由推荐系统直接产生,写入 Kafka——为了弥补缺少 Flink 的 ETL 能力,推荐系统做了相应配合,修改 Kafka Topic 的消息格式直接适配 ClickHouse 表的 Schema;

  •敏捷 BI 平台也适配了一下实时的场景,可以支持交互式的查询分析;

  •如果实时数据有问题,也可以从 Hive 把数据导入至 ClickHouse 中,除此之外,业务方还会将 1% 抽样的离线数据导入过来做一些简单验证,1% 抽样的数据一般会保存更久的时间。

  除了技术选型和实现方案,我们在支持推荐系统的实时数据时遇到过不少问题,其中最大的问题随着推荐系统产生的数据量越来越大,单个节点的消费能力也要求越来越大,主要碰到如下问题:

  02- 挑战与解决方案

  问题一:写入吞吐量不足

  在有大量辅助跳数索引的场景下,索引的构建严重影响写入吞吐量。

  解决方案——异步构建索引

  社区版本的实现里的具体逻辑如下:

  •解析输入数据生成内存中数据结构的 Block;

  •然后切分 Block,并按照表的 schema 构建 columns 数据文件;

  •最后扫描根据 skip index schema 去构建 skip index 文件。三个步骤完成之后才会算 Part 文件构建完毕。

  在需要保证构建完 columns 数据之后用户即可正常查询的前提下,ByteHouse 同步完成前面两步,第三步把构建好的 Part 放入到一个异步索引构建队列中,由后台线程构建索引文件。

  在改成异步后,整体的写入吞吐量大概能提升 20%。

  问题二:Kafka 消费能力不足

  社区版本的 Kafka 表,内部默认只会有一个消费者,这样会比较浪费资源并且性能达不到性能要求。

  尝试优化过程:

  •尝试通过增大消费者的个数来增大消费能力,但社区的实现是由一个线程去管理多个的消费者,多个消费者消费到的数据最后仅能由一个输出线程完成数据构建,所以这里没能完全利用上多线程和磁盘的潜力;

  •尝试通过创建多张 Kafka Table 和 Materialized View 写入同一张表,但是对于运维会比较麻烦。

  解决方案——支持多线程消费

  前面提到的优化手段都不尽如人意,最后决定改造 Kafka Engine 在其内部支持多个消费线程,简单来说就是每一个线程它持有一个消费者,然后每一个消费者负责各自的数据解析、数据写入,这样的话就相当于一张表内部同时执行多个的 INSERT Query。

  通过多线程实现多消费者同时消费写入表,写入性能达到接近于线性的提升。

  问题三:出现故障无法保证数据完整性

  在主备模式下,如果数据同时两个节点都写入,一旦一个节点出现故障,新启的节点恢复过程中容易出现各种问题,包括性能下降,无法保证分片,最严重可能导致查询结果不正确。

  解决方案——确保主备模式下只会写入一个主备其中一个节点

  为了避免两个节点消费这个数据,改进版的 Kafka Engine 参考了 ReplicatedMergeTree 基于 ZooKeeper 的选主逻辑。对于每一对副本的一对消费者,会尝试在 ZooKeeper 上完成选主逻辑,确保选举成为主节点的消费者才能消费,另一个节点则会处于一个待机状态。

  有了这样的单节点消费机制, 系统会检测 ReplicatedMergeTree 表数据是否完整,如果数据不完整则代表不能正常服务,此时消费者会主动出让 Leader,让副本节点上成为消费者,也就是新写入的数据并不会写入到缺少数据的节点,对于查询而言,由于查询路由机制的原因也不会把 Query 路由到缺少数据的节点上,所以一直能查询到最新的数据。

  改进 Kafka Engine 确保主备模式下只有一个节点能消费数据,即使出现节点故障在新节点恢复过程中同样保障了解决了数据完整性的问题。

  广告投放实时数据

  第二个典型案例关于广告的投放数据,一般是运营人员需要查看广告投放的实时效果。由于业务的特点,当天产生的数据往往会涉及到多天的数据。这套系统原来基于 Druid 实现的,Druid 在这个场景会有一些难点:

  选择了 ClickHouse 之后能解决 Druid 不足的地方,但还是有部分问题需要解决:

  问题一:Buffer Engine 无法和 ReplicatedMergeTree 一起使用

  社区提供了 Buffer Engine 为了解决单次写入生成过多 Parts 的问题, 但是不太能配合 ReplicatedMergeTree 一起工作, 写入不同 Replica 的 Buffer 仅缓存了各自节点上新写入的数据,导致查询会出现不一致的情况。

  解决方案改进了 Buffer Engine 做了如下的调整和优化:

  •我们选择将 Kafka/Buffer/MergeTree 三张表结合起来,提供的接口更加易用;

  •把 Buffer 内置到 Kafka Engine 内部, 作为 Kafka Engine 的选项可以开启/关闭,使用更方便;

  •Buffer table 内部类似 pipeline 模式处理多个 Block;

  •支持了 ReplicatedMergeTree 情况下的查询。

  首先确保一对副本仅有一个节点在消费,所以一对副本的两个 Buffer 表,只有一个节点有数据。如果查询发送到了没有消费的副本,会额外构建一个特殊的查询逻辑,从另一个副本的 Buffer 表里读取数据。

  增强 Buffer Engine,解决了Buffer Engine 和 ReplicatedMergeTree 同时使用下查询一致性的问题。

  问题二:出现宕机后可能会出现数据丢失后者重复消费的情况

  ClickHouse 缺少事务支持。一批次写入只写入部分 Part 后出现宕机,因为没有事务保障重启后可能出现丢失或者重复消费的情况。

  解决方案

  参考了 Druid 的 KIS 方案自己管理 Kafka Offset,实现单批次消费/写入的原子语义:实现上选择将 Offset 和 Parts 数据绑定在一起,增强了消费的稳定性。每次消费时,会默认创建一个事务,由事务负责把 Part 数据和 Offset 一同写入磁盘中,如果出现失败,事务会一起回滚 Offset 和写入的 Part 然后重新消费。

  确保了每次插入数据的原子性,增强了数据消费的稳定性。

  结语

  实时数据分析是ClickHouse的优势场景,结合字节跳动实时数据场景的特点,我们对 ClickHouse 进行了优化和改造,并将这些能力沉淀到了 ByteHouse 上。ByteHouse 基于自研技术优势和超大规模的使用经验,为企业大数据团队带来新的选择和支持,以应对复杂多变的业务需求,高速增长的数据场景。

  未来,ByteHouse将不断以字节和外部实践输出行业用户,帮助企业更好地构建交互式大数据分析平台。

网站简介

科技玩吧是一个聚焦科技与创新的资讯平台,我们将提供有趣而专业的内容,包括家电数码、人工智能、区块链、物联网、云计算、科技生活等相关讯息,拥有科技内容报道、科技时事热评、新品评测等内容形式,覆盖核心新媒体平台。

科技玩吧运营主体为天津笔尖文化传媒有限公司,隶属于亿媒汇(北京)整合营销顾问有限公司。亿媒汇(北京)整合营销顾问有限公司是一家植根于新媒体时代,深耕于网络整合营销十数年的新型网络公关公司,截至目前,公司凭借自身优势和丰富传播实践,业务范围已覆盖全国32个地区,服务逾2000家企业,拥有全国五大中心,数百起行业案例典范和独家优势资源,是在中国传播业内拥有良好声誉的整合营销服务公司。

联系我们

意见反馈:zhangmiao@bjyimeihui.com.cn

稿件投诉:zhangmiao@bjyimeihui.com.cn

内容合作QQ:852324779

商务合作:BD@bjyimeihui.com.cn

微信公众号

Copyright ©2021 天津笔尖文化传媒有限公司 iyiou.com. All Rights Reserved            ICP许可证:京B2-20190160 | 津ICP备2021006600号-1 | 京公网安备11010502039453号

忘记密码?
*用户名
*手机号
*输入验证码
*设置密码(6位数以上+字母)
*再次输入密码
找回密码
*手机号
*输入验证码
*设置密码(6位数以上+字母)
*再次输入密码
科技玩吧用户注册协议与隐私政策

请您细阅此重要提示,并完整阅读根据您的具体情况进行选择。


请您确认您或您所代表的机构是符合《中华人民共和国证券投资基金法》、《中华人民共和国信托法》、《私募投资基金监督管理暂行办法》、《信托公司集合资金信托计划管理办法》、《证券公司客户资产管理业务管理办法》、《证券公司集合资产管理业务实施细则》、《基金管理公司特定客户资产管理业务试点办法》及其他相关法律法规所认定的合格投资者。


一、根据我国《私募投资基金监督管理暂行办法》的规定,私募基金合格投资者的标准如下:

1、具备相应风险识别能力和风险承担能力,投资于单只私募基金的金额不低于100万元且符合下列相关标准的单位和个人:

(1)净资产不低于1000万元的单位;

(2)个人金融资产不低于300万元或者最近三年个人年均收入不低于50万元。(前款所称金融资产包括银行存款、股票、债券、基金份额、资产管理计划、银行理财产品、信托计划、保险产品、期货权益等。)

2、下列投资者视为合格投资者:

(1)社会保障基金、企业年金、慈善基金;

(2)依法设立并受国务院金融监督管理机构监管的投资计划;

(3)投资于所管理私募基金的私募基金管理人及其从业人员;

(4)中国证监会规定的其他投资者。


二、根据我国《信托公司集合资金信托计划管理办法》的规定,信托计划合格投资者的标准如下:

1、投资一个信托计划的最低金额不少于100万元人民币的自然人、法人或者依法成立的其他组织;

2、个人或家庭金融资产总计在其认购时超过100万元人民币,且能提供相关财产证明的自然人;

3、个人收入在最近三年内每年收入超过20万元人民币或者夫妻双方合计收入在最近三年内每年收入超过30万元人民币,且能提供相关收入证明的自然人。


三、根据我国《证券公司客户资产管理业务管理办法》的规定,集合资产管理计划合格投资者的标准如下:

1、个人或者家庭金融资产合计不低于100万元人民币;

2、公司、企业等机构净资产不低于1000万元人民币。


依法设立并受监管的各类集合投资产品视为单一合格投资者。


如果确认您或您所代表的机构是一名“合格投资者”,并将遵守适用的有关法规请点击“接受”键以继续浏览本公司网站。如您不同意任何有关条款,请直接关闭本网站。


“本网站”指由上海景林资产管理有限公司(以下简称“本公司”)所有并及其网站内包含的所有信息及材料。本网站所发布的信息、观点和数据有可能因所基于的信息发布日之后的情势或其他因素的变更而不再准确或失效,本公司不承诺及时更新不准确或过时的信息、观点以及数据。


本网站介绍的信息、观点和数据仅供一般性参考,不应被视为购买或销售任何金融产品的某种要约,亦非对任何交易的正式确认。投资有风险,投资产品的过往业绩并不预示其未来表现,本公司不对产品财产的收益状况做出任何承诺或担保,投资者不应依赖本网站所提供的数据做出投资决策,在做出投资决策前应认真阅读相关产品合同及风险揭示等宣传推介文件,并自行承担投资风险。