电子商务网站建设需要的语言及特点6,做网站域名的公司,虫虫 wordpress 群发,推荐个网站免费的导读
百度MEG上一代大数据产品存在平台分散、质量不均和易用性差等问题#xff0c;导致开发效率低下、学习成本高#xff0c;业务需求响应迟缓。为了解决这些问题#xff0c;百度MEG内部开发了图灵3.0生态系统#xff0c;包括Turing Data Engine(TDE)计算引擎、Turing Dat…导读
百度MEG上一代大数据产品存在平台分散、质量不均和易用性差等问题导致开发效率低下、学习成本高业务需求响应迟缓。为了解决这些问题百度MEG内部开发了图灵3.0生态系统包括Turing Data Engine(TDE)计算引擎、Turing Data Studio(TDS)数据开发治理平台和Turing Data Analysis(TDA)可视化BI产品。依托图灵3.0生态我们进而形成了一套新的开发范式——“OneData开发范式”其关键在于可视化分析与数据集的构建。
TDE-ClickHouse作为图灵3.0生态中重要的基础引擎之一专注于为业务提供海量数据下的自助秒级分析能力。通过高性能的数据查询能力与高效的数据导入通路支持业务更及时、敏捷地对海量数据进行分析通过稳定可靠的分布式架构在减少资源和运维成本的同时严控引擎侧的数据质量。
01 百度MEG数据中台解决方案
1.1 背景与问题
上一期的Geek说我们分享了图灵3.0中的数据开发治理平台TDSTuring Data Studio这一期我们分享图灵3.0生态中的一个重要的基础引擎TDE-ClickHouse。首先我们再回顾一下图灵3.0生态的发展背景
百度MEG上一代大数据产品存在平台多、质量参差不齐和易用性差的问题。这些问题导致开发人员面临较高的研发依赖、开发效率低下和高昂的学习成本业务部门则感知需求支持迟缓、数据产出延迟及数据质量低的问题。
1.2 图灵3.0生态概述
为解决上述问题我们构建了新一代大数据解决方案——“图灵3.0”旨在覆盖数据全生命周期支持全链路数据操作提供高效敏捷且统一的强大数据生态系统其中包括数据计算引擎、数据开发和数据分析三个核心部分
1TDETuring Data Engine图灵生态的计算引擎包括ClickHouse和Spark
2TDSTuring Data Studio一站式数据开发治理平台
3TDATuring Data Analysis新一代可视化BI分析产品。 △图灵3.0生态产品
TDA以可视化分析为主的产品形态要求底层引擎需要具备秒级响应的能力。CH凭借列式存储、数据压缩、向量化执行等特性以及对硬件资源的极致使用在查询性能方面表现出众。因此在可视化分析场景我们选用CH作为核心计算引擎对于超大数据量的查询及ETL加工场景则通过Spark支持。
1.3 OneDate开发范式
依托图灵3.0生态产品体系我们进而形成了一套新的开发范式——“OneData 开发范式”其中关键在于可视化分析与数据集的构建为业务提供海量数据下的自助秒级分析能力。
传统的分层数仓建模方法将数据分为4层包括ODSOperational Data Store、DWDData Warehouse Detail、DWSData Warehouse Summary和ADSApplication Data Store。在这种建模方法中数据开发侧作为需求的被动承接方根据业务侧提出的数据需求进行数据开发与交付存在需求交付周期长、人力成本高等问题。
OneData开发范式引入数据集的概念其中数据开发侧根据具化的业务主题与领域知识主动建立对应数据集并支持数据集的后续迭代业务侧则基于数据集进行交互式的自助拖拽分析极大的提升了数据开发效率降低了数据运维成本。 △OneData开发范式
1.4 ClikHouse的挑战
在OneData开发范式中数据开发侧与业务侧的依赖关系从之前的需求-交付解耦为以数据集为中心的建设。在实践中大部分数据集同之前DWS层的表类似会结合业务场景建设得更加成体系保证数据需求尽量不重不漏。ADS层则彻底消失无需数据RD单独开发。这种情况下DWS层数据相对于ADS层数据膨胀了好几个数量级但是要求查询性能不明显低于之前直接查询ADS层数据这样就对CH的查询性能提出了极高的要求。
百度MEG业务实践过程中对CH的要求是保证百亿级的数据分析请求能秒级响应。因此为了提升CH的查询性能我们做了大量的优化工作。
此外随着CH在内部的大规模使用在数据导入和分布式架构方面也暴露出一些不足之处比如
1大规模数据导入难以保证导入任务的稳定性以及时效性甚至产生级联的资源抢占问题
2CH分布式架构存在运维成本高等问题并且缺乏集群层面的事务支持等高级功能。
这篇文章将从查询性能、数据导入和分布式架构三个方面介绍我们对CH所做的优化工作。
02 ClickHouse查询性能优化
2.1 计算机分层解耦聚合层硬件加速
原生CH架构主要采用单层同质的分布式架构集群中所有数据节点的资源配置相同数据按照分片划分并做副本冗余存储在各个节点的本地磁盘中。
查询客户端会随机选择一个数据节点作为协调者节点并发起查询请求。相比其他数据节点协调者节点除了本地子查询的计算外协调者节点额外负责:
1初始查询拆解成子查询后下发
2合并各个子查询的结果后返回。
协调者节点需要额外的网络IO来获取其他节点的结果以及更多的CPU来合并结果。在大数据量和复杂查询场景下网络IO和合并结果会占用大部分时间。因此在理想状态下协调者节点需要更高的CPU和网络配置但在CH原生的单层同质架构下让所有节点都具备高规格资源配置会导致成本明显上涨并出现资源浪费。
因此我们将协调者额外的职责抽离出来独立成一层聚合层”。聚合层节点拥有更高的CPU、内存和网络吞吐能力其本身不存储数据。所有客户端查询都会先路由到聚合层再由聚合层作为协调者与CH集群的数据节点交互。同时聚合层的存在让跨物理CH集群的查询比如跨集群 Join变为可能。 △计算分层解耦
2.2 数据多级聚合
数据开发侧首先基于OneData开发范式在数据建模层面进行数据聚合基于大宽表事实表 维度表并结合业务主题抽取出相应的维度聚合表作为CH数据集。为满足业务侧的拖拽式分析CH数据集多为细粒度主题宽表单表百字段单天数亿行数据。
而在实际查询场景中由于大部分查询请求都是报表类型的查询单次查询涉及平均个位数字段返回结果集数百行数据因此需要在保证查询灵活性的同时不能影响报表类查询的性能此时需要在CH计算引擎层面进行透明的数据聚合。
计算引擎层我们实现了两层数据预聚合
1引入聚合表基于Projection实现对查询中间状态的预聚合避免对原始明细数据的大量磁盘扫描
2缓存查询结果将最终查询结果缓存在外部内存缩短查询链路并避免重复查询带来的多余磁盘IO。 △数据多级聚合
2.2.1自动Projection
经过对各类聚合表的选型对比我们最终选择Projection因为和传统聚合表相比Projection有两点优势
1Projection与底表数据强一致: 如果Projection中有数据缺失查询会自动透传到底表
2对客户端完全透明无需修改业务SQL引擎会自动判断是否命中Projection。 △ClickHouse Projection
同时我们与下游BI平台打通针对BI平台中的高频查询自动创建Projection并对Projection进行全生命周期自动化管理具体包括
Projection识别 解析查询SQL识别其中的查询字段包括维度与指标字段与计算函数 基于成本评估聚合效果过滤低效的Projection并结合其他拦截策略比如集群负载等做服务降级 生成待创建的Projection语句。
Projection生命周期管理 Projection创建主要基于生成的Projection语句并在CH集群创建 Projection删除主要关注命中率较低的Projection的挖掘以及回收 Projection物化主要关注数据上卷在历史存量数据中生效。 △自动Projection建设
2.2.2 查询结果Cache
对于查询结果的缓存原生CH的QueryCache存在如下问题
1单机Cache多个“聚合层”实例的Cache无法共享
2只有基于时间的过期机制无一致性保证底层数据更新后可能查到错误数据。
因此我们在CH的查询入口层CHProxy添加了QueryCache机制通过缓存最终查询结果以缩短查询链路并保证了查询结果的全局可见性同时在数据导入过程中引入版本机制版本变更时触发存量Cache的自动失效以保证结果缓存与底层数据的一致性。上线后各个CH集群查询平响最多下降50%。 △Proxy QueryCache建设
2.3 高基数精准UV查询
基于以上一系列的通用性查询性能优化后虽然查询平响得到较好的优化但是P90、P99指标改善却不明显。为此我们对CH集群的查询SQL进行挖掘与分析发现大部分长尾SQL来自高基数的精准UV查询SQL查询格式如下
SELECT keys, COUNT(DISTINCT cuid) FROM xxx GROUP BY keys
该类查询的特点是底表数据量大、字段基数高为了对结果去重需要维护高成本的HashSet。业界常见的解决思路包括
1近似算法如HyperLogLog预估基数存在1%左右的误差大多数业务无法接受
2在数据入库前预聚合但由于UV的不可加和特性在动态维度场景下不满足需求。
对查询耗时进行拆解分析发现由于数据随机分布在各个分片上需要在聚合层进行二次去重才能得到正确结果聚合层成为计算热点。在整个查询过程中子查询结果的网络传输和聚合层的二次去重耗时占到整个查询耗时的90%。
基于以上问题为了在不影响查询结果准确性的前提下降低聚合层的计算负载我们进行了两阶段的优化
1NoMerge查询在数据入库时根据cuid预划分数据查询时将聚合层的去重计算下推到各个CH分片聚合层只需要执行轻量级的NoMerge计算
2ProjectionRoaringBitMap使用Projection优化磁盘扫描数据量使用BitMap优化Set计算进一步减少中间状态大小。
2.3.1 NoMerge查询
第一阶段我们基于数据预划分引入了NoMerge查询的优化方案:
1在数据入库时对数据进行预划分保证相同cuid的数据落在同一个分片上实现数据正交
2改写CH原生的COUNT(DISTINCT)实现逻辑分片节点不再返回去重后的结果集而是只上报子结果集的大小
3聚合层只需要对子查询返回的结果集大小求和即可得到最终的UV值。
通过这种方法在高基数去重计数的查询场景下可以获得5-10倍的性能收益。 △NoMerge优化COUNT(DISTINCT)
2.3.2 ProjectionRoaringBitMap
第二阶段我们尝试用Projection结合RoaringBitMap进一步优化UV查询的性能。传统UV计算通过HashSet保存中间状态而在高基数场景下由于数据压缩比效果较差预计算带来的收益不明显因此我们引入RoaringBitmap数据结构替换Hashset减少中间状态大小提升数据的压缩与传输效果。 △RBM优化COUNT(DISTINCT)
2.4 RBO优化
参考对UV查询的性能优化我们继续推进对特定类型查询的优化以降低对应类型复杂查询的耗时。由于下游BI平台对常用的查询SQL按模板进行封装并提供给用户直接拖拽使用因此大量查询SQL具备相同的范式。对这些相同类型的查询SQL进行性能分析并采取针对性优化可以以少量成本换取较大的查询性能收益其中RBO (基于规则的优化器) 是一种比较合适的优化选择下面以Case-When查询优化为例进行说明。
Case-When查询具体包含如下几类形式
# case 1等价于 col_a A
CASE WHEN col_a A THEN X WHEN col_a IN (B, C) THEN Y ELSE Z
END IN (X)# case 2等价于 col_b A
CASE col_b WHEN A THEN X WHEN B THEN Y ELSE Z END
IN (X)# case3等价于 col_c A
IF(col_c A, X, Y) X
完整的Case-When查询示例如下
SELECT _key, _value
FROM_table
WHERE CASE WHEN col_a A THEN X WHEN col_a IN (B, C) THEN Y ELSE Z END IN (X)
该Case-When查询可能存在如下问题1无法命中索引2存在冗余计算。我们对此使用RBO规则对Case-When查询进行改写优化AST改写过程可以参考下图。上线后命中规则的SQL查询耗时降低20% - 40%。 △Case-When查询流程改写
03 ClickHouse数据导入优化
除查询性能外数据导入也是衡量数仓引擎性能以及易用性的关键标准之一高效快捷的数据导入可以很大程度提升业务的数据开发与分析效率。
MEG数据中台的导入场景以周期性离线导入为主大部分数据为天级例行导入。我们前期主要使用原生CH的Min-Batch数据Insert实现数据导入但是随着业务的覆盖以及接入数据量的增大该导入方式暴露出以下问题
1入口节点热点类似于原生查询原生导入首先会在集群内选择一个入口节点写数然后入口节点根据策略将数据分发到其他分片导入速度可能受限于入口节点的带宽
2写放大CH底层数据采用LSM-Tree组织原生导入首先在CH本地内存组织数据积累到一定量后以Part文件形式落盘CH会定期对磁盘上的多个Part进行合并Part合并会带来额外的写开销。 △原生数据写入
基于以上描述可以看出CH Min-Batch Insert在离线导入的背景下对业务的意义不大反而额外的数据合并会抢占一定的机器资源影响业务查询的稳定性。因此我们建设了一套BulkLoad的导入机制尽量保证读写分离避免读写间的资源抢占。
BulkLoad导入整体分为两个阶段
1数据构建离线任务从数据源摄取数据构建为CH内部数据结构而后将多个 Part合并为一个Part最后将数据打包推送到分布式文件存储后称AFS
2数据配送通过两阶段提交的方式对构建好的数据进行校验并按路由规则配送到CH对应节点。 △数据BulkLoad写入
BulkLoad导入在大规模数据导入的场景下表现出良好的吞吐百亿行级数据导入耗时小于两小时。此外采用预计算的方式剥离数据导入需要的资源可以更好保证稳定的查询性能。最后我们将构建得到的数据同时作为CH的冷备数据提升整体容灾能力。
此外针对增长、反作弊等数据实时性要求较高的业务场景我们还提供了不重不丢、秒级延迟的流式导入目前线上单流最高导入并发超过百万QPS。同时针对部分小数据量的临时分析场景为复用CH的查询能力我们打通了CH与AFS数据的即时查询通路。
04 ClickHouse分布式架构升级
4.1 云原生化
MEG数据中台前期主要基于物理机搭建CH集群随着接入业务的增多以及数据规模的持续增加集群扩容与运维效率明显满足不了规模的增长速度具体体现如下
1弹性化部署效率低需要人工维护CH集群拓扑比如人工配置集群拓扑以满足分片反亲和
2大规模部署运维成本高物理机需要自运维并且集群扩缩容需要人工同步业务表结构。
为提升CH集群部署效率以及降低集群运维成本我们将CH集群进行云原生化改造。与一般的无状态服务如 Web Server 等不同CH作为有状态数据库服务云原生化改造需要解决以下问题
1为追求CH极致性能CH数据存放在本地磁盘需要保证容器重建后本地数据不丢
2公司内部PaaS平台不支持Kubernetes后称K8sService需要使用其他服务发现方式 并维护集群拓扑关系
3保证分片可用性和反亲和部署。
Operator in K8s是一个可以简化应用配置、管理和监控的K8s扩展方法CH也发起开源项目 ClickHouse-Operator用于在K8s上部署和管理CH。结合公司内现有的PaaS平台Pandora、Opera、EKS等综合考虑接入成本、服务完整性、成熟度等因素最终选择基于ClickHouse-Operator实现CH集群部署在EKS。
主要实施路径为
首先在EKS集群中声明CH的CRDCustomResourceDefinition资源然后将Operator部署到EKS集群中。当有CH集群创建、扩/缩容、修改CH配置需求时通过Operator调和能力reconcile完成有状态的工作负载StatefulSet、配置管理组件ConfigMap和 命名服务BNS等资源的创建、更新。 △ClickHouse云原生架构
针对容器重建后本地数据丢失的问题我们采用两套数据自动恢复机制从正常副本拷贝数据或从AFS备份数据重建本地数据。业务可视自身情况权衡成本和服务稳定性选择适合业务场景的数据透明恢复方案。
对于集群的服务发现功能我们引入厂内经过高并发验证的BNS以提供相应能力。对于集群拓扑关系的维护首先通过StatefulSet创建出来的Pod自带固定编号以此就有了对应的分片、副本顺序然后通过ConfigMap维护集群的拓扑关系集群变更时通过自定义Controller监听Pod状态并及时同步最新的拓扑关系。 △ClickHouse集群拓扑关系
最后我们通过Pod Availability机制结合Readiness Gates保障集群可用性并通过给Node打标签的方式实现Shard反亲和部署。
目前我们已实现全量集群虚拟化部署总规模3000节点在资源成本、部署周期、维护成本都有明显的收益。
4.2 集群协调服务
虽然CH云原生化极大降低了集群的部署与运维成本使得CH集群的规模增长速度能够满足业务的接入需求但是规模的持续增长也对CH的架构稳定性和数据质量保证提出了更高的要求。在原生CH集群的一致性方案中副本间日志和数据的同步主要通过 ZooKeeper后称ZK 实现分片间元数据的一致性则通过串行化执行DDL语句来实现。原生一致性方案在CH规模增长过程中暴露出以下问题
1架构稳定性基于ZK实现的主从架构稳定性差ZK容易成为集群热点
2数据正确性缺乏集群层面的事务支持脏读、脏写导致的错误数据不如没有数据。
为解决以上问题我们对原生CH架构进行了改造其核心思路为
1构建轻量级集群元信息服务Meta将依赖ZK的主从架构切换为以Meta为底座的无主架构提升CH集群稳定性的同时消除ZK运维压力
2基于全局Meta服务结合Quorum协议、MVCC机制重构数据导入、恢复、DDL等流程同时实现原子导入等高级功能解决数据正确性问题。
首先是集群协调者服务的升级。集群Meta服务将元数据的存储和访问服务进行分层解耦其中无状态的服务层可根据集群负载按需扩缩容存储层保存CH集群的库表以及数据文件等元信息保证Meta服务的全局一致性。 △ClickHouse协调服务升级
然后是数据同步机制的升级。ZK主要保证CH副本间的数据一致性无法提供集群分片间的全局事务性失败的数据导入任务引入的不完整数据可能导致查询时出现脏读以及数据恢复时出现脏写。为此我们引入全局的轻量级版本机制查询、写入、数据恢复等流程根据特定版本读写数据以提供全流程数据服务的强一致性。 △ClickHouse数据同步机制升级
05 总结与展望
TDE-ClickHouse作为图灵3.0生态中重要的基础引擎之一凭借其强大的计算性能为业务提供海量数据下的自助秒级分析能力。其中高性能的数据查询能力与高效的数据导入通路可以支持下游业务更及时、敏捷地对海量数据进行分析提供数据驱动的洞察能力辅助业务决策稳定可靠的分布式架构在减少资源成本与运维成本的同时严格保障了CH侧的数据质量为下游业务提供准确无误的数据反馈。
目前百度MEG数据中台的CH资源规模已超过35万核计算、10PB存储覆盖30业务线单日BI分析查询PV超过15万查询平响小于3秒P90小于7秒。
此外我们也在不断完善MEG数据中台CH的各项能力包括存算分离减少资源与运维成本提升规模弹性湖仓融合降低数据迁移与探索成本以及特定场景与类型的查询性能优化等。
随着AI等领域的发展数据规模定会进一步激增数据的重要性也会愈发明显未来数据使用需求的变更、新硬件的出现、以及数据库相关技术理论的发展也会不断推动数据产品形态的更迭我们也会持续关注与跟进。
————END————
推荐阅读
用增结算数仓化改造在/离线调度系统的构建与应用
百度视觉搜索架构演进实践
智算基石全栈加速百度百舸 4.0 的技术探索和创新
HelixFold 3 全球首个完整复现 AlphaFold 3百度智能云 CHPC 为人类生命探索提供算力平台支撑
百度搜索结果波动的极致治理