聊点技术|数据爆炸性增长,Bonree ONE 存储如何做到稳如泰山
背景
新一代的 Bonree ONE 主要体现在轻盈、有序、精准三个亮点,而这三个方向都离不开一个稳定、可靠、高效的数据存储底座。目前,Bonree ONE 基于 Clickhouse 进行存储,容纳了包括 APM、RUM、LOG、会话、用户行为分析等多个业务模块的场景数据。
存储的难点
Bonree ONE 容纳模块较多,数据使用场景复杂多变,对于底层数据存储,主要难点如下:
· 数据写入量大,数据量级要可以扩展到 PB 级别的数据摄入;
· 业务流量存在波峰和波谷,而且波峰和波谷的差距较大,存在突发超高峰写入的场景;
· 查询场景复杂,有 olap 分析、明细数据查询以及复杂的多字段排序场景;
· 查询稳定性要求较高,对于告警、重要指标要做到 ms 级别响应;
· 集群维护场景复杂度高,要应对集群扩缩容、数据均衡以及数据重分布等场景;
围绕 Clickhouse 的优化
针对以上难点,我们需要在写入、读取、多租户以及 failover 机制的策略响应上进行优化,满足 Bonree ONE 应对超大数据量应用场景的需求。
写入优化
· 按表攒批
Clickhouse 是擅长按批写入数据的,批次的数据越大,吞吐量越高。为应对多场景数据涉入的状况和减少业务端对数据存储感知的需求,我们通过消费节点来完成攒批逻辑,根据每个表的个性化定制策略,实现攒批效果的最大化,这既能满足业务效率的要求,又能实现 Clickhouse 数据摄入的最大吞吐量。
· 限流
在有限存储资源的情况下,Clickhouse 集群支持的摄入量是有限的,过大的数据写入主要有两个维度的原因,一个是写入的数据量过多,另一个是写入的峰值过高。前者会通过告警功能送达运维团队,通过扩容或者数据裁剪的操作来解决问题。后者则通过限流来保证存储集群的稳定性。目前,在 consumer 节点,我们增加了窗口逻辑来满足限流操作策略介入的需要,比如每秒写入次数、写入时间间隔等。
读取优化
为支持多业务有更稳定的数据使用效率,在数据查询上,高频查询的响应效率务必高效,我们主要从以下角度着手优化:
· 查询加速
· orderBy 和 primaryKey 的高效使用:orderBy 相关字段是表数据的排序设置,它对高频查询的效率有重要。一般 orderBy 的设置要尽量覆盖当前表业务的高频查询,从低基数到高基数进行排序设置。primaryKey 默认与 orderBy 一致,如果 filter 条件没有覆盖所有的 orderBy 字段,则可以提取部分字段作为 primaryKey ,但是 primaryKey 必须是 orderBy 字段的前缀。
· 索引:针对等值过滤使用 BF 索引,针对范围查询使用 minmax 索引,针对全文检索,使用 tokenbf 索引。
· 物化视图:针对固定优化查询场景,使用物化视图,满足数据一致性的同时,大大提高查询效率。
· projection:针对部分预聚合场景,使用 projection 的效率更高,而且有更友好的自动路由,减少业务侵入。
· 压缩和编码
Clickhouse 提供了多种编码以及多种编解码器,极大提高数据的压缩效率,节省 IO、存储等资源。Clickhouse 支持的压缩算法如下:
·NONE : No Compression.
·LZ4 : Applies LZ4 fast compression.
·LZ4HC[(level)] : LZ4 HC (high compression) algorithm with configurable level.
·ZSTD[(level)] : ZSTD compression algorithm with configurable level.
经过测试对比,ZSTD 的压缩效率是 LZ4 的 5~~6 倍。
若想要更高的压缩效率,数据的存储编码是一种更好的优化手段。Clickhouse 提供的编码算法如下:
·Delta : This approach stores the difference between 2 neighbor values. It can be combined with LZ4 and ZSTD.
·DoubleDelta : This approach stores the difference between 2 neighbor delta values (delta of deltas). Suitable for time series data.
·Gorilla : Calculates XOR between current and previous value. Suitable for slowly changing floating numbers.
·T64 : It crops unused high bits of values in integer data types(include Enum, Date, DateTime) and puts them into a 64×64 bit matrix.
·FPC : Used in floating point values. XOR between the actual value and the predicted value.
针对以上编码算法的特性,时间字段我们选择基于 DoubleDelta 编码的 ZSTD(1)压缩算法,String 类型使用 ZSTD(1)的压缩算法。
· 字段类型精细化
Clickhouse 提供了非常精细的数据字段进行压缩,比如整数就支持 int8、int16、int32、int64,Clickhouse 之所以这么细化数据类型,是为了高效的存储和计算,所以在业务使用端,也要做到精确化管理。
· 低基数的 String 使用 LowCardinality(String)。
· 能用更少位数的数据存储,就选择最少位数的数据存储,比如优先使用 int8,而不是默认使用 int64。
· 半结构化数据优先使用 Map 结构,其次是 JSON 结构。
多租户
Clickhouse 为了保障多业务稳定查询,支持了多租户,减少业务之间的影响。我们基于 Clickhouse 的多租户能力,给予每条产品线单独的租户,实现租户资源个性化配置,满足不同业务不同优先级的诉求。
系统是根据各个租户的业务重要程度与场景响应需求来制定对应的租户资源显示的。目前 Clickhouse 支持了多租户,但是对于 Clickhouse 内部的资源隔离其实是不具备的,在这一点上,我们是通过完整的监控告警链路来跟进,减少资源冲突带来的不稳定性,支持租户资源的快速释放,从而快速解决某些应急场景。
failover 策略
数据的摄入和读取需要高可用机制来满足需求,比如写入端某个 consumer 节点异常,或者某个 clickhouse 节点异常等情况,我们如何保证集群的稳定性。
当 consumer 节点或者 clickhouse 节点遇到异常时,ch-manager 节点能够感知到节点异常进行流量调度,使异常节点不影响数据正常摄入和查询,同时调整流量写入策略,保证 consumer 节点写入的稳定性,避免发生级联雪崩状况。
效果
· 写入效率:Bonree ONE 最新版本的写入效率较春季版本提高 3-5 倍,且稳定性更强,能够从容应对超预期的流量写入。
· 读取效率:目前 Bonree ONE 公有云生产环境 Clickhouse 集群的读取效率,TP99 在 S 级以内。
· 稳定性:Clickhouse 集群支持任意单节点服务掉线,而不影响集群整体的写入和查询,consumer 任意单节点掉线,也不影响集群整体写入。
最后
在 Bonree ONE 应用场景愈发复杂的情况下,系统对数据存储的要求会越来越高,我们会在资源管理、实时性等方向上继续深入研究,让 Bonree ONE 在轻盈、有序、精准的方向上走得更远更稳,同时我们也会积极分享我们的改进方案,跟大家一起学习探讨。
评论