一、ClickHouse 简介
ClickHouse 是一个用于联机剖析(OLAP)的列式数据库管理系统(DBMS),反对 PB 级数据量的交互式剖析,ClickHouse 最后是为 YandexMetrica 世界第二大 Web 剖析平台而开发的。多年来始终作为该零碎的外围组件被该零碎继续应用着。目前为止,该零碎在 ClickHouse 中有超过 13 万亿条记录,并且每天超过 200 多亿个事件被解决。它容许间接从原始数据中动静查问并生成报告。自 2016 年开源以来,ClickHouse 凭借其数倍于业界顶尖剖析型数据库的极致性能,成为交互式剖析畛域的后起之秀,倒退速度十分快。
二、ClickHouse 的架构简述
ClickHouse 是一种分布式的数据库管理系统,不同于其余支流的大数据组件,它并没有采纳 Hadoop 生态的 HDFS 文件系统,而是将数据寄存于服务器的本地盘,同时应用数据正本的形式来保障数据的高可用性。
ClickHouse 应用分布式表实现数据的分布式存储和查问。下图演示了一个分布式表是如何存储的:
分片(Shard):蕴含数据的不同局部的服务器,要读取所有数据必须拜访所有的分片。通过将分布式表的数据寄存到多个 Shard 实现计算和存储的横向扩大。
正本(Replica):每个切片的数据都蕴含多个正本,要读取数据时拜访任一副本上的数据即可。通过正本机制保障存储数据的单节点生效时数据的可用性。只有 MergeTree 类型的表引擎能够反对多正本。ClickHouse 是在表的引擎而不是数据库引擎实现数据的正本性能的,所以正本是表级别的而不是服务器级别的。数据在插入 ReplicatedMergeTree 引擎的表的时候会做数据的主备同步以实现数据的多正本,在同步的过程中应用 ZooKeeper 做分布式协调。
分布式表 (Distributed table): 应用分布式引擎创立的分布式表并不存储数据,然而可能将查问工作散布到多台服务器上解决。在创立分布式表的过程中,ClickHouse 会先在每个 Shard 上创立本地表,本地表只在对应的节点内可见,而后再将创立的本地表映射给分布式表。这样用户在拜访分布式表的时候,ClickHouse 会主动依据集群的架构信息,将申请转发给对应的本地表。
综上所述,一个 ClickHouse 集群由分片组成,而每个分片又由多个数据正本组成。一个正本对应了组成 ClickHouse 集群中的一个服务器节点,并应用该服务器节点上的本地盘存储数据。通过分布式表、数据分片以及数据正本,ClickHouse 实现了集群的横向扩大能力并提供数据的高可用爱护。
三、数据的分层存储
1. 数据的分层存储
从 19.15 这个版本开始,ClickHouse 开始反对 multi-volume storage 这个性能,它容许将 ClickHouse 表存储在蕴含多个设施的卷当中,利用这个个性,咱们能够在 volume 中定义不同类型的磁盘,依据数据的“冷”、“热”水平将数据寄存在不同类型的磁盘上(咱们能够称之为 Tier Storage),以实现性能与老本的均衡。
以下是 Altinity 网站上对于 multi-volume storage 的架构图。
ClickHouse 的配置文件中和磁盘相干的术语:
- 磁盘(Disk):曾经格式化成文件系统的块设施。
- 默认磁盘(Default Disk):在服务器设置中通过 path 参数指定的数据存储,默认门路为 /var/lib/clickhouse/。
- 卷(Volume):有序的磁盘的汇合。
- 存储策略(Storage Policy):卷的汇合以及卷之间数据挪动的规定。
ClickHouse 存储及存储相干的策略是写在配置文件中的,你能够在 /etc/clickhouse-server/config.xml 文件中增加对于卷、磁盘以及存储策略的定义,也能够在 /etc/clickhouse-server/config.d 目录中新建 xml 类型的配置文件,增加相干的存储的定义。
2. ClickHouse 反对的磁盘类型
ClickHouse 次要反对 DiskLocal 和 DiskS3 两种罕用的磁盘类型。
2.1 DiskLocal 类型磁盘
DiskLocal 类型磁盘应用服务器本地磁盘,并指明数据存储的门路。ClickHouse 有一个名为 default 的 DiskLocal 类型的磁盘,门路为 /var/lib/clickhouse/。
同样我能够自定义新增 DiskLocal 类型的磁盘,在 ClickHouse 中新增一个 DiskLocal 类型的磁盘,应用门路问 /data,步骤如下:
a. 服务器新挂载一块硬盘,并格式化文件系统并挂载在 /data 目录下。
b. 在 /etc/clickhouse-server/config.d 目录下新建一个名为 storage.xml 的文件,并增加如下内容:
<yandex>
<storage_configuration>
<disks>
<localdisk> <!-- disk name -->
<path>/data/</path>
</localdisk>
</disks>
<policies>
<local>
<volumes>
<main>
<disk>localdisk</disk>
</main>
</volumes>
</local>
</policies>
</storage_configuration>
</yandex>
c. 重启 clickhouse-server 服务之后,查看新加的磁盘:
2.2 DiskS3 类型磁盘
ClickHouse 反对 DiskS3 类型磁盘,应用 S3 接口拜访存储于对象存储上的数据,原生反对 AWS 对象存储 S3 以及腾讯云对象存储 COS。
上面咱们在 ClickHouse 中再增加一个 DiskS3 类型的磁盘,这里咱们应用腾讯云存储 COS 的一个存储桶作为例子,编辑 /etc/clickhouse-server/config.d/storage.xml 文件,内容如下:
<yandex>
<storage_configuration>
<disks>
<localdisk> <!-- disk name -->
<path>/data/</path>
</localdisk>
<cos>
<type>s3</type>
<endpoint>http://example-1250000000.cos.ap-shanghai.myqcloud.com/ck/</endpoint>
<access_key_id>AKIDxxxxxxxx</access_key_id>
<secret_access_key>xxxxxxxxxxx</secret_access_key>
</cos>
</disks>
<policies>
<local>
<volumes>
<main>
<disk>localdisk</disk>
</main>
</volumes>
</local>
<cos>
<volumes>
<main>
<disk>cos</disk>
</main>
</volumes>
</cos>
</policies>
</storage_configuration>
</yandex>
在下面的配置文件中,咱们定义了两个磁盘,一个名为 localdisk 的 Disklocal 类型的磁盘,应用本地 /data 门路存储数据,另外一个是名为 cos 的 DiskS3 类型的磁盘,应用腾讯云对象存储的 example-1250000000 存储桶存储数据,并须要在配置文件中配置能够拜访该存储桶账号的 SecretId 和 SecretKey,下面的例子中 access_key_id 和 secret_access_key 别离对应拜访 COS 存储桶账号的 SecretId 和 SecretKey。接下来在策略中咱们定义了两个策略用于将数据存储至本地磁盘或者对象存储 COS。
在 ClickHouse 中从新加载配置后,能查问到方才咱们定义的磁盘及存储策略:
在前面的章节咱们会具体演示如何将 ClickHouse 表中的数据存储在本地存储或者对象存储 COS 上。
3. 数据挪动策略
通过在配置文件中配置多个不同类型的磁盘以及存储策略,ClickHouse 可能将数据存储在不同的存储介质中,同时 ClickHouse 还反对配置挪动策略以实现数据在不同存储介质之间主动的挪动。
3.1 基于 move factor 的数据挪动策略
这是一种基于文件大小以及卷(volume)中各个磁盘(Disk)容量应用状况来挪动数据的策略。
上面的例子中,咱们建设了一个名为“moving_from_local_to_cos”的策略,在策略中咱们定义了两种存储,第一个是名为“hot”的卷,这个卷中有一个名为 localdisk 的磁盘并设置这个磁盘上的文件最大值为 1GB;第二个是名为“cold”的卷,这个卷中有一个名为 cos 的磁盘。
最初是 move_factor 参数,示意当卷的可用容量低于 move_factor 参数设定的值的时候,数据将被主动的挪动到下一个卷,本例中当 hot 卷的容量低于 30% 的时候,hot 卷中的数据将被主动的挪动到 cold 卷。
<moving_from_local_to_cos>
<volumes>
<hot>
<disk>localdisk</disk>
<max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
</hot>
<cold>
<disk>cos</disk>
</cold>
</volumes>
<move_factor>0.3</move_factor>
</moving_from_local_to_cos>
有一点须要强调的是,配置文件里各个卷的程序十分重要,当 ClickHouse 有新数据写入的时候,数据会优先写入到第一个卷,再顺次写入前面的卷。同时 move factor 的的挪动策略也是将数据从后面的卷挪动到前面的卷。所以咱们在定义卷的时候,要把数据优先写入的卷放在配置文件的后面。在理论的应用场景中个别是把高性能存储放在后面,把高容量低成本的存储放在前面,这样实现新的热数据寄存在高性能存储以获取极致的实时查问性能、老的历史冷数据寄存在高容量存储以获取较低的存储老本以及较好的批量查问性能。
3.2 基于 TTL 的数据挪动策略
ClickHouse 反对表级别的 TTL 表达式,容许用户设置基于工夫的规定,从而可能主动的在指定的磁盘或者卷之间挪动数据,以实现了数据在不同的存储层之间的分层存储。上面列举了几种比拟典型的 TTL 的写法,从例子咱们能够看出,TTL 表达式只是一个简略的 SQL 表达式,里边蕴含了工夫以及工夫的距离,上面是 TTL 的一些例子:
TTL date_time + INTERVAL 1 MONTH
TTL date_time + INTERVAL 15 HOUR
TTL date_time + toIntervalMonth(ttl)
TTL date_time + toIntervalHour(ttl)
TTL date_time + INTERVAL ttl MONTH
TTL date_time + INTERVAL ttl HOUR
在新建表的时候,咱们能够在建表的 SQL 语句前面加上 TTL 的表达式,用于依据 TTL 设置的工夫策略在磁盘或者卷之间挪动或者删除数据块。
TTL date_time + INTERVAL 6 MONTH DELETE,
date_time + INTERVAL 1 WEEK TO VOLUME 'localdisk',
date_time + INTERVAL 4 WEEK TO DISK 'cos';
上面是一个残缺的建表的语句,并配置了 TTL,依据 LastModifiedDate 中的工夫,默认将数据块搁置到 ttlhot 卷,当 LastModifiedDate 的值超过三个月时将对应的数据块挪动到 ttlcold 卷。
CREATE TABLE cos_inventory_ttl (
appid UInt64,
bucket String,
key String,
size UInt64,
LastModifiedDate DateTime,
etag String,
storage_class String,
IsMultipartUploaded String,
Replicationstatus String
) ENGINE = MergeTree()
ORDER BY LastModifiedDate
TTL LastModifiedDate to volume 'ttlhot',
LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'
SETTINGS
storage_policy='ttl',
index_granularity=8192;
四、基于腾讯云存储 COS 的分层存储实现
在后面的章节,咱们介绍了 ClickHouse 分布式表的数据是如何存储、ClickHouse 反对的磁盘类型以及如何配置数据在各类型存储中挪动的策略,接下来咱们来具体介绍一下如何利用 ClickHouse 的这些个性以及对象存储 COS 的劣势来解决咱们在应用 ClickHouse 中遇到的一些问题。
1. 以后 ClickHouse 数据存储的问题
在和应用 ClickHouse 交换的时候,客户常常会有这样一个困扰:谋求极致查问性能个别是客户抉择应用 ClickHouse 的起因,所以客户个别会抉择腾讯云的增强型 SSD 云硬盘寄存 ClickHouse 的数据,用于晋升查问的性能,然而增强型 SSD 云硬盘价格昂贵,综合性能及老本思考,客户会抉择将比拟老的历史数据从 ClickHouse 中革除。尽管绝大多数的查问都集中在最新的数据上,然而业务方偶然还是会有拜访老的历史数据的需要,如何均衡老本以及业务方偶然拜访历史数据的需要成为 ClickHouse 零碎管理者头疼的问题。
以下面提到的客户的困扰为例,依据业务方的需要,ClickHouse 集群须要尽可能存储更长时间的数据,如果这些长时间保留的数据都寄存在增强型 SSD 云盘上,老本将会十分的高。而在理论的业务场景中,可能有 95% 以上的查问交互都产生在最近一天生成的数据上,剩下 5% 的的工作都是产生在较早的数据上的批量查问工作,如果将大量的拜访频率较低的历史数据都放在高老本的增强型 SSD 上,会造成极大的容量及性能的节约。
下图是援用 Altinity 的一个 ClickHouse 在理论应用中对于查问频率和对应的数据工夫的统计:
2. 腾讯云存储 COS 的劣势
对象存储 COS 是腾讯云存储产品,是无目录层次结构、无数据格式限度、无容量下限,反对 HTTP/HTTPS 协定拜访的分布式存储服务。
COS 以存储桶的形式组织数据,存储桶空间无容量下限,按需应用、按量计费、按需扩大。应用 COS 作为备份存储有如下劣势:
- 按需应用按量结算:COS 开服即用,开明即可用,登录腾讯云官网注册账号后,一键式开明 COS 服务,就可应用,无需建设老本。COS 提供海量的存储空间,无需布局存储容量。COS 提供按量付费的形式,防止资源节约、升高应用老本。
- 高牢靠高可用性:COS 提供高达 99.99% 的服务可用性,以及高达 12 个 9 的数据持久性,为数据提供牢靠的保障。
- 高性能:单个存储桶 QPS 可达 30,000 以及 15Gbit/ s 带宽。
- 凋谢兼容:COS 提供全兼容行业标杆 AWS S3 的接口,提供 terrafrom 等多种生态工具反对。
- 数据安全:COS 提供多租户权限隔离,反对 HTTPS 加密传输,反对 SSE-KMS 加密等多种数据加密形式。
- 低成本:提供具备竞争力的产品定价,提供规范存储、低频存储以及归档存储三种类型,并反对数据生命周期治理,进一步升高云存储老本。
基于以上推腾讯云对象存储 COS 的劣势,咱们举荐应用腾讯云增强型 SSD 云盘以及腾讯云对象存储 COS 构建 ClickHouse 的分层存储构造。增强型 SSD 云盘寄存最近工夫生成并且拜访频繁的“热数据”、COS 寄存较早工夫生成且拜访不频繁的“冷数据”,并在建表的时候应用 TTL 实现数据依据特定工夫策略的主动沉降。
通过设置的数据分层策略,咱们实现了将最新生成的、交互式查问频率较高的数据寄存在高性能的增强型 SSD 云盘上,同时依据数据的拜访场景设置策略,当数据不再被高频率交互式查问拜访时将数据转移到高容量、低成本的二级存储上 COS,在不就义交互式查问性能的状况下极大地升高了总体应用老本。
通过该计划咱们可能同时兼顾以下各方面:
- 极致性能:最新的数据寄存在增强型 SSD 云盘,为业务的即时查问提供极致性能;同时 COS 提供的高带宽、高并发为历史数据的批量查问提供了较高的性能。
- 超大容量:腾讯云对象存储 COS 提供了无容量下限的存储空间,将历史数据寄存在 COS 上后,不必再放心磁盘空间有余删除数据后导致无奈满足业务部门较早数据查问的需要。
- 低成本:绝对于本地存储,COS 提供了更低的老本和更高的可用性。除了规范存储以外,COS 还提供老本更低的规范、低频、归档以及深度归档四种类型存储,依据数据须要拜访的频率需要,将数据沉降至对应的存储类型,进一步降低成本。
3. 基于 COS 的 ClickHouse 数据分层实现
在配置数据分层之前,咱们提前准备如下环境:
- 本地存储:挂载增强型 SSD 硬盘,并格式化为本地文件系统,挂载到 /data 门路,用于寄存热数据。
- COS 存储桶:新建 COS 存储桶,用于寄存冷数据,获取具备拜访该存储桶权限账号的 SecretId 以及 SecretKey。
3.1 配置 ClickHouse 磁盘及策略
首先咱们须要配置 /etc/clickhouse-server/config.d/storage.xml 文件,在配置中的 <disks> 局部定义本地磁盘的门路以及 COS 存储桶的 URL、拜访账号的 SecretId 和 SecretKey,同时在 <policies> 中定义名为 <ttl> 的策略,该策略中定义了 <ttlhot> 和 <ttlcold> 两个卷,别离蕴含本地存储以及 COS 存储桶。
以下是配置文件的具体内容(请依据理论场景替换本地门路以及 COS 的 URL、access_key_id 和 secret_access_key):
<yandex>
<storage_configuration>
<disks>
<localdisk> <!-- disk name -->
<path>/data/</path>
</localdisk>
<cos>
<type>s3</type>
<endpoint>http://example-1250000000.cos.ap-shanghai.myqcloud.com/ck/</endpoint>
<access_key_id>AKIDxxxxxxxx</access_key_id>
<secret_access_key>xxxxxxxxxxx</secret_access_key>
</cos>
</disks>
<policies>
<ttl>
<volumes>
<ttlhot>
<disk>localdisk</disk>
<max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
</ttlhot>
<ttlcold>
<disk>cos</disk>
<max_data_part_size_bytes>5368709119</max_data_part_size_bytes>
</ttlcold>
</volumes>
</ttl>
</policies>
</storage_configuration>
</yandex>
批改完配置文件之后,在 clickhouse 客户端从新加载配置后就能看到新配置的磁盘及策略:
3.2 导入数据至 ClickHouse
实现存储配置后,咱们须要建设一个配置了 TTL 策略的表,并往表中导入数据以验证咱们配置的分层策略。
这里我抉择咱们一个 COS 存储桶的清单作为导入的数据源,首先依据清单中各列的内容,在 ClickHouse 中新建一个名为 cos_inventory_ttl 的表,同时配置 TTL 策略,依据 LastModifiedDate 的值将热数据寄存至 ttlhot 卷,而三个月以上的冷数据寄存至 ttlcold 卷。
CREATE TABLE cos_inventory_ttl (
appid UInt64,
bucket String,
key String,
size UInt64,
LastModifiedDate DateTime('Asia/Shanghai'),
etag String,
storage_class String,
IsMultipartUploaded String,
Replicationstatus String
) ENGINE = MergeTree()
ORDER BY LastModifiedDate
TTL LastModifiedDate to volume 'ttlhot',
LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'
SETTINGS
storage_policy='ttl',
index_granularity=8192;
而后再将生成的清单文件下载到本地并解压成 csv 文件,而后将 csv 数据批量导入到 ClickHouse 数据库中:
for i in *.csv
do
echo $i;
cat $i |sed 's/+08:00//g' |clickhouse-client -u default --password='123456' --query="INSERT INTO cos_inventory_ttl FORMAT CSV";
done
3.3 验证数据
数据导入实现后,咱们首先查看总共导入的数据的行数:
接下来,咱们能够查问数据的分区寄存的存储卷:
这里咱们能够看到,数据曾经依照预期存储在不同的磁盘上,其中约两千多万行数据寄存在本地磁盘,约六千多万行数据寄存在 COS 上。
接下来咱们能够做一个查问测试,这里咱们统计一下 cos-user/ 目录下最近三个月份生成的文件的总大小:
五、总结
通过配置在 ClickHouse 中配置不同的存储介质以及相应的策略,咱们实现了 ClickHouse 数据在不同存储介质的主动存储。COS 有限的存储容量以及超低的存储老本,使咱们的 ClickHouse 集群在提供极致查问性能的同时又能以低成本的形式实现数据的长期寄存。
六、参考文档
1、ClickHouse 官网文档
2、Altinity 网站参考文档
- https://altinity.com/blog/201…
- https://altinity.com/blog/202…
- https://altinity.com/presenta…
3、《腾讯云 ClickHouse 反对数据平衡服务》
4、《交互式剖析畛域,为何 ClickHouse 可能杀出重围?》
5、对象存储 COS 文档核心