Clickhouse
介绍
ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。
列式数据库:来自不同列的值被单独存储,来自同一列的数据被存储在一起
在传统的行式数据库系统中,数据按如下顺序存储:
#0
89354350662
1
Investor Relations
1
2016-05-18 05:19:20
#1
90329509958
0
Contact us
1
2016-05-18 08:10:20
#2
89953706054
1
Mission
1
2016-05-18 07:38:00
#N
…
…
…
…
…
处于同一行中的数据总是被物理的存储在一起。
常见的行式数据库系统有:MySQL、Postgres和MS SQL Server。
在列式数据库系统中,数据按如下的顺序存储:
WatchID:
89354350662
90329509958
89953706054
…
JavaEnable:
1
0
1
…
Title:
Investor Relations
Contact us
Mission
…
GoodEvent:
1
1
1
…
EventTime:
2016-05-18 05:19:20
2016-05-18 08:10:20
2016-05-18 07:38:00
…
这些示例只显示了数据的排列顺序。来自不同列的值被单独存储,来自同一列的数据被存储在一起。
常见的列式数据库有: Vertica、 Paraccel (Actian Matrix,Amazon Redshift)、 Sybase IQ、 Exasol、 Infobright、 InfiniDB、 MonetDB (VectorWise, Actian Vector)、 LucidDB、 SAP HANA、 Google Dremel、 Google PowerDrill、 Druid、 kdb+。
OLAP(理解为就是用来分析的)
OLAP场景的关键特征
绝大多数是读请求
数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。
已添加到数据库的数据不能修改。
对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
宽表,即每个表包含着大量的列
查询相对较少(通常每台服务器每秒查询数百次或更少)
对于简单查询,允许延迟大约50毫秒
列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)
事务不是必须的,比如在银行的一笔交易记录,就是一个典型的事务。
对数据一致性要求低
每个查询有一个大表。除了他以外,其他的都很小。
查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中
OLTP(理解为就是用来记录的)
联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改。比如在银行的一笔交易记录,就是一个典型的事务。 OLTP的特点一般有: 1.实时性要求高。我记得之前上大学的时候,银行异地汇款,要隔天才能到账,而现在是分分钟到账的节奏,说明现在银行的实时处理能力大大增强。 2.数据量不是很大,生产库上的数据量一般不会太大,而且会及时做相应的数据处理与转移。 3.交易一般是确定的,比如银行存取款的金额肯定是确定的,所以OLTP是对确定性的数据进行存取 4.高并发,并且要求满足ACID原则。比如两人同时操作一个银行卡账户,比如大型的购物网站秒杀活动时上万的QPS请求。
列式数据库更适合OLAP场景:针对分析类查询,通常只需要读取表的一小部分列,在列式数据库中你可以只读取你需要的数据


针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。例如,如果只需要读取100列中的5列,这将帮助你最少减少20倍的I/O消耗。
表引擎
MergeTree
Clickhouse 中最强大的表引擎当属 MergeTree (合并树)引擎及该系列(*MergeTree)中的其他引擎。
只有 MergeTree 系列里的表可支持副本:ReplicatedMergeTree。
Distributed
分布式引擎本身不存储数据, 但可以在多个服务器上进行分布式查询。 读是自动并行的。读取时,远程服务器表的索引(如果有的话)会被使用。 分布式引擎参数:服务器配置文件中的集群名,远程数据库名,远程表名,数据分片键(可选)。 示例:
将会从位于«logs»集群中 default.hits 表所有服务器上读取数据。 远程服务器不仅用于读取数据,还会对尽可能数据做部分处理。
接口
命令行客户端
http客户端
HTTP接口允许您在任何编程语言的任何平台上使用ClickHouse。我们使用它在Java和Perl以及shell脚本中工作。
默认情况下,clickhouse-server会在8123端口上监控HTTP请求(这可以在配置中修改)。
基本语法
建立表
先创建本地表,再创建分布式表。
Distributed(cluster, datebase, local_table[, sharding_key])
cluster需要写成在config里自定义的cluster名称
database是分片数据库的名称
local_table是分片本地表的名称
最后一项sharding_key是选填的,可以是一个表达式,例如rand(),也可以是某列 如user_id
将会从位于«cluster»集群中 datebase.local_table表所有服务器上读取数据。
优化建表
sharding key
分布式表,选择合适的有意义的列作为sharding key.没有的话,再选择rand()。参考资料
I am trying to understand how to choose the shard key in Clickhosue ? and how clickhosue chooses which shard? for example, i have a table with 3 columns : user_id, timestamp, city_id.
should i shard by user_id or by City?
i use murmurHash3_64 function.
murmurHash3_64(city_id = 1) return :
First of all you need to understand why do you need sharding by some meaningful column. Why you could not use rand()?
Usually it's not a question what to use, because the sharding naturally follows the business requirements. If you don't have such requirements then you should use rand().
CH uses modulo operation + weight . It's very simple. If you have 6 shards then 956517343494314387 % 6 = 5 === shard number 5. So the rows with the same city_id will be placed on the same shard.
So if you chose city_id as shard key and the distribution by the city usually unequal so the shading will be unequal too. All rows for the big cities like New York or Mexico will in the one shard.
So user_id looks more appropriate as sharding key.
新旧建表语句
在表引擎名称上加上 Replicated 前缀。例如:ReplicatedMergeTree。
Replicated*MergeTree 参数
zoo_path— ZooKeeper 中该表的路径。replica_name— ZooKeeper 中的该表的副本名称。
示例:
已弃用的建表语法示例:
分区(partition by)、索引(order by)、表参数(8192)
分区粒度根据业务特点决定,不宜过粗或过细。一般选择按天分区,也可以指定为 Tuple(),以单表一亿数据为例,分区大小控制在 10-30 个为最佳。新数据插入到表中时,这些数据会存储为按主键排序的新片段(块)。插入后 10-15 分钟,同一分区的各个片段会合并为一整个片段。
必须指定索引列,ClickHouse 中的**索引列即排序列,通过 order by 指定,一般在查询条件中经常被用来充当筛选条件的属性被纳入进来;可以是单一维度,也可以是组合维度的索引;通常需要满足高级列在前、查询频率大的在前原则;还有基数特别大的不适合做索引列,如用户表的 userid 字段;通常筛选后的数据满足在百万以内为最佳。**
Index_granularity 是用来控制索引粒度的,默认是 8192,如非必须不建议调整。
调试
使用format TabSeparatedWithNames导出列表名,否则不显示列表名,然后使用正则 +替换成为,即可展示帮助调试。
数据类型
浮点数
NaN和Inf
与标准SQL相比,ClickHouse 支持以下类别的浮点数:
Inf– 正无穷
-Inf– 负无穷
NaN– 非数字
处理方法:
其他
注意点(应该是echo和curl中才需要,因为格式影响代码执行)
条件=号要贴着两边
换行空格要预留
经常遇到from前面没有空格,从而报错
curl的话要用global。。。
and要换行
group by 使用内存限制
默认情况下,ClickHouse会限制group by使用的内存量,默认设置为9.31GB,由users.xml文件中max_memory_usage参数控制,可以分别为每个用户设置不同的内存量。
在运行任务前增加配置,当然前提是你有足够的内存。增加这个参数:
如果你没有那么多的内存可用,ClickHouse可以通过设置这个“溢出”数据到磁盘:
根据文档,如果需要使用max_bytes_before_external_group_by,建议将max_memory_usage设置为max_bytes_before_external_group_by大小的两倍。 (原因是聚合需要分两个阶段进行:1.查询并且建立中间数据 2.合并中间数据。 数据“溢出”到磁盘一般发生在第一个阶段,如果没有发生数据“溢出”,ClickHouse在阶段1和阶段2可能需要相同数量的内存)。
如果发现还是报内存不够或者服务器直接崩溃,报错如下:
设置partial_merge_join = 1,但是运行速度会很慢。
read timeout at /usr/share/perl5/vendor_perl/Net/HTTP/Methods.pm
connect_timeout, receive_timeout, send_timeout¶
Timeouts in seconds on the socket used for communicating with the client.
Default value: 10, 300, 300.
采用receive_timeout=600,提高socket时间。
Last updated