数据分片是将数据进行横向切分,这是一种在面对海量数据的场 景下,解决存储和查询瓶颈的有效手段,是一种分治思想的体现。 ClickHouse支持分片,而分片则依赖集群。每个集群由1到多个分片组成,而每个分片则对应了ClickHouse的1个服务节点。分片的数量上限 取决于节点数量(1个分片只能对应1个服务节点)。
当创建好了这张表之后,那么一次批量插入,就可能形成多个分区,其实每个分区,就是表存储目录中的一个子文件夹
假设用一个 文件夹来存储这张表的所有数据,为了提高效率,可以考虑把 表的所有数据,按照某个维度,分割成多个子文件夹,假设以日期字段为例, 查询不同的月份,到表文件夹的不同子文件夹中寻找即可
对于 OLAP 技术来说,一般都是这对大量行少量列做聚合分析,所以列式存储技术基本可以说是 OLAP 必用的技术方案。列式存储相比于行式存储,列式存储在分析场景下有着许多优良的特性。
MergeTree 的主键使用 PRIMARY KEY 定义,待主键定义之后,MergeTree 会依据index_granularity 间隔(默认 8192 行),为数 据表生成一级索引并保存至 primary.idx 文件内。一级索引是稀疏索引,意思就是说:每一段数据生成一条索引记录,而不是每一条数据都生成索引, 如果是每一条数据都生成索引,则是稠密索引。稀疏索引的好处,就是少量的索引标记,就能记录大量的数据区间位置信息,比如不到 24414 条标记信 息,就能为 2E 条数据提供索引(算法:200000000 / 8192)。在 ClickHouse 中,一级索引常驻内存。总的来说: 一级索引和标记文件一一对齐,两个 索引标记之间的数据,就是一个数据区间,在数据文件中,这个数据区间的所有数据,生成一个压缩数据块。
又称之为跳数索引。目的和一级索引一样,是为了减少待搜寻的数据的范围。跳数索引的默认是关闭的,需要通过参数来开启,索引生成粒度由 granularity 控制,如果生成了二级索引,则会在分区目录下生成额外的:skp_idx_[Column].idx
与 skp_idx_[Column].mrk
文件。跳数索引的生成规则:按照特定规则每隔 granularity 个 index_granularity 条数据,就会 生成一条跳数索引。比如 minmax 跳数索引,生成的是:granularity 个 index_granularity 条数据内的最大值最小值生成一条索引,如果将来需要针对 构建二级索引的这个字段求最大值最小值,则可以帮助提高效率。跳数索引一共支持四种类型:minmax(最大最小)、set(去重集合)、 ngrambf_v1(ngram 分词布隆索引) 和 tokenbf_v1(标点符号分词布隆索引),一张数据表支持同时声明多个跳数索引。比如:
GRANULARITY = 你在创建二级索引索引的指定的
INDEX_GRANULARITY = 8192 构建一条主键索引
GRANULARITY * INDEX_GRANULARITY 构建一条 二级索引
- CREATE TABLE skip_test(
- ID String,
- URL String,
- Code String,
- EventTime Date,
- INDEX a ID TYPE minmax GRANULARITY 5,
- INDEX b (length(ID) * 8) TYPE set(2) GRANULARITY 5,
- INDEX c (ID, Code) TYPE ngrambf_v1(3, 256, 2, O) GRANULARITY 5,
- INDEX d ID TYPE tokenbf_v1(256, 2, 0) GRANULARITY 5
- ) ENGINE= MergeTree()
- order by id;
关于跳数索引支持的多种类型的区别:
ClickHouse 的数据存储文件 column.bin 中存储是一列的数据,由于一列是相同类型的数据,所以方便高效压缩。在进行压缩的时候,请 注意:一个压缩数据块由头信息和压缩数据两部分组成,头信息固定使用 9 位字节表示,具体由 1 个 UInt8(1字节)整型和 2 个 UInt32(4字节)整型 组成,分别代表使用的压缩算法类型、压缩后的数据大小和压缩前的数据大小。每个压缩数据块的体积,按照其压缩前的数据字节大小,都被严格控制在 64KB~1MB,其上下限分别由 min_compress_block_size(默认65536=64KB)与 max_compress_block_size(默认1048576=1M)参数指定。具体压 缩规则:
原理的说法: 每 8192 条记录,其实就是一条一级索引、一个索引区间压缩成一个数据块。
1、单个批次数据 size < 64KB:如果单个批次数据小于 64KB,则继续获取下一批数据,直至累积到size >= 64KB时,生成下一个压缩数据块。如果平均每条 记录小于8byte,多个数据批次压缩成一个数据块
2、单个批次数据 64KB <= size <=1MB:如果单个批次数据大小恰好在 64KB 与 1MB 之间,则直接生成下一个压缩数据块。
3、单个批次数据 size > 1MB:如果单个批次数据直接超过 1MB,则首先按照 1MB 大小截断并生成下一个压缩数据块。剩余数据继续依照上述规则执行。此时, 会出现一个批次数据生成多个压缩数据块的情况。如果平均每条记录的大小超过 128byte,则会把当前这一个批次的数据压缩成多个数据块。