最近用于OLAP场景的列式数据库ClickHouse挺火的,这里简单讲一下安装,部署和使用。不过阿里云都有SaaS版直接使用了,没有的才要自己搭🤡
单机版
1. 安装部署
单机安装,怎么快怎么来,实际上就这些:
sudo apt-get install apt-transport-https ca-certificates dirmngr
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E0C56BD4
echo "deb https://repo.clickhouse.tech/deb/stable/ main/" | sudo tee \
/etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
sudo apt-get install -y clickhouse-server clickhouse-client
sudo service clickhouse-server start
clickhouse-client
2. 启动命令
如果找不到service的话,debian可以直接去这目录,另外也可以看看实际启动命令是啥,
启动:
$debian /usr/sbin/service clickhouse-server start
# 启动配置见
vim /etc/systemd/system/clickhouse-server.service
3. 配置文件
存储配置
这里是参考官方文档抄的存储策略,直接写在config.d
目录下的storage.xml
(默认SSD,触发条件时迁移hdd)
<yandex>
<storage_configuration>
<disks>
<fast_ssd>
<path>/data/fast_ssd/</path>
</fast_ssd>
<hdd1>
<path>/home/clickhouse/hdd1/</path>
</hdd1>
</disks>
<policies>
<moving_from_ssd_to_hdd>
<volumes>
<hot>
<disk>fast_ssd</disk>
<max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
</hot>
<cold>
<disk>hdd1</disk>
</cold>
</volumes>
<move_factor>0.2</move_factor>
</moving_from_ssd_to_hdd>
</policies>
</storage_configuration>
</yandex>
4. 建表
举个例子(实际使用必须确定清楚表引擎和聚合函数),这里只是现场想个例子展示预聚合用法:
- 表引擎使用:
MergeTree
,简单聚合函数 - order by就是主键了
- 按时间分区
- 存储策略是优先SSD,上面那个
- 存储时间两个月
create table test.user_info
(
record_time DateTime('Asia/Shanghai'),
user String,
cost Float64
)ENGINE = MergeTree()
ORDER BY (record_time,user)
PARTITION BY record_time
SETTINGS storage_policy = 'moving_from_ssd_to_hdd'
TTL record_time + INTERVAL 2 MONTH
-- 创建物化视图,比如每天每个用户cost总量
CREATE MATERIALIZED VIEW user_info_daily_mv
ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(day)
SETTINGS storage_policy = 'moving_from_ssd_to_hdd'
ORDER BY (day,user)
AS SELECT
toStartOfDay(record_time) AS day,
user ,
sum(cost) as cost_count
FROM test.user_info
GROUP BY (day,user)
集群版(带副本)
1. zookeeper集群部署
正式环境貌似要设置zookeeper的日志清理
测试用compose直接起
version: '3.1'
services:
zoo1:
image: zookeeper
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo2:
image: zookeeper
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo3:
image: zookeeper
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
手动安装
这部分删了,手动装挺麻烦的,这部分不大确定,虽然是能跑起来
2. 安装clickhouse
同上
3. 更新配置(2分片2副本)
不建议一个clickhouse-server拥有两个replicas来自不同shard。(除了性能问题,还会存在分布式DDL无法使用)
见CIRCULAR REPLICATION CLUSTER TOPOLOGY IN CLICKHOUSE中的设计和github上issue所提的问题
即每台机器是代表某个分片的某个副本
所有配置文件
- config.xml (主配置文件)
- users.xml (用户及配置限制)
- storeage.xml (存储与策略配置)
- metrika.xml(集群配置)
config.xml (主配置文件)
<listen_host>0.0.0.0</listen_host>
storage.xml (存储与策略配置)
见单机版,冷热数据划分,实际规则
- part超过1G的迁移
- ssd快不够容量时迁移
user.xml(用户配置)
- 配置文件见user settings
- 可以设置个默认密码,用户账号管理用SQL-driven workflow
metrika.xml文件(cluster配置)
- 申请4台机器,两个分片,2个副本
- 1和2的机器在同一个分片下,3和4在同一个分片下
<yandex>
<remote_servers>
<test_cluster>
<shard>
<!-- <secret></secret> -->
<!-- Optional. Shard weight when writing data. Default: 1. -->
<weight>1</weight>
<!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
<internal_replication>true</internal_replication>
<replica>
<!-- Optional. Priority of the replica for load balancing (see also load_balancing setting). Default: 1 (less value has more priority). -->
<!-- <priority>1</priority> -->
<host>xx.xxx.xx.xx1</host>
<port>9000</port>
</replica>
<replica>
<host>xx.xxx.xx.xx2</host>
<port>9000</port>
</replica>
</shard>
<shard>
<weight>1</weight>
<internal_replication>true</internal_replication>
<replica>
<host>xx.xxx.xx.xx3</host>
<port>9000</port>
</replica>
<replica>
<host>xx.xxx.xx.xx4</host>
<port>9000</port>
</replica>
</shard>
</test_cluster>
</remote_servers>
<!-- 这里其实就是标记当前机器属于哪个shard,以及副本代号 -->
<macros>
<shard>01</shard>
<replica>xx.xxx.xx.xx1<replica>
</macros>
<!-- ZK-->
<zookeeper>
<node index="1">
<host>xx.xxx.xx.xx1</host>
<port>2181</port>
</node>
<node index="2">
<host>xx.xxx.xx.xx2</host>
<port>2182</port>
</node>
<node index="3">
<host>xx.xxx.xx.xx3</host>
<port>2183</port>
</node>
</zookeeper>
</yandex>
宏定义(统一建表语句)
这里不设置layer层了,没必要
记得每个节点都必须更新这个!!!
注意同一个shard的节点的shard配置必须一致!!
<macros>
<shard>01</shard>
<replica>hostname</replica>
</macros>
最终配置文件
丢到config.d目录下覆盖默认配置
- xxx.xml(合并了listen配置和storeage配置)
- metrika.xml(单独,这部分是热更新,无需重启)
用户配置丢到user.d目录下覆盖默认配置
- users.xml
集群样例
具体可以去查看system的cluster表,看看集群配置是否生效了
4. 每个节点启动click server(确定互通)
- 9000端口用于clickhouse互通与clickhouse-client
- 8123端口为http访问
5. 建表
/*分布式DDL建库*/
CREATE DATABASE test ON CLUSTER 'test_cluster'
/*分布式DDL建库,树引擎其实可以不写,就是默认值来的*/
CREATE TABLE test.test_info_local ON CLUSTER 'test_cluster'(
......
)ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test/test_info_local','{replica}')
PARTITION BY record_time
ORDER BY (record_time)
TTL record_time + INTERVAL 6 MONTH
SETTINGS storage_policy = 'moving_from_ssd_to_hdd'
/*分布式DDL建立原始数据分布表*/
CREATE TABLE test.test_info_local on CLUSTER 'test_cluster'
as test.test_info
ENGINE = Distributed(test_cluster,test,test_info_local,rand())
/*以下不写了,基本看官方文档详细点*/
/*物化视图有实际table的,只不过默认隐藏,我们也可以手动创建*/
/*分布式DDL创建物化视图*/
/*这里因为提前建好复制表了,不需要再设置engine那些*/
/**分布式DDL 创建全局视图*/
- 分布式DDL跑一次就够了
6. 实际应用
写本地表
最好直接写本地表,因为直接写分布式表,在clickhouse上还要再同步一次,实际上相当于双写了
读分布式表
7. 测试
性能方面简单的可以看官方说明,尽量批量写,这里其实还会涉及到clickhouse里part的概念,不细说了
We recommend inserting data in packets of at least 1000 rows, or no more than a single request per second.
8. 个人经验
- 表引擎要留意清楚,个人一般使用最多的是
SummingMergeTree
或者AggregatingMergeTree
,分布式就加个replica
前缀 - clickhouse允许相同主键的数据存在,是否去重以及去重的规则具体看表引擎决定。
- clickhouse不保证part merge的时机,这个是坑,某些实际应用场景时就会感受到的
- 可以对视图再进行视图的聚合,不过要注意,本质上是insert事件触发了视图,视图并不知道原表的数据
- 分布式用到zookeeper(这玩意还是没那么好用),这里依赖它主要是在分布式DDL执行和ReplicaMergeTree主备状态同步上(对于每个insert的数据part,clickhouse都会通过几个事务将记录添加到zookeeper上)
有问题欢迎留言~