使用 HaMergeTree 表引擎时,ByteHouse 的数据分片需要结合分布式表引擎(Distributed)一起使用。
Distributed 表引擎本身不存储任何数据,它能够作为分布式表的一层代理,在集群内部自动展开数据写入、分发、查询、路由等工作。

从上图可以看出一张表分成了两部分:
_local 后缀进行命名。本地表是承接数据的载体,可以使用 非 Distributed 的任意表引擎,我们建议使用 HaMergeTree,或 HaUniqueMergeTree而为了让整个集群的每一个节点都可查,也需要将分布式表建到每个节点上。因此,对于一张业务表,需要在每个节点上都分别创建一张分布式表,和一张本地表。架构如下图:
当 Distributed 表执行查询操作的时候,会依次查询每个分片的数据,然后再汇总返回。
当对 Distributed 表的执行写入时,会先写入本地,再根据分片键(Shard Key)计算数据应该写入哪些节点,建立远程链接,再分发到这些节点。
但这样做有一些缺点:
因此,ByteHouse 的读写建议为:插入 local 表,读 Distributed 表。不直接插入 Distributed 表。当然,这样就需要业务在写入前针对 Shard Key 提前拆好数据,分别写入不同的 Local 表。
分布式表的建表语句示例如下:
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name ON CLUSTER clustern( name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr], name2 [type] [DEFAULT|MATERIALIZED|ALIAS expr],... ) ENGINE = Distributed(cluster,database,table,[sharding_key]) [PARTITION BY expr] [ORDER BY expr] [PRIMARY KEY expr] [SAMPLE BY expr] [SETTINGS name=value, ...]
分片键使用示例:
-- 分片键可以是一个具体的整型字段 -- 按照用户 ID 划分 Distributed(cluster,database,table,userid)-- 分片键也可以是返回整型的表达式 -- 按照随机数划分 Distributed(cluster,database,table,rand())-- 按照用户 ID 的散列值划分 Distributed(cluster,database,table,intHash64(userid))