一、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 MONTHTTL date_time + INTERVAL 15 HOURTTL date_time + toIntervalMonth(ttl)TTL date_time + toIntervalHour(ttl)TTL date_time + INTERVAL ttl MONTHTTL 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 LastModifiedDateTTL LastModifiedDate to volume 'ttlhot',  LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'SETTINGSstorage_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 LastModifiedDateTTL LastModifiedDate to volume 'ttlhot',  LastModifiedDate + toIntervalMonth(3) TO VOLUME 'ttlcold'SETTINGSstorage_policy='ttl',index_granularity=8192;

而后再将生成的清单文件下载到本地并解压成csv文件,而后将csv数据批量导入到ClickHouse数据库中:

for i in *.csvdoecho $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文档核心