第2.4章 StarRocks表设计——分区分桶与副本数

目录

一、数据分布

1.1 概述

1.2 数据分布方式

1.2.1 Round-Robin

1.2.2 Range

1.2.3 List

1.2.4 Hash

1.3 StarRocks的数据分布方式

1.3.1 不分区+ Hash分桶

1.3.2 Range分区+Hash分桶

三、分区

3.1 分区概述

3.2 创建分区

3.2.1 手动创建分区

3.2.2 批量创建分区

3.2.3 动态分区

四、分桶

4.1 分桶概述

4.2 设置分桶键

4.2.1 哈希分桶

4.3 确定分桶数量

4.3.1 建表时

4.3.2 建表后

五、建表调优

5.1 数据倾斜

5.2 高并发

5.3 高吞吐

5.4 元数据管理

六、分区分桶及副本之间的关系

该篇文章介绍StarRocks-2.5.4版本的分区分桶及副本相关内容,有误请指出~

一、数据分布

1.1 概述

      建表时,通过设置合理的分区和分桶,使数据均衡分布在不同节点上,查询时能够有效裁剪数据扫描量,最大限度的利用集群的并发性能,从而提升查询性能。

1.2 数据分布方式

      分布式数据库中常见的数据分布方式有:Round-Robin、Range、List 和 Hash。如下图所示:

1.2.1 Round-Robin

        以询的方式把数据逐个放置在相邻节点上。

1.2.2 Range

      按照分区进行数据分区,如下图所示,区间[1-3] 、[4-6]分别对应不同的范围(Range)。

适用场景:数据简单有序,并且通常按照连续日期/数值范围来查询和管理数据,range分区是常用的分区方式。

1.2.3 List

      直接基于离散的各个取值做数据分布,例如性别,省份等数据就满足这种离散的特性(离散:取值是有限的),每个离散值会映射到一个节点上,多个不同的取值可能也映射到相同节点上。适用场景:按照枚举值来查询和管理数据,比如经常按照国家和城市来查询和管理数据,则可以使用该方式,选择分区列为 city

1.2.4 Hash

      通过哈希函数把数据映射到不同节点上。

总结:可以根据具体的业务场景需求组合使用这些数据分布方式,常见的组合方式有 Hash+Hash、Range+Hash、Hash+List。

1.3 StarRocks的数据分布方式

   StarRocks支持两层的数据划分。第一层是Partition分区,支持Range、List或者不分区(不分区代表全表只有一个分区)。第二层是 Bucket分桶(Tablet),StarRocks-2.5.4版本分桶方式只有Hash哈希分桶。StarRocks常见的两种数据分布方式如下:

1.3.1 不分区+ Hash分桶

      概述: 一张表只有一个分区,分区按照分桶键和分桶数量进一步进行数据划分,分桶规则: Hash算法(分桶键)% 分桶数

    建表语句:

#不分区+ Hash分桶,分桶键为site_id
CREATE TABLE site_access(
    site_id INT DEFAULT '10',
    city_code SMALLINT,
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(site_id, city_code, user_name)
DISTRIBUTED BY HASH(site_id) BUCKETS 10;

1.3.2 Range分区+Hash分桶

      概述:一张表拆分成多个分区,每个分区按照分桶键和分桶数量进一步进行数据划分,分桶规则: Hash算法(分桶键)% 分桶数

     建表语句:

#分区键为partition_no,分桶键为cbhtbm:
create table test.ods_cbht (
      cbhtbm                string               comment "",
      fbfbm                 string               comment "",
      cbfbm                 string               comment "",
      cbfs                  string               comment "",
      cbqxq                 datetime             comment "",
      cbqxz                 datetime             comment "",
      partition_no          bigint               comment ""
) engine=olap
duplicate key(cbhtbm)
comment ""
partition  by   range(partition_no) (
start("110000")  end ("160000")  every (10000),
start("210000")  end ("240000")  every (10000),
start("310000")  end ("380000")  every (10000),
start("410000")  end ("470000")  every (10000),
start("500000")  end ("550000")  every (10000),
start("610000")  end ("660000")  every (10000),
start("710000")  end ("720000")  every (10000),
start("810000")  end ("830000")  every (10000)
)
distributed by hash(cbhtbm) buckets 8
properties (
"replication_num" = "3",
"in_memory" = "false",
"storage_format" = "default"
);

三、分区

3.1 分区概述

   (1)分区用于将数据划分成不同的区间。分区的主要作用是将一张表按照分区键拆分成不同的管理单元,针对每一个管理单元选择相应的存储策略,比如副本数分桶数冷热策略存储介质等。StarRocks支持在一个集群内使用多种存储介质,将新数据所在分区放在SSD盘上,利用 SSD优秀的随机读写性能来提高查询性能,将旧数据存放在 SATA 盘上,以节省数据存储的成本。   

  (2)选择合理的分区列可以有效的裁剪查询数据时扫描的数据量。业务系统中⼀般会选择根据时间进行分区,以优化大量删除过期数据带来的性能问题,同时也方便冷热数据分级存储。选择分区单位时需要综合考虑数据量、查询特点、数据粒度等因素。

  • 示例 1:表单月数据量很小,可以按月分区,相比于按天分区,可以减少元数据数量,从而减少元数据管理和调度的资源消耗
  • 示例 2:表单月数据量很大,而大部分查询条件精确到天,如果按天分区,可以做有效的分区裁减,减少查询扫描的数据量。
  • 示例 3:数据要求按天过期,可以按天分区。

  (3)StarRocks支持手动创建分区、批量创建分区、动态分区

3.2 创建分区

     选择合理的分区键可以有效的裁剪扫描的数据量,常见的分区键为时间或者区域,目前支持分区键的数据类型为日期和整数类型

3.2.1 手动创建分区

#分区键event_day,类型是DATE
CREATE TABLE site_access(
    event_day DATE,
    site_id INT DEFAULT '10',
    city_code VARCHAR(100),
    user_name VARCHAR(32) DEFAULT '',
    pv BIGINT SUM DEFAULT '0'
)
AGGREGATE KEY(event_day, site_id, city_code, user_name)
PARTITION BY RANGE(event_day)
(
    PARTITION p1 VALUES LESS THAN ("2020-01-31"),
    PARTITION p2 VALUES LESS THAN ("2020-02-29"),
    PARTITION p3 VALUES LESS THAN ("2020-03-31")
)
DISTRIBUTED BY HASH(site_id) BUCKETS 10;

3.2.2 批量创建分区

  • 建表时批量创建日期分区

       当分区键为日期类型时,建表时通过 start、end指定批量分区的开始日期和结束日期,every子句指定分区增量值。并且every子句中用 interval关键字表示日期间隔,目前仅支持日期间隔的单位为day、week、month、year。

#如下,批量分区的开始日期为2021-01-01和结束日期为2021-01-04,增量值为一天:
create table site_access (
    datekey date,
    site_id int,
    city_code smallint,
    user_name varchar(32),
    pv bigint default '0'
)
engine=olap
duplicate key(datekey, site_id, city_code, user_name)
partition by range (datekey) (
    start ("2021-01-01") end ("2021-01-04") every (interval 1 day)
)
distributed by hash(site_id) buckets 10
properties (
    "replication_num" = "3" 
);


#则相当于在建表语句中使用如下partition by子句:前闭后开
partition by range (datekey) (
    partition p20210101 values [('2021-01-01'), ('2021-01-02')),
    partition p20210102 values [('2021-01-02'), ('2021-01-03')),
    partition p20210103 values [('2021-01-03'), ('2021-01-04'))
)
  • 建表时批量创建区划分区 

      当分区键为区域类型时,建表时通过 start、end指定批量分区的开始和结束,every子句指定分区增量值

create table test.ods_cbht (
      cbhtbm                string               comment "",
      fbfbm                 string               comment "",
      cbfbm                 string               comment "",
      cbfs                  string               comment "",
      cbqxq                 datetime             comment "",
      cbqxz                 datetime             comment "",
      partition_no          bigint               comment ""

) engine=olap
duplicate key(cbhtbm)
comment ""
partition  by   range(partition_no) (
start("110000")  end ("160000")  every (10000),
start("210000")  end ("240000")  every (10000),
start("310000")  end ("380000")  every (10000),
start("410000")  end ("470000")  every (10000),
start("500000")  end ("550000")  every (10000),
start("610000")  end ("660000")  every (10000),
start("710000")  end ("720000")  every (10000),
start("810000")  end ("830000")  every (10000)
)
distributed by hash(cbhtbm) buckets 8
properties (
"replication_num" = "3",
"in_memory" = "false",
"storage_format" = "default"
);

3.2.3 动态分区

    可以按需对新数据动态创建分区,同时 StarRocks 会自动删除过期分区,从而确保数据的实效性,实现对分区的生命周期管理(Time to Life,简称 “TTL”),降低运维管理的成本。详细配置见文章:

动态分区 | StarRocks动态分区功能开启后,您可以按需为新数据动态地创建分区,同时 StarRocks 会⾃动删除过期分区,从而确保数据的时效性。https://docs.starrocks.io/zh/docs/2.5/table_design/dynamic_partitioning/

四、分桶

4.1 分桶概述

      分区按照分桶键和分桶数量进一步进行数据划分,一个分区按分桶方式被分成了多个桶 bucket,每个桶的数据称之为一个Tablet。StarRocks一般采用Hash算法作为分桶算法。在同一分区内,分桶键哈希值相同的数据会划分到同一个Tablet(数据分片),Tablet 以多副本冗余的形式存储,是数据均衡和恢复的最⼩单位,数据导入和查询最终都下沉到所涉及的 Tablet 副本上。ps:建表时,如果使用哈希分桶,则必须指定分桶键。

4.2 设置分桶键

4.2.1 哈希分桶

      对每个分区的数据,StarRocks会根据分桶键和分桶数量进行哈希分桶。哈希分桶中,使用特定的列值作为输入,通过哈希函数计算出一个哈希值,然后将数据根据该哈希值分配到相应的桶中。

 (1)优点

  • 提高查询性能。相同分桶键值的行会被分配到一个分桶中,在查询时能减少扫描数据量。
  • 均匀分布数据。通过选取较高基数(唯一值的数量较多)的列作为分桶键,能更均匀的分布数据到每一个分桶中。

 (2)如何选择分桶键

  • 如果查询比较复杂,则建议选择高基数的列为分桶键,保证数据在各个分桶中尽量均衡,提高集群资源利用率。
  • 如果查询比较简单,则建议选择经常作为查询条件的列为分桶键,提高查询效率。

  (3)注意事项

  • 建表时,如果使用哈希分桶,则必须指定分桶键。
  • 组成分桶键的列仅支持整型、decimal(数值型)、date/datetime(日期型)、char/varchar/string (字符串)数据类型。

  (4)案例

     案例一:假设site_id为高基数列,site_access表采用site_id作为分桶键

#假设site_id为高基数列,site_access表采用site_id作为分桶键
create table site_access(
    event_day date,
    site_id int default '10',
    city_code varchar(100),
    user_name varchar(32) default '',
    pv bigint sum default '0'
)
aggregate key(event_day, site_id, city_code, user_name)
partition by range(event_day) (
    partition p1 values less than ("2020-01-31"),
    partition p2 values less than ("2020-02-29"),
    partition p3 values less than ("2020-03-31")
)
distributed by hash(site_id);

    案例二:如果site_id分布十分不均匀,那么采用上述分桶方式会造成数据分布出现严重的倾斜,进而导致系统局部的性能瓶颈。需要调整分桶的字段,以将数据打散,避免性能问题。 例如,可以采用site_id、city_code组合作为分桶键,将数据划分得更加均匀。

# 如果site_id分布十分不均匀,那么采用上述分桶方式会造成数据分布出现严重的倾斜,进而导致系统局部的性能瓶颈。需要调整分桶的字段,以将数据打散,避免性能问题。
# 例如,可以采用site_id、city_code组合作为分桶键,将数据划分得更加均匀。
create table site_access
(
    site_id int default '10',
    city_code smallint,
    user_name varchar(32) default '',
    pv bigint sum default '0'
)
aggregate key(site_id, city_code, user_name)
distributed by hash(site_id,city_code);

    案例一 采用 site_id的分桶方式对于短查询十分有利,能够减少节点之间的数据交换,提高集群整体性能;案例二 采用 site_id、city_code的组合分桶方式对于长查询有利,能够利用分布式集群的整体并发性能

  • 短查询是指扫描数据量不大、单机就能完成扫描的查询。

  • 长查询是指扫描数据量大、多机并行扫描能显著提升性能的查询。

4.3 确定分桶数量

4.3.1 建表时

方式一:自动设置分桶数量

  自 2.5.7 版本起,支持根据机器资源和数据量自动设置分区中分桶数量。假设 BE 数量为 X,StarRocks 推断分桶数量的策略如下:

X <= 12  tablet_num = 2X
X <= 24  tablet_num = 1.5X
X <= 36 tablet_num = 36
X > 36  tablet_num = min(X, 48)

create table site_access(
    site_id int default '10',
    city_code smallint,
    user_name varchar(32) default '',
    pv bigint sum default '0'
)
aggregate key(site_id, city_code, user_name)
distributed by hash(site_id,city_code); --无需手动设置分桶数量

# 如果需要开启该功能,配置FE动态参数 enable_auto_tablet_distribution=true。 建表后执行show partitions来查看为分区自动设置的分桶数量。

方式二:手动设置分桶数量

    确定分桶数量方式可以是:首先预估每个分区的数据量,然后按照每10 GB原始数据划分一个 Tablet计算,从而确定分桶数量。 单个Tablet的数据量理论上没有上下界,但建议在 1G - 10G 的范围内。如果单个Tablet 数据量过小,则数据的聚合效果不佳,且元数据管理压力大。如果数据量过大,则不利于副本的迁移、补齐。

-- 手动指定分桶个数的创建语法
distributed by hash(site_id) buckets 20

4.3.2 建表后

  • 新增一个分区时,参照上述的建表分桶设置规则
  • 已建分区:已创建分区的分桶数量不能修改

五、建表调优

   基于业务实际情况,在设计表结构时选择合理的分区键和分桶键,可以有效提高集群整体性能。

5.1 数据倾斜

     如果业务场景中单独采用倾斜度大的列做分桶,很大程度会导致访问数据倾斜,可以采用多列组合的方式进行分桶,将数据打散,使得各Tablet 数据更加均匀。

5.2 高并发

   分区和分桶应该尽量覆盖查询语句所带的条件,这样可以有效减少扫描数据,提高并发。

5.3 高吞吐

   尽量把数据打散,让集群以更高的并发扫描数据,完成相应计算。

5.4 元数据管理

   Tablet 过多会增加 FE/BE 的元数据管理和调度的资源消耗。

六、分区分桶及副本之间的关系

   数据库information_schema存储了关于StarRocks实例中所有对象的大量元数据信息。可以在表tables_config查看表的分区、分桶信息。

  • 表,分区,分桶以及副本的关系:

      Table (逻辑描述) -- > Partition(分区:管理单元) --> Bucket(分桶:每个分桶就是一个数据分片:Tablet,数据划分的最小逻辑单元)

    分区是逻辑概念,分桶是物理概念。每个分区partition内部会按照分桶键,采用哈希分桶算法将数据划分为多个桶bucket,每个桶的数据称之为一个数据分片tablet(实际的物理存储单元)。根据建表设置的副本数,计算有多少个副本在其他节点上(负载均衡)。如上图所示,当BE节点数和副本数一致时,每个BE节点会保留这个表对应的所有的tablet的数据(自身hash分桶对应的tablet数据和其他节点tablet的副本)

    一个表的Tablet总数量等于 = Partition num * Bucket num* Replica Num ,上述案例就等于 3*3*3 =27 

  • 表,分区,分桶,tablet,rowset,segment文件的关系:

     数据在导入时,最先落到磁盘上的是当前导入批次生成的rowset文件,每一次导入事务的成功,都会生成一个带有版本号的rowset文件。rowset文件由多个segment文件组成,segment文件是由segment writer生成的文件块。

    待补充~

注:参考文章:

数据分布 | StarRocks

第2.4章:StarRocks表设计--分区分桶与副本数_strrocks 建表分区-CSDN博客

数据划分 - Apache Doris

聊聊分布式 SQL 数据库Doris(三)-腾讯云开发者社区-腾讯云

【Doris】Doris存储层设计介绍1——存储结构设计解析_doris 存储原理-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/399732.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微服务篇之负载均衡

一、Ribbon负载均衡流程 二、Ribbon负载均衡策略 1. RoundRobinRule&#xff1a;简单轮询服务列表来选择服务器。 2. WeightedResponseTimeRule&#xff1a;按照权重来选择服务器&#xff0c;响应时间越长&#xff0c;权重越小。 3. RandomRule&#xff1a;随机选择一个可用的服…

Java 那些诗一般的 数据类型 (1)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

如何实现一个K8S DevicePlugin?

什么是device plugin k8s允许限制容器对资源的使用&#xff0c;比如CPU和内存&#xff0c;并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时&#xff0c;就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架&#xff0c;你可以用…

一文读懂函数式接口、Lambda表达式、Stream

文章目录 前言版本函数式接口定义特点使用 Lambda表达式主要场景用法无参写法有参写法 Lambda 表达式的基础&#xff1a;函数式接口 类型推断自定义函数接口使用 Lambda 表达式底层实现JDK7JDK8 this 的含义JDK7JDK8 Stream特点操作Stream 流创建中间操作和终端操中间操作无状…

vue.js el-tooltip根据文字长度控制是否提示toolTip

一、需求&#xff1a;如何判断当前文本文字是否超出文本长度&#xff0c;是否需要出现提示toolTip。效果图如下&#xff1a; 二、实现&#xff1a; 1、表格字段鼠标放置el-popover出现 “引用主题” 的具体内容&#xff1b; <!-- 表格字段&#xff1a;引用主题 --> <…

006 矢量数据属性表的使用和关联

1 空间属性关系 1.1 数据导入和图层组合 读取数据 除了使用关键项的连接之外&#xff0c;还有一种根据属性组合中的空间位置关系进行组合的方法。 在本节中&#xff0c;我们将介绍一种方法&#xff0c;用于将空间关系中的多边形数据属性与任意点数据属性相结合。 我们使用的是…

文件上传漏洞--Upload-labs--Pass11--(GET)00绕过

一、环境准备&#xff1a; php版本&#xff1a;推荐 php5.2.17&#xff08;官方推荐版本&#xff09;。小于php5.3.4也可以&#xff0c;但是要在 php.ini 配置文件中手动将 magic_quotes_gpc 的状态改为 Off。 magic_quotes_gpc的作用是对 get请求、post请求、cookie...传入的…

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…

【开源】JAVA+Vue.js实现高校学生管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 学院课程模块2.3 学生选课模块2.4 成绩管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学院课程表3.2.3 学生选课表3.2.4 学生成绩表 四、系统展示五、核心代码5.1 查询课程5.2 新…

FPS游戏漫谈弱网环境时延优化

游戏在弱网情况下会变得体验很差&#xff0c;玩家的直观感受就是我的操作怎么没有反应&#xff0c;整个游戏世界都是一卡一顿的。这个就是因为网络问题导致了游戏体验变差。 那什么是弱网环境&#xff1f;弱网环境就是指网络不好的环境&#xff0c;尤其是移动网络下&#xff0…

Java毕业设计-基于springboot的人才招聘管理系统-第68期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于springboot的人才招聘管理系统&#xff1a;前端jquery、easyui&#xff0c;后端 maven、springmvc、spring、jpa、hibernate&#xff0c;集成职位浏览、我的简历、投…

web前端宝藏题库,适用于0-3年前端工程师...

前些天意外认识了一个前端大佬&#xff0c;某大厂在职&#xff0c;我怕打扰就没敢多聊&#xff0c;没想到大佬挺平易近人&#xff0c;很亲切的给我出谋划策&#xff0c;还给了我一套面试题&#xff0c;难度不是很高&#xff0c;但是胜在全面十分契合我现在的状况&#xff0c;所…

在VsCode中通过Cookie登录LeetCode

在vscode中配置好leetcode之后&#xff0c;一般最常用的就是通过cookie登录leetcode ; 首先点击sign in &#xff0c; 然后选择最下面的 &#xff0c; LeetCode Cookie ! 然后输入username(也就是你的lc用户名) 或者 你leetcode绑定的邮箱 ; 输入完成之后 ; 就是要你输入你的l…

UE5 C++ 创建可缩放的相机

一.要将相机设置在Pawn类里 1.在MyPawn头文件里&#xff0c;加上摇臂和相机组件 #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" 2.在Pawm里声明SceneComponet&#xff0c;SpringArmComponent,CameraComponent组件…

6.【架构师成长之路】职场新人:维护一张能力图谱

文章目录 导言一、能力图谱就是技能体系1、时刻提醒你&#xff0c;你有一个目标2、你可以知道靠近目标的具体方式3、你会变得更加自信 二、周期性review自己的能力图谱1、review能力项进度2、review能力项完整度3、固定周期review 本文总结说明 导言 上两篇文章我们讲了&#…

C语言中关于#include的一些小知识

写代码的过程中&#xff0c;因为手误&#xff0c;重复包含了头文件 可以看到没有报错 如果是你自己编写的头文件&#xff0c;那么如果没加唯一包含标识的话&#xff0c;那么编译器会编译报错的。如果是系统自带的头文件&#xff0c;由于其每个头文件都加了特殊标识&#xff0c…

【动态规划】【矩阵快速幂】LeetCode2851. 字符串转换

作者推荐 【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II 涉及知识点 【矩阵快速幂】封装类及测试用例及样例 LeetCode 2851. 字符串转换 给你两个长度都为 n 的字符串 s 和 t 。你可以对字符串 s 执行以下操作&#xff1a; 将 s 长度为 l &#xff08;0 <…

安达发|APS排产软件的机台产线任务甘特图功能详解

在现代制造业中&#xff0c;高级计划与排产是制造业运营的关键环节。为了提高生产效率、降低成本并确保产品质量&#xff0c;企业需要对生产过程进行精细化管理。APS&#xff08;高级计划与排产&#xff09;系统作为一种先进的生产计划和调度工具&#xff0c;可以帮助企业实现这…

在计算机上设置和使用 KVM

为了使用 gem5 的 KVMCPU 来快进你的模拟&#xff0c;你必须有一个 KVM 兼容的处理器并且在你的机器上安装了 KVM。本页将引导您完成在计算机上启用 KVM 并将其与 gem5 一起使用的过程。 注意&#xff1a;以下教程假设 X86 Linux 主机。本教程的各个部分可能不适用于其他体系结…

IBM V5000存储更换控制器及电源模块

LED故障状态 后面板故障状态 系统内电源模块报错信息(可安全卸下状态为"是"&#xff0c;此时可直接热拔插) 控制器报错信息&#xff08;当前已是脱机状态可直接拔插&#xff0c;该型号控制器不需要更换缓存可直接热拔插更换&#xff09; 更换故障备件应先核对新旧备件…