前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ClickHouse 入门:数据查询流程解析

ClickHouse 入门:数据查询流程解析

作者头像
LakeShen
发布2022-06-23 14:54:08
2.7K0
发布2022-06-23 14:54:08
举报
文章被收录于专栏:数据库和大数据技术原理解析

前言

ClickHouse 是一款 ROLAP 列式数据库,在海量数据分析场景中,能够帮助我们快速得到想要的"分析性"数据。本文主要从个人视角讲解 ClickHouse 一次数据查询的整体流程,更多的是自己的一些理解和思考,如有不对,欢迎指出和交流。

一、ClickHouse 数据组织形式

1.1 ClickHouse 集群、分片、副本含义

一个 ClickHouse 集群是通过分片组成。ClickHouse 分片可以由一台或者多台机器构成,当多台机器组成一个分片时,其中一个节点为主副本节点,其余则为数据副本节点,比如上图,副本数则为 1。一个 ClickHouse 集群可以由多台机器构成,当然也可以根据不同业务特性进行划分,多个集群,但每个集群都有少量机器。

ClickHouse 分片你可以理解为就是 ClickHouse 一个单机数据库实例(副本节点也算),多个这种单机数据库实例构成一个 ClickHouse 集群。分片是指包含数据不同部分的服务器(要读取所有数据,必须访问所有分片)。ClickHouse 通过分片,将一张表的数据水平分割在不同的节点上,随着业务的发展,当表数据的大小增加到很大时,也能够通过水平扩容, 保证数据的存储。

副本则是存储复制数据的服务器(要读取所有数据,访问任一副本上的数据即可)。ClickHouse 通过副本节点进行数据冗余存储,用空间来换取数据可用性,当主副本节点不可用时,能够选择其他副本节点进行数据服务。

1.2 MergeTree 表数据组织形式

MergeTree 表引擎数据组织形式从单个分片视角来看,底层通过目录 + 文件的方式进行组织。首先,ClickHouse 会有数据根目录,假设数据根目录为:

代码语言:javascript
复制
/data/clickhouse/data

现在用户创建了一个数据库为 lake 的数据库,那么在这个根目录创建一个为 lake的目录:

代码语言:javascript
复制
/data/clickhouse/data/lake

当有多个数据库时,底层数据目录结构为:

代码语言:javascript
复制
clichouse根目录路径/数据库名称

此时在 lake数据库中创建一个名为 hello_lake 的数据表,分区键为日期键(形式为YYYYMMDD),当插入第一批次数据后,假设插入的数据都属于 20210323 这个分区,那么底层表的数据目录结构为:

代码语言:javascript
复制
/data/clickhouse/data/lake/hello_lake/20210323_1_1_0

ClickHouse 每插入一批次数据,则会在底层形成一个或者多个分区目录,具体看插入数据中是否有多个分区的数据。假设现在有插入了一批 20210323 这个分区的数据,那么底层会多一个目录, 2021032322_0,分区相同,但是分区后面的数字不同。关于分区后面数字的解析,具体细节,可以参见《ClickHouse 原理解析与应用实践》6.2.2 章节。

在分区目录中,就是存放的具体数据,分区目录中有这些文件:

primary.idx 是索引文件,会按照你创建表时,指定的 primary key 排序(如果不指定,默认和 order by key 相同),[Column].bin 为列压缩后数据,[Column]表示列的名称,当有多个列时,就会有多个这样的文件。[Column].mrk 表示索引编号与 bin 文件中便宜量的映射。

二、ClickHouse 数据查询流程

2.1 业务方表使用形式

在生产环境中,业务方在使用 ClickHouse 时,一般会使用到两种类型的表:

  1. Replicated + MergeTree 系列的本地表,同时会定义分区键,一般会按天进行分区。
  2. 业务查询则使用 Distributed 表。

数据的写入是直接写入到各个分片上面的本地表,本地表用来真正数据存储,Distributed 表引擎的表则用于数据的查询,Distributed 表引擎本身不存储数据, 但可以在多个服务器(分片)上进行分布式查询。简单理解,Distributed 表引擎只是你真实数据表(本地表)的代理,在进行数据查询时,它会将查询请求发送到各个分片上,结合索引(如果有),并行进行查询计算,最终将结果进行合并,返回到 Client。

2.2 Distributed 表数据查询流程

下面是一次对于 Distributed 表引擎类型表查询的流程:

整体上查询过程分为 6 个步骤:

  1. Client 发送查询语句到 ClickHouse 代理,一般为 Http 请求,同时查询语句一般会设定分区范围进行查询。
  2. ClickHouse 代理根据负载均衡策略,选取一个请求节点(集群中的一个分片),将查询语句转到请求节点中。
  3. 请求节点将语句转换,比如如果用到了 Distributed 表,将其转成文为本地表,之后将查询语句请求到 ClickHouse 集群所有分片进行数据查询。
  4. 每个分片执行完查询语句后,返回结果给请求节点。
  5. 请求节点根据用户的查询逻辑,合并最终的结果,并返回给 ClickHouse 代理。
  6. 最终,ClickHouse 代理将结果返回给客户端,业务层进行数据的使用。

在分片上执行查询语句时,会根据查询语句中的分区范围,先进行分区级别的数据过滤。之后在满足分区条件的目录中,通过 primary.idx 文件,结合索引键的取值范围,查询出索引编号的范围,然后通过查询列的 [Column].mrk 文件,找到其 [Column].bin 文件中的偏移量对应关系,最终将数据加载到内存进行分析和计算。

三、其他

在对 Distributed 表引擎类型表进行查询时,一定要注意子查询的使用姿势,比如下面的语句:

代码语言:javascript
复制
select A,B,C from Y where H = 100 and 
Z in (select Z from Y where D in ('a', 'b') )

其中 Y 是 Distributed 表引擎的表,假设 ClickHouse 集群有 10 台机器,那么上面的语句最终会有 100 次查询(N的平方,N 为集群分片数),可能会使查询时间变长,这里可以用 GLOBAL IN 来减少查询次数来进行代替,当然,GLOBAL IN 语法会存在网络数据的分发,同时数据会以临时的内存表存在内存中,所以子查询中的数据不宜过大,如果表数据中存在重复数据的话,也可以通过 Distinct 进行数据去重。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LakeShen 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、ClickHouse 数据组织形式
    • 1.1 ClickHouse 集群、分片、副本含义
      • 1.2 MergeTree 表数据组织形式
      • 二、ClickHouse 数据查询流程
        • 2.1 业务方表使用形式
          • 2.2 Distributed 表数据查询流程
          • 三、其他
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档