StarRocks

目录

StarRocks

基本概念

系统架构

功能

排序键

物化视图

数据导入

使用

库表创建

数据类型

注意事项

新增分区

修改字段类型

问题

问题1:

问题2:

问题3:

问题4:

问题5:

ClickHouse与StarRocks的对比


StarRocks

StarRocks是新一代企业级MPP数据库。StarRocks重新定义了MPP分布式架构,集群可扩展至数百节点,支持PB级数据规模,是当前唯一可以在大数据规模下进行在线弹性扩展的企业级分析型数据库。StarRocks还打造了全新的向量化执行引擎,单节点每秒可处理多达100亿行数据。

  • StarRocks致力于满足企业用户的多种数据分析场景,支持多种数据模型(明细表, 聚合表), 多种导入方式

    (批量), 可整合和接入多种现有系统(Spark, Flink, Hive, ElasticSearch)。

  • StarRocks兼容MySQL协议, 可使用MySQL客户端和常用BI工具对接StarRocks来进行数据分析。

  • StarRocks采用分布式架构, 对table进行水平划分并以多副本存储. 集群规模可以灵活伸缩, 能够支持10PB

    级别的数据分析; 支持MPP, 并行加速计算; 支持多副本, 具有弹性容错能力。

  • StarRocks采用关系模型, 使用严格的数据类型, 使用列式存储引擎, 通过编码和压缩技术, 降低读写放大.

    使用向量化执行方式, 充分挖掘多核CPU的并行计算能力, 从而显著提升查询性能。

  • StarRocks根据摄入数据和实际存储数据之间的映射关系, 其中明细表对应明细模型(Duplicate Key),聚合

    表对应聚合模型(Aggregate Key),更新表对应更新模型(Unique Key)和主键模型(Primary Key)。

为了描述方便, 我们借鉴关系模式中的主键概念, 称StarRocks表的维度列的取值构成数据表的排序键, StarRocks的排序键对比传统的主键具有:

  • 数据表所有维度列构成排序键, 所以后文中提及的排序列, key列本质上都是维度列。

  • 排序键可重复, 不必满足唯一性约束。

  • 数据表的每一列, 以排序键的顺序, 聚簇存储。

  • 排序键使用稀疏索引。

基本概念

FE:FrontEnd StarRocks的前端节点,负责管理元数据,管理客户端连接,进行查询规划,查询调度等工作。

BE:BackEnd StarRocks的后端节点,负责数据存储,计算执行,以及compaction,副本管理等工作。

Broker:StarRocks中和外部HDFS/对象存储等外部数据对接的中转服务,辅助提供导入导出功能。

Tablet:StarRocks 表的逻辑分片,也是StarRocks中副本管理的基本单位,每个表根据分区和分桶机制被划分成多个Tablet存储在不同BE节点上。

系统架构

StarRocks 集群由FE和BE构成, 可以使用MySQL客户端访问StarRocks集群。

查询流程如下:

① MySQL客户端执行DQL SQL命令。

② FE解析, 分析, 改写, 优化和规划, 生成分布式执行计划。

③ 分布式执行计划由 若干个可在单台be上执行的plan fragment构成, FE执行exec_plan_fragment, 将

plan fragment分发给BE,指定其中一台BE为coordinator。

④ BE执行本地计算, 比如扫描数据。

⑤ 其他BE调用transimit_data将中间结果发送给BE coordinator节点汇总为最终结果。

⑥ FE调用fetch_data获取最终结果。

⑦ FE将最终结果发送给MySQL client。

功能

排序键

StarRocks中为加速查询,在内部组织并存储数据时,会把表中数据按照指定的列进行排序,这部分用于排序的列(可以是一个或多个列),可以称之为Sort Key。明细模型中Sort Key就是指定的用于排序的列(即 DUPLICATEKEY 指定的列),聚合模型中Sort Key列就是用于聚合的列(即 AGGREGATE KEY 指定的列),更新模型中Sort Key就是指定的满足唯一性约束的列(即 UNIQUE KEY 指定的列)。下图中的建表语句中Sort Key都为 (site_id、city_code)。

如何选择排序列:

当Sort Key涉及多个列的时候,谁先谁后也有讲究,区分度高、经常查询的列建议放在前面。

有两点需要注意:

  • 排序列的定义必须出现在建表语句中其他列的定义之前。

  • 排序列的顺序是由create table语句中的列顺序决定的。

物化视图

物化视图是一种预先计算的技术,同RollUp表,预先计算是为了减少查询时现场计算量,从而降低查询延迟。明细表包含所有原始的导入数据,因此可对明细表进行任意维度分析,而物化视图正是为了解决明细表的任意维度分析的预先聚合而提出,同时物化视图的功能是RollUp表的超集,原有的RollUp功能都可通过物化视图来实现。

物化视图的使用场景有:

  • 分析需求覆盖明细数据查询以及固定维度聚合查询两方面。

  • 需要做对排序键前缀之外的其他列组合形式做范围条件过滤。

  • 需要对明细表的任意维度做粗粒度聚合分析。

注:

  1. 如果表存在delete 操作,不建议创建物化视图(可能会导致删除数据失败);

  2. 仅明细模型支持聚合函数物化视图;

  3. 物化视图的聚合函数的参数仅支持单列, 比如: sum(a+b)不支持。

  4. 如果删除语句的条件列,在物化视图中不存在,则不能进行删除操作。如果一定要删除数据,则需要先将物化视图删除,然后方可删除数据。

  5. 单表上过多的物化视图会影响导入的效率:导入数据时,物化视图和 base 表数据是同步更新的,如果一张表的物化视图表超过10张,则有可能导致导入速度很慢。这就像单次导入需要同时导入10张表数据是一样的。

  6. 相同列,不同聚合函数,不能同时出现在一张物化视图中,比如:select sum(a), min(a) from table 不支持。 物化视图的创建语句目前不支持JOIN和WHERE, 也不支持GROUP BY的HAVING子句。

  7. 不能同时创建多个物化视图, 只能等待上一个物化视图创建完成, 才能创建下一个物化视图。

数据导入

StarRocks提供了多种导入方式,用户可以根据数据量大小、导入频率等要求选择最适合自己业务需求的导入方式。

为适配不同的数据导入需求,StarRocks 系统提供了5种不同的导入方式,以支持不同的数据源(如HDFS、Kafka、本地文件等),或者按不同的方式(异步或同步)导入数据。

所有导入方式都支持 CSV 数据格式。其中 Broker Load 持 Parquet 和 ORC 数据格式。

1.Broker Load

Broker Load 通过 Broker 进程访问并读取外部数据源,然后采用 MySQL 协议向 StarRocks 创建导入作业。提交的作业将异步执行,用户可通过 SHOW LOAD 命令查看导入结果。

Broker Load适用于源数据在Broker进程可访问的存储系统(如HDFS)中,数据量为几十GB到上百GB。

hdfs servicenames = HDFS43394

2.Spark Load

Spark Load 通过外部的 Spark 资源实现对导入数据的预处理,提高 StarRocks 大数据量的导入性能并且节省StarRocks 集群的计算资源。Spark load 是一种异步导入方式,需要通过 MySQL 协议创建导入作业,并通过SHOW LOAD 查看导入结果。

Spark Load适用于初次迁移大数据量(可到TB级别)到StarRocks的场景,且源数据在Spark可访问的存储系统(如HDFS)中。

3.Stream Load

Stream Load是一种同步执行的导入方式。用户通过 HTTP 协议发送请求将本地文件或数据流导入到StarRocks中,并等待系统返回导入的结果状态,从而判断导入是否成功。

Stream Load适用于导入本地文件,或通过程序导入数据流中的数据。

例: curl --location-trusted -u root:root -H "Expect:100-continue" -H "column_separator:," -T

/data/clickhouse-test/ads_guider_saas_share_rank_d/ads_guider_saas_share_rank_d_af.1 -XPUT http://10.12.114.170:8030/api/db_sente_test/ads_guider_saas_share_rank_d/_stream_load

4.Routine Load

Routine Load(例行导入)提供了一种自动从指定数据源进行数据导入的功能。用户通过 MySQL 协议提交例行导入作业,生成一个常驻线程,不间断的从数据源(如 Kafka)中读取数据并导入到 StarRocks 中。

5.Insert Into

类似 MySQL 中的 Insert 语句,StarRocks 提供 INSERT INTO tbl SELECT ...; 的方式从 StarRocks 的表中读取数据并导入到另一张表。或者通过 INSERT INTO tbl VALUES(...); 插入单条数据。

使用

库表创建

一、 建库

建库语法:

CREATE DATABASE IF NOT EXISTS 库名;

例:

CREATE DATABASE IF NOT EXISTS mp_aries;

查看创建结果:

SHOW DATABASES;

二、 建表

  1. 表引擎

    StarRocks支持4种表引擎,可以根据实际情况选择合适的表引擎

引擎名称引擎说明场景备注
olap默认引擎正常使用这个默认引擎,一般就用这个
mysql访问mysql外部表
hive访问hive外部表
broker访问broker
  1. 表模型

    StarRocks支持3种数据模型,可以根据实际情况选择合适的模型

模型名称模型定义说明场景
明细模型DUPLICATE KEY原始数据,同主键数据不会去重合并,类似于ck的MergeTree数据更新不频繁。不用更新的日志、行为记录表,导入数据的来源一般为日志数据或者是时序数据, 以追加写为主要特点, 数据产生后就不会发生太多变化。
更新模型UNIQUE KEY同样是原始明细数据,同主键数据会覆盖更新,类似于ck的ReplacingMergeTree已经写入的数据有大量的更新需求;应该是sente最通常的场景,
聚合模型AGGREGATE KEY存储聚合数据,相同主键的数据会按照聚合规则汇总成一行,类似于ck的AggregatingMergeTree业务方进行的查询为汇总类查询,比如sum、count、 max等类型的查询;不需要召回原始明细数据,直接提供聚合结果的特定场合,表中数据大大减少,性能高
  1. 创建表

    建表语法:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, ...]
[, index_definition1[, ndex_definition12,]]) -- 列定义,基本类似mysql
[ENGINE = [olap|mysql|broker|hive]] -- engine一般就选默认的olap,可以省略这个语句
[key_desc] -- 设置数据模型以及主键字段
[COMMENT "table comment"] -- 表备注
[partition_desc] -- 分区设置,不是分区表可以不用写
[distribution_desc] -- 分布设置(哈希,分桶)
[rollup_index] -- 上卷设置(不使用可以忽略)
[PROPERTIES ("key"="value", ...)] -- 附加参数配置(副本数、存储介质、动态分区,
如果不是分区表可以用默认的不用设置)
[BROKER PROPERTIES ("key"="value", ...)]; -- broker附加参数(针对broker引擎,一般用不到)     
  

注意:

  • 建表时,Key列不能用Float或者Double类型,可用Decimal类型表示小数。

  • VARCHAR最长可为65533字节(由于前两个字节用于表示长度,因此比65535少两个字节)。

  • StarRocks只支持UTF8编码,不支持GBK等编码。

  • StarRocks不支持修改表中的列名。

  • SQL 最大长度默认10000字节,可以通过fe.conf的 expr_child_limit 修改

数据类型

分类常用类型字节数说明
整数(starrocks整数都是有符号的)tinyint1数据范围: -128 ~ 127
smallint2数据范围:-32768 ~ 32767
int4数据范围: -2147483648 ~ 2147483647
bigint8数据范围: -9223372036854775808 ~ 9223372036854775807
largeint16数据范围:-2^127 ~ 2^127 - 1
浮点数float432位浮点数
double864位浮点数
定点数decimal(precision, scale)16保证精度的小数类型。默认是 DECIMAL(10, 0) precision: 1 ~ 38 scale: 0 ~ precision其中整数部分为:precision - scale不支持科学计数法
字符串不定长varchar(n)变长字符串,n为最大长度,范围:1-65536
定长char(n)固定长度n的字符串,范围:1-255
不定长string任意长度的字符串 (建议用这个)
日期与时间日期date3日期类型,'2021-01-08',精确到天,范围:0000-01-01 ~ 9999-12-31
时间datetime8日期时间类型,'2021-01-08 13:13:13',精确到秒,范围:0000-01-01 00:00:00 ~ 9999-12-31 23:59:59
特殊类型hllhll列类型,不需要指定长度和默认值,长度根据数据的聚合程度系统内控制,并且HLL列只能通过配套的hll_union_agg、Hll_cardinality、hll_hash进行查询或使用
bitmapbitmap列类型,不需要指定长度和默认值。表示整型的集合,元素最大支持到2^64 - 1
注意事项
  1. Starrocks建表时字段默认都是可空的(NULL),如果需要设置为非空,建表语句加上NOT NULL修饰 (这点跟官方文档不一样,待确认)

    建议在sql中显示指定,非空的就设置NOT NULL, 可空的就设置NULL

  2. Starrocks没有0-1布尔类型,用tinyint取代,只存储0和1两种值即可

    为了使用方便、节省存储空间、查询性能等方面考虑,强烈建议库表设计时按照如下原则

    1)所有的字段都需要根据业务意义考虑好所使用的字段类型,并且在各个表中保持一致;

    例如:order_num,订单数量,设置为bigint了,那么就在所有涉及的表中,把表达订单数量这个含义的字段,都使用bigint

    再如:user_age,用户年龄,设计为tinyint了,那么就都是tinyint,不要这里设计成bigint,那里是tinyint

    2)在1)的前提下,考虑字段类型设计时,尽量设计成最小范围/最小性能消耗的字段

    例如:

    a) 尽量考虑字段设置为非空,允许为空会占用额外存储空间影响性能。主键必须设置非空,非主键在不影响业务需要前提下尽可能做到非空设置默认值

    b) 如果是时间日期类型,尽量用Date/DateTime,避免用字符串

    c) 如果能保证固定是数字,就不要用字符串

    d) 如果是整数,就不要用Float/Double/Decimal

    e) 对于金额之类场景,精度要求高的,可以用decimal; 普通的浮点数场景,可以使用Float/Double

    f) 如果能用范围小的整数,就不要用范围大的类型,比如age 导购年龄,我们用户不会超过100,那么tinyint (-128 - 127)就是一个合理的选择

    g) 对于固定的字符串类型,比如是、否,可以存储char(1);

新增分区

-- 首先, 关闭动态分区功能
alter table mp_sente.ads_cmn_saas_member_d set ("dynamic_partition.enable" = "false");
-- 然后,将历史的分区补上
-- 第一个日期写需要同步的历史数据最早日期
-- 第二个日期写当前表最早的那个分区
alter table mp_sente.ads_cmn_saas_member_d add partitions start ("2019-04-01") end ("2019-12-20") every (interval 1 day); -- 补上从2019-06-01(含)到2019-12-20(不含)的分区
-- 最后,恢复动态分区功能
alter table mp_sente.ads_cmn_saas_member_d set ("dynamic_partition.enable" = "true");

修改字段类型

期望是将bigint 修改为 decimal

  1. 在sr支持的情况下是可以直接通过下面的修改命令操作,鉴于sr暂时不支持下面的修改操作,故选择了重新建表

  2. 尝试替换原子表,发现还是用不了,替换命令需要保持两个原子表完全一样

  3. 最终操作

    --第一步,创建新新结构表
    CREATE TABLE mp_sente.ads_gdr_saas_guide_olap_dwm_bak LIKE mp_sent.ads_gdr_saas_guide_olap_dwm;
    -- 第二步老表移动数据到新表
    INSERT INTO mp_sente.ads_gdr_saas_guide_olap_dwm_bak
    SELECT * FROM mp_sente.ads_gdr_saas_guide_olap_dwm;
    -- 第三步核对数据量是否一致
    SELECT 'new' t,count(1) sl        FROM mp_sente.ads_gdr_saas_guide_olap_dwm_bak
    UNION ALL
    SELECT 'old' t,count(1) sl        FROM mp_sente.ads_gdr_saas_guide_olap_dwm;
    --第四步修改表名称
    ALTER TABLE ads_gdr_saas_guide_olap_dwm RENAME ads_gdr_saas_guide_olap_dwm_1;
    ALTER TABLE ads_gdr_saas_guide_olap_dwm_bak RENAME ads_gdr_saas_guide_olap_dwm;
    --第五步删除老表
    DROP TABLE ads_gdr_saas_guide_olap_dwm_1;

问题

问题1:

解决方案,强制下载驱动文件

问题2:

可以直接删除表,重建,不用必须删除文件

问题3:

output_sr 两个文件需要先执行tmp文件,然后再执行这个

问题4:

数据质量问题,sr的建表默认设置的非空

解决办法,把hive的设置默认值,或者把sr的建表语句中的非空去掉

问题5:

org.jkiss.dbeaver.model.sql.DBSQLException: SQL 错误 [1064] [42000]:

The query contains multi count distinct or sum distinct, each can't have multi columns.

不能多字段去重

select
    count(DISTINCT user_id) as perCount,
    count(DISTINCT user_id , round_id) as shakeCount
from
    wall_t_shake_record
优化后

SELECT
    wall_id,
    count(DISTINCT user_id),
    count(DISTINCT concat(user_id,'_', round_id))
FROM
    wall_t_shake_record
GROUP BY
    wall_id ;

ClickHouse与StarRocks的对比

StarRocksClickHouse
标准SQL语言的支持支持标准的SQL语言,兼容MySQL协议,现有业务SQL无需改写不支持标准的SQL语言
分布式join支持各种主流分布式join,不仅支持大宽表模型,还支持星型模型和雪花模型几乎不支持分布式join,推荐大宽表
高并发查询现代化MPP数据分布方式,数据按照分片的方式保存,小查询只需要用到部分机器资源,极大地提高并发查询量传统MMP数据分布式,小查询会极大消耗集群资源,无法实现高并发查询,并且无法通过扩容的方式来提高并发能力
MPP架构现代化MPP架构,可以实现多层聚合,能够执行复杂的SQL查询,大表join,高基数聚合查询等Scatter-Gather模式,聚合操作依赖单点完成,操作数据量大时存在明显的性能瓶颈
Exactly once 语义数据导入有事务保证,可以实现Exactly once语义,数据导入“不丢不重”无法保证数据写入的“不丢不重”
集群扩容现代化MPP数据分布式方式,扩容时只需要迁移部分数据分片走即可,系统自动完成,不影响线上服务传统MPP数据分布式,数据扩容时需要进行数据重分布,需要人工操作,工作量巨大,影响线上服务
运维不依赖任务外部系统,整个系统只有两种进程,自动故障恢复,极简运维分布式方案依赖Zookeeper,在集群扩大时,Zookeeper会变成性能瓶颈,额外运维和维护成本高
社区生态开源社区的核心研发人员都是中国人开源社区被俄罗斯公司把持
优点单表查询和多表查询性能都很强,可以同时较好支持宽表查询场景和复杂多表查询。支持高并发查询。支持实时数据微批ETL处理。流式和批量数据写入都能都比较强。兼容MySQL协议和标准SQL。很强的单表查询性能,适合基于大宽表的灵活即席查询。包含丰富的MergeTree Family,支持预聚合。非常适合大规模日志明细数据写入分析。
缺点周边生态比较不完善。部分SQL语法不支持。不支持真正的删除与更新。Join方式不是很友好。并发能力比较低。MergeTree合并不完全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值