前言
ClickHouse是“俄罗斯Google”——Yandex公司在2016年开源的面向OLAP的列式存储数据库,近来发展非常迅猛,国内很多大厂都在生产环境中广泛使用。随着业务体量的扩张,我们的业务人员逐渐有了分析海量用户行为和点击流数据的需求,经过各种调研,最终敲定ClickHouse为最佳方案(成功挤掉了之前有丰富实操经验的Kudu哈哈)。
本文就来记录一个ClickHouse开发测试集群的安装与部署过程。
前置条件
- 7台阿里云ECS,每台52 vCPU,192GB内存,3TB * 4云盘(测试业务都是混布的,所以请不要太在意节点规格=。=)
- 操作系统CentOS 7.5
- 配置SSH互信,修改ulimit,关闭防火墙和虚拟内存等等,不再赘述
- ClickHouse版本19.16.14.65
下载并安装RPM包
先安装依赖项。
yum -y install libicu perl-JSON-XS
ClickHouse的RPM包由Altinity提供,可以直接wget到服务器上。
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-common-19.16.14.65-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-common-static-19.16.14.65-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-server-19.16.14.65-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-debuginfo-19.16.14.65-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-test-19.16.14.65-1.el7.x86_64.rpm/download.rpm
wget --content-disposition https://packagecloud.io/Altinity/clickhouse/packages/el/7/clickhouse-client-19.16.14.65-1.el7.x86_64.rpm/download.rpm
然后安装之。
rpm -ivh clickhouse-server-common-19.16.14.65-1.el7.x86_64.rpm
rpm -ivh clickhouse-common-static-19.16.14.65-1.el7.x86_64.rpm
rpm -ivh clickhouse-server-19.16.14.65-1.el7.x86_64.rpm
rpm -ivh clickhouse-debuginfo-19.16.14.65-1.el7.x86_64.rpm
rpm -ivh clickhouse-test-19.16.14.65-1.el7.x86_64.rpm
rpm -ivh clickhouse-client-19.16.14.65-1.el7.x86_64.rpm
安装完毕后,启动脚本clickhouse-server位于/etc/init.d目录下,而主要的配置文件config.xml、users.xml位于/etc/clickhouse-server目录下。
高可用拓扑
ClickHouse与ElasticSearch类似,也有数据分片(shard)和副本(replica)的概念。但是ClickHouse只允许一个实例持有一个分片,所以在生产环境中,一般采用两个甚至多个对等的集群互相复制和热备(依靠ReplicatedMergeTree引擎族实现复制表),当某集群上的某节点挂掉后,可以由其他集群上持有对应分片的节点顶上,实现高可用。
但是,我们现在手上只有一个7节点的小集群,并且尚处在试运行阶段,没有必要大动干戈,所以可以采用每个节点启动两个ClickHouse实例,且每个分片的两个副本都位于相邻节点上的“环形副本”(circular replication)拓扑方案,如下图所示,很容易理解。
当然,在实际生产环境中,还是强烈推荐使用对等集群实现高可用。
配置config.xml
config.xml包含了除用户、配额设置之外的所有与ClickHouse服务相关的配置项。首先将它复制一份出来并命名为config2.xml,作为节点上另一个实例的配置。
cp config.xml config2.xml
注意,config.xml中可以使用
config.xml、config2.xml相同的配置项
ClickHouse集群节点配置
按照上文的图示来配置如下的7分片2副本方案,两个实例分别占用9000和9001端口。这两个端口也分别是同机两个ClickHouse实例的TCP端口,下文会说。
1
true
ck-node001
9000
default
default
ck-node002
9001
default
default
1
true
ck-node002
9000
default
default
ck-node003
9001
default
default
1
true
ck-node003
9000
default
default
ck-node004
9001
default
default
1
true
ck-node004
9000
default
default
ck-node005
9001
default
default
1
true
ck-node005
9000
default
default
ck-node006
9001
default
default
1
true
ck-node006
9000
default
default
ck-node007
9001
default
default
1
true
ck-node007
9000
default
default
ck-node001
9001
default
default
- sht_ck_cluster_1是集群标识,可以自行规定,在创建分布式表(引擎为Distributed)时需要用到。
- weight表示每个分片的写入权重值,数据写入时会有较大概率落到weight值较大的分片,这里全部设为1。
- internal_replication表示是否启用内部复制,即写入数据时只写入到一个副本,其他副本的同步工作靠复制表和ZooKeeper异步进行,显然设为true是科学的。
ZK集群节点配置
ClickHouse的复制表强依赖于ZooKeeper(作为元数据存储)。我们直接复用了原本存在的3节点ZK集群。
zk-node001
2181
zk-node002
2181
zk-node003
2181
数据压缩配置
这里只是取消了原来的注释而已。
10000000000
0.01
lz4
- min_part_size是可被压缩的数据块的最小大小,默认值10GB。
- min_part_size_ratio是可被压缩的数据块占全表大小的最小比例,默认值1%。
- method是压缩算法,可选lz4和zstd。
连接、并发查询配置
由于并非真正的线上集群,并且集群里还有HDFS等服务在跑,所以设得比较小一些。
128
3
16
ClickHouse本身也不是为了密集OLTP查询而设计的,所以最大并发查询数不会很大,默认值为100。
时区配置
Asia/Shanghai
config.xml、config2.xml不同的配置项
为了方便对比,以下都贴截图,左侧为config.xml,右侧为config2.xml。 截图会被压糊,还是文本吧= =
日志配置
注意要写到不同的路径下。
- config.xml
trace
/var/log/clickhouse-server/clickhouse-server.log
/var/log/clickhouse-server/clickhouse-server.err.log
1000M
10
- config2.xml
trace
/var/log/clickhouse-server2/clickhouse-server2.log
/var/log/clickhouse-server2/clickhouse-server2.err.log
1000M
10
端口配置
包含HTTP、TCP、节点间通信的端口。注意TCP端口分别与上文副本配置的端口号一致,HTTP和节点间通信端口不要与副本的端口冲突。
- config.xml
8123
9000
9009
- config2.xml
8124
9001
9010
目录路径配置
包含数据目录、临时目录、用户文件目录和输入schema目录,两个实例各使用一块硬盘(分别挂载到/data3和/data4)。
- config.xml
/data3/clickhouse/data/
/data3/clickhouse/tmp/
/data3/clickhouse/user_files/
/data3/clickhouse/format_schemas/
- config2.xml
/data4/clickhouse/data/
/data4/clickhouse/tmp/
/data4/clickhouse/user_files/
/data4/clickhouse/format_schemas/
复制表宏(macros)配置
该配置在每个节点的每个实例上都不同,且可以自有配置。这里可以包含3个元素:
- layer:复制表的层级。在大型集群(比如ClickHouse的发源地Yandex.Metrica)中可能会有多级备份,不过我们自然只有1级了。
- shard:实例所持有的分片ID。
- replica:实例所持有的副本ID。
这样,我们在使用ReplicatedMergeTree引擎族创建表时,就不必在ZK路径里分别指定这些值,直接用{layer}、{shard}、{replica}等替代即可。通过“高可用规划”一节的图,就可以写出对应的配置。以node001节点为例:
- config.xml
01
01
01-01-1
- config2.xml
01
07
01-07-2
副本的命名采用了{layer}-{shard}-{replica序号}的方式,更易读。
配置users.xml
users.xml包含了用户、配额设置。结构比较简单,直接贴全文吧。
8
8000000000
0
random
8
8000000000
0
random
1
37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f
::/0
default
default
3600
0
0
0
0
0
这里基本上采用了默认设置,即用户名、密码、profile和配额设置均为default。注意写密码时用SHA256加密后的值:
echo -n 'default' | sha256sum | tr -d '-'
另外,需要根据集群实际情况配置max_threads(单个查询能使用的最多线程数)以及max_memory_usage(单个查询能使用的最多内存量)参数。
修改启动脚本
将原始的启动脚本clickhouse-server复制一份。
cp clickhouse-server clickhouse-server2
clickhouse-server修改数据目录:
CLICKHOUSE_DATADIR_OLD=/data3/clickhouse/data_old
CLICKHOUSE_DATADIR=/data3/clickhouse/data
clickhouse-server2除了修改数据目录之外,还得修改日志、配置、PID和cron文件:
CLICKHOUSE_LOGDIR=/var/log/clickhouse-server2
CLICKHOUSE_DATADIR_OLD=/data4/clickhouse/data_old
CLICKHOUSE_DATADIR=/data4/clickhouse/data
CLICKHOUSE_CRONFILE=/etc/cron.d/clickhouse-server2
CLICKHOUSE_CONFIG=$CLICKHOUSE_CONFDIR/config2.xml
CLICKHOUSE_PIDFILE="$CLICKHOUSE_PIDDIR/$PROGRAM-2.pid"
启动、试运行
推荐先手动把前文涉及到的各种目录(数据目录之类的)mkdir出来,然后再启动。
service clickhouse-server start
service clickhouse-server2 start
在任一节点上打开一个客户端,查询system.clusters系统表,可以得到正确的集群分片和副本信息。
~ clickhouse-client -m -h 127.0.0.1 --password default --port 9000
ClickHouse client version 19.16.14.65.
Connecting to 127.0.0.1:9000 as user default.
Connected to ClickHouse server version 19.16.14 revision 54427.
testdev1-bigdata-ck-node001 :) select * from system.clusters;
SELECT *
FROM system.clusters
┌─cluster──────────┬─shard_num─┬─shard_weight─┬─replica_num─┬─host_name───────────────────┬─host_address─┬─port─┬─is_local─┬─user────┬─default_database─┬─errors_count─┬─estimated_recovery_time─┐
│ sht_ck_cluster_1 │ 1 │ 1 │ 1 │ testdev1-bigdata-ck-node001 │ 10.1.17.3 │ 9000 │ 1 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 1 │ 1 │ 2 │ testdev1-bigdata-ck-node002 │ 10.1.17.4 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 2 │ 1 │ 1 │ testdev1-bigdata-ck-node002 │ 10.1.17.4 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 2 │ 1 │ 2 │ testdev1-bigdata-ck-node003 │ 10.1.17.252 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 3 │ 1 │ 1 │ testdev1-bigdata-ck-node003 │ 10.1.17.252 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 3 │ 1 │ 2 │ testdev1-bigdata-ck-node004 │ 10.1.17.251 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 4 │ 1 │ 1 │ testdev1-bigdata-ck-node004 │ 10.1.17.251 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 4 │ 1 │ 2 │ testdev1-bigdata-ck-node005 │ 10.1.17.2 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 5 │ 1 │ 1 │ testdev1-bigdata-ck-node005 │ 10.1.17.2 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 5 │ 1 │ 2 │ testdev1-bigdata-ck-node006 │ 10.1.17.1 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 6 │ 1 │ 1 │ testdev1-bigdata-ck-node006 │ 10.1.17.1 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 6 │ 1 │ 2 │ testdev1-bigdata-ck-node007 │ 10.1.17.250 │ 9001 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 7 │ 1 │ 1 │ testdev1-bigdata-ck-node007 │ 10.1.17.250 │ 9000 │ 0 │ default │ │ 0 │ 0 │
│ sht_ck_cluster_1 │ 7 │ 1 │ 2 │ testdev1-bigdata-ck-node001 │ 10.1.17.3 │ 9001 │ 0 │ default │ │ 0 │ 0 │
└──────────────────┴───────────┴──────────────┴─────────────┴─────────────────────────────┴──────────────┴──────┴──────────┴─────────┴──────────────────┴──────────────┴─────────────────────────┘
14 rows in set. Elapsed: 0.001 sec.
到此为止,一个高可用的ClickHouse集群就建立好了。
The End
关于复制表、分布式表的原理和演示,就留到下一篇来写吧,这篇已经够长了。
看天气好像要下雨了,春雨贵如油。
民那晚安。