ClickHouse分布式表的使用
背景
当数据量剧增的时候,clickhouse是采用分片的方式进行数据的存储的,类似于redis集群的实现方式。然后想进行统一的查询的时候,因为涉及到多个本地表,可以通过分布式表的方式来提供统一的入口。
分布式表的写入
听了很多大厂的分享,专家的讲解,都是建议不要直接写分布式表,大厂毕竟是大厂,基于大厂的数据量这样是合理的。凡事都要结合实际,结合自己的业务场景。就像我们一天的数据量可能不到TB级别,整个clickhouse的机器规模不过6台,所以我们决定,还是直接写分布式表,如果性能真的出了问题,再改由写入本地表的方式。官方的建议最优方案也是写本地表,查询分布式表。对于分布式表的 INSERT,数据块只写本地文件系统。之后会尽快地在后台发送到远程服务器。你可以通过查看表目录中的文件列表(等待发送的数据)来检查数据是否成功发送:/var/lib/clickhouse/data/database/table/ 。
分布式表创建语法
Distributed(clusterName, databaseName, tableName[, sharding_key])
1、集群标识符(clusterName)
注意不是复制表宏中的标识符,而是<remote_servers>中指定的那个。
2、本地表所在的数据库名称(databaseName)
3、本地表名称(tableName)
4、(可选的)分片键(sharding key)
该键与config.xml中配置的分片权重(weight)一同决定写入分布式表时的路由,即数据最终落到哪个物理表上。它可以是表中一列的原始数据(如site_id),也可以是函数调用的结果,如上面的SQL语句采用了随机值rand()。注意该键要尽量保证数据均匀分布,另外一个常用的操作是采用区分度较高的列的哈希值,如intHash64(user_id)。
分布式表的查询
写入的时候一般会结合业务,将业务相关的数据放到一个分片上。如上所说的sharding key使用intHash64(user_id)。
需要通过特定键连接数据(IN或JOIN)的查询。如果数据是通过这个键分片的,那么可以使用本地IN或JOIN而不是GLOBAL IN或GLOBAL JOIN,这要高效得多。
大量的服务器(数百或更多)用于大量的小查询(单个客户的查询——网站、广告商或合作伙伴)。为了使小查询不影响整个集群,在单个碎片上为单个客户端定位数据是有意义的。可以设置双层分片:将整个集群划分为“层”,其中一层可以由多个分片组成。单个客户机的数据位于单个层上,但可以根据需要将碎片添加到一个层中,数据在其中随机分布。为每一层创建分布式表,并为全局查询创建一个共享分布式表。