ClickHouse应用开发建议
合理配置最大并发数
ClickHouse处理速度快是因为采用了并行处理机制,即使一个查询,默认也会用服务器一半的CPU去执行,所以ClickHouse对高并发查询的场景支持的不够。官方默认的最大并发数是100,可以根据实际场景调整并发配置,建议不超过200。
部署负载均衡组件,查询基于负载均衡组件进行,避免单点查询压力太大影响性能
ClickHouse支持连接集群中的任意节点查询,如果查询集中到一台节点,可能会导致该节点的压力过大并且可靠性不高。建议使用ClickHouseBalancer或者其他负载均衡服务,均衡查询负载,提升可靠性。
合理设置分区键,控制分区数在一千以内,分区字段使用整型
- 建议使用toYYYYMMDD(表字段pt_d)作为分区键,表字段pt_d是date类型。
- 如果业务场景需要做小时分区,使用toYYYYMMDD(表字段pt_d)、toYYYYMMDD(表字段pt_h)做联合分区键,其中toYYYYMMDD(表字段pt_h)是整型小时数。
- 如果保存多年数据,建议考虑使用月做分区,例如toYYYYMM(表字段pt_d)。
- 综合考虑数据分区粒度、每个批次提交的数据量、数据的保存周期等因素,合理控制part数量。
查询时最常使用且过滤性最高的字段作为主键,依次按照访问频度从高到低、维度基数从小到大来排
数据是按照主键排序存储的,查询的时可以通过主键快速筛选数据,创建表时合理的设置主键能够大大减少读取的数据量,提升查询性能。例如所有的分析,都需要指定业务的id,则可以将业务id字段作为主键的第一个字段。
根据业务场景合理设置稀疏索引粒度
ClickHouse的主键索引采用的是稀疏索引存储,稀疏索引的默认采样粒度是8192行,即每8192行取一条记录在索引文件中。
使用建议:
- 索引粒度越小,对于小范围的查询更有效,避免查询资源的浪费。
- 索引粒度越大,则索引文件越小,索引文件的处理会更快。
- 超过10亿的表索引粒度可设为16384,其他设为8192或者更小值。
本地表建表参考
本地表创建参考:
CREATE TABLE mybase_local.mytable ( `did` Int32, `app_id` Int32, `region` Int32, `pt_d` Date ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/mybase_local/mytable', '{replica}') PARTITION BY toYYYYMMDD(pt_d) ORDER BY (app_id, region) SETTINGS index_granularity = 8192, use_minimalistic_part_header_in_zookeeper = 1;
使用说明:
- 表引擎选择:
- ZooKeeper上的表信息注册路径,用于区分集群中的不同配置:
/clickhouse/tables/{shard}/{databaseName}/{tableName}:{shard}是分片名称,{databaseName}是数据库名称,{tableName}是复制表名称。
- order by 主键字段:
查询时最常使用且过滤性最高的字段作为主键。依次按照访问频度从高到低、维度基数从小到大来排。排序字段不宜太多,建议不超过4个,否则merge的压力会较大。排序字段不允许为null,如果存在null值,需要进行数据转换。
分布式表建表参考
CREATE TABLE mybase.mytable AS mybase_local.mytable ENGINE = Distributed(cluster_3shards_2replicas, mybase_local, mytable, rand());
使用说明:
- 分布式表名称:mybase.mytable。
- 本地表名称:mybase_local.mytable。
- 通过“AS”关联分布式表和本地表,保证分布式表的字段定义跟本地表一致。
- 分布式表引擎的参数说明:
cluster_3shards_2replicas:逻辑集群名称。
mybase_local:本地表所在库名。
mytable:本地表名。
rand():可选参数,分片键(sharding key),可以是表中一列的原始数据(如did),也可以是函数调用的结果,如随机值rand()。注意该键要尽量保证数据均匀分布,另外一个常用的操作是采用区分度较高的列的哈希值,如intHash64(user_id)。
根据业务场景表的字段选择最小满足的类型使用
数值类型:UInt8/UInt16/UInt32/UInt64, Int8/Int16/Int32/Int64, Float32/Float64等,选择不同长度,性能差别较大。
基于大宽表进行数据分析,不建议使用大表join大表的操作,对分布式join查询转化成本地表的join查询操作,提升性能
ClickHouse分布式join的性能较差,建议在模型侧将数据聚合成大宽表再导入ClickHouse。分布式join的查询转成本地表的join查询,不仅省去大量的节点间数据传播,同时本地表参与计算的数据量也会少很多。业务层再基于所有分片本地join的结果进行数据汇总,性能会有数量级的提升。
设置合理的part大小
min_bytes_to_rebalance_partition_over_jbod参数表示参与在JBOD卷中磁盘之间自动平衡分发part的最小size,该值不能设置得太小或者太大。
若该值设置得太小,小于max_bytes_to_merge_at_max_space_in_pool/1024,那么clickhouse server进程将会启动失败,另外还会引发不必要的part在磁盘间移动。
若该值设置得过大,则很难有part达到这个条件,比如:min_bytes_to_rebalance_partition_over_jbod大于max_data_part_size_bytes(卷中的磁盘可以存储的part的最大大小),则没有part能达到自动平衡的条件。