Distributed 原理解析


文章目录

  • Distributed 原理解析
  • 1 定义形式
  • 2. 分片写入流程
  • 2.1 分片规则
  • 2.1.1 分片权重
  • 2.1.2 slot
  • 2.1.3 选择函数
  • 2.2 数据写入核心流程
  • 2.3 副本复制的核心流程
  • 2.4 分布式查询流程



Distributed表引擎是分布式表的代名词,不存储

任何数据,只是作为代理,能够自动路由到集群中的各个节点,所以其需要和其他的表引擎一起工作。

一张分片表由两部分组成:

  • 本地表:通常用_local结尾,主要承载数据。
  • 分布式表:通常用_all结尾,其与本地表形成一对多的映射关系,通过分布式表可以操作多张本地表。

clickhouse ENGINES 没有materializedmysql clickhouse distribute_大数据

1 定义形式

一张Distributed表引擎的定义形式如下:

ENGINE = Distributed(cluster, database, table, [, sharding_key])

其中参数的含义如下:

  1. cluster:集群名称,与配置中的自定义名称对应。
  2. database和table:对应的数据库与数据表的名称
  3. sharding_key:分片键,可以通过这个值将数据分布到各个host节点的本地表。

对于Distributed表来说,其建表语句如下:

CREATE TABLE test_all ON CLUSTER sharding_simple {
	id UINT64
}ENGINE = Distributed(sharding_simple, default, test_local, rand())

这里的部分集群名称,沿用之前的blog

上面建表语句的语义可以理解为:代理本地表default.test_local,他们分布在集群sharding_simple的各个shard,数据写入时会根据rand()随机函数取值来决定写入哪一个分片。

这里先创建Distributed表在创建本地表。

注意ON CLUSTER sharding_simple这个语义是在每一个分片节点上面创建一个Distributed表。【不是必须的

clickhouse ENGINES 没有materializedmysql clickhouse distribute_权重_02

接着创建本地表,使用分布式DDL语句可以迅速创建各个节点的本地表:

CREATE TABLE test_local ON CLUSTER sharding_simple (
	id UINT64
)ENGINE = MergeTree()
ORDER BY id
PARTITION BY id

这里对该表的操作注意事项进行概括:

  1. 如果要彻底删除一张分布式表,那么Distributed和本地表都要删干净!
  2. 不支持任何的MUTATION查询,包括ALTER、DELETE、ALTER UPDATE

2. 分片写入流程

2.1 分片规则

2.1.1 分片权重

在之前可以看到ENGINE = Distributed(sharding_simple, default, test_local, rand())中的rand()。这个值意味着分布式表可以通过这个值映射到不同的本地表。这里需要引入分片权重的概念。

<!-- 1分片 1副本 -->
<sharding_simple> <!-- 自定义集群名字 -->
  <shard> <!-- 分片 -->
    ...
    <weight>10</weight> <!-- 分片权重 -->
  </shard>
  <!-- 分割 -->
  <shard> <!-- 分片 -->
    ...
    <weight>20</weight>
  </shard>
</sharding_simple>

如果分片权重越大,那么其被写入的数据也会越多。

2.1.2 slot

slot的概念可以理解成一个个坑。slot的总和是所有分片的权重之和。如上面的配置,slot的数量等于30。slot按照权重元素的取值范围,与对应的分片形成映射关系。如果slot在[0,10)之间则写入第一个分片;如果slot值落在[10,20]之间则放入第二个分片。

2.1.3 选择函数

选择函数主要用于判断待写入数据应该被写入什么分片。

  1. 写出slot取值,计算公式如下:
    clickhouse ENGINES 没有materializedmysql clickhouse distribute_大数据_03
  2. 基于slot值找到对应的数据分片

整个流程演示,这边使用表格的方式进行演示。

数据插入

公式值

slot

shard

(10)

10 % 30

10

Shard2

(30)

30 % 30

0

Shard1

(201)

200 % 30

21

Shard2

(50)

55 % 30

20

Shard2

2.2 数据写入核心流程

流程:

  1. 向第一个分片节点写入本地分片数据
  2. 第一个分片建立远端连接,准备发送远端分片数据
  3. 第一个分片向远端分片发送数据
  4. 第二个分片接受并写入本地
  5. 由第一个分片确认完成写入

clickhouse ENGINES 没有materializedmysql clickhouse distribute_大数据_04

2.3 副本复制的核心流程

这个部分根据建表的MergeTree类型,分成两种:

  • ReplicatedMergeTree:之前就说过,这种引擎使用了zookeeper的能力来实现副本之间的同步。那么可以想到,Distributed表即使向每一个分片中的一个副本写入数据,分片中的每个副本都可以有完整的数据!
  • MergeTree:这个也是一种方式,由于没有上述的特性,Distributed表写入时需要照顾到所有副本!这个就会出现写入瓶颈。

我们这边换个思路,既然使用了MergeTree来做分布式多机clickhouse,那我们为什么要用副本呢?

考虑使用raid5集群和高性能服务器不就阔以缓和了。【手动滑稽

还有一种考虑,那就是提高服务器成本,搞个单机的。

实际业务应用效果貌似还不错。