Mongodb sharding知识库
2017-07-03 10:07 Kevin.hhl 阅读(401) 评论(0) 收藏 举报一. MongoDB sharing类型
1.1 Range

[minkey,x1)区间值,都是前闭后开,属于某个chunk,一个chunk只能落到某一个shard,随着集群数据量的增大,如开开启rebalance,chunk也会在shard 之间move 。
满足如下特点的适合Range的shard key:
a.基数高。
b.shard key的值不会出现某些值重复(聚集多),简单说值的分布比较均匀。如果可能不均匀,可以考虑多列做shard key。
c.shard key的写入(insert)不是递增或递减的(否则会出现某段时间集中写某个shard,写入不均匀)。
1.2 Hash
目前Hash sharding只支持单列。
满足如下特点的适合Hash的shard key:
1.3 tag aware sharding/zone
zone 是在3.4 开始引入,是tag aware sharding的升级版本,简单的理解是自定义某些范围的数据到某个zone,每个zone可以包含有若干个shard,这种很方便由DBA来设置数据在物理上的分布,比如说不希望某些范围的数据分布在多个shard,这样可能会影响性能,这种情况下可以指定这些范围的数据在某一个shard;还有跨机房部署sharding,使用zone可以保证数据分布和应用在同一个机房,不会有跨地域。
例子:比如要按照地域省份来做sharding,分布在物理不同的城市的数据落到当地的shard上。
beijing shanghai shenzhen guangzhou ------> zone
shard01 shard02 shard03 shard04 ------->shard分片
上面shard01指定到zone: beijing, shard01指定到zone: beijing, shard02指定到zone: shanghai, shard03指定到zone: shenzhen, shard04指定到zone: guangzhou
可以理解zone是shard上的逻辑管理,最后我们要指定各个zone 的数据范围,也既是该zone下所有shard存放数据的范围。
满足如下特点的适合zone的shard key:
a.业务需要指定某些特定的shard key到某些shard上。
b.跨机房部署sharding,业务访问在同一机房的shard。
二. MongoDB Sharding的限制
2.1 不支持group命令。
2.2 单个document 的操作必须包含shard key。 All updateOne(), removeOne(), and deleteOne()。
2.3 跨shard的unique key需要把完整的shard key作为unique key的前缀部分。
三. 如何选择合理的shard key
3.1 从业务/db出发
比如是db遇到容量问题,写多读少,写是主要瓶颈,此时sharding 要考虑的是分散写入IO,同时要考虑业务读的性能,读请求的数据尽量都在一个shard,保证读取数据的性能。
业务特点都是选择shard key的关键因素,
3.2 基数
核心原则:保证shard key 的值比较均匀分布,把chunk维持在一定规模大小,不会产生巨大的chunk,大chunk 很多无法split,导致在shard 间移动代价大。
考虑作为shard key的基数,如果适合做range sharding 的shard key只有一列,但是该列的基数很低或者有某些值有堆积聚集严重,需要考虑增加一列(比如_id,created_time)
3.3 可靠性
比如评论数据,id和user_id都是可以作为shard key,它们都可以让数据分布比较均匀,但从系统可靠性考虑,假如某个shard的不可用,如果使用id 作为shard key,几乎大部分用户有评论丢失,影响的范围用户较多,如果使用user_id 作为shard key,一个shard 不可用(比如总共有4个shard),影响的用户大约是1/4。
3.4 写扩展
写操作尽量落到每个shard,流量均匀。
3.5 读隔离
请求读尽量落到同一个shard,不要跨shard读数据,会有性能问题。
3.6 从设计模式上优化shard key
业务多多维度查询,使业务的写入、查询落到某个shard。shard key 本身就是索引,直接通过shard key查询,减少创建其他索引。
比如下面是
{
_id: ObjectId("4d084f78a4c8707815a601d7"),
user_id : 42 ,
title: "sunset at the beach",
upload_time : "2011-01-02T21:21:56.249Z" ,
data: ...,
}
你也能构造一个客户id,让它包括图片上传时间对应的月度信息和一个唯一标志符(ObjectID,数据的MD5等)。记录看起来就像下面这个样子的:
{
_id: "2011-01-02_4d084f78a4c8707815a601d7",
user_id : 42 ,
title: "sunset at the beach",
upload_time : "2011-01-02T21:21:56.249Z" ,
data: ...,
为了使同一user的文档都落到某一个shard上,改造_id成如下格式:
id: {userid}_2011-01-02__4d084f78a4c8707815a601d7 这样用户按照月份时间维度查询自己上传的图片,都落到同一个shard上。
浙公网安备 33010602011771号