fc013 发表于 2022-8-19 15:25:07

Apache Doris 实战之冷热数据缓存管理

本帖最后由 fc013 于 2022-8-19 15:26 编辑




问题导读:

1、怎样构建缓存层?
2、怎样清理缓存文件?
3、怎样清理垃圾文件?



缓存层的构建

缓存层的定位

TABLET 下面有着多个 Segment,一部分是热数据,存储在本地目录下;另一部分是冷数据,存储是远程存储集群(S3)下。缓存层即是在两者之间增加了一层,用于将远程数据映射到本地文件。

如下图,FileCache 即是冷数据在本地的缓存层,其是远程数据在本地的镜像,当访问的Segment 是冷数据(存储在远程集群)时,会触发生成缓存层,将远程数据拉取到本地,生成缓存文件。这样在下一次访问时,可以直接读取缓存文件,而不需要从远程集群上拉取数据。


缓存文件的生成

在默认情况下,冷数据存储在远程集群上,本地是没有缓存文件的。只有当用户的查询请求需要访问到冷数据时,缓存文件才是有用的。因此,缓存文件的生成是通过查询请求来触发的。

当一个查询请求到来时,SQL 被解析并重组成 PlanFragment ,通过元数据指定到 BE 里的Tablet 上,而 Tablet 本身是由多个 Segment 组成。当访问的 Segment 是热数据(本地文件)时,直接读取本地文件即可;当访问的 Segment 是冷数据(远程文件)时,直接读取远程文件代价是较高的,这时就会触发缓存机制,生成缓存文件。



缓存文件的结构

缓存文件是远程文件的映射,缓存文件中每一条数据,在远程文件上都有对应的存在。但是这并不说缓存文件就等于是远程文件,两者之间是存在区别的。这是因为:

远程文件一般是比较大的,将这么大的文件整个拉取到本地的代价很高,反而会影响到查询的效率。

查询请求在下推时,往往只是读取Segment其中一部分数据,比如在 Select * from Table limit 1 这样的请求中,需要使用的往往只是其中几 KB 的数据,这时将几 GB 大小的文件全部拉到本地反而会增加不必要的时间开销。

同一个 Segment 中的缓存数据也存在着使用频率的差异,有可能只是 Segment 其中的一小部分数据被经常使用,当需要清理缓存数据时,我们更希望将使用不频繁的数据清除。

正因为如此,缓存文件采取了文件切割的方式,也即是说,远程的文件会被拆分成几个相对较小的子文件存放在本地作为缓存。当对 Segment 进行读取的时候,该请求会定位到远程文件指定位置的数据( offset + length ),缓存机制将从远程文件中切分一部分出来,作为子文件写入到本地的缓存目录下。



缓存文件的清理

任何一个事物都有其生命周期,缓存文件作为映射文件同样如此。当某些缓存文件不再需要时,需要对其进行清理,以释放出空间,供其他文件使用。

根据缓存文件的重要性、磁盘的容量情况等,缓存文件的清理分成以下几种策略:

按活跃时间清理

这是最常见的清理策略,缓存文件在生成之后的一段时间内,用户再次访问该段数据的可能性是最高的,因此这时也是缓存数据最活跃的时期。随着时间的推移,用户访问该数据的可能性变小。当用户有较长的一段时间未访问时,该数据已经不活跃,即可对其进行清理。

BE 中使用 CacheManager 来对这些缓存进行管理,当用户的查询触发并生成了 Cache 文件时,这些 Cache 文件会注册到 CacheManager 中。

最后活跃时间是用于检查的重要指标,每当一个 Cache 被访问到时,其最后活跃时间即会更新,代表着该 Cache 近期有活跃动作。

CacheManager 会定时检查这些缓存文件的最后活跃时间,当某些 Cache 的最后活跃时间较早时,代表着该 Cache 已经不再活跃,CacheManager 将对这些 Cache 进行清除。



按磁盘占用情况清理

缓存文件占用的是本地磁盘空间。当占用的空间足够大的时候,可能会影响本地文件的读写,这就需要对这些缓存文件进行清理。

当缓存文件较多时,很可能很多缓存文件并没有达到活跃时间的阈值,而这时候其占用的磁盘空间已经过大了,这就需要提前将这些文件进行清理。

清理的时候,将缓存文件按最后活跃时间分成几个批次,从较早的文件开始,按时间逐步清理,直到降低到指定的磁盘占用空间上限。

垃圾文件清理

由于BE本身有可能出现重启、IO 异常等情况,缓存文件也可能生成一些垃圾文件。例如:文件写到一半时 IO 异常、文件生成过程中BE重启等。这些文件并不处在 CacheManager 的管理之中,为了保证缓存层的干净,需要定期对这些文件进行清理。

由于在原本的逻辑中 Tablet 层已经有了一个垃圾文件清理的模块,会清理异常的 Tablet 。因此,缓存层的清理不需要再关注那些异常的 Tablet ,只需要关注 TabletManager 中管理的Tablet 即可。

缓存层垃圾清理对 TabletManager 中的 Tablet 目录进行遍历,查询每一个缓存目录,检查其是否在 CacheManager 中已经注册。如果在 CacheManager 中已经存在,这些 Cache 就不是垃圾文件,可以通过前面的两种缓存清理策略进行清理。如果在 CacheManager 中不存在,这些 Cache 则有可能是垃圾缓存,这时需要检查这些缓存文件的生成时间,根据生成时间来决定是否删除。

总结

本文介绍了 DORIS 冷热数据的缓存层实现及其管理,缓存层是冷热数据中比较重要的模块,直接影响到冷热数据的查询效率。缓存文件的重点是对远程文件的切分,以及本地缓存文件的重复使用。

缓存层不只在冷热数据中发挥作用,该模块同时可以在外表、外部数据读写等方面发挥作用,未来也是存算分离中的重要组成部分。后续的版本将会对缓存层进行更多的拓展。







最新经典文章,欢迎关注公众号http://www.aboutyun.com/data/attachment/forum/201903/18/215536lzpn7n3u7m7u90vm.jpg

---------------------
作者:ApacheDoris
来源:weixin
原文:技术实现 | Apache Doris 冷热数据缓存管理


页: [1]
查看完整版本: Apache Doris 实战之冷热数据缓存管理