编者按
ClickHouse自从2016年开源以来,在数据分析(OLAP)领域火热,各个大厂纷纷跟进大规模使用。百分点在某国家级项目中的完成了多数据中心的ClickHouse集群建设,目前存储总量超10PB,日增数据100TB左右,预计流量今年会扩大3倍。本文是结合百分点在前期设计中的经验对ClickHouse做的整理,其中,第二章节最佳实践部分是基于我们的业务场景以及数据规模,经过大量的测试及总结后得到的结论,并且充分保证了整个系统日后的稳定运行,极具参考意义。
作者: 邹立民 赵群 目录 ClickHouse介绍特点
适用场景
核心概念
部署安装
服务器的选择
分布式集群
表的创建
数据的写入
业务查询
跨中心访问
最佳参数实践
集群监控
版本升级
MergeTree
ReplacingMergeTree
SummingMergeTree
Replicated*MergeTree
Distributed
- 绝大多数请求都是用于读访问
- 表很“宽”,即表中包含大量的列
- 在处理单个查询时需要高吞吐量
- 每次查询中大多数场景查询一个大表
- 查询结果显著小于数据源,即数据有过滤或聚合
百分点最佳实践
▶ 部署安装
(1)部署包的获取 ClickHouse官方并没有提供RPM安装包,这里就为大家提供一个标准渠道。 资源地址:https://packagecloud.io/Altinity。 页面提供2个目录:![5466749b22020d9ba2208fb6438b4697.png](https://i-blog.csdnimg.cn/blog_migrate/13cf75cd4a071316275010f9dcbd97e4.png)
▶ 服务器的选择
![eea62c378a93d66e186dfa7f3bcd7457.png](https://i-blog.csdnimg.cn/blog_migrate/934f3f2e565c34047fd7cceac8712dca.png)
▶分布式集群
![22fc02048222eb72148b7589f56d1725.png](https://i-blog.csdnimg.cn/blog_migrate/a9a050cb25b01a4d762bbb40b50e8d23.png)
![ac95c4364b037c421766d43ec67abbab.png](https://i-blog.csdnimg.cn/blog_migrate/9d63be75a8ac5491091dc87630daeb61.png)
- 集群配置
/etc/clickhouse-server/metrika.xml
然后,在/etc/clickhouse-server下新建metrika.xml文件,并且插入以下内容。
true
example1
9000
example2
9000
true
example3
9000
example4
9000
1
01
example1
2181
example2
2181
example3
2181
10000000000
0.01
lz4
说明:
- clickhouse_remote_servers与config.xml中的incl属性值对应;
- cluster_with_replica是集群名,可以自定义;
- Shard即为数据分片;
- internal_replication=true 这个参数和数据的写入,自动复制相关。从生产环境角度考虑,我们都是复制表,通过本地表写入,这里配置true就好。不推荐也不需要考虑其他情况;
- macros是使用复制引擎时指定的ZooKeeper路径中占位符替换的信息。(注意这里的配置在创建Distribute表时会用到,见【表的创建】,注意这里不同的shard和replica需要区分开来,通常集群中的每个节点都不一样的;
- ZooKeeper-servers来同步数据,指定当前集群的ZooKeeper信息即可;
- clickhouse_compression数据的压缩。
▶ 表的创建
我们这里以有副本模式的数据写入为例,首先在每一个节点创建本地表,可以到每个实例上运行一次建表语句。 (1) 创建本地表![bcd516e89739098732029dcd8f9f1b1e.png](https://i-blog.csdnimg.cn/blog_migrate/2ac071cb664d63a706bc23d43ed45a7b.png)
- /clickhouse/tables/{shard}/test:代表的是这张表在ZooKeeper上的路径。即配置在相同Shard里面的不同replica的机器需要配置相同的路径,不同Shard的路径不同;
- {replica}:分片的名称,可以理解是机器名,即需要每台机器都不同;
- 集群的配置,{shard}{replica}配置在配置文件metrika.xml中。
![f20c50f5b387cff0b6b20725f777841a.png](https://i-blog.csdnimg.cn/blog_migrate/da051f59e305b2c412f25cd0c2937cfe.png)
![784a2b364b88aacd11f2bdba7672074c.png](https://i-blog.csdnimg.cn/blog_migrate/7132ac9f15eb98e611749dba3f6ba9ca.png)
▶ 数据的写入
禁止分布式写入,采用本地表写入。 社区很多伙伴在分享时,也都提到了禁止使用分布式表写入,我们也一样。 禁止使用的原因是需要设计及减少Part的生成频率,这对整个集群的稳定性和整体性能有着决定的作用,这个在之前我司的分享中曾经介绍过,我们控制批次的上线和批次的时间窗口,保障写入操作对每个节点的稳定压力。 这里也分享下我们在做评估写入稳定性测试的结果,作为大家可借鉴的评估思路,其本质是平衡好合并速度和Part数量的关系,一定是需要相对均衡的。![b6237cd716400c8cac5af351f5328806.png](https://i-blog.csdnimg.cn/blog_migrate/0dd5ed6bd3649e96e7260ebf90f212b2.png)
▶ 业务查询
业务查询入口要保障查询高可用,需要提供负载均衡和路由的能力。一些大厂都会有自己的LB基础设施。其实大家可以能够观察ClickHouse提供两个网络端口分别是: HTTP默认8123; TCP默认9000; ClickHouse的JDBC客户端是通过HTTP的方式与ClickHouse进行交互的,我们可以判断场景的可以基于HTTP协议做负载均衡,路由的中间件是可以满足需求的,这样我们的选择其实就有很多了。基于传统运维常见中间件的如:LVS,Nginx,HAProxy都有相关的能力,这里我们选用了Nginx。 我们基于它实现2个目的:(1)负载均衡能力(2)采集请求响应日志。![264d92dcf59ba1d611604b0a3b3e3862.png](https://i-blog.csdnimg.cn/blog_migrate/77342e3c80cc5949c863ef34ca267ecc.png)
▶ 跨中心访问
在我们的业务中,需要实现跨数据中心的分析,可以利用ClickHouse的灵活配置化分布式特性,将多数据中心的所有集群的分片都添加到一个ClickHouse实例中,并在该ClickHouse实例上创建分布式表,作为客户端查询的统一入口。如下图所示。![92bf679d1442b1c88b66f9f24e4ca9e3.png](https://i-blog.csdnimg.cn/blog_migrate/37dab9bd25541859ace497b414709dc0.png)
▶ 最佳参数实践
在实际项目中,无论是写入、查询以及保证集群稳定运行,需要配置一些参数来维护集群的状态,下属表格中的参数是我们根据依据线上业务总结出来的最佳实践参数。如果大家基于ClickHouse的生产使用,我们希望使用者理解其中每一个参数的含义,和配置的目的,社区的交流过程发现很多同行中经常遇到一些问题,实际都可以从表格中得到答案。 请注意,其中很多参数配置是对集群的稳定性有着决定性的作用。在理解的基础上,大家才能结合自己的硬件和业务设置自己的最佳参数实践。![2edef9526aaa443d666fe53bb329ad58.png](https://i-blog.csdnimg.cn/blog_migrate/fd043a9fdd37bb418e77059d15d850e3.png)
![99f888f5dee0b6208c50982dc20f2691.png](https://i-blog.csdnimg.cn/blog_migrate/6ffedcbd139d92070299b486660e50c1.png)
![51c72b431ec062e2559dea1433240cde.png](https://i-blog.csdnimg.cn/blog_migrate/9b7792882047d1713f534dd92f56afab.png)
▶ 集群监控
ClickHouse集群监控通常使用ClickHouse Exporter + Prometheus +Grafana方式, Exporter负责信息采集,时序数据库Prometheus存储相关日志,并用Grafana进行展现, Grafana基于ClickHouse的监控主题可以查询社区贡献的插件。![ffc1c6629e5371e69637fbc9d0240b58.png](https://i-blog.csdnimg.cn/blog_migrate/c98394126bc6b6c0345216cb50633edb.png)
![9a7765bafcfda0273669f098d8993bd0.png](https://i-blog.csdnimg.cn/blog_migrate/f8bbae49349cb76dbabf4b91ad3c1372.png)
在数据模型版本兼容的情况下,可以使用如下方式升级版本 总体流程:
- 停止当前进程
- 然后卸载已安装的ClickHouse相关安装包
- 备份当前集群的配置文件config.xml、metrika.xml、users.xml
- 安装新的安装包
- 使用备份的配置文件覆盖自动生成的文件
![e5ddf4447ceb98893262b57c7a26b913.png](https://i-blog.csdnimg.cn/blog_migrate/42321f27785731098b9ba6889410b995.png)
![3de07b46da583a908ec42ecf6f3cb61f.png](https://i-blog.csdnimg.cn/blog_migrate/5f4882cd08ca9db6890179d7b1e799a3.png)
![9eb94ccbb484f19d969249a79bb65f66.png](https://i-blog.csdnimg.cn/blog_migrate/ca46f45b434309a03fc5ff2a2ac7b2af.png)
![31daf4085cac57a9340becaa67c8b1f5.png](https://i-blog.csdnimg.cn/blog_migrate/c177a0711b9dbc1843785ad2a1cea9a9.png)
附常用引擎
▶ MergeTree
MergeTree是ClickHouse中最强大的表引擎。在大量数据写入时数据,数据高效的以批次的形式写入,写入完成后在后台会按照一定的规则就行数据合并,并且MergeTree引擎家族还有很多扩展引擎*MergeTree,注意,Merge引擎不属于*MergeTree系列。 建表:CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
- ENGINE—引擎名和参数。ENGINE = MergeTree(). MergeTree 引擎没有参数
- PARTITION BY—分区键
- ORDER BY—表的排序键
- PRIMARY KEY—主键【默认情况下主键跟排序键(由 `ORDER BY` 子句指定)相同】
- SAMPLE BY—用于抽样的表达式
- SETTINGS—影响 MergeTree 性能的额外参数:
▶ ReplacingMergeTree
该引擎和MergeTree的不同之处在于它会删除具有相同主键的重复项。数据的去重只会在合并的过程中出现。合并会在未知的时间在后台进行,所以你无法预先作出计划。有一些数据可能仍未被处理。因此,ReplacingMergeTree适用于在后台清除重复的数据以节省空间,但是它不保证没有重复的数据出现。同时ReplacingMergeTree在一定程度上可以弥补ClickHouse不能对数据做更新的操作。 建表:CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver])
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
- 合并的时候,ReplacingMergeTree 从所有具有相同主键的行中选择一行留下:
▶ SummingMergeTree
该引擎继承自MergeTree。区别在于,当合并 SummingMergeTree 表的数据片段时,ClickHouse 会把所有具有相同主键的行合并为一行,该行包含了被合并的行中具有数值数据类型的列的汇总值。如果主键的组合方式使得单个键值对应于大量的行,则可以显著的减少存储空间并加快数据查询的速度。 建表:CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = SummingMergeTree([columns])
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
- columns - 包含了将要被汇总的列的列名的元组。可选参数。
▶ Replicated*MergeTree
- ReplicatedMergeTree
- ReplicatedSummingMergeTree
- ReplicatedReplacingMergeTree
- ReplicatedAggregatingMergeTree
- ReplicatedCollapsingMergeTree
- ReplicatedVersionedCollapsingMergeTree
- ReplicatedGraphiteMergeTree
example1
2181
example2
2181
example3
2181
▶ Distributed
以上引擎都是数据存储引擎,但是该引擎-分布式引擎本身不存储数据,但可以在多个服务器上进行分布式查询。读是自动并行的。读取时,远程服务器表的索引会被使用。 建表:CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = Distributed(cluster, db, table_name, [policy_name])
分布式引擎参数:
服务器配置文件中的集群名,远程数据库名,远程表名,数据分布策略。
致 谢
在ClickHouse的学习、评测、应用及对集群的维护过程中,得到了来自同行以及ClickHouse中文社区,还有ClickHouse研发团队的巨大帮助,尤其感谢新浪高鹏的帮助,为我们解决使用过程中的难题提供了思路,同时还为我们的集群架构提出了很多非常有建设性的指导建议。
相关文章
1 | 百分点认知智能实验室出品:智能问答中的对抗攻击及防御策略 |
2 | 百分点认知智能实验室出品:情感分析在舆情中的研发实践(上) |
3 | 一文讲透预训练模型的改进训练算法 ,轻松达到State of the Art |
4 | 百分点认知智能实验室出品:深度迁移学习十八问 |
![17cdbf73fd8a1f002f34b7e587215c14.png](https://i-blog.csdnimg.cn/blog_migrate/a82ebad29bd864506a3463dd22bdbe6a.jpeg)