交互式分析领域,为何 ClickHouse 能够杀出重围?+ 查看更多
交互式分析领域,为何 ClickHouse 能够杀出重围?
+ 查看更多
发布日期:2021-01-13 17:15
一、交互式分析之 ClickHouse
1. 交互式分析简介
交互式分析,也称 OLAP(Online Analytical Processing),它赋予用户对海量数据进行多维度、交互式的统计分析能力,以充分利用数据的价值进行量化运营、辅助决策等,帮助用户提高生产效率。
交互式分析主要应用于统计报表、即席查询(Ad Hoc)等领域,前者查询模式较固定,后者即兴进行探索分析。代表场景例如:移动互联网中 PV、UV、活跃度等典型实时报表;互联网内容领域中人群洞察、关联分析等即席查询。
交互式分析,也称 OLAP(Online Analytical Processing),它赋予用户对海量数据进行多维度、交互式的统计分析能力,以充分利用数据的价值进行量化运营、辅助决策等,帮助用户提高生产效率。
交互式分析主要应用于统计报表、即席查询(Ad Hoc)等领域,前者查询模式较固定,后者即兴进行探索分析。代表场景例如:移动互联网中 PV、UV、活跃度等典型实时报表;互联网内容领域中人群洞察、关联分析等即席查询。

- 大多数访问是读请求。
- 写入通常为追加写,较少更新、删除操作。
- 读写不关注事务、强一致等特性。
- 查询通常会访问大量的行,但仅部分列是必须的。
- 查询结果通常明显小于访问的原始数据,且具有可理解的统计意义。
2. 百花齐放下的 ClickHouse

其中,ClickHouse 作为一款 PB 级的交互式分析数据库,最初是由号称 “ 俄罗斯 Google ” 的 Yandex 公司开发,主要作为世界第二大 Web 流量分析平台 Yandex.Metrica(类 Google Analytic、友盟统计)的核心存储,为 Web 站点、移动 App 实时在线的生成流量统计报表。


二、ClickHouse 架构
1.集群架构

- Shard :集群内划分为多个分片或分组(Shard 0 … Shard N),通过 Shard 的线性扩展能力,支持海量数据的分布式存储计算。
- Node :每个 Shard 内包含一定数量的节点(Node,即进程),同一 Shard 内的节点互为副本,保障数据可靠。ClickHouse 中副本数可按需建设,且逻辑上不同 Shard 内的副本数可不同。
- ZooKeeper Service :集群所有节点对等,节点间通过 ZooKeeper 服务进行分布式协调。
2.数据模型
(1)逻辑数据模型
CREATE TABLE table_local ON CLUSTER cluster_test
(
OrderKey UInt32, # 列定义
OrderDate Date,
Quantity UInt8,
TotalPrice UInt32,
……
)
ENGINE = MergeTree() # 表引擎
PARTITION BY toYYYYMM(OrderDate) # 分区方式
ORDER BY (OrderDate, OrderKey); # 排序方式
SETTINGS index_granularity = 8192; # 数据块大小
# 然后,创建分布式表
CREATE TABLE table_distribute ON CLUSTER cluster_test AS table_local
ENGINE = Distributed(cluster_test, default, table_local, rand()) # 关系映射引擎
- MergeTree :ClickHouse 中使用非常多的表引擎,底层采用 LSM Tree 架构,写入生成的小文件会持续 Merge。
- Distributed :ClickHouse 中的关系映射引擎,它把分布式表映射到指定集群、数据库下对应的本地表上。

(2)物理存储模型
- 数据分区:每个分片副本的内部,数据按照 PARTITION BY 列进行分区,分区以目录的方式管理,本文样例中表按照时间进行分区。
- 列式存储:每个数据分区内部,采用列式存储,每个列涉及两个文件,分别是存储数据的 .bin 文件和存储偏移等索引信息的 .mrk2 文件。
- 数据排序:每个数据分区内部,所有列的数据是按照 ORDER BY 列进行排序的。可以理解为:对于生成这个分区的原始记录行,先按 ORDER BY 列进行排序,然后再按列拆分存储。
- 数据分块:每个列的数据文件中,实际是分块存储的,方便数据压缩及查询裁剪,每个块中的记录数不超过 index_granularity,默认 8192。
- 主键索引:主键默认与 ORDER BY 列一致,或为 ORDER BY 列的前缀。由于整个分区内部是有序的,且切割为数据块存储,ClickHouse 抽取每个数据块第一行的主键,生成一份稀疏的排序索引,可在查询时结合过滤条件快速裁剪数据块。

三、ClickHouse核心特性
ClickHouse 为什么会有如此高的性能,获得如此快速的发展速度?下面我们来从 ClickHouse 的核心特性角度来进一步介绍。
ClickHouse 采用列存储,这对于分析型请求非常高效。一个典型且真实的情况是:如果我们需要分析的数据有 50 列,而每次分析仅读取其中的 5 列,那么通过列存储,我们仅需读取必要的列数据,相比于普通行存,可减少 10 倍左右的读取、解压、处理等开销,对性能会有质的影响。
这是分析场景下,列存储数据库相比行存储数据库的重要优势。这里引用 ClickHouse 官方一个生动形象的动画,方便大家理解:







- SQL 方言:在常用场景下,兼容 ANSI SQL,并支持 JDBC、ODBC 等丰富接口。
- 权限管控:支持 Role-Based 权限控制,与关系型数据库使用体验类似。
- 多机多核并行计算:ClickHouse 会充分利用集群中的多节点、多线程进行并行计算,提高性能。
- 近似查询:支持近似查询算法、数据抽样等近似查询方案,加速查询性能。
- Colocated Join:数据打散规则一致的多表进行 Join 时,支持本地化的 Colocated Join,提升查询性能。
……
四、ClickHouse 的不足
基于 ClickHouse 的当前架构,实现自动均衡相对复杂,导致相关问题的根因在于 ClickHouse 分组式的分布式架构:同一分片的主从副本绑定在一组节点上,更直接的说,分片间数据打散是按照节点进行的,自动均衡过程不能简单的搬迁分片到新节点,会导致路由信息错误。而创建新表并在集群中进行全量数据重新打散的方式,操作开销过高。

但 ClickHouse 并不适合实时写入,原因在于 ClickHouse 并非典型的 LSM Tree 架构,它没有实现 Memory Table 结构,每批次写入直接落盘作为一棵 Tree(如果单批次过大,会拆分为多棵 Tree),每条记录实时写入会导致底层大量的小文件,影响查询性能。
五、结语
分享到:
推荐精彩博文