MogoDB 分片键
MongoDB 根据分片键分割 collection 中的文档,然后分配到分片集群的成员中。
分片键可以是一个存在于每个文件中的索引字段或者复合索引字段。
MongoDB 使用不同范围的分片键值来分割 collection 中的数据。不同分片键范围是不重叠的并且每个分片键范围与一个 chunk 关联。
选择分片键
选择的分片键要尽量使 chunks 平滑的分配到集群的分片中。如果不那么做,会影响集群的性能:
- 假设所有的 chunks 都被分配到一个 分片中,那么整个集群的能力就是这一台分片的能力
- 假设 chunks 没有均匀分配,集中在一个分片中,那么这个分片可能会成为瓶颈。因为总的耗时取决于最慢的那个分片
为了选择出好的分片键,还需要了解分片键的以下性质
- 基数性
- 频率
- 单调改变
基数性
分片键的基数性决定了平衡器可以创建的最大 chunks 数目。
在任意时刻,一个唯一的键值对只能存在于不超过一个的 chunk 中。现有一个基数性为 4 的分片键,那么在集群中最多有 4 个(有效的) chunks,因为增加额外的分片不会带来收益,每个 chunk 储存一个唯一的分片键。
然而高的基数性也不能保证数据在集群中平滑分配,这还与频率和单调性有关。当选择分片键时,这三个因素都要考虑到。
频率
分片键的频率指给定的分片键值在文件中多常出现。
如果大部分的文件只包含一部分分片键,那么储存大部分文件的分片会成为集群的瓶颈。如果大部分文件只包含一个分片键,那么对应的 chunk 会很大并且不可分割。这就会降低集群的性能。
如果你的数据模型需要在一个高频率的分片键,考虑使用一个唯一的或者低频率的复合索引代替。
单调改变的分片键
单调改变指分片键是单调递增或单调递减的,这样的分片键更容易插入到集群中的一个分片中(而不是均匀分配)。
发生这种情况的原因是每个集群都有两个 chunk 捕捉超出边界的分片键。一个捕捉超出(分片键的)最大值的分片键,一个捕捉小于最小值的分片键。
如果一个分片键是单调递增的,那么在一定时刻之后,所有新增都会进入到 [maxKey, 正无穷] 这个 chunk。同理,单调递减的分片键会进入 [负无穷, minKey]。包含对应 chunk 的分片就会成为写操作的瓶颈。
唯一索引
只有使用整个分片键作为其前缀的唯一索引才能确保其是跨分片唯一的[2]。
哈希分片
哈希分片使用一个字段的哈希索引作为分片键来分割数据。
哈希分片以牺牲查询隔离性为代价来提供分布更加均匀的分片集群。分片值相邻的文档更不可能在同样的分片上,因此对应给定的范围查询 mongos 更可能去执行广播查询。同时,mongos 也能匹配相等的查询到一个分片上。
哈希分片键
选择作为哈希分片键的字段应该有高基数性。假设没有高基数性,那么数据就会集中到某些分片上而不是均匀分配到所有分片,然后数据过多的分片会造成瓶颈。
理想的哈希分片键是单调性的字段,比如 ObjectId 或者时间。
分片键的限制
大小
分片键的大小不能超过 512 bytes。
分片键索引类型
分片键的索引可以是在分片键上递增的索引,一个以分片键为前缀的在分片键上递增的复合索引或是一个哈希索引。
分片键索引不能是在分片键字段上的多键索引、文本索引或者地理空间索引。
分片键不可改变
如果你一定要改变分片键:
- 导出所有数据
- Drop 旧的分片 collection
- 设置新的分片键
- 预先分割分片键的范围来确保初始分配是均匀的
- 导入数据
文档中的分片键不可改变
你不能修改分片键在文本中的对应字段的值。
参考
- https://docs.mongodb.com/manual/core/sharding-shard-key/#shard-key
- https://docs.mongodb.com/manual/reference/limits/#sharded-clusters
MogoDB 分片键的更多相关文章
- MongoDB 分片键的选择与案例
MongoDB版本:3.6 一.分片键类别 1.升序片键 升序片键例如:日期时间字段.自增字段. 2.随机分发片键 随机分发片键例如:用户名.邮件名.UUID.MD5值或者是其它的一些没有规律的值的列 ...
- MongoDB 分片键分类与数据分发
In sharded clusters, if you do not use the _id field as the shard key, then your application must en ...
- mogodb分片配置
下图展示了在MongoDB中使用分片集群结构分布: 上图中主要有如下所述三个主要组件: Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个repli ...
- MongoDB之分片集群与复制集
分片集群 1.1.概念 分片集群是将数据存储在多台机器上的操作,主要由查询路由mongos.分片.配置服务器组成. ●查询路由根据配置服务器上的元数据将请求分发到相应的分片上,本身不存储集群的元数据, ...
- 在一台机器上模拟mongodb分片
首先选择一个目录在其中建立以下2个文件夹:data和log 在data下建立9个文件夹: 其中前3个为配置服务器所在文件夹,按照官网要求,一个集群需要3个config server rs-a-n和rs ...
- MongoDB分片之数据分割方式
随着移动互联网的发展,大量的非结构化数据随之产生,不仅对数据库存储大数据提出了新的要求,同时对于查询数据和进行大数据分析也提出了苛刻的要求,这些显然是单服务器处理能力无法满足的,自然建立一个集群是不可 ...
- 从零搭建mongo分片集群的简洁方法
一.目录 1.mongo路径,config数据路径,shard数据路径
- mongodb 手动分片的命令汇总
手动分片的操作 自动分片会带来性能的下降. 所以要合理使用手动分片. 并且配合Tag一起使用. # 对于4个shard的程序, 预先处理的指令1. 加入分片服务器sh.addShard( " ...
- 【MongoDB】在windows平台下mongodb的分片集群(五)
本篇接着上面的四篇继续讲述在window平台下mongodb的分片集群搭建. 在分片集群中也照样能够创建索引,创建索引的方式与在单独数据库中创建索引的方式一样.因此这不再多说.本篇主要聚焦在分片键的选 ...
随机推荐
- Linux 多线程环境下 进程线程终止函数小结(转)
pthread_kill: pthread_kill与kill有区别,是向线程发送signal.,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数. ...
- WireShake的使用
转自点击打开链接 之前写过一篇博客:用 Fiddler 来调试HTTP,HTTPS. 这篇文章介绍另一个好用的抓包工具wireshark, 用来获取网络数据封包,包括http,TCP,UDP,等网络协 ...
- 【MyBatis学习07】动态sql
1. 动态sql 动态sql是mybatis中的一个核心,什么是动态sql?动态sql即对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装.就拿上一篇博文中对用户的综合查询一例来 ...
- 使用swap 清空vector
//最简单的使用swap,清除元素并回收内存 vector <int>().swap(vecInt); //清除容器并最小化它的容量, // vecInt.swap(vector<i ...
- 获取文本中你须要的字段的 几个命令 grep awk cut tr sed
1,grep 2,awk 3,cut 4,tr 5,sed 实例1 获取本地IP地址 /sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v ine ...
- pthread_create11121
#include <stdlib.h> #include <stdio.h> #include <pthread.h> void* test(void* args) ...
- core image几个滤镜样例 oc版本号和swift版本号
oc版本号 //万花筒模式 + (CGImageRef) getKaleidoscope:(CIContext *)context { CIImage * image = [CIImage image ...
- android.app.Service-android:process=":remote"属性解说
在学习Android Service组件的过程中碰到了一个问题,就是在Android应用的声明文件Manifest.xml中有时候会对相关的服务标签设置一个android:process=”:remo ...
- composer 初始化办法和方法
php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php php -r &qu ...
- iOS 学习笔记七 【博爱手把手教你使用2016年gitHub Mac客户端】
iOS 学习笔记七 [博爱手把手教你使用gitHub客户端] 第一步:首先下载git客户端 链接:https://desktop.github.com 第二步:fork 大神的代码[这里以我的代码为例 ...