ClickHouse学习笔记之分片集群
文章目录
- 介绍
- 集群写入流程
- 集群读取流程
- 配置集群
- 使用集群
介绍
副本虽然可以提高数据的可用性,但每台服务器必须容纳全量数据,没有支持数据的横向扩容。要解决数据水平切分问题,需要引入分片的概念,通过分片把一份完整的数据进行切分,不同的分片分布到不同的节点上,再通过Distributed
分布表引擎把数据拼接起来使用。
分布引擎本身不存储数据,而是通过分布式逻辑进行不同分片的分布式数据的写入、分发和路由。
因为ClickHouse的集群是表级别的,所以实际企业大部分做了高可用,但没有分片,以避免降低查询性能和操作集群的复杂度。
集群写入流程
以3分片,每个分片2个副本,共6个结点为例:
绿色表示打开分片内部复制的情况,黄色表示关闭分片内部复制的情况。打开分片内部复制时,客户端向分布式表distribute hdp1
发送写命令,distribute hdp1
只会向三个切片的一个副本写入数据,上图中即为hdp1 s1r1
、hdp3 s2r3
和hdp5 s3r5
,而后每个副本向该切片的另一个副本再写入数据,即hdp1 s1r1
向hdp2 s1r2
、hdp3 s2r3
向hdp4 s2r4
、hdp5 s3r5
向hdp6 s3r6
写入数据。关闭分片内部复制时,distribute hdp1
就得自己向所有副本写入数据。
集群读取流程
以3分片,每个分片2个副本,共6个结点为例:
当客户端向分布表发送读命令时,分布表向每个分片预读取数据,并计算错误数errors_count
,优先选择分片内错误数小的副本数据,如果存在多个拥有最小错误数的副本,则通过随机、顺序、第一顺位优先或host
名称近似四种方式之一选择其中一个副本的数据,最后将每个分片的数据进行拼接,作为最终的读取结果返回给客户端。
配置集群
进入/etc/clickhouse-server
目录
[root@scentos szc]# cd /etc/clickhouse-server
[root@scentos clickhouse-server]#
修改config.xml
文件
[root@scentos clickhouse-server]# vim config.xml
将<remote_servers>
标签修改成如下内容:
<remote_servers>
<szc_cluster>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>scentos</host>
<port>9000</port>
</replica>
</shard>
</szc_cluster>
</remote_servers>
<szc_cluster>
为集群名称,<shard>
为分片,<internal_replication>
表示是否打开分片内部复制,<replica>
为分片副本,分片内部可以配置多个副本,集群内部可以配置多个分片,但每个分片的副本数不用一样。
然后打开<macros>
标签的注释,配置当前机器的分片id和副本id:
<macros>
<shard>01</shard>
<replica>rep_01_1</replica>
</macros>
最后重启ClickHouse:
[root@scentos clickhouse-server]# systemctl restart clickhouse-server
使用集群
首先通过副本合并树创建数据表:
create table st_order_mt on cluster szc_cluster (
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
) engine
=ReplicatedMergeTree('/clickhouse/tables/01/st_order_mt','rep_01_1')
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id,sku_id);
szc_cluster
为使用的集群名称,ReplicatedMergeTree('/clickhouse/tables/01/st_order_mt','rep_01_1')
中的参数含义如下:
/clickhouse/tables/01/st_order_mt
:/clickhouse/tables
固定,01
为建表的分片id,st_order_mt
为表名;rep_01_1
为建表的副本ID
在某个副本建表后,所有分片的所有副本都会拥有这张表。
执行结果如下图所示:
然后创建分布式表:
create table st_order_mt_all2 on cluster szc_cluster
(
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
)engine = Distributed(szc_cluster,default, st_order_mt,hiveHash(sku_id));
szc_cluster
为集群名称,Distributed(szc_cluster,default, st_order_mt,hiveHash(sku_id)
中参数含义如下:
szc_cluster
表示使用的集群名称;default
表示使用的数据库名称;st_order_mt
表示该分布式表控制的表名称;hiveHash(sku_id)
表示分片方法,即通过计算sku_id
的哈希值来确定数据所属的分片。
执行结果如下图所示:
然后我们可以通过分布式表st_order_mt_all2插入数据:
insert into st_order_mt_all values
(201,'sku_001',1000.00,'2020-06-01 12:00:00') ,
(202,'sku_002',2000.00,'2020-06-01 12:00:00'),
(203,'sku_004',2500.00,'2020-06-01 12:00:00'),
(204,'sku_002',2000.00,'2020-06-01 12:00:00'),
(205,'sku_003',600.00,'2020-06-02 12:00:00');
也可以通过分布式表st_order_mt_all2
查询数据:
数据表和分布式表存在于集群中所有结点上,如果我们读写数据表,就只能读写结点所在分片的数据,不能读写跨分片结点的数据,因此集群模式下,我们必须通过分布式表进行全局的跨分片读写。
lanjianzz: 请问为什么我使用./rtspin -w -v -p 0 -q 2 10 1000 2 &创建第二个任务时会显示前一个任务已停止,使用cat /proc/litmus/stats指令也会使任务停止
m0_69916613: 为啥我是第5个错误可以我改了还是不行呀
SHarK1751007466: 请问,一开始监控没问题,第二天出现no data 是什么原因
soSOnone: 天啊!!!一定要备份啊!!!
源码怪: 建表语句PROPERTIES虽然说非必需,但是没有它就是建不了