多维分区
当用户需要提高数据访问性能,可以使用表分区或数据库分区,但是在数据量快速增长的场景下性能会逐渐下降,多维分区可以解决这一问题。本文档将介绍多维分区的实现原理和操作实例。
原理介绍
多维分区主要用于处理既要减少数据访问量,又要提高数据并行计算能力的场景。多维分区示意图:
- 对主集合进行表分区,将多个分区映射到不同的子集合上
- 针对某一个子集合,使用数据库分区,将子集合中的数据切分到不同的数据组中
- 当需要访问某一范围内的数据时,既可以将数据访问集中在若干个子集合中,又能同时发挥不同复制组并行计算的能力,从而提高处理速度和性能
业务场景举例
下面以银行业务账单为例,简单介绍一下多维分区的作用。
- 账单数据具有很强的时间特性,比如查询某月的账单。针对这一特性可以将时间作为分区键,先对主集合进行表分区,将一个月的数据映射到一个子集合上。
- 针对子集合(一个月内的数据),以帐号 id 再进行一次数据库分区,将数据映射到多个数据组上。
- 当需要查询某个月的账单时,数据库首先会集中到某一个子集合上去查询,而不会访问其它集合的数据,访问的数据量大大减少;而由于子集合做了数据库分区,查询又可以在多个数据组中并行计算,从而提高处理性能。
多维分区操作实例
多维分区在操作上,可以先对子集合做数据库分区,然后再通过表分区将子集合挂载到主集合上。
创建主集合
main.bill
,分区键为bill_date
,分区方式为 range:> db.createCS( "main" )
> db.main.createCL( "bill", { IsMainCL: true, ShardingKey: { bill_date: 1 }, ShardingType: "range" } )
创建子集合
bill.201905
,分区键为帐号id
字段,分区方式为 hash ,hash 值总数为 4096 个, 集合所在复制组为 group1:> db.createCS( "bill" )
> db.bill.createCL( "201905", { ShardingKey: { id: 1 }, ShardingType: "hash", Partition: 4096, Group: "group1" } )
执行切分命令,将集合
bill.201905
中,帐号id
的 hash 值范围在 [2048, 4096) 的记录,从复制组 group1 切分到复制组 group2 中:> db.bill.201905.split( "group1", "group2", { Partition: 2048 }, { Partition: 4096 } )
通过挂载操作,将主集合
main.bill
和子集合bill.201905
进行关联:> db.main.bill.attachCL( "bill.201905", { LowBound: { create_date: "201905" }, UpBound: { create_date: "201906" } } )