云原生主键模型:高效、弹性,省钱又省心

文摘   2024-08-30 11:01   北京  
作者:罗一鑫,StarRocks Committer,主要负责存储引擎相关的工作。

导读:

在 StarRocks 3.3.1 版本中,我们推出了云原生持久化索引,旨在解决本地磁盘持久化索引的关键问题。本文将详细探讨其优势,并对比云原生与本地磁盘持久化索引在大批量导入、小批实时导入以及弹性调度等场景中的表现。尤其在弹性调度场景中,云原生架构使延迟性能提升至本地磁盘的 10 倍。

主键模型是 StarRocks 全新设计开发的存储引擎,其主要优势在于支撑实时数据更新的同时,也能保证高效的复杂即席查询性能。通过主键表,实时分析业务能够在最新数据上进行分析,从而实现及时决策,突破了传统 T+1 数据延迟的限制。主键表中的主键具备唯一非空约束,用于唯一标识每一行数据。如果新数据的主键值与表中原数据的主键值相同,则存在唯一约束冲突,新数据将替代原有数据。

从 StarRocks 3.1 版本开始,主键模型开始支持存算分离架构的部署模式。在主键模型的实现中,主键索引是其核心组件。主键索引保存了从主键与对应数据位置的映射关系,从而可以帮助我们实现:

  1. 在 upsert/delete 操作中对旧数据的快速标记删除
  2. 部分列更新
  3. 高并发点查加速
  4. ......

在之前的版本中,存算分离架构下支持了两类主键索引实现:

  1. 内存索引
  2. 基于本地磁盘的持久化索引
内存索引由于大量占用内存资源,目前已不推荐使用,默认转为基于本地磁盘的持久化索引。虽然持久化索引显著降低了内存开销,并提供强劲的性能,但在云原生场景下仍存在以下问题:
  1. 磁盘空间的使用与 local data cache 管理不统一,可能导致磁盘空间抢占问题。
  2. 扩缩容不够灵活。调度迁移后的 tablet,需要在新节点上重建索引,耗时长,影响实时数据导入。
  3. Compute Node 节点需挂载足够大的本地磁盘。

引入云原生持久化索引

为了解决本地磁盘的持久化索引存在的问题,从 StarRocks 3.3.1 版本开始,我们推出了云原生持久化索引,其主要优势包括:

  1. 索引文件存储在对象存储通过和数据文件一致的 local data cache 来做访问加速,实现缓存统一管理。
  2. 支持弹性扩缩容。调度迁移后的 tablet 只需拉取少量数据即可完成索引重建,不影响导入的实时性。
  3. 不再要求 Compute Node 节点挂载本地磁盘,减少了对磁盘空间的硬性要求,进一步降低了硬件成本。

导入性能对比

为了评估云原生持久化索引的实际性能提升,我们对比了云原生持久化索引与本地磁盘持久化索引在以下几种场景中的表现:

  1. TPCH100G 数据批量导入
  2. 订单表小批实时导入
  3. 弹性调度测试

通过对这些场景的性能测试,我们将详细分析云原生持久化索引在延迟性能上的显著提升,以及在实际应用中的优势。

1

测试环境

1 FE : ecs.g6.xlarge (4c 16g) - PL0
1 BE : ecs.g6.4xlarge (16c 64g) - PL1


2

对比版本

Version: branch-3.3-2b87854


3

测试场景

TPC-H 100G 数据批量导入

建表语句:
CREATE TABLE `lineitem_pk` (
  `l_shipdate` date NOT NULL COMMENT "",
  `l_orderkey` int(11) NOT NULL COMMENT "",
  `l_linenumber` int(11) NOT NULL COMMENT "",
  `l_partkey` int(11) NOT NULL COMMENT "",
  `l_suppkey` int(11) NOT NULL COMMENT "",
  `l_quantity` decimal(15, 2) NOT NULL COMMENT "",
  `l_extendedprice` decimal(15, 2) NOT NULL COMMENT "",
  `l_discount` decimal(15, 2) NOT NULL COMMENT "",
  `l_tax` decimal(15, 2) NOT NULL COMMENT "",
  `l_returnflag` varchar(1) NOT NULL COMMENT "",
  `l_linestatus` varchar(1) NOT NULL COMMENT "",
  `l_commitdate` date NOT NULL COMMENT "",
  `l_receiptdate` date NOT NULL COMMENT "",
  `l_shipinstruct` varchar(25) NOT NULL COMMENT "",
  `l_shipmode` varchar(10) NOT NULL COMMENT "",
  `l_comment` varchar(44) NOT NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(`l_shipdate`, `l_orderkey`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`l_orderkey`) BUCKETS 96
PROPERTIES (
"compression" = "LZ4",
"datacache.enable" = "true",
"enable_async_write_back" = "false",
"replication_num" = "1",
"storage_volume" = "builtin_storage_volume",
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL|CLOUD_NATIVE"
);


CREATE TABLE `orders_pk` (
  `o_orderkey` int(11) NOT NULL COMMENT "",
  `o_orderdate` date NOT NULL COMMENT "",
  `o_custkey` int(11) NOT NULL COMMENT "",
  `o_orderstatus` varchar(1) NOT NULL COMMENT "",
  `o_totalprice` decimal(15, 2) NOT NULL COMMENT "",
  `o_orderpriority` varchar(15) NOT NULL COMMENT "",
  `o_clerk` varchar(15) NOT NULL COMMENT "",
  `o_shippriority` int(11) NOT NULL COMMENT "",
  `o_comment` varchar(79) NOT NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(`o_orderkey`, `o_orderdate`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`o_orderkey`) BUCKETS 96
PROPERTIES (
"compression" = "LZ4",
"datacache.enable" = "true",
"enable_async_write_back" = "false",
"replication_num" = "1",
"storage_volume" = "builtin_storage_volume",
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL|CLOUD_NATIVE"
);

导入语句:

insert into lineitem_pk select * from lineitem;
insert into orders_pk select * from orders;
导入结果:

订单表小批实时导入

建表语句:
CREATE TABLE tbl_pk (
  `lo_orderkey` string,
  `lo_linenumber` int(11),
  `lo_custkey` int(11),
  `lo_partkey` int(11),
  `lo_suppkey` int(11),
  `lo_orderdate` varchar(15),
  `lo_orderpriority` varchar(16),
  `lo_shippriority` int(11),
  `lo_quantity` int(11),
  `lo_extendedprice` int(11),
  `lo_ordtotalprice` int(11),
  `lo_discount` int(11),
  `lo_revenue` int(11),
  `lo_supplycost` int(11),
  `lo_tax` int(11),
  `lo_commitdate` bigint(11),
  `lo_shipmode` varchar(11)
)
PRIMARY KEY(lo_orderkey,lo_linenumber,lo_custkey,lo_partkey,lo_suppkey,lo_orderdate)
COMMENT "OLAP"
DISTRIBUTED BY HASH(lo_orderkey,lo_linenumber,lo_custkey,lo_partkey,lo_suppkey,lo_orderdate) BUCKETS 6
PROPERTIES (
"replication_num" = "1",
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL|CLOUD_NATIVE"
);
导入语句:
curl --location-trusted -u root: -T .../fake_data$loop_file.csv -XPUT -H label:stream_load_$uuid -H "timeout:86400" -H "max_filter_ratio:0.1" http://$host_ip:$http_port/api/$database_name/tbl_pk/_stream_load
导入数据为大小7.6G随机生成的订单数据,切分为100个文件,分100次导入。

导入结果:

弹性调度测试

建表语句:
CREATE TABLE tbl_pk (
  `lo_orderkey` string,
  `lo_linenumber` int(11),
  `lo_custkey` int(11),
  `lo_partkey` int(11),
  `lo_suppkey` int(11),
  `lo_orderdate` varchar(15),
  `lo_orderpriority` varchar(16),
  `lo_shippriority` int(11),
  `lo_quantity` int(11),
  `lo_extendedprice` int(11),
  `lo_ordtotalprice` int(11),
  `lo_discount` int(11),
  `lo_revenue` int(11),
  `lo_supplycost` int(11),
  `lo_tax` int(11),
  `lo_commitdate` bigint(11),
  `lo_shipmode` varchar(11)
)
PRIMARY KEY(lo_orderkey,lo_linenumber,lo_custkey,lo_partkey,lo_suppkey,lo_orderdate)
COMMENT "OLAP"
DISTRIBUTED BY HASH(lo_orderkey,lo_linenumber,lo_custkey,lo_partkey,lo_suppkey,lo_orderdate) BUCKETS 1
PROPERTIES (
"replication_num" = "1",
"enable_persistent_index" = "true",
"persistent_index_type" = "LOCAL|CLOUD_NATIVE"
);
测试过程:
  1. 首先导入数据。

  2. 停止 BE 节点,清理磁盘中的持久化索引文件和缓存,以模拟扩缩容调度后 tablet 被调度到新节点上的情况。

  3. 发起新的导入事务,该事务的耗时中会包含重建索引的时间。通过对比该事务的延迟,验证云原生索引的弹性。

测试结果:

4

总结分析

  1. 无论是大批导入或是小批实时导入,云原生主键索引性能与本地磁盘索引性能基本持平。

  2. 在弹性调度场景中,得益于云原生的架构,云原生持久化索引的延迟性能提升达到了本地磁盘持久化索引的 10 倍。

如何使用

从 StarRocks 3.3.1 版本开始,我们支持了云原生持久化索引。要启用该功能,可以在建表语句中通过指定 persistent_index_type 为 CLOUD_NATIVE。例如:

CREATE TABLE `orders` (
  `o_orderkey` int(11) NOT NULL COMMENT "",
  `o_orderdate` date NOT NULL COMMENT "",
  `o_custkey` int(11) NOT NULL COMMENT "",
   ...
) ENGINE=OLAP
PRIMARY KEY(`o_orderkey`, `o_orderdate`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`o_orderkey`) BUCKETS 96
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE" // LOCAL | CLOUD_NATIVE
);
LOCAL 为本地磁盘主键索引(目前默认使用)。

CLOUD_NATIVE为云原生主键索引。

建表完成后,可以通过show create table 语句来确认云原生索引是否成功开启。

目前暂时不支持通过 alter table 语句来动态调整持久化索引的实现类型。

如果您当前正在使用存算分离的主键模型表,并且受到本地磁盘持久化索引的几大缺陷困扰,欢迎尝试新发布的云原生主键索引。虽然云原生主键索引仍处于早期版本,许多实现仍有提升空间,我们将持续优化和改进。您的使用反馈对我们至关重要,欢迎随时提供意见和建议,让我们一起做得更好!

扫描下方二维码,添加小助手,加入存算分离技术交流群!

关于 StarRocks 

Linux 基金会项目 StarRocks 是新一代极速全场景 MPP 数据库,遵循 Apache 2.0 开源协议。

面世三年来,StarRocks 致力于帮助企业构建极速统一的湖仓分析新范式,是实现数字化转型和降本增效的关键基础设施。目前,全球 400 家以上市值超过 70 亿元人民币的顶尖企业选择用 StarRocks 来构建新一代数据分析能力,这些企业包括腾讯、携程、平安银行、中原银行、中信建投、招商证券、大润发、百草味、顺丰、京东物流、TCL、OPPO 等。StarRocks 也已经和全球云计算领导者亚马逊云、阿里云、腾讯云等达成战略合作关系。

StarRocks 全球开源社区也正飞速成长。目前,StarRocks 的 GitHub star 数已达 8500,吸引了超过 350 位贡献者和数十家国内外行业头部企业参与共建,用户社区也有过万人的规模。凭借其卓越的表现,StarRocks 荣获了全球著名科技媒体 InfoWorld 颁发的 2023 BOSSIE Award 最佳开源软件奖项。


金融:中信建投中原银行 | 申万宏源 | 平安银行 | 中欧财富


互联网:微信|小红书|网易邮箱|滴滴|美团餐饮SaaS | B站|携程 | 同程旅行芒果TV|得物 |贝壳|汽车之家欢聚集团腾讯腾讯音乐金山办公


游戏:腾讯游戏|波克城市37手游 | 游族网络


新经济:蔚来汽车|理想汽车|顺丰|京东物流跨越速运 | 大润发华润万家TCL |万物新生 | 百草味 | 多点 DMALL 酷开科技


StarRocks 技术内幕:极速湖仓神器:物化视图存算分离,兼顾降本与增效   |实时更新与极速查询如何兼得Query Cache,一招搞定高并发跨集群数据迁移易用性全面提升StarRocks vs.TrinoStarRocks & Iceberg强强联合


StarRocks
StarRocks 是 Linux 基金会旗下的开源项目,专注于打造世界顶级的分析型数据库,以帮助企业建立“极速统一”的湖仓新范式。目前, StarRocks 已成功帮助全球数百家大型企业构建新一代数据分析能力。
 最新文章