前言概述
StarRocks表概述
一、StarRocks表设计
定义恰当数据字段类型对StarRocks查询的优化是非常重要的,从查询效率的角度考虑,我们可以遵循两条原则: 1、如果数据没有Null,可以指定Not Null属性; 2、尽量使用数字列代替字符串列。
1、分区键选择:当前分区键仅支持日期类型和整数类型,为了让分区能够更有效的裁剪数据,我们一般也是选取时间列作为分区键。 2、分区粒度选择:StarRocks 的分区粒度视数据量而定,单个分区原始数据量建议维持在100G以内。
1、分桶键选择:分桶的目的我们一直在说是为了将数据打散,所以分桶键就需要选择高基数的列(去重后数据量最大的列)。分桶后的数据如果出现严重的数据倾斜,就可能导致系统局部的性能瓶颈,所以我们也可以视情况使用两个或三个列作为分桶键,尽量的将数据均匀分布。我们可以show语句查看表中的数据分布情况: 2、分桶数:分桶数的设置需要适中,如果分桶过少,查询时查询并行度上不来(CPU多核优势体现不出来)。而如果分桶过多,会导致元数据压力比较大,数据导入导出时也会受到一些影响。 3、分桶数的设置通常也建议以数据量为参考,从经验来看,每个分桶的原始数据建议不要超过5个G,考虑到压缩比,也即每个分桶的大小建议在100M-1G之间。 4、若不好估算数据量,我们也可以将分桶数设为:分桶数=“BE个数BE节点CPU核数”或者“BE个数BE节点CPU核数/2”,这样一般也不会有什么问题。这里需要注意的是,已创建分区的分桶数不能修改(有其他方式能实现,但比较麻烦),所以前期设定合适的分桶数非常重要。
需要注意的是:由于存储引擎会为主键建立索引,而在导入数据时会把主键索引加载在内存中,所以主键模型对内存的要求比较高,还不适合主键特别多的场景。目前比较适合的两个场景是:
1、 数据有冷热特征,即最近几天的热数据才经常被修改,老的冷数据很少被修改。典型的例子如 MySQL 订单表实时同步到 StarRocks 中提供分析查询。其中,数据按天分区,对订单的修改集中在最近几天新创建的订单,老的订单完成后就不再更新,因此导入时其主键索引就不会加载,也就不会占用内存,内存中仅会加载最近几天的索引。
2、大宽表(数百到数千列)。主键只占整个数据的很小一部分,其内存开销比较低。比如用户状态和画像表,虽然列非常多,但总的用户数不大(千万至亿级别),主键索引内存占用相对可控。
Caused by: java.io.IOException: com.starrocks.connector.flink.manager.StarRocksStreamLoadFailedException: Failed to flush data to StarRocks, Error response:
{"Status":"Fail","BeginTxnTimeMs":0,"Message":"close index channel failed, load_id=bc4eb485-f99b-1f20-ffd9-e7e7e22925ab","NumberUnselectedRows":0,"CommitAndPublishTimeMs":0,"Label":"2434c3d7-9cef-45b0-b057-482b9a0032cd","LoadBytes":1056,"StreamLoadPutTimeMs":1,"NumberTotalRows":0,"WriteDataTimeMs":14,"TxnId":1355616,"LoadTimeMs":15,"ReadDataTimeMs":0,"NumberLoadedRows":0,"NumberFilteredRows":0}
1、相较更新模型,主键模型(Primary Key)可以更好地支持实时/频繁更新的功能。如果表写入是离线任务,或者更新频率很低则不需要使用主键模型,因为主键模型相对于更新模型有更大的内存消耗。 2、主键表把主键加载到内存中的最小维度是分区,所以主键表如果有冷热数据的概念,可以根据时间增加分区键,减小写入时主键部分消耗的内存。(默认主键表在写入的时候会表写入对应分区主键加载到内存中,如10分钟没有写入需求才会把这部分内存释放)
CREATE TABLE xxxx (
pid BIGINT ( 20 ) NOT NULL DEFAULT '0' COMMENT '企业ID',
task_id VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '任务ID t_task表ID',
userwid VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '用户 t_task表creator_wid',
username VARCHAR ( 150 ) NOT NULL DEFAULT '' COMMENT '用户姓名',
sales_talk_id VARCHAR ( 64 ) NOT NULL DEFAULT '' COMMENT '线路ID, t_task表sales_talk_id',
gap VARCHAR ( 50 ) NOT NULL DEFAULT '' COMMENT '通话间隔 yyyy-MM-dd:HH',
gap_time VARCHAR ( 50 ) NOT NULL DEFAULT '' COMMENT '通时间隔 1-10秒,10-60秒, 1-3分 , 3分以上',
count BIGINT ( 20 ) NOT NULL DEFAULT '0' COMMENT '数量',
create_time datetime NOT NULL COMMENT '创建时间',
update_time datetime NOT NULL COMMENT '更新时间') PRIMARY KEY(pid, task_id, userwid,username, sales_talk_id, gap, gap_time) COMMENT '概览-通话时长'DISTRIBUTED by HASH(pid) BUCKETS 8;
1、不需要实时更新的主键表都改用更新模型。 2、写入有冷热概念的表,全部增加分区键。 3、检查所有主键表的数据生命周期,删除多余数据。
以单个分区大小在 100G 以内,单个 Tablet 数据分配在100M-1G为标准,对表的分区分桶做重新规划,具体方式是: a. 把天级别分区改为月级别分区 b. 对于分桶过多,数据量不大的表,减少分桶数量
bos_id
bigint(20) NOT NULL COMMENT "组织架构树id",vid
bigint(20) NOT NULL COMMENT "节点id",path
varchar(65533) NULL COMMENT "父节点路径",prod_id
bigint(20) NOT NULL COMMENT "产品id",prod_inst_id
bigint(20) NOT NULL COMMENT "产品实例id",st
tinyint(4) NOT NULL COMMENT "数据统计类型0:全部, 1:自身, 2:全部子节点",consign_type
tinyint(4) NOT NULL COMMENT "交付单状态0:待发单;1:发单;2确认收货",order_no
bigint(20) NOT NULL COMMENT "订单号",dd
date NOT NULL COMMENT "日期",merchant_id
bigint(20) NOT NULL COMMENT "商户id",vid_type
bigint(20) NOT NULL COMMENT "节点类型",consign_vid
bigint(20) NULL COMMENT "处理vid",create_time
datetime NOT NULL COMMENT "创建时间"
CREATE TABLE
table1
(dd
date NOT NULL COMMENT "日期",bos_id
bigint(20) NOT NULL COMMENT "组织架构树id",vid
bigint(20) NOT NULL COMMENT "节点id",path
varchar(65533) NULL COMMENT "父节点路径",prod_id
bigint(20) NOT NULL COMMENT "产品id",prod_inst_id
bigint(20) NOT NULL COMMENT "产品实例id",st
tinyint(4) NOT NULL COMMENT "数据统计类型0:全部, 1:自身, 2:全部子节点",consign_type
tinyint(4) NOT NULL COMMENT "交付单状态0:待发单;1:发单;2确认收货",order_no
bigint(20) NOT NULL COMMENT "订单号",merchant_id
bigint(20) NOT NULL COMMENT "商户id",vid_type
bigint(20) NOT NULL COMMENT "节点类型",consign_vid
bigint(20) NULL COMMENT "处理vid",create_time
datetime NOT NULL COMMENT "创建时间"
) ENGINE=OLAP
UNIQUE KEY(dd
,bos_id
,vid
,path
,prod_id
,prod_inst_id
,st
,consign_type
,order_no
)
COMMENT "履约分析_待发货待发单待备货"
PARTITION BY RANGE(dd
)
(PARTITION p2022 VALUES [('1970-01-01'), ('2023-01-01')),
PARTITION p2023 VALUES [('2023-01-01'), ('2024-02-01')),
PARTITION p202401 VALUES [('2023-02-01'), ('2024-03-01')))
DISTRIBUTED BY HASH(bos_id
,order_no
) BUCKETS 6
PROPERTIES (
"replication_num" = "3",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "MONTH",
"dynamic_partition.time_zone" = "Asia/Shanghai",
"dynamic_partition.start" = "-2147483648",
"dynamic_partition.end" = "1",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "6",
"dynamic_partition.start_day_of_month" = "1",
"in_memory" = "false",
"storage_format" = "DEFAULT"
);
二、StarRocks监控
1、Cluster Number:starrocks 集群总数
2、Frontends Status:fe节点状态(1为alive,0为dead)
3、Backends status:be节点状态(1为alive,0为dead)
4、Cluster FE JVM Heap Stat:fe内存使用情况(所有fe节点的平均值)
5、Cluster BE CPU Idle:be节点cpu使用情况(所有be节点的平均值)
6、Cluster BE Mem Stat:be节点内存使用情况(所有be节点的平均值)
7、Cluster QPS Stat:集群qps
8、Capacity used percentage:集群存储使用百分百
9、Disk State:be节点磁盘的状态(1为正常,0为异常)
1、FE Node:FE节点的总数
2、FE Alive:alive状态 FE节点数
3、BE Node:BE节点的总数
4、BE Alive:alive状态 BE节点数
5、Total Capacity:集群整体的存储
6、Used Capacity:已使用的存储
7、Max Replayed journal id:当前最新的journal id
8、Scheduling Tablets:集群中正在调度(被复制)的tablet数量(tablet缺失,不一致,unhealthy,balance 都会触发tablet 的复制),一般情况下,该值超过50需要检查一下集群的负载。
1、 RPS:每个FE的每秒请求数。请求包括发送到FE的所有请求。
2、 QPS:每个FE的每秒查询数。查询仅包括 Select 请求。
3、 99th Latency:每个FE 的 99th个查询延迟情况。
4、 Query Percentile:左 Y 轴表示每个FE的 95th 到 99th 查询延迟的情况。右侧 Y 轴表示每 1 分钟的查询率。
5、 Query Error:左 Y 轴表示累计错误查询次数。右侧 Y 轴表示每 1 分钟的错误查询率。通常,错误查询率应为 0。
6、 Connections:每个FE的连接数量
7、Slow Query:慢查询的数量(累计值)
1、Broker Load Job:每个负载状态下的Broker Load 作业数量的统计。
2、Insert Load Job:由 Insert Stmt 生成的每个 Load State 中的负载作业数量的统计。
3、Report queue size:Master FE 中报告的队列大小
4、Schema Change Job:正在运行的Schema 更改作业的数量。
5、Broker load tendency:Broker Load 作业趋势报告
6、Insert Load tendency:Insert Stmt 生成的 Load 作业趋势报告
7、Load submit:显示已提交的 Load 作业和 Load 作业完成的计数器。
8、Rollup Job:正在运行Rollup 构建作业数量
1、Txn Begin/Success on FE:事务开始/完成的数量,及速率,可以侧面衡量集群的写入频率
2、Txn Failed/Reject on FE:事务失败/拒绝的速率,可以侧面衡量集群写入失败的情况
3、Publish Task on BE:发布任务请求总数和错误率。(注意每个节点取得是错误的概率,集群正常情况下这个应该为0)
4、Txn Requset on BE:在 BE 上显示 txn 请求这里包括:begin,exec,commit,rollback四种请求的统计信息
5、Txn Load Bytes/Rows rate:事务写入速度,左 Y 轴表示 txn 的总接收字节数。右侧 Y 轴表示 txn 的Row 加载率。
1、JVM Heap:FE 服务堆内存使用(2.0.2 版本 FE 内部有内存架构有问题,有统计不全的情况,该值不是极为准确,可以作为 FE 负载变化的参考)
2、JVM Non Heap:非堆内存的使用
3、JVM Direct Buffer:指定 FE 的 JVM 直接缓冲区使用情况。左 Y 轴显示已用/容量直接缓冲区大小。
4、JVM Threads:集群FE JVM线程数。用来参考FE的负载情况
5、JVM Young:指定 FE 的 JVM 年轻代使用情况。
6、JVM Old:指定 FE 的 JVM 老年代使用情况。
7、JVM Young GC:指定 FE 的 JVM 年轻 GC 统计信息(总数和平均时间)。
8、JVM Old GC:指定 FE 的 JVM 完整 GC 统计信息(总数和平均时间)。
1、BE CPU Idle:BE 的 CPU 空闲状态。低表示 CPU 忙。说明CPU的利用率越高
2、BE Mem:这里是监控集群中每个BE的内存使用情况
3、Net send/receive bytes:每个BE节点的网络发送(左 Y)/接收(右 Y)字节速率,除了“IO”
4、Disk Usage:BE节点的storage的大小(注意这个只是/data/starrocks/storage目录的大小,实际机器上面可能会比这个大,有log或者系统使用的磁盘)
5、Tablet Distribution:每个 BE 节点上的 Tablet 分布情况,原则上分布式均衡的,如果差别特别大,就需要去分析原因。(该值不宜过大,太大会消耗FE,以及BE的内存,我们做过相关压测一个 Tablet 大概消耗FE 5KB的内存,并且改值随着整体 Tablet 总量增加而增加。默认一张表的 Tablet 数=分区数分桶数3副本)
1、BE FD count:BE的文件描述符( File Descriptor)使用情况。左 Y 轴显示使用的 FD 数量。右侧 Y 轴显示软限制打开文件数。(可以理解为文件句柄)
2、BE thread num:BE的线程数(用来衡量be的并发情况,当前16core机器在400左右为正常值)
3、BE tablet_writer_count:be节点上面正在做写入的tablet 数量(用来衡量be写入负载)
4、Disk written bytes:be节点上磁盘的写速度。
5、Disk bytes_read:be节点上磁盘的读速度。
6、Disk IO util:每个 BE 节点上磁盘的 IO util 指标,数值越高表示IO越繁忙。
1、BE Compaction Base:BE的Base Compaction压缩速率。左Y轴显示be节点压缩速率,右Y轴显示的整个集群累计做base compaction的大小。
2、BE Compaction Cumulate:BE的Base Cumulate压缩速率。左Y轴显示be节点压缩速率,右Y轴显示的整个集群累计做Cumulate compaction的大小。
1、BE Scan Bytes:BE扫描效率,这表示处理查询时的读取率。(该值可以结合qps一起参考集群的查询压力)
2、BE Scan Rows:BE扫描行的效率,这表示处理查询时的读取率。
3、Tablet Meta Write:左Y 轴显示了tablet header 的写入速率。右侧 Y 轴显示每次写入操作的持续时间。
4、Tablet Meta Read:左Y 轴显示了tablet header 的读取速率。右侧 Y 轴显示每次读操作的持续时间。
1、Tablets Report failed:BE Tablet 汇报给FE的失败率。(正常值是0,如果该值异常,考虑排查FE BE通信,或者FE BE负载是否有问题)
2、Delete failed:BE 做删除操作的失败率。(一般不会出现失败,如果删除失败检查一下磁盘是否正常)
3、Finish task report failed:BE向FE汇报的失败率。(正常值是0,如果该值异常,考虑排查FE BE通信,或者FE BE负载是否有问题)
4、Tablets Report:BE向FE做全量Tablet汇报的频率(正常的值是在0.67左右,如果该值减少,需要排查一下BE节点的负载情况)
5、Delete task:BE做删除操作的频率。(用来监控集群删除数据的频率,一般情况是0,如果该值比较大,需要排查集群是否在做 删表,删库操作)
6、Finish task report:BE节点运行Task的频率(可以用来衡量BE的繁忙程度和并发)
1、Base Compaction failed:Base compaction失败率(BE做大合并的失败率,正常是0,如果该值异常,需要检查Be compaction内存,以及BE的IO是否正常。)
2、Cumulative Compaction failed:Cumulative Compaction(BE做小合并的失败率,正常是0,如果该值异常,需要检查Be compaction内存,以及BE的IO是否正常。)
3、Clone failed:tablet clone的失败率(Tabelt 做副本修复或者均衡的时候会clone,该值异常检查一下BE的IO)
4、Base Compaction task:Be做base compaction的频率。(用来反应当前集群的compaction大压力,如果Tablet 不及时做compaction,会影响读写性能,可以调整base compaction的并发来调整)
5、Cumulative Compaction task:BE做cumulative compaction的频率。(用来反应当前集群的小compaction压力,如果Tablet 不及时做compaction,会影响读写性能,可以调整cumulative compaction的并发来调整)
6、Clone task:BE节点Tablet 做复制的频率(这个可以结合 scheduler tablet监控一起来判断集群的Tablet复制的情况)
1、Create tablet:新建Tablet 频率(一般新建表,新建分区,写数据会伴随着tablet数的增加,改值可以用来衡量集群的写入频率)
2、Single Tablet Report:tablet的汇报频率(左侧 Y 轴表示指定任务的失败率。通常,它应该是 0。右侧 Y 轴表示所有 Backends 中指定任务的总数。)
3、Create tablet failed:新建Tablet 失败率(一般新建表,新建分区,写数据会伴随着tablet数的增加,该值正常是0,如果该值异常要检查一下集群是否有建表,建分区失败的情况)
1、BE used Mem:BE服务使用的总内存(当前BE节点配置的内存基本都为机器内存的80%,如果使用内存超了需要,排查内存具体消耗在哪里,具体优化或者分析是否需要扩容)
2、BE query Mem:查询部分消耗的内存。(对于64G内存的机器,当前该值的限制是40G,该内存需要结合QPS,慢查询一起治理优化)
3、BE load Mem:导入任务消耗的内存。(对于64G内存的机器,当前该值的限制是13G,如果该值大,需要连接集群Show Load;查看当前的导入任务,建议超过10G大小的数据,不要再业务高峰期操作)
4、BE meta Mem:BE消耗元数据总内存。(在查询和导入的时候,BE会把相关的Tablet元数据加载到内存中,这部分内存目前没有命令可以主动释放,需要重启节点才能释放)
1、BE compaction Mem:BE服务做compaction使用的内存。(对于64G的机器,当前该值的限制是14G,建议超过10G大小的数据,不要再业务高峰期操作,否则做compaction会很消耗内存,影响集群的查询)
2、BE column_pool Mem:column pool 内存池,用于加速存储层数据读取的 Column Cache。(在做查询的时候,会把部分缓存保留在内存中,该内存没有命令主动释放,只能重启节点才能释放)
3、BE page cache Mem:BE 存储层 Page 缓存。(当前集群都没有开启Page cache)
4、BE CPU per core cache Mem:CPU per core 缓存,用于加速小块内存申请的 Cache。
1、BE Consistency Mem:集群做Tablet 一致性校验的时候消耗的内存(集群会周期性的自动触发做一致性校验,有不一致的之后会伴随着Tablet 的复制,改情况为正常情况)
2、BE Primary Key Mem:主键索引消耗的内存。(对于64G的机器,该值的限制是26G,默认主键表在写入的时候,会把目标分区的主键索引都加载到内存中,如果该值过大,可以联系运维,访问BE 8040端口查看主键内存消耗的集群情况,找到对应的表做对应治理)
3、 BE Tablet Clone Mem:Tablet 复制时消耗的内存(如果该值过大,需要排查集群tablet的健康情况,一般会伴随大量的Tablet Scheduler)
总结