关于数据库:Apache-Doris-冷热分层技术如何实现存储成本降低-70

82次阅读

共计 10758 个字符,预计需要花费 27 分钟才能阅读完成。

在数据分析的理论场景中,冷热数据往往面临着不同的查问频次及响应速度要求。例如在电商订单场景中,用户常常拜访近 6 个月的订单,工夫较长远的订单拜访次数非常少;在行为剖析场景中,需反对近期流量数据的高频查问且时效性要求高,但为了保障历史数据随时可查,往往要求数据保留周期更为长远;在日志剖析场景中,历史数据的拜访频次很低,但需长时间备份以保障后续的审计和回溯的工作 … 往往历史数据的利用价值会随着时间推移而升高,且须要应答的查问需要也会随之锐减。而随着历史数据的一直增多,如果咱们将所有数据存储在本地,将造成大量的资源节约。

为了解决满足以上问题,冷热数据分层技术应运而生,以更好满足企业降本增效的趋势。顾名思义,冷热分层是将 热数据 别离 存储在 老本不同 的存储介质上,例如热数据存储在老本更高的 SSD 盘上、以进步时效数据的查问速度和响应能力,而冷数据则存储在绝对低成本的 HDD 盘甚至更为便宜的对象存储上,以升高存储老本。咱们还能够依据理论业务需要进行灵便的配置和调整,以满足不同场景的要求。

冷热分层个别实用于以下需要场景:

  • 数据存储周期长:面对历史数据的一直减少,存储老本也随之减少;
  • 冷热数据拜访频率及性能要求不同:热数据拜访频率高且须要疾速响应,而冷数据拜访频率低且响应速度要求不高;
  • 数据备份和复原老本高:备份和复原大量数据须要耗费大量的工夫和资源。
  • ……

更高存储效率的冷热分层技术

自 Apache Doris 0.12 版本引入动静分区性能,开始反对对表分区进行生命周期治理,能够设置热数据转冷工夫以及存储介质标识,通过后台任务将热数据从 SSD 主动冷却到 HDD,以帮忙用户较大水平地升高存储老本。用户能够在建表属性中配置参数 storage_cooldown_time 或者 dynamic_partition.hot_partition_num 来控制数据从 SSD 冷却到 HDD,当分区满足冷却条件时,Doris 会主动执行工作。而 HDD 上的数据是以多正本的形式存储的,并没有做到最大水平的老本节约,因而对于冷数据存储老本依然有较大的优化空间。

为了帮忙用户进一步升高存储老本,社区在已有性能上进行了优化,并在 Apache Doris 2.0 版本中推出了 冷热 数据 分层的性能。冷热数据分层性能使 Apache Doris 能够将冷数据下沉到存储老本更加低廉的对象存储中,同时冷数据在对象存储上的保留形式也从多正本变为单正本,存储老本进一步降至原先的三分之一,同时也缩小了因存储附加的计算资源老本和网络开销老本。

如下图所示,在 Apache Doris 2.0 版本中反对三级存储,别离是 SSD、HDD 和对象存储。用户能够配置使数据从 SSD 下沉到 HDD,并应用冷热分层性能将数据从 SSD 或者 HDD 下沉到对象存储中。

以私有云价格为例,云磁盘的价格通常是对象存储的 5-10 倍,如果能够将 80% 的冷数据保留到对象存储中,存储老本至多可升高 70%。

咱们应用以下公式计算节约的老本,设冷数据比率为 rate,对象存储价格为 OSS,云磁盘价格为 CloudDisk

$1 – \frac{rate * 100 * OSS + (1 – rate) * 100 * CloudDisk}{100 * CloudDisk}$

这里咱们假如用户有 100TB 的数据,咱们依照不同比例将冷数据迁徙到对象存储,来计算一下 如果应用冷热分层之后,相较于全量应用一般云盘、SSD 云盘 可节约 多少 老本

  • 阿里云 OSS 规范存储老本是 120 元 / T / 月
  • 阿里云一般云盘的价格是 300 元 / T / 月
  • 阿里云 SSD 云盘的价格是 1000 元 / T / 月

例如在 80% 冷数据占比的状况下,残余 20% 应用一般云盘每月仅破费 80T120 + 20T * 300 = 15600 元,而全量应用一般云盘则须要破费 30000 元,通过冷热数据分层节俭了 48% 的存储老本。如果用户应用的是 SSD 云盘,那么破费则会从全量应用需破费的 100000 元升高到 80T120 + 20T * 1000 = 29600 元,存储老本最高升高超过 70%!

使用指南

若要应用 Doris 的冷热分层性能,首先须要筹备一个对象存储的 Bucket 并获取对应的 AK/SK。当准备就绪之后,上面为具体的应用步骤:

1. 创立 Resource

能够应用对象存储的 Bucket 以及 AK/SK 创立 Resource,目前反对 AWS、Azure、阿里云、华为云、腾讯云、百度云等多个云的对象存储。

CREATE RESOURCE IF NOT EXISTS "${resource_name}"
PROPERTIES(
"type"="s3",
"s3.endpoint" = "${S3Endpoint}",
"s3.region" = "${S3Region}",
"s3.root.path" = "path/to/root",
"s3.access_key" = "${S3AK}",
"s3.secret_key" = "${S3SK}",
"s3.connection.maximum" = "50",
"s3.connection.request.timeout" = "3000",
"s3.connection.timeout" = "1000",
"s3.bucket" = "${S3BucketName}"
);

2. 创立 Storage Policy

能够通过 Storage Policy 控制数据冷却工夫,目前反对绝对和相对两种冷却工夫的设置。

CREATE STORAGE POLICY testPolicy
PROPERTIES(
"storage_resource" = "remote_s3",
"cooldown_ttl" = "1d"
);

例如上方代码中名为 testPolicystorage policy 设置了新导入的数据将在一天后开始冷却,并且冷却后的冷数据会寄存到 remote_s3 所示意的对象存储的 root path 下。除了设置 TTL 以外,在 Policy 中也反对设置冷却的工夫点,能够间接设置为:

CREATE STORAGE POLICY testPolicyForTTlDatatime
PROPERTIES(
"storage_resource" = "remote_s3",
"cooldown_datetime" = "2023-06-07 21:00:00"
);

3. 给表或者分区设置 Storage Policy

在创立出对应的 Resource 和 Storage Policy 之后,咱们能够在建表的时候对整张表设置 Cooldown Policy,也能够针对某个 Partition 设置 Cooldown Policy。这里以 TPCH 测试数据集中的 lineitem 表举例。如果须要将整张表都设置冷却的策略,则能够间接在整张表的 properties 中设置:

CREATE TABLE IF NOT EXISTS lineitem1 (
L_ORDERKEY INTEGER NOT NULL,
L_PARTKEY INTEGER NOT NULL,
L_SUPPKEY INTEGER NOT NULL,
L_LINENUMBER INTEGER NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATEV2 NOT NULL,
L_COMMITDATE DATEV2 NOT NULL,
L_RECEIPTDATE DATEV2 NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)
DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
PARTITION BY RANGE(`L_SHIPDATE`)
(PARTITION `p202301` VALUES LESS THAN ("2017-02-01"),
PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
)
DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
PROPERTIES (
"replication_num" = "3",
"storage_policy" = "${policy_name}"
)

用户能够通过 show tablets 取得每个 Tablet 的信息,其中 CooldownReplicaId 不为 -1 并且 CooldownMetaId 不为空的 Tablet 阐明应用了 Storage Policy。如下方代码,通过 show tablets 能够看到下面的 Table 的所有 Tablet 都设置了 CooldownReplicaId 和 CooldownMetaId,这阐明整张表都是应用了 Storage Policy。

TabletId: 3674797
ReplicaId: 3674799
BackendId: 10162
SchemaHash: 513232100
Version: 1
LstSuccessVersion: 1
LstFailedVersion: -1
LstFailedTime: NULL
LocalDataSize: 0
RemoteDataSize: 0
RowCount: 0
State: NORMAL
LstConsistencyCheckTime: NULL
CheckVersion: -1
VersionCount: 1
QueryHits: 0
PathHash: 8030511811695924097
MetaUrl: http://172.16.0.16:6781/api/meta/header/3674797
CompactionStatus: http://172.16.0.16:6781/api/compaction/show?tablet_id=3674797
CooldownReplicaId: 3674799
CooldownMetaId: TUniqueId(hi:-8987737979209762207, lo:-2847426088899160152)

咱们也能够对某个具体的 Partition 设置 Storage Policy,只须要在 Partition 的 Properties 中加上具体的 Policy Name 即可:

CREATE TABLE IF NOT EXISTS lineitem1 (
L_ORDERKEY INTEGER NOT NULL,
L_PARTKEY INTEGER NOT NULL,
L_SUPPKEY INTEGER NOT NULL,
L_LINENUMBER INTEGER NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATEV2 NOT NULL,
L_COMMITDATE DATEV2 NOT NULL,
L_RECEIPTDATE DATEV2 NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL
)
DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
PARTITION BY RANGE(`L_SHIPDATE`)
(PARTITION `p202301` VALUES LESS THAN ("2017-02-01") ("storage_policy" = "${policy_name}"),
PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
)
DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
PROPERTIES ("replication_num" = "3")

这张 Lineitem1 设置了两个分区,每个分区 3 个 Bucket,另外正本数设置为 3,能够计算出一共有 23 = 6 个 Tablet,那么正本数一共是 63 = 18 个 Replica,通过 show tablets 命令能够查看到所有的 Tablet 以及 Replica 的信息,能够看到只有局部 Tablet 的 Replica 是设置了 CooldownReplicaId 和 CooldownMetaId。用户能够通过 ADMIN SHOW REPLICA STATUS FROM TABLE PARTITION(PARTITION)` ` 查看 Partition 下的 Tablet 以及 Replica,通过比照能够发现其中只有属于 p202301 这个 Partition 的 Tablet 的 Replica 设置了 CooldownReplicaId 和 CooldownMetaId,而属于 p202302 这个 Partition 下的数据没有设置,所以依旧会全副寄存到本地磁盘。以上表的 Tablet 3691990 为例,该 Tablet 属于 p202301,截取 show tablets 拿到的局部要害信息如下:

*****************************************************************
TabletId: 3691990
ReplicaId: 3691991
CooldownReplicaId: 3691993
CooldownMetaId: TUniqueId(hi:-7401335798601697108, lo:3253711199097733258)
*****************************************************************
TabletId: 3691990
ReplicaId: 3691992
CooldownReplicaId: 3691993
CooldownMetaId: TUniqueId(hi:-7401335798601697108, lo:3253711199097733258)
*****************************************************************
TabletId: 3691990
ReplicaId: 3691993
CooldownReplicaId: 3691993
CooldownMetaId: TUniqueId(hi:-7401335798601697108, lo:3253711199097733258)

能够察看到 3691990 的 3 个正本都抉择了 3691993 正本作为 CooldownReplica,在用户指定的 Resource 上也只会保留这个正本的数据。

4. 查看数据信息

咱们能够依照上述 3 中的 Linetem1 来演示如何查看是应用冷热数据分层策略的 Table 的数据信息,个别能够通过 show tablets from lineitem1 间接查看这张表的 Tablet 信息。Tablet 信息中辨别了 LocalDataSize 和 RemoteDataSize,前者示意存储在本地的数据,后者示意曾经冷却并挪动到对象存储上的数据。具体信息可见下方代码:

下方为数据刚导入到 BE 时的数据信息,能够看到数据还全副存储在本地。

*************************** 1. row ***************************
TabletId: 2749703
ReplicaId: 2749704
BackendId: 10090
SchemaHash: 1159194262
Version: 3
LstSuccessVersion: 3
LstFailedVersion: -1
LstFailedTime: NULL
LocalDataSize: 73001235
RemoteDataSize: 0
RowCount: 1996567
State: NORMAL
LstConsistencyCheckTime: NULL
CheckVersion: -1
VersionCount: 3
QueryHits: 0
PathHash: -8567514893400420464
MetaUrl: http://172.16.0.8:6781/api/meta/header/2749703
CompactionStatus: http://172.16.0.8:6781/api/compaction/show?tablet_id=2749703
CooldownReplicaId: 2749704
CooldownMetaId:

当数据达到冷却工夫后,再次进行 show tablets from table 能够看到对应的数据变动。

*************************** 1. row ***************************
TabletId: 2749703
ReplicaId: 2749704
BackendId: 10090
SchemaHash: 1159194262
Version: 3
LstSuccessVersion: 3
LstFailedVersion: -1
LstFailedTime: NULL
LocalDataSize: 0
RemoteDataSize: 73001235
RowCount: 1996567
State: NORMAL
LstConsistencyCheckTime: NULL
CheckVersion: -1
VersionCount: 3
QueryHits: 0
PathHash: -8567514893400420464
MetaUrl: http://172.16.0.8:6781/api/meta/header/2749703
CompactionStatus: http://172.16.0.8:6781/api/compaction/show?tablet_id=2749703
CooldownReplicaId: 2749704
CooldownMetaId: TUniqueId(hi:-8697097432131255833, lo:9213158865768502666)

除了通过上述命令查看数据信息之外,咱们也能够在对象存储上查看冷数据的信息。以腾讯云为例,能够在 Policy 指定的 Bucket 的 Path 下能够查看冷却过后的数据的信息:

进入对应文件后能够看到数据和元数据文件

咱们能够看到在对象存储上数据是单正本。

5. 查问

假如 Table Lineitem1 中的所有数据都曾经冷却并且上传到对象存储中,如果用户在 Lineitem1 上进行对应的查问,Doris 会依据对应 Partition 应用的 Policy 信息找到对应的 Bucket 的 Root Path,并依据不同 Tablet 下的 Rowset 信息下载查问所需的数据到本地进行运算。

Doris 2.0 在查问上进行了优化,冷数据第一次查问会进行残缺的 S3 网络 IO,并将 Remote Rowset 的数据下载到本地后,寄存到对应的 Cache 之中,后续的查问将主动命中 Cache,以此来保障查问效率。(性能比照可见后文评测局部)。

6. 冷却后持续导入数据

在某些场景下,用户须要对历史数据进行数据的修改或补充数据,而新数据会依照分区列信息导入到对应的 Partition 中。在 Doris 中,每次数据导入都会产生一个新的 Rowset,以保障冷数据的 Rowset 在不会影响新导入数据的 Rowset 的前提下,满足冷热数据同时存储的需要。Doris 2.0 的冷热分层粒度是基于 Rowset 的,当达到冷却工夫时会将以后满足条件的 Rowset 全副上传到 S3 上并删除本地数据,之后新导入的数据生成的新 Rowset 会在达到冷却工夫后也上传到 S3。

查问性能测试

为了测试应用冷热分层性能之后,查问对象存储中的数据是否占用会较大网络 I/O,从而影响查问性能,因而咱们以 SSB SF100 标准集为例,对冷热分层表和非冷热分层表进行了查问耗时的比照测试。

配置:均在 3 台 16C 64G 的机器上部署 1FE、3BE 的集群

临时无奈在飞书文档外展现此内容

如上图所示,在充沛预热之后(数据曾经缓存在 Cache 中),冷热分层表共耗时 5.799s,非冷热分层表共耗时 5.822s,由此可知,应用冷热分层查问表和非冷热分层表的查问性能简直雷同。这表明,应用 Doris 2.0 提供的冷热分层性能,不会对查问性能造成的影响。

冷热分层技术的具体实现

存储形式的优化

在 Doris 之前的版本中,数据从 SSD 冷却到 HDD 后,为了保证数据的高可用和可靠性,通常会将一个 Tablet 存储多份正本在不同 BE 上,为了进一步降低成本,咱们在 Apache Doris 2.0 版本引入了对象存储,推出了冷热分层性能。因为对象存储自身具备高牢靠高可用性,冷数据在对象存储上只须要一份即可,元数据以及热数据依然保留在 BE,咱们称之为本地正本,本地正本同步冷数据的元数据,这样就能够实现多个本地正本共用一份冷却数据的目标,无效防止冷数据占用过多的存储空间,从而升高数据存储老本。

具体而言,Doris 的 FE 会从 Tablet 的所有可用本地正本中抉择一个本地正本作为上传数据的 Leader,并通过 Doris 的周期汇报机制同步 Leader 的信息给其它本地正本。在 Leader 上传冷却数据时,也会将冷却数据的元数据上传到对象存储,以便其余正本同步元数据。因而,任何本地正本都能够提供查问所需的数据,同时也保障了数据的高可用性和可靠性。

冷数据 Compaction

在一些场景下会有大量修补数据的需要,在大量补数据的场景下往往须要删除历史数据,删除能够通过 delete where实现,Doris 在 Compaction 时会对合乎删除条件的数据做物理删除。基于这些场景,冷热分层也必须实现对冷数据进行 Compaction,因而在 Doris 2.0 版本中咱们反对了对冷却到对象存储的冷数据进行 Compaction(ColdDataCompaction)的能力,用户能够通过冷数据 Compaction,将扩散的冷数据从新组织并压缩成更紧凑的格局,从而缩小存储空间的占用,进步存储效率。

Doris 对于本地正本是各自进行 Compaction,在后续版本中会优化为单正本进行 Compaction。因为冷数据只有一份,因而人造的单正本做 Compaction 是最优良计划,同时也会简化解决数据抵触的操作。BE 后盾线程会定期从冷却的 Tablet 依照肯定规定选出 N 个 Tablet 发动 ColdDataCompaction。与数据冷却流程相似,只有 CooldownReplica 能执行该 Tablet 的 ColdDataCompaction。Compaction 下刷数据时每积攒肯定大小(默认 5MB)的数据,就会上传一个 Part 到对象,而不会占用大量本地存储空间。Compaction 实现后,CooldownReplica 将冷却数据的元数据更新到对象存储,其余 Replica 只需从对象存储同步元数据,从而大量缩小对象存储的 IO 和节点本身的 CPU 开销。

冷数据 Cache

冷数据 Cache 在数据查问中具备重要的作用。冷数据通常是数据量较大、应用频率较低的数据,如果每次查问都须要从对象中读取,会导致查问效率低下。通过冷数据 Cache 技术,能够将冷数据缓存在本地磁盘中,进步数据读取速度,从而进步查问效率。而 Cache 的粒度大小间接影响 Cache 的效率,比拟大的粒度会导致 Cache 空间以及带宽的节约,过小粒度的 Cache 会导致对象存储 IO 效率低下,Apache Doris 采纳了以 Block 为粒度的 Cache 实现。

如前文所述,Apache Doris 的冷热分层会将冷数据上传到对象存储上,上传胜利后本地的数据将会被删除。因而,后续波及到冷数据的查问均须要对对象存储发动 IO。为了优化性能,Apache Doris 实现了基于了 Block 粒度的 Cache 性能,当近程数据被拜访时会先将数据依照 Block 的粒度下载到本地的 Block Cache 中存储,且 Block Cache 中的数据拜访性能和非冷热分层表的数据性能统一(可见后文查问性能测试)。

具体来讲,前文提到 Doris 的冷热分层是在 Rowset 级别进行的,当某个 Rowset 在冷却后其所有的数据都会上传到对象存储上。而 Doris 在进行查问的时候会读取波及到的 Tablet 的 Rowset 进行数据聚合和运算,当读取到冷却的 Rowset 时,会把查问须要的冷数据下载到本地 Block Cache 之中。基于性能考量,Doris 的 Cache 依照 Block 对数据进行划分。Block Cache 自身采纳的是简略的 LRU 策略,能够保障越是应用程度较高数据越能在 Block Cache 中寄存的久。

结束语

Apache Doris 2.0 版本实现了基于对象存储的冷热数据分层,该性能能够帮忙咱们无效升高存储老本、进步存储效率,并进步数据查问和解决效率。将来,Apache Doris 将会基于冷热数据分层以及弹性计算节点,为用户提供更好的资源弹性、更低的应用老本以及更灵便的负载隔离服务。

在前段时间推出的 Apache Doris 2.0 Alpha 版本中,曾经实现了单节点数万 QPS 的高并发点查问能力、高性能的倒排索引、高效稳固的内存治理、基于代价模型的全新查问优化器以及 Pipeline 执行引擎等,欢送大家下载体验。与此同时,Apache Doris 2.0 Beta 版本也将于近两周上线。除了已知性能外,还会进一步反对 Unique 模型上的局部列更新,并将 Pipeline 执行引擎、查问优化器、主键模型 Merge-on-Write 等最新个性作为稳固性能默认开启,并蕴含了社区近期对性能方面的诸多优化,具体性能测试后果敬请期待后续社区动静。

为了让用户能够体验社区开发的最新个性,同时保障最新性能能够播种到更广范畴的应用反馈,咱们建设了 2.0 版本的专项反对群,请大家填写申请,欢送宽广社区用户在应用最新版本过程中多多反馈应用意见,帮忙 Apache Doris 继续改良。

作者介绍:

杨勇强,SelectDB 联结创始人、技术副总裁

岳靖、程宇轩,SelectDB 存储层研发工程师

正文完
 0