【技术预研】StarRocks官方文档浅析(2)

背景说明

基于starRocks官方文档,对其内容进行一定解析,方便大家理解和使用。
若无特殊标注,startRocks版本是3.2。
下面的章节和官方文档保持一致。

参考文档

产品简介 | StarRocks

StarRocks

StarRocks 是一款高性能分析型数据仓库,使用向量化、MPP 架构、CBO、智能物化视图、可实时更新的列式存储引擎等技术实现多维、实时、高并发的数据分析。StarRocks 既支持从各类实时和离线的数据源高效导入数据,也支持直接分析数据湖上各种格式的数据。StarRocks 兼容 MySQL 协议,可使用 MySQL 客户端和常用 BI 工具对接。同时 StarRocks 具备水平扩展,高可用、高可靠、易运维等特性。广泛应用于实时数仓、OLAP 报表、数据湖分析等场景。

内容说明
高性能分析型数据仓库相比于oltp,更适合olap
向量化基于CPU层级的优化(clickhouse有相关优化)
MPP 架构相比于hadoop架构更适合olap
CBO优化多表join的执行时,starRocks内部的执行先后顺序
智能物化视图用于实现单表的实时数据转换,类似clickhouse的物化视图
可实时更新的列式存储引擎可支持实时update
兼容 MySQL可使用mysql相关语法和client工具

表设计


如图所示,一般数据库只有database和table两层,但因为starRocks是湖仓一体化的设计,可以读取外部数据源,所以在外面增加一层进行区分。相当于原来是两层目录,现在是三层目录。
除了常规的视图外,还提供了物化视图。物化视图还分为同步物化视图和异步物化视图,前者相对简单,作用于单表,后者的功能相对复杂,作用于多表。
支持权限控制,分为基于用户标识的访问控制和基于角色的访问控制。

表概览

简单说明表相关信息,入门说明。
有几种表类型,数据怎么分布的,数据有哪些类型,以及其他特性。

数据模型

StarRocks 支持四种数据模型,分别是明细模型 (Duplicate Key Model)、聚合模型 (Aggregate Key Model)、更新模型 (Unique Key Model) 和主键模型 (Primary Key Model)。主键模型逐渐替代更新模式,所以只需要关注三种模型。

明细模型

单纯的事实表,只是把数据写入,不涉及更新合并。适合作为ods层建表,用于存储每天接入的数据。
建表有两个地方需要注意:
DUPLICATE KEY:排序键,不会触发去重,但会影响查询效率(因为数据是按照排序键排列的,影响检索效率)。
DISTRIBUTED BY:默认要配置分桶,降低数据倾斜的风险

CREATE TABLE IF NOT EXISTS detail (
    event_time DATETIME NOT NULL COMMENT "datetime of event",
    event_type INT NOT NULL COMMENT "type of event",
    user_id INT COMMENT "id of user",
    device_code INT COMMENT "device code",
    channel INT COMMENT ""
)
DUPLICATE KEY(event_time, event_type)
DISTRIBUTED BY HASH(user_id)
PROPERTIES (
"replication_num" = "3"
);

聚合模型

相当于实现sum groupby key。但存在的问题是,无法回滚到历史。建议用于ads层,聚合逻辑场景,且如果遇到脏数据,重新计算的成本相对低。
建表有三个地方需要注意:
AGGREGATE KEY:排序键,但会影响查询效率(因为数据是按照排序键排列的,影响检索效率)。【如果不配置这项,则默认是非指标计算的其他列。但建议是显示配置,因为显示配置,如果有列既不是排序键,又不是指标列,则会建表报错】
DISTRIBUTED BY:默认要配置分桶,降低数据倾斜的风险
聚合函数配置:支持SUM、MAX、MIN等可累加的函数

CREATE TABLE IF NOT EXISTS example_db.aggregate_tbl (
    site_id LARGEINT NOT NULL COMMENT "id of site",
    date DATE NOT NULL COMMENT "time of event",
    city_code VARCHAR(20) COMMENT "city_code of user",
    pv BIGINT SUM DEFAULT "0" COMMENT "total page views"
)
AGGREGATE KEY(site_id, date, city_code)
DISTRIBUTED BY HASH(site_id)
PROPERTIES (
"replication_num" = "3"
);

更新模型

可以不关注,反正后续被主键模型替代。
更新模型整体上采用了 Merge-On-Read 的策略。虽然写入时处理简单高效,但是查询时需要在线聚合多版本。并且由于 Merge 算子的存在,谓词和索引无法下推,严重影响了查询性能。

主键模型

主键模型采用了 Delete+Insert 的策略,保证同一个主键下仅存在一条记录,这样就完全避免了 Merge 操作。【存储换时间,通过直接对数据进行标记,如果发生替换,则直接对旧数据标记为-1,这样查询的时候,直接过滤即可】

建表有两个地方需要注意:
PRIMARY KEY:主键,分区列和分桶列必须在,否则会影响查询效率(因为数据是按照主键排列的,影响检索效率)。
DISTRIBUTED BY:默认要配置分桶,降低数据倾斜的风险
ORDER BY:数据合并,可以根据这里的列(解决部分数据延迟,而旧数据更新的场景。例如:1号的订单,2号、3号分别发生状态变更,3号的数据先来,2号的数据后来,如果不配置其他列,模式是入库时间更新,会导致3号数据被删除,保留2号的状态。所以需要配置状态变更时间,而不是默认入库时间)
enable_persistent_index:是否支持索引持久化,就是索引对内存有压力,所以默认开启,可以持久化到磁盘上,降低内存溢出风险。

create table users (
    user_id bigint NOT NULL,
    name string NOT NULL,
    email string NULL,
    address string NULL,
    age tinyint NULL,
    sex tinyint NULL,
    last_active datetime,
    property0 tinyint NOT NULL,
    property1 tinyint NOT NULL,
    property2 tinyint NOT NULL,
    property3 tinyint NOT NULL
) PRIMARY KEY (user_id)
DISTRIBUTED BY HASH(user_id)
ORDER BY(`address`,`last_active`)
PROPERTIES (
    "replication_num" = "3",
    "enable_persistent_index" = "true"
);

数据分布

数据分布的核心是,通过分区、分桶来限制tablet大小【tablet,就是最小的存储单元,官方建议是在1-10GB】。太大的话,导致查询以及合并效率降低,太小的话,会增加内存压力和检索时长。

表达式分区(推荐)

支持时间连续和枚举值,两种场景。
就是可以选择一个时间戳或则日期字段,配置一下分区粒度(现在支持hour、day、month、year,暂不支持week),就可以形成分区。
如果是之前的话,需要自己转换为对应样式才可以。
例如:“2024-01-05 11:11:33”,按照year分区,需要转换为“2024”,按照month分区,需要转化为“2024-01”,按照day分区,需要转换为“2024-01-05”。现在只需要配置hour、day、month、year枚举值即可。
partition_live_number:保留的分区数量,用于控制磁盘占用。

CREATE TABLE site_access2 (
    event_day DATETIME NOT NULL,
    site_id INT DEFAULT '10',
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT DEFAULT '0'
) 
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY date_trunc('month', event_day)
DISTRIBUTED BY HASH(event_day, site_id)
PROPERTIES(
    "partition_live_number" = "3" -- 只保留最近 3 个分区
);

周粒度的分区无法直接配置,但可以利用分区表达式 time_slice(),设置分区列为 event_day,分区粒度为七天。将一周的数据存储在一个分区中,利用分区裁剪可以显著提高查询效率

CREATE TABLE site_access3 (
    event_day DATETIME NOT NULL,
    site_id INT DEFAULT '10',
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY time_slice(event_day, INTERVAL 7 day)
DISTRIBUTED BY HASH(event_day, site_id);

最后,还有说明分区导入数据的方式。

List分区

需要手动创建分区。
就是类似咱们按照店铺分区,但现在说有些店铺算一起的,查询的时候不想一个个查,就给这些店铺增加一个统一的分区。

CREATE TABLE t_recharge_detail2 (
    id bigint,
    user_id bigint,
    recharge_money decimal(32,2), 
    city varchar(20) not null,
    dt varchar(20) not null
)
DUPLICATE KEY(id)
PARTITION BY LIST (city) (
   PARTITION pCalifornia VALUES IN ("Los Angeles","San Francisco","San Diego"), -- 这些城市同属一个州
   PARTITION pTexas VALUES IN ("Houston","Dallas","Austin")
)
DISTRIBUTED BY HASH(`id`);

动态分区

和表达式分区相比,动态分区,只能支持时间类型的字段。好处是可以控制存储文件的范围。

CREATE TABLE site_access(
event_day DATE,
site_id INT DEFAULT '10',
city_code VARCHAR(100),
user_name VARCHAR(32) DEFAULT '',
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY RANGE(event_day)(
PARTITION p20200321 VALUES LESS THAN ("2020-03-22"),
PARTITION p20200322 VALUES LESS THAN ("2020-03-23"),
PARTITION p20200323 VALUES LESS THAN ("2020-03-24"),
PARTITION p20200324 VALUES LESS THAN ("2020-03-25")
)
DISTRIBUTED BY HASH(event_day, site_id)
PROPERTIES(
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-3",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.history_partition_num" = "0"
);

临时分区

用于调整数据分布策略包括分区范围、分桶数、以及部分属性,例如副本数、存储介质。
类似咱们创建一张新表和原来字段一致,但数据分布策略有调整,重新导入数据。
因为支持原子替换(ALTERTABLE table1 SWAP WITH table2;),大概率这种比直接换表效率高。
应用场景:

  1. 原子覆盖写操作
  2. 调整分区数据的查询并发
  3. 修改分区策略

数据压缩

StarRocks 支持四种数据压缩算法:LZ4、Zstandard(或 zstd)、zlib 和 Snappy。StarRocks 默认使用 LZ4,建表后不能修改压缩格式。
通常来说,这些算法的压缩率排名如下:zlib > Zstandard > LZ4 > Snappy。
但压缩率越高,导入和查询性能越差,因为需要解析的成本越高。
所以在内存空间没有硬性要求的情况下,建议选择使用 LZ4 或 Zstandard 算法。

排序键和前缀索引

前缀索引,相当于是排序键的索引。
查询数据时,您可以使用排序列指定过滤条件,StarRocks 不需要扫描全表即可快速找到需要处理的数据,降低搜索的复杂度,从而加速查询。
举个例子:根据日期+店铺排序,如果查询2023年1月份伊利的数据,那么只要找到2023年1月1日到2023年1月31日的数据,根据二分法,针对日期列进行检索,不需要判断每一行是不是。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值