概述
在ClickHouse集群中使用复制表引擎ReplicatedMerge*Tree
建立本地表,插入的数据会在ClickHouse的副本间进行自动复制,实现数据的高可用效果
安装配置
RPM安装
从官网直接下载安装包 https://repo.clickhouse.tech/deb/stable/main/
直接使用 rpm -ivh
命令安装就OK
建议新建用户clickhouse并加入sudoers
注意所有安装包的版本要相同
clickhouse-common-static
— ClickHouse编译的二进制文件
clickhouse-server
— 创建clickhouse-server软连接,并安装默认配置服务
clickhouse-client
— 创建clickhouse-client客户端工具软连接,并安装客户端配置文件
clickhouse-common-static-dbg
— 带有调试信息的ClickHouse二进制文件(非必要)
基础配置
/etc/clickhouse-server
目录为clickhouse的主配置目录
启动时默认加载config.xml
和users.xml
在config.d
和users.d
目录下的所有附加xml文件也会被加载(需要满足clickhouse的配置文件语法)
config.xml
常用配置如下:
<!-- 日志 -->
<logger>
<level>trace</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>10</count>
</logger>
<!-- jdbc连接端口 -->
<http_port>8123</http_port>
<!-- client 连接端口 -->
<tcp_port>9000</tcp_port>
<!-- 服务器之间交换数据的端口 -->
<interserver_http_port>9009</interserver_http_port>
<!-- 本机域名 -->
<interserver_http_host>这里需要用域名,如果后续用到复制的话</interserver_http_host>
<!-- 监听IP,默认是ipv6的格式,如果没有开启则需要修改 -->
<listen_host>0.0.0.0</listen_host>
<!-- 最大连接数,默认4096 -->
<max_connections>64</max_connections>
<!-- 最大并发查询数,默认100 -->
<max_concurrent_queries>16</max_concurrent_queries>
<!-- 存储路径 -->
<path>/var/lib/clickhouse/</path>
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
<!-- metrika.xml中的节点映射,替换config.xml中的对应的节点配置 -->
<remote_servers incl="clickhouse_remote_servers" />
<zookeeper incl="zookeeper_servers" optional="true" />
<macros incl="macros" optional="true" />
<!-- 引用外部配置,这里引用的是集群配置,metrika.xml默认路径是/etc/metrika.xml -->
<include_from>/etc/clickhouse-server/metrika.xml</include_from>
启动&连接
启动命令 sudo systemctl start clickhouse-server
命令行连接 clickhouse-client -u root --password --port 9000
(默认9000端口可以不加port参数)
JDBC连接 jdbc:clickhouse://10.10.10.10:8123
集群配置
ClickHouse集群信息基于手工编写配置文件metrika.xml
,默认加载/etc/metrika.xml,为了方便管理我们在主配置文件中引用/etc/clickhouse-server/metrika.xml
,集群搭建完毕后可查询系统表system.clusters
,查看集群配置信息
ClickHouse的集群层级,对应metrika.xml配置中的
macros
节点:
- 集群《layer》 => 分片《shard》 => 副本《replica》 (每个ClickHouse实例都可以看做一个副本)
具体集群部署方案放在后续详细介绍
metrika.xml
配置如下:
<yandex>
<clickhouse_remote_servers>
<!-- 自定义的集群名称 -->
<ck_cluster>
<!-- 分片信息 -->
<shard>
<!-- 分布式表写入数据是否只写入到一个副本,配合复制表引擎使用,默认false -->
<internal_replication>true</internal_replication>
<!-- 分片副本信息,这里指定的用户名密码只能是明文,如果需要密文密码需要将配置指向users.xml中的profile中 -->
<replica>
<host>VM_102_21_centos</host>
<port>9000</port>
<user>xxx</user>
<password>xxx</password>
</replica>
<replica>
<host>VM_102_22_centos</host>
<port>9001</port>
<user>xxx</user>
<password>xxx</password>
</replica>
</shard>
</ck_cluster>
</clickhouse_remote_servers>
<!-- Replicated*MergeTree会用到zk -->
<zookeeper_servers>
<node index="1">
<host>vm162centos31</host>
<port>2181</port>
</node>
<node index="2">
<host>vm162centos32</host>
<port>2181</port>
</node>
<node index="3">
<host>vm162centos33</host>
<port>2181</port>
</node>
</zookeeper_servers>
<!-- Replicated*MergeTree建表语句的参数,指定zk的存储目录用 -->
<macros>
<layer>ck_cluster</layer>
<shard>shard01</shard>
<replica>replica01</replica>
</macros>
……
</yandex>
常用的表引擎
分布式表 Distributed
分布式引擎本身不存储数据, 但可以在多个服务器上进行分布式查询。
读是自动并行的。读取时,远程服务器表的索引(如果有的话)会被使用。
我们可以引申理解它就相当于关系型数据库中的视图概念。
示例:
ENGINE = Distributed(<集群名称>, <库名>, <表名>[, sharding_key])
与分布式表对应的是本地表,也就是上面的<表名>
参数,查询分布式表的时候,ClickHouse会自动查询所有分片,然后将结果汇总后返回
向分布式表插入数据
ClickHouse会根据分片权重将数据分散插入到各个分片中
默认情况下,每个分片中所有副本都会写入数据
或者通过参数internal_replication
配置每个分片只写入其中一个副本,使用复制表(Replicated*MergeTree)管理数据的副本
数据副本 Replicated*MergeTree
ReplicatedMergeTree
ReplicatedSummingMergeTree
ReplicatedReplacingMergeTree
ReplicatedAggregatingMergeTree
ReplicatedCollapsingMergeTree
ReplicatedVersionedCollapsingMergetree
ReplicatedGraphiteMergeTree
- 只有MergeTree系列引擎支持Replicated前缀
- 副本是表级别的,不是整个服务器级的。所以,服务器里可以同时有复制表和非复制表
- 副本不依赖分片。每个分片有它自己的独立副本
- 数据副本使用到Zookeeper,需要在
metrika.xml
中配置zk的集群信息 - SELECT 查询并不需要借助 ZooKeeper ,副本并不影响 SELECT 的性能,查询复制表与非复制表速度是一样的
- 默认情况下,INSERT 语句仅等待一个副本写入成功后返回。如果数据只成功写入一个副本后该副本所在的服务器不再存在,则存储的数据会丢失。要启用数据写入多个副本才确认返回,使用
insert_quorum
选项 - 数据块会去重。对于被多次写的相同数据块(大小相同且具有相同顺序的相同行的数据块),该块仅会写入一次
示例:
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/table_name', '{replica}')
大括号中的参数是metrika.xml
中macros
配置的,每个节点读取自己的配置信息,统一了建表语句
第一个参数用于zk中的目录结构,用了layer-shard名称分层
第二个参数是副本名,用于标识同一个表分片的不同副本,同个分片中不同副本的副本名称要唯一
分布式集群方案
方案1.0:MergeTree + Distributed
每个分片中只有一个副本,数据存储在本地表(MergeTree),查询分布式表,引擎自动向所有分片查询数据并计算后返回
优势
架构简单,单机和分布式都可以用
劣势
单点问题,数据丢失风险大
方案2.0:MergeTree + Distributed + 多副本
在方案一的基础上为每个节点增加副本
优势
在1.0的基础上,数据安全有了保障,任何一个实例或者服务器挂掉了,不影响集群查询服务
劣势
如果某个节点挂了,恢复以后可以将丢失的增量数据补全,但是如果硬盘彻底损坏,存量数据基本无法恢复,且这种方案不能用两个节点互为主备,会造成数据错乱
方案3.0:ReplicatedMergeTree + Distributed + 多副本
把2.0方案中的数据表引擎替换成ReplicatedMergeTree
,并设置分布式写入时只写入分片的一个节点:internal_replication
设置为true
实现同一个分片中,写入一个节点的数据后,自动同步到其他的副本中
下图实现的是一个节点启动多个ClickHouse实例
优势
由ReplicatedMergeTree
表引擎管理数据副本(依赖Zookeeper),无须担心节点挂掉后数据的同步和丢失问题
劣势
集群配置比较复杂, macros
配置分片和副本需要仔细
metrika.xml
配置
节点扩展
单节点多实例部署
多套配置文件
将/etc/clickhouse-server/
目录下的config.xml
、users.xml
、metrika.xml
复制到/etc/clickhouse-server/replica02/
目录下
并对config.xml
中配置的目录和端口做如下修改:
<!-- 日志目录 -->
<logger>
<log>/var/log/clickhouse-server/replica02/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/replica02/clickhouse-server.err.log</errorlog>
</logger>
<!-- 端口 -->
<http_port>8124</http_port>
<tcp_port>9001</tcp_port>
<mysql_port>9005</mysql_port>
<interserver_http_port>9010</interserver_http_port>
<!-- 数据目录 -->
<path>/var/lib/clickhouse/replica02/</path>
<tmp_path>/var/lib/clickhouse/replica02/tmp/</tmp_path>
<user_files_path>/var/lib/clickhouse/replica02/user_files/</user_files_path>
<!-- user配置 -->
<user_directories>
<local_directory>
<!-- Path to folder where users created by SQL commands are stored. -->
<path>/var/lib/clickhouse/replica02/access/</path>
</local_directory>
</user_directories>
<include_from>/etc/clickhouse-server/replica02/metrika.xml</include_from>
<format_schema_path>/var/lib/clickhouse/replica02/format_schemas/</format_schema_path>
多套服务启动文件
复制 /etc/systemd/system/clickhouse-server.service
重命名为 clickhouse-server-replica02.serviced
修改启动时加载的配置指向新的文件上,同时pid-file需要跟服务名称保持一直,否则启动不起来
ExecStart=/usr/bin/clickhouse-server --config=/etc/clickhouse-server/replica02/config.xml --pid-file=/run/clickhouse-server/clickhouse-server-replica02.pid
修改完毕后,重新加载systemd服务 system daemon-reload
然后使用命令启动多实例 sudo systemctl start clickhouse-server-replica02
集群验证
通过客户端登录任意节点,查询集群配置信息
select * from system.clusters;
集群数据写入
写入分布式表
分布式表会跨服务器分发插入数据,仅仅是简单的请求转发,同时写入多个副本无法保证副本数据的一致性,长时间可能会造成副本数据有些不一样
所以不推荐直接写入分布式表
利用ReplicatedMergeTree引擎写入本地表
将数据副本的同步过程交给ClickHouse的复制表引擎管理
可以自已指定要将哪些数据写入哪些服务器,并直接在每个分片上执行写入,并且你可以使用任何分片方案。对于复杂业务特性的需求,这可能是非常重要的
官方推荐这种方案