【Doris】 技术实现 - 冷热数据存储(二)

本文深入探讨Apache Doris的冷热数据存储实现,包括热数据转冷的StoragePolicy配置,如指定冷却时间点和活跃时间,以及冷数据的读写操作。在读取时,Doris通过LocalFileReader和S3FileReader合并本地和远程数据,而在写入时,新数据先存储在本地,适时与远程冷数据合并。此外,文章还提及了冷数据的文件合并和表结构修改等后续话题。

前言

上一篇文章[Apache Doris 技术实现 - 冷热数据存储(一)]主要讲述了冷热数据存储与存算分离之间的关系,结合数据仓库的历史,分析了存算分离在实时数仓上面的局限性,相比起分布式计算类项目(spark、flink),实时数仓只能做到有限制的存算分离。并根据这一现状,描述了一个冷热数据与存算分离结合的模型。接下来,我会先后讲述该模型的几个主要模块的原理与实现:热数据转冷、冷数据读写。

热数据转冷

热数据转冷是冷热数据存储重要的一步,所有冷热数据的相关操作都以此为开始,当数据转为冷数据后,将会有冷热数据同步等多方面的问题需要考虑。

冷热数据转换规则StoragePolicy

StoragePolicy由FE的PolicyMgr进行管理,用来配置冷热数据的转换规则。该信息会随着心跳同步给每一个BE(refreshStoragePolicy()),BE将以此作为数据进行冷热数据转换的依据。

根据用户的使用习惯,以及数据的业务特性,冷热数据转换规则可分为两类:

**第一类:**明确指定冷却时间点:有些数据拥有时间特性,前一年的数据在后一年就已经失去了时效性,这种数据通过指定具体的时间来界定其转为冷数据的时间。

CREATE STORAGE POLICY testPolicy
PROPERTIES(
“storage_resource” = “s3”,指定冷数据存储使用的资源名称,见SHOW RESOURCE
“cooldown_datetime” = “2022-06-02 00:00:00”,//指定热数据转为冷数据的时间。
);

**第二类:**根据活跃时间指定数据冷却时间:有些数据有着固定的活跃时间,比如用户行为数据,每月生成的用户行为数据在当月是使用最频繁的,而随着时间的推移,这些数据的重要性逐步降低,最终转为不活跃数据。这种情况下可以对数据指定活跃时间,当数据活跃时间结束后,该数据转为冷数据。

CREATE STORAGE POLICY testPolicy2

PROPERTIES(

“storage_resource” = “s3”,

“cooldown_ttl” = “1d”//指定数据活跃时间,超过这一时间,热数据将转为冷数据。

);

TABLE的冷热数据配置

冷热数据的调度流程,是从TABLE的冷热数据配置信息开始。在建表时指定所要使用的冷热数据规则名(storage_policy),映射为StoragePolicy。

CREATE TABLE (

……

) PROPERTIES (

“storage_policy” = “storage_policy_name1”

);

上面的配置,可以为整个表指定冷热数据规则,而大多数情况下,我们的数据是拆分成多个PARTITION的,每个PARTITION所需要的冷热数据规则有可能是不同的,这时就需要针对PARTITION来进行配置:

ALTER TABLE TblPxy01 ADD PARTITION

p2 VALUES [(“10000”), (“20000”))

(“remote_storage_policy” = “testPolicy”);

配置中的storage_policy信息存放在PARTITION的每个TABLET中,当创建及修改TABLET时,storage_policy信息随着TABLET下发给BE,由BE来判断该TABLET何时可以开始进行冷热数据转换。

冷热数据转换守护进程(cooldown_tasks_producer_thread)

如下图所示,cooldown_tasks_producer_thread是BE的一条守护进程,其对本BE的所有存活的TABLET进行遍历,检查每个TABLET的配置信息。当发现该TABLET配置了storage_policy,说明需要对其进行冷热数据转换。

根据storage_policy中的配置,BE将从缓存信息中的StoragePolicy列表中获取对应的规则信息,然后根据这个规则,判断当前tablet是否需要进行冷热数据转换,将数据存放于远程存储集群上(如S3)。

冷数据读写

冷热数据模型下的存储结构

正如前一篇文章所说的,DORIS的存算分离,是基于冷热数据模型的存算分离。这种情况下,数据的存储结构与原本的线本地存储结构有着巨大的不同。

了解过DORIS的代码结构的朋友应该都知道,BE在存储TABLET数据的时候,TABLET下面还会有ROWSET和SEGMENT的划分。其中ROWSET代表着数据导入批次,同一个ROWSET一般代表着一个批次的导入任务,比如一次stream load,一个begin/commit事务等,都对应一个ROWSET,ROWSET的这种特性,意味着其具有着事务的特点,即是说,同一个rowset可以作为一个独立的数据单元存在,其中的数据要么全部有效,要么全部无效。

正因为如此,以rowset为基本单元对数据进行冷热转换,可以更容易的解决冷热数据迁移过程中有新数据写入的问题。

如下图所示,对于进入冷热数据转换状态的TABLET,其ROWSET被分成两部分。

一部分在本地,这部分数据往往是新写入的数据,还未触发上传操作。

另一部分在远程存储集群(S3/HDFS),这部分数据相对较早,是在此前已经触发上传到了存储集群上的数据。

冷数据读取

当冷数据需要读取的时候,由于数据已经被拆分成了两部分,需要从本地和远程存储集群(S3/HDFS)上分别读取数据。

如下图所示,本地文件和远程文件的读取被封装成了一个FileReader的虚基类,实现两个派生类LocalFileReader和S3FileReader,分别对应本地文件读取与S3文件读取。当有读取请求到达TABLET时,TABLET会根据条件找到对应的ROWSET,这些ROWSET有些是本地存储,有些是远程存储(S3)。通过映射关系,ROWSET找到各自的FileReader,完成数据读取,合并后即是完整的TABLET数据。

在这里,远程数据文件为了保证读取效率,可以有多种优化的方向,比如加一层本地缓存,比如使用本地索引等。这些在后续文章中详细说明。

冷数据写入

与冷数据读取相似,冷数据写入也封装了一个FileWriter虚基类,如下图所示:

新写入的数据会在TABLET的本地存储部分新增一个ROWSET,这与普通的TABLET相同,也保证了冷数据也可写入的特性。而这部分写入到本地的数据在某个时间点会与远程的冷数据进行合并,并上传到远程存储集群。这一步骤则是由前文提到的守护进程cooldown_tasks_producer_thread来完成的。

总结

本文介绍了DORIS冷热数据转换的基本功能,热数据转冷与冷数据读写。关于冷热数据的实现,还有很多方面可讲。比如冷数据的文件合并(COMPACTION)、冷数据的表结构修改(SCHEMA_CHANGE)、冷热数据由多副本转单副本等,请期待后续的技术分享。

- 作者介绍 -

彭翔宇
百度 PALO 团队资深研发工程师,丰富的大数据工程研发经验,Apache Doris 冷热存储模块主要实现者,擅长 Doris 生态化组件研发。

相关阅读

Apache Doris 技术实现 - 冷热数据存储(一)

Apache Doris 开源社区链接参考

https://github.com/apache/doris

### Doris冷热数据分表存储的实现 #### 方案概述 在Doris环境中实施冷热数据分离策略能够显著优化资源利用率并提高查询效率。对于冷热数据的管理,通常采用不同的物理介质来分别存放不同类型的数据——即热数据存放在高性能SSD盘上以保障快速访问;而冷数据则迁移到成本较低的大容量HDD硬盘或其他长期存储设施内。 #### 方法一:基于分区表的时间窗口迁移机制[^1] 创建带有时间字段作为分区键的表结构,在此基础之上设定合理的生命周期规则。每当达到预设阈值时(比如某个月份结束),自动触发后台作业将该时间段内的记录转移至专门用于保存历史档案的新建子表里。具体操作如下: ```sql CREATE TABLE IF NOT EXISTS hot_data ( `id` BIGINT(20), `event_time` DATETIME, ...其余字段... ) PARTITION BY RANGE(event_time)( PARTITION p_202309 VALUES LESS THAN ('2023-10-01'), PARTITION p_max VALUES LESS THAN MAXVALUE ); INSERT INTO cold_storage SELECT * FROM hot_data WHERE event_time < '指定日期'; DELETE FROM hot_data WHERE event_time < '指定日期'; ``` 上述SQL语句展示了如何构建一个按月划分区间的源表以及怎样把过期条目转移到目标位置的过程。 #### 方法:利用物化视图加速查询响应速度[^4] 除了简单的搬移之外,还可以考虑引入物化视图技术进一步增强系统的灵活性与表现力。通过预先计算好常用组合条件下的汇总统计信息,并将其持久化下来供后续检索调用,从而减轻实时处理的压力。例如针对频繁发生的聚合类需求建立相应的中间结果集: ```sql CREATE MATERIALIZED VIEW mv_sales_summary AS SELECT product_id, SUM(sales_amount), COUNT(*) as order_count FROM sales_records GROUP BY product_id; ``` 这样即使面对海量级规模的历史订单明细也能迅速给出精确答案而不必每次都重新遍历整个集合。 #### 方法三:借助外部工具完成自动化运维流程 考虑到手动编写脚本可能带来的维护难题,推荐使用诸如xxl-job这样的开源框架来进行周期性的巡检工作。它允许开发者定义复杂的调度计划并通过HTTP接口远程控制集群内部的动作。这样一来不仅简化了日常管理工作而且提高了任务执行的成功率。 ```json { "jobDesc": "定期清理旧版本", "author": "admin", "scheduleConf": "* 0/5 * * * ? ", "executorHandler": "/api/clean-old-data" } ``` 以上配置片段描述了一个每隔五分钟运行一次的任务实例,负责检查是否存在超过保留期限未被访问过的对象并将它们标记为待回收状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值