【技术预研】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工具

表设计

【技术预研】StarRocks官方文档浅析(2)_第1张图片
如图所示,一般数据库只有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日的数据,根据二分法,针对日期列进行检索,不需要判断每一行是不是。

你可能感兴趣的:(大数据,starRocks,数据库)