字节跳动旗下的企业级技术服务平台火山引擎正式对外公布「ByteHouse」,解决开源技术上手难 & 试错老本高的痛点,同时提供商业产品和技术支持服务。
作为国内规模最大的 ClickHouse 用户,目前字节跳动外部的 ClickHouse 节点总数超过 1.5W 个。综合来说,字节跳动宽泛的业务增长剖析很多都建设在 ClickHouse 为根底的查问引擎上。
在打造 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 将一直以字节和内部最佳实际输入行业用户,帮忙企业更好地构建交互式大数据分析平台,并更宽泛地与 ClickHouse 研发者社群共享教训,独特推动 ClickHouse 社区的倒退。
火山引擎 ByteHouse
对立的大数据分析平台。目前提供企业版和云数仓两种版本,企业版是基于开源 ClickHouse 的企业级剖析型数据库,反对用户交互式剖析 PB 级别数据,通过多种自研表引擎,灵便反对各类数据分析和利用;云数仓版作为云原生的数据分析平台,实现对立的离线和实时数据分析,并通过弹性扩大的计算层和分布式存储层,无效升高企业大数据分析 TCO。点击申请体验
欢送关注字节跳动数据平台同名公众号