2. 网络连接优化
网络连接的优化的核心本质就是减少连接的使用 。特别是数据需要Shuffle 的时候,下一轮 Stage的每一个节点需要从上一轮Stage的每一个节点拉取数据 。当一个集群的节点比较多的时候,如果存在比较多的复杂 Query(Stage多,并行度(节点数)比较大),集群的Worker节点会建立非常多的连接,如下图所示,单节点建立的连接数与集群节点数、并发stage数成正比 。
文章插图
字节内部的clickhouse集群规模非常大,最大的集群(单集群几千台规模)在目前 ClickHouse 的执行模式下单机最大可能会建立上几万个网络连接 。因此如果支持复杂 Query 执行,由于stage变多了,需要优化网络连接,特别是支持连接复用 。我们通过尽可能复用连接,在不同节点之间只会建立固定数目的连接,不同的查询会复用这些连接,不随 query 和 stage 的规模而增长 。
3. 网络传输优化
在数据中心领域,远程直接内存访问(RDMA)是一种绕过远程主机操作系统内核访问其内存中数据的技术,由于不经过操作系统,不仅节省了大量CPU资源,同样也提高了系统吞吐量、降低了系统的网络通信延迟,尤其适合在大规模并行计算机集群中有广泛应用 。
由于ClickHouse在计算层面做了很多优化,而网络带宽相比于内存带宽要小不少,在一些数据量传输特别大的场景,网络传输会成为一定的瓶颈 。为了提升网络传输的效率和提升数据exchange的吞吐,一方面我们引入压缩来降低传输数据量,另一方面我们引入 RDMA 来减少一定的开销 。经过测试,在一些数据传输量大的场景,有不小的收益 。
4. runtime Filter
Join算子通常是OLAP引擎中最耗时的算子 。如果想优化 Join 算子,可以有两种思路,一方面可以提升Join算子的性能,例如更好的Hash Table实现和Hash算法,以及更好的并行 。另一方面可以尽可能减少参与Join计算的数据 。
Runtime Filter在一些场景,特别是事实表join维度表的星型模型场景下会有比较大的效果 。因为这种情况下通常事实表的规模比较大,而大部分过滤条件都在维度表上,事实表可能要全量join维度表 。Runtime Filter的作用是通过在 Join 的 probe 端(就是左表)提前过滤掉那些不会命中Join的输入数据来大幅减少 Join 中的数据传输和计算,从而减少整体的执行时间 。以下图为例:
文章插图
左表并没有直接过滤条件,右表带有过滤条件item.proce > 1000 。当完成右表查询时,可以确定item.id 的范围和集合,根据join类型inner join和join条件sales.item_id=item.id可以推断出sales.item的范围和集合 。我们可以把sales.item 的范围和集合作为一个过滤条件,在join前过滤sales的数据 。
我们在复杂查询上支持了Runtime Filter,目前主要支持minmax和bloomfilter 。
总体执行流程如下:
①build plan segment worker(right table)会将生成的单节点 runtime filter 发送到coordinator节点;
②coordinator 在等待各个 worker的 runtime filter 都发送完成之后进行一次merge操作,将合并好的 runtime filter 分发到各个 execute plan segment worker(left table)节点中去;
③在 runtime filter 构造期间,execute plan segment(left table) 需要等待一定的时间,在超时之前如果runtime filter已经下发,则通过 runtime filter 执行过滤 。
这里需要思考一个问题,Runtime filter column 是否构建索引(主键、skip index等)和命中prewhere?如果runtime filter的列(join column)构建了索引是需要重新生成 pipeline 的 。因为命中索引后,可能会减少数据的读取,pipeline并行度和对应数据的处理range都可能发生变化 。如果runtime filter的列跟索引无关,可以在计划生成的时候预先带上过滤条件,只不过一开始作为占位是空的,runtime filter下发的时候把占位信息改成真正的过滤条件即可 。这样即使runtime filter 下发超时了,查询片段已经开始执行了,只要查询片段没有执行完,之后的数据仍然可以进行过滤 。
需要注意的是,runtime filter 是一种特殊场景下的优化,其针对的场景是右表数据量不大,且构建的 runtime filter 对左表有比较强的过滤效果 。如果右表数据量比较大,构建runtime filter比较慢,或者对左表的数据过滤效果很差甚至没有,那么 runtime filter 反而会增加查询的耗时 。因此,要根据数据的特征和规模来决定是否开启 。
推荐阅读
- 前囟门跳动
- 孙悟空身世大揭秘?孙悟空的真实身份究竟是谁
- 卢伟冰|卢伟冰揭秘Redmi G Pro游戏本“狂暴调校”:45W+125W双拷不降频
- 阿里开源的一个插件化前端框架,腾讯、美团、字节都在用
- 大揭秘慈禧与珍妃?光绪为什么不保护珍妃_4
- 希特勒的阴谋?大揭秘希特勒
- 崇祯吊死煤山地点?崇祯帝煤山自尽地址_1
- 孙权最后投降了吗?孙权害死他哥
- 康熙和纪晓岚有关系吗?康熙和纪晓岚有关系吗
- 古代的地图是如何绘制的?古代是如何画地图的