网站建设漠环熊掌号,做的网站有广告图片,东莞手机网站建设公司,做外贸一般在什么网站数据分片#xff08;Sharding#xff09;是分布式数据库分而治之 (Divide And Conquer) 这一设计思想的体现。过去的单机数据库在大数据量下往往面临存储和 IO 的限制#xff0c;而分布式数据库则通过数据划分的规则#xff0c;将数据打散分布至不同的机器或节点上#xf…数据分片Sharding是分布式数据库分而治之 (Divide And Conquer) 这一设计思想的体现。过去的单机数据库在大数据量下往往面临存储和 IO 的限制而分布式数据库则通过数据划分的规则将数据打散分布至不同的机器或节点上形成分布式存储因此突破了单机存储空间和 IO 的瓶颈、使库表数据量可以无限拓展。
数据分片主要有范围分片或哈希分片这两种方式而在实际数据库的实现中往往呈现为分区和分桶两种形式。分区一般是按照时间或其他连续值对数据进行划分在执行查询操作时可以通过分区裁剪过滤不必要的范围扫描提升执行效率同时也使得对分区数据的增删改等管理操作更为便捷。而分桶则是按照某个关键字执行哈希运算将相同哈希值的数据放到一起这样可以有效定位数据、避免数据倾斜。
在 Apache Doris 中同样也遵从一定的数据分布规则。数据以关系表Table的形式进行呈现会依次按照先分区Partition、再分桶Bucket的方式划分最终在同一个分桶中的数据会形成数据分片Tablet。Tablet 是 Apache Doris 中多副本高可用、集群间数据调度与均衡的最小物理存储单位。 图1Table-Partition-Tablet 之间的关系
# 现状与问题
在 Doris 中分区与分桶是如何创建的我们以一个网站站点的建表实例说明分区与分桶的创建方式该网站的站点建表语句如下
-- 该表记录了某个时间点在某个站点上各个用户的pv数据
CREATE TABLE demo.test_tbl(sdate DATE, -- 日期site INT, -- 站点idcity VARCHAR(64), -- 城市user VARCHAR(32) DEFAULT , -- 用户名pv BIGINT -- pv量
) ENGINEolap DUPLICATE KEY(sdate, site, city)
[PARTITION_DESC]
[BUCKET_DESC]
PROPERTIES (replication_num 1);
其中 [PARTITION_DESC] 表示创建分区的详细语句[BUCKET_DESC] 表示创建分桶的语句。 创建分区
Apache Doris 支持两种分区形式List Partition 与 Range Partition。
List Partition
List Partition 相当于对分区的列值进行枚举因此选择的分区列最好是有区分度的可枚举值例如本例中的 city。根据 city 列的枚举值创建多个 List Partition则 PARTITION_DESC可以写为
-- 以city作为分区列创建华北、东北、华中、西南等分区
PARTITION BY LIST(city)
(PARTITION p_huabei VALUES IN (beijing, tianjin, shijiazhuang),PARTITION p_dongbei VALUES IN (shenyang, dalian),PARTITION p_huazhong VALUES IN (wuhan, changsha)PARTITION p_xinan VALUES IN (chengdu, chongqing)
)Range Partition
创建 Range partition 一般使用时间列Range Partition 又可以分为静态和动态两种方式
- 静态 Range Partition
此类 Partition 的创建会生成一个左闭右开的区间定义一个分区只需要指定右边界该分区的左边界由上一个分区的右边界确定PARTITION_DESC可以写为
-- 以sdate这个时间列作为分区列
-- 日期处于[min, 2023-01-01)的数据都放到名为p2022的分区下
-- 日期处于[2023-01-01, 2023-01-02)的数据都放到名为p20230101的分区下
-- 日期处于[2023-01-02, 9999-12-31)的数据都放到名为pmax的分区下
PARTITION BY RANGE(sdate)
(PARTITION p2022 VALUES LESS THAN (2023-01-01),PARTITION p20230101 VALUES LESS THAN (2023-01-02),PARTITION pmax VALUES LESS THAN (9999-12-31)
)
可以看出p20230101 这个分区的左边界由 p2022 分区的右边界确定而 pmax 的左边界由 p20230101 的右边界确定。需注意的是此处为了举例说明动态分区使用了一个很大的边9999-12-31实际业务中很少会直接创建从 2023-01-02 到 9999-12-31 的分区。
- 动态 Range Partition
上述静态的分区需要手动指定边界分区个数太多使用起来也不方便。动态 Range Partition 帮助我们解决了这个问题只需指定一些分区的参数即可动态创建PARTITION_DESC 相对更简单只需指定哪个列作为分区列即可
PARTITION BY RANGE(sdate)()剩余参数需要在PARTITION进行配置
PROPERTIES (dynamic_partition.enable true,dynamic_partition.time_unit DAY,dynamic_partition.start -30,dynamic_partition.end 3,dynamic_partition.prefix p,dynamic_partition.create_history_partitiontrue,replication_num 1
); 动态分区参数说明如下 创建分桶
分桶在物理层面即数据分片Tablet。在数据表完成分区后指定部分列作为分桶列将这些列数据中相同哈希值的数据合到一起形成了 Tablet。一个表中 Tablet 总数量 分区数Partition numx 分桶数Bucket numx 数据副本数Replication_num。
[BUCKET_DESC] 语句非常简单只需要一句
DISTRIBUTED BY HASH(site) BUCKETS 20此时指定以 site 列的哈希值作为分桶并且分桶个数设置为 20 个需要注意的是这里的 20 仅作为示例合适的分桶个数需要根据分区大小来确定。实际上单个分桶即 Tablet 的数据量理论上没有上下界但建议在 1GB - 10GB 的范围内即假设分区大小为 20GB那么分桶个数设置为 10-20 个是合适的。 不足与思考
从以上对分区分桶的介绍相信有不少用户和读者仍能发现其中一些不足之处 分区数量过多的情况下使用 List Partition 或者静态 Range Partition 会使得 SQL 较为繁琐编写起来费时费力 若是使用动态 Range Partition则需要掌握多个参数使用方式不友好且学习成本较高而当存在大量历史冷数据来说动态 Range Partition 只能指定单一粒度无法灵活组合不同的分区粒度 分桶个数的设置十分依赖用户对 Apache Doris 数据分布机制和业务数据本身的理解使用门槛较高。不合理的分桶设置将对系统性能和稳定性造成一定程度冲击分桶数太多将导致单个 Tablet 的数据量过小数据聚合效果不佳、查询性能不能得到有效发挥并且元数据管理压力大个数太少则单个 Tablet 包含的数据量过大不利于副本的迁移、补齐且会增加 Schema Change 或者 Rollup 操作失败重试的代价。
# 批量分区与Auto Bucket的设计与实现
克服数据库的复杂性是 Apache Doris 一直追求的目标之一针对以上分区分桶存在的易用性问题在 Apache Doris 最新的版本中已经得到解决。
在 Apache Doris 1.2.1 版本中我们新增了批量创建分区功能简洁的语法和灵活的使用方式让批量创建历史分区更加得心应手而针对分桶设置带来的学习成本Apache Doris 在即将发布的 1.2.2 版本中新增了 Auto Bucket 自动分桶推算功能分桶个数不再依赖于人工设置通过规则的智能计算即可保证合理的数据划分降低用户学习成本的同时还可以最大化提升用户开发效率。 批量创建分区
批量创建分区功能在前期充分调研了用户的需求本着简洁、强大、易用的设计目标将设计核心锁定在几个要素中 时间区间范围会考虑开闭问题 时间跨度即每个分区的时间维度的大小 时间单位年、月、日、时、周等
结合前面提到的网站站点模型假设其数据包含从几年前直到现在的全量信息想要将十年内的数据按每一天一个分区进行创建。在批量分区功能中PARTITION_DESC只需要一句并且不用在PARTITION中设置分区相关参数
-- 当然分区创建个数受到max_multi_partition_num参数控制该值默认为4096有需求可以修改
PARTITION BY RANGE(sdate)
(FROM (2013-01-01) TO (2023-01-01) INTERVAL 1 DAY
)从这个 case 来看批量分区功能的语法更为简洁但该功能的易用性和灵活性远不止于此。
从这个 case 来看批量分区功能的语法更为简洁但该功能的易用性和灵活性远不止于此。
假设有另一批数据公司前几年的数据量较大且为冷数据故可以将一年的数据合到一个分区里面而后来因为业务迅速发展需要将每一月的数据作为一个分区随着公司业务进一步发展按月分区已经不能满足快速增长的数据需求需要按周进行分区……时至今日公司每天产生海量数据可能需要按小时分区才能符合需求。根据这个场景不难写出批量分区创建的 PARTITION_DESC
-- 此处需要注意如果要使用小时级别的分区则分区列必须是datetime类型
-- 同样的分区创建个数也受到max_multi_partition_num参数控制
PARTITION BY RANGE(sdate)
(FROM (2000-01-01) TO (2021-01-01) INTERVAL 1 YEAR,FROM (2021-01-01) TO (2022-01-01) INTERVAL 1 MONTH,FROM (2022-01-01) TO (2023-01-01) INTERVAL 1 WEEK,FROM (2023-01-01) TO (2023-02-01) INTERVAL 1 DAY,FROM (2023-02-01 00) TO (2099-12-31 23) INTERVAL 1 HOUR
)
除了上述不同时间粒度的分区可以灵活组合外还可以将静态 Range Partition 和批量分区功能结合起来。例如需要将该公司 2022-01-01 到 2023-01-01 的数据按天创建分区2022-01-01 之前的数据归到一个名为pold分区中我们可以将静态分区和批量分区组合起来PARTITION_DESC如下
PARTITION BY RANGE(sdate)
(PARTITION pold VALUES LESS THAN (2022-01-01),FROM (2022-01-01) TO (2023-01-01) INTERVAL 1 DAY
)
批量分区创建功能支持不同时间粒度其语法简洁有力且各种类型分区可以灵活组合在面对大量历史分区和部分特殊分区的需求时该功能显得游刃有余可以极大提高开发效率。
批量分区功能 PRhttps://github.com/apache/doris/pull/13772 Auto Bucket 自动分桶推算
以往创建分桶时需要手动设定分桶数而自动分桶推算功能是 Apache Doris 可以动态地推算分桶个数使得分桶数始终保持在一个合适范围内让用户不再操心桶数的细枝末节。
首先说明一点为了方便阐述该功能该部分会将桶拆分为两个时期的桶即初始分桶以及后续分桶。这里的初始和后续只是本文为了描述清楚该功能而采用的术语Apache Doris 分桶本身没有初始和后续之分
从上文中创建分桶一节我们知道BUCKET_DESC非常简单但是需要指定分桶个数而在自动分桶推算功能上BUCKET_DESC的语法直接将分桶数改成Auto并新增一个 Properties 配置即可
-- 旧版本指定分桶个数的创建语法
DISTRIBUTED BY HASH(site) BUCKETS 20-- 新版本使用自动分桶推算的创建语法
DISTRIBUTED BY HASH(site) BUCKETS AUTO
properties(estimate_partition_size 100G)
新增的配置参数estimate_partition_size表示一个单分区的数据量。该参数是可选的如果没有给出则 Doris 会将 estimate_partition_size 的默认值取为 10GB。
从上文中已经得知一个分桶在物理层面就是一个Tablet为了获得最好的性能建议 Tablet 的大小在1GB - 10GB 的范围内。那么自动分桶推算是如何保证 Tablet 大小处于这个范围内的呢总结起来不外乎几个原则 若是整体数据量较小则分桶数不要设置过多 若是整体数据量较大则应使桶数跟总的磁盘块数相关充分利用每台 BE 机器和每块磁盘的能力
初始分桶推算
从原则出发理解自动分桶推算功能的详细逻辑就变得简单了
首先来看初始分桶
1. 先根据数据量得出一个桶数 N。首先使用 estimate_partition_size 的值除以 5按文本格式存入 Doris 中有 5 比 1 的数据压缩比计算得到的结果为 100MB则取 N1 1GB则取 N2 1GB则每一个 GB 一个分桶
2. 根据 BE 节点数以及每个 BE 节点的磁盘容量计算出桶数 M。其中每个 BE 节点算 1每 50G 的磁盘容量算 1那么 M 的计算规则为M BE 节点数 *( 一块磁盘块大小 / 50GB) * 磁盘块数例如有 3 台 BE每台 BE 都有 4 块 500GB 的磁盘那么 M 3 * (500GB / 50GB) * 4 120
3. 得到最终的分桶个数计算逻辑 先计算一个中间值 x min(M, N, 128) 如果 x N并且x BE节点个数则最终分桶为 y 即 BE 节点个数否则最终分桶数为 x
上述过程伪代码表现形式为
int N 计算N值;
int M 计算M值;int y BE节点个数;
int x min(M, N, 128);if (x N x y) {return y;
}
return x;
有了上述算法咱们再引入一些例子来更好地理解这部分逻辑
case 1:
数据量 100 MB10 台 BE 机器2TB * 3 块盘
数据量 N 1
BE 磁盘 M 10 * (2TB/50GB) * 3 1230
x min(M, N, 128) 1
最终: 1
case 2:
数据量 1GB, 3 台 BE 机器500GB * 2 块盘
数据量 N 2
BE 磁盘 M 3 * (500GB/50GB) * 2 60
x min(M, N, 128) 2
最终: 2
case 3:
数据量 100GB3 台 BE 机器500GB * 2 块盘
数据量 N 20
BE 磁盘 M 3 * (500GB/50GB) * 2 60
x min(M, N, 128) 20
最终: 20
case 4:
数据量 500GB3 台 BE 机器1TB * 1 块盘
数据量 N 100
BE 磁盘 M 3 * (1TB /50GB) * 1 60
x min(M, N, 128) 63
最终: 63
case 5:
数据量 500GB10 台 BE 机器2TB * 3 块盘
数据量 N 100
BE 磁盘 M 10 * (2TB / 50GB) * 3 1230
x min(M, N, 128) 100
最终: 100
case 6:
数据量 1TB10 台 BE 机器2TB * 3 块盘
数据量 N 205
BE 磁盘 M 10 * (2TB / 50GB) * 3 1230
x min(M, N, 128) 128
最终: 128
case 7:
数据量 500GB1 台 BE 机器100TB * 1 块盘
数据量 N 100
BE 磁盘 M 1 * (100TB / 50GB) * 1 2048
x min(M, N, 128) 100
最终: 100
case 8:
数据量 1TB, 200 台 BE 机器4TB * 7 块盘
数据量 N 205
BE 磁盘 M 200 * (4TB / 50GB) * 7 114800
x min(M, N, 128) 128
最终: 200
可以看到详细逻辑与原则是匹配的。
后续分桶推算
上述是关于初始分桶的计算逻辑后续分桶数因为已经有了一定的分区数据可以根据已有的分区数据量来进行评估。后续分桶数会根据最多前 7 个分区数据量的 EMA[1]短期指数移动平均线值作为estimate_partition_size 进行评估。此时计算分桶有两种计算方式假设以天来分区往前数第一天分区大小为 S7往前数第二天分区大小为 S6依次类推到 S1 如果 7 天内的分区数据每日严格递增则此时会取趋势值 有6个delta值分别是 S7 - S6 delta1, S6 - S5 delta2, ... S2 - S1 delta6 由此得到平均的delta值 avg_delta (delta1 delta2 ... delta6) / 6 (S7 - S1) / 6 那么今天的estimate_partition_size S7 avg_delta 非第一种的情况此时直接取前几天的 EMA 平均值 今天的 estimate_partition_size EMA(S1, ..., S7) 根据上述算法初始分桶个数以及后续分桶个数都能被计算出来。跟之前只能指定固定分桶数不同由于业务数据的变化有可能前面分区的分桶数和后面分区的分桶数不一样这对用户是透明的用户无需关心每一分区具体的分桶数是多少而这一自动推算的功能会让分桶数更加合理。
自动分桶推算功能 PRhttps://github.com/apache/doris/pull/15250 效果
当我们有了合适的分区分桶时导入数据导到 Doris 后数据会依照建表语句中的分区分桶列进行存储。上述网站站点数据的存储示例如图示 图2Doris 分区分桶后的数据存储
此时如果执行 SQL 查询 select * from test_tbl where sdate 2020-03-23 and site 1根据谓词 sdate 2020-03-23 可以定位到分区 p20200323谓词 site 1 能定位到该分区下的 bucket_1。假设有 30 天数据自动分桶推算得到的分桶个数为 20 个。则经过明确的分区分桶谓词下推则可以将数据全表扫描量变为原来的 1/60030 天*20 个桶 600极大减少了数据的扫描范围、提高了查询的效率。
# 总结
整体来看批量创建分区功能语法简洁有力解决了用户针对大量历史数据分区创建的难题既避免了手动创建大量分区的低效语法又避免了动态分区大量参数的学习使用成本且方式灵活多变、随意搭配组合各种类型的分区大大提升了 Doris 在建表过程中的易用性。自动分桶推断功能智能高效用户不需再关心分桶的细枝末节系统自动帮助用户扩缩不同分区的分桶数真正做到桶随业务变降低学习成本的同时更是提升了查询效率。
在与社区用户持续沟通中我们也不断收获着许多新的需求例如分区列为非时间列等因此后续我们仍将继续完善对其他分区列的支持例如数字分区列的批量创建等。最后我们期待倾听更多用户的声音在不断回馈用户以极简易用的使用体验的同时也期待有更多人参与到 Apache Doris 的建设中来欢迎你的加入 文章转载自: http://www.morning.spftz.cn.gov.cn.spftz.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.nkqnn.cn.gov.cn.nkqnn.cn http://www.morning.lthpr.cn.gov.cn.lthpr.cn http://www.morning.cxtbh.cn.gov.cn.cxtbh.cn http://www.morning.hpkgm.cn.gov.cn.hpkgm.cn http://www.morning.lctrz.cn.gov.cn.lctrz.cn http://www.morning.dbdmr.cn.gov.cn.dbdmr.cn http://www.morning.jrqw.cn.gov.cn.jrqw.cn http://www.morning.pkwwq.cn.gov.cn.pkwwq.cn http://www.morning.bgrsr.cn.gov.cn.bgrsr.cn http://www.morning.ymjrg.cn.gov.cn.ymjrg.cn http://www.morning.drbd.cn.gov.cn.drbd.cn http://www.morning.mrskk.cn.gov.cn.mrskk.cn http://www.morning.mwqbp.cn.gov.cn.mwqbp.cn http://www.morning.wdhhz.cn.gov.cn.wdhhz.cn http://www.morning.qprtm.cn.gov.cn.qprtm.cn http://www.morning.snktp.cn.gov.cn.snktp.cn http://www.morning.rzdpd.cn.gov.cn.rzdpd.cn http://www.morning.znmwb.cn.gov.cn.znmwb.cn http://www.morning.xdfkrd.cn.gov.cn.xdfkrd.cn http://www.morning.dxrbp.cn.gov.cn.dxrbp.cn http://www.morning.rfkyb.cn.gov.cn.rfkyb.cn http://www.morning.wjqyt.cn.gov.cn.wjqyt.cn http://www.morning.gsjfn.cn.gov.cn.gsjfn.cn http://www.morning.phxdc.cn.gov.cn.phxdc.cn http://www.morning.qpqb.cn.gov.cn.qpqb.cn http://www.morning.cbpkr.cn.gov.cn.cbpkr.cn http://www.morning.qgwpx.cn.gov.cn.qgwpx.cn http://www.morning.rmfw.cn.gov.cn.rmfw.cn http://www.morning.jmspy.cn.gov.cn.jmspy.cn http://www.morning.fqhbt.cn.gov.cn.fqhbt.cn http://www.morning.xbmwm.cn.gov.cn.xbmwm.cn http://www.morning.ddrdt.cn.gov.cn.ddrdt.cn http://www.morning.txkrc.cn.gov.cn.txkrc.cn http://www.morning.clbzy.cn.gov.cn.clbzy.cn http://www.morning.rtsd.cn.gov.cn.rtsd.cn http://www.morning.nzlqt.cn.gov.cn.nzlqt.cn http://www.morning.fqcdh.cn.gov.cn.fqcdh.cn http://www.morning.yqndr.cn.gov.cn.yqndr.cn http://www.morning.mqldj.cn.gov.cn.mqldj.cn http://www.morning.xnpml.cn.gov.cn.xnpml.cn http://www.morning.pjrql.cn.gov.cn.pjrql.cn http://www.morning.mnccq.cn.gov.cn.mnccq.cn http://www.morning.zsyqg.cn.gov.cn.zsyqg.cn http://www.morning.qjtbt.cn.gov.cn.qjtbt.cn http://www.morning.thnpj.cn.gov.cn.thnpj.cn http://www.morning.jjmrx.cn.gov.cn.jjmrx.cn http://www.morning.fqyxb.cn.gov.cn.fqyxb.cn http://www.morning.c7617.cn.gov.cn.c7617.cn http://www.morning.bwxph.cn.gov.cn.bwxph.cn http://www.morning.cwgfq.cn.gov.cn.cwgfq.cn http://www.morning.mpsnb.cn.gov.cn.mpsnb.cn http://www.morning.rhzzf.cn.gov.cn.rhzzf.cn http://www.morning.mrskk.cn.gov.cn.mrskk.cn http://www.morning.zqwp.cn.gov.cn.zqwp.cn http://www.morning.dwhnb.cn.gov.cn.dwhnb.cn http://www.morning.mbaiwan.com.gov.cn.mbaiwan.com http://www.morning.mpmtz.cn.gov.cn.mpmtz.cn http://www.morning.wfzlt.cn.gov.cn.wfzlt.cn http://www.morning.fnywn.cn.gov.cn.fnywn.cn http://www.morning.mqtzd.cn.gov.cn.mqtzd.cn http://www.morning.4q9h.cn.gov.cn.4q9h.cn http://www.morning.nrbcx.cn.gov.cn.nrbcx.cn http://www.morning.hcsnk.cn.gov.cn.hcsnk.cn http://www.morning.sxhdzyw.com.gov.cn.sxhdzyw.com http://www.morning.hcsqznn.cn.gov.cn.hcsqznn.cn http://www.morning.rfgc.cn.gov.cn.rfgc.cn http://www.morning.dlhxj.cn.gov.cn.dlhxj.cn http://www.morning.rlhh.cn.gov.cn.rlhh.cn http://www.morning.dnzyx.cn.gov.cn.dnzyx.cn http://www.morning.rbbgh.cn.gov.cn.rbbgh.cn http://www.morning.yfstt.cn.gov.cn.yfstt.cn http://www.morning.sbrrf.cn.gov.cn.sbrrf.cn http://www.morning.pfnwt.cn.gov.cn.pfnwt.cn http://www.morning.lrdzb.cn.gov.cn.lrdzb.cn http://www.morning.nrbqf.cn.gov.cn.nrbqf.cn http://www.morning.lbbyx.cn.gov.cn.lbbyx.cn http://www.morning.lswgs.cn.gov.cn.lswgs.cn http://www.morning.spbp.cn.gov.cn.spbp.cn