首先要了解项目的情况,检查使用情况

对集合进行分片时,要选择一个或者两个字段拆分数据,这个键叫做片键 一旦拥有对个分片,在修改片键几乎是不肯能的事情,因此选择合适的片键是非常重要的.
对集合分片之前要问自己集合问题
  1. 计划做多少分片`?拥有三个分片的集群要比1000个的更具有灵活性,随着集群变得越来越大 不应做那些需要查询所有分片的查询,因此几乎所有查询都需包含片键
  2. 分片是为了减少读写延迟么?延迟就是某个操作花费的时间.降低写延迟的方式通常是将请求发送到地理位置更近的服务器或者更强大的机器上
  3. 分片是为了增加读写吞吐量么? 吞吐量是指集群在同一时间能够处理的请求数量,增加吞吐量通常需要提高并行性,并确保请求被均衡的分布到各集群成员上
  4. 分片是为了增加系统资源么?如果是这样 可能会希望尽量保持工作集较小

根据这些问题来对不用的片键进行评估,并判断所选的片键是否适用于自己的情况,这样做能够提供所需要的目标查询么?能够按所需方式提高系统吞吐量或者减少读写延迟么?如需保持工作集的小巧,这样做可以打到要求么?

 
升序片键
升序片键 有点类似于date字段或者objectId 是一种随着时间稳定增长的字段,自增长的主键是升序键的另一个例子.假如我们依据升序键做片键 如使用objectId的集合中的"_id"键 如果基于_id分片 那么集合会根据不同的_id范围被拆分为多个块,
假设要创建一个新的文档 会插入哪个块呢?答案是范围最接近$maxKey的快 也就是最大块. 这样每次添加的文档都会出现这个块中,这样会带来需要不量的属性 首先所有的写请求都会被路由到找这个分片中,该快是唯一一个不断增长和拆分的块,因为只有他接收写请求,随着数据的不断插入 当达到拆分阀值的时候  mongos 就会对该块进行拆分 所以该块不断拆分出小块
这种模式进程导致mongodb的数据均衡处理变得更为困难,因为所有的新快都死由同一个分片创建的,因此必须不断的将一些快移至其他分片,而不能像在一个比较均衡发布的系统中那样 只需要纠正那些比较小的不均衡就好了
随机分发的片键
随机分发的键可以是用户名 邮件地址 udid(唯一设备标识符) md5散列值 或者是数据集中其他一些没有规律的键 随着数据的不断插入 数据的随机性一位置 新插入的数据会比较均衡的分布在不同的块中,由于写入数据是随机分发的 各个分片增长的速度应该大致相同,这就减少了需要进行迁移的次数
随机分发片键的唯一弊端在于:mongodb在随机访问超出ram大小的数据时效率不高.如果拥有足够多的ram或者不介意系统性能的话 使用随机片键在集群上分配负载时非常好的
基于位置的片键
可以是用户的ip 经纬度 或者地址 位置片键不必也实际的物理位置字段相关 这里的位置比较抽象 数据会依据这个位置进行分组.无论如何 所有与该键值比较接近的文档都会保存在同一范围的块中,这样可以比较方便的将数据与相应的用户, 以及相关联的数据保存在一起
假如我们有一个集合文档按照IP地址进行分片 文档会依据IP地址被分成不同的块,冰水机分布在集群中
 如果希望特定范围的块出现在特定分片中  可以在分片中添加tag 然后为块指定相应的tag
sh.addShardTag("shard0000":"USPS")
sh.addShardTag("shard0001":"Apple")
sh.addShardTag("shard0002":"Apple")
然后创建下列规则 
sh.addTagRange("test.ips",{"ip":"056.000.000.000"},{"ip":"057.000.000.000"},"USPS")
sh.addTagRange("test.ips",{"ip":"017.000.000.000"},{"ip":"018.000.000.000"},"Apple")
均衡器在移动块时,会试图将这些范围的块移动到这些分片上,注意该过程不会立即生效,没有被打过标签的块仍会正常移动.
 片键策略
 
散列片键
 
如果追求的是数据加载速度的极致,那么散列片键是最佳选择,散列片键可使其他任何键随机分发.因此打算在大量查询中使用升序键但同时又希望写入数据随机分发的话,散列片键会是非常好的选择.
弊端 是无法使用散列片键做指定目标的范围查询.
创建一个散列片键 首先要创建散列索引 db.users,ensureIndex({"username":"hashed"}) 然后对集合分片 sh.shardConllection("app.users",{"username":"hashed"})
使用散列片键存在着一定的局限性.首先不能使用unique选项.其次,与其他片键一样,不能使用数组字段.最后注意,浮点型的值会先被取整,然后才会进行散列,所以1和1.999会得到相同的散列值
 
流水策略
 
如果有一些服务器比其他服务器更强大,我们会希望让这些强大的服务器处理更多负载,比如说 一个使用SSD的分片能够处理10被与其他机器的负载.幸运的是,我们有10个其他分片.可强制将所有新数据插入到SSD,然后让均衡器将旧的块移动到其他分片上 这样能够提供比转式磁盘更低的延迟
 
为了实现这个策略 需将最大范围的块分布在SSD上  为SSD指定一个标签  sh.addShardTag("shard-name","ssd")
将升序键的当前值一直到正无穷范围的块指定分布在SSD分片上,以便后续也日请求均被发到SSD分片上 sh.addTagRange("dbname.collName",{"_id":ObjectId()},{"_id":MaxKey},"ssd")
现在 所有插入的请求俊辉被路由到这个块上,这个块始终位于标签为ssd的分片上.
 
但是 除非修改标签范围,否则从升序键的当前值一直到正无穷的这个范围则被固定在了这回分片上  可以创建一个定时任务每天更新一次标签范围 如下
use config
var tag = db.tags.findOne{{"ns":"dbName.collName","max" : {"shardKey": MaxKey }}} // 获得拥有最大key的块 
tag.min.shardKey = ObjectId() //修改该块的最小键的值 为当前的objectId
db.tags.save(tag) //保存
这样前一天的块就可以被移动到其他分片上了
此策略的另一个弊端是 需要做一些修改才能进行拓展 如果写请求超出了SSD的处理能力 想要将负载均衡的分不到当前服务器和另一台服务器并不简单
 
如果没有高性能的服务器来处理插入流水 或者没有使用标签 那么就不要将升序键用作片键,否则所有请求都会被路由到同意分片上.
 
多热点
 
单个mongod服务器在处理升序写请求时是最有效的,他和分片相冲突 写请求均匀分布在集群中 分片才是最高效的.这种技术会创建多个热点(最好每个分片都创建几个热点) 写请求于是会均衡的分布在集群内 而单个分片上则是以升序分布的

mongodb分片片键的选择(持续更新中)的更多相关文章

  1. Pig基础学习【持续更新中】

    *本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.* Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的,可以作为MapR ...

  2. Pig语言基础-【持续更新中】

      ***本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.***   Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的, ...

  3. 《WCF技术剖析》博文系列汇总[持续更新中]

    原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...

  4. HBase常见问题答疑解惑【持续更新中】

    HBase常见问题答疑解惑[持续更新中] 本文对HBase开发及使用过程中遇到过的常见问题进行梳理总结,希望能解答新加入的HBaser们的一些疑惑. 1. HTable线程安全吗? HTable不是线 ...

  5. fastadmin 后台管理框架使用技巧(持续更新中)

    fastadmin 后台管理框架使用技巧(持续更新中) FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架,具体介绍,请查看文档,文档地址为:https://doc. ...

  6. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  7. 史上最全的spark面试题——持续更新中

    史上最全的spark面试题——持续更新中 2018年09月09日 16:34:10 为了九亿少女的期待 阅读数 13696更多 分类专栏: Spark 面试题   版权声明:本文为博主原创文章,遵循C ...

  8. 前端面试题总结——HTML(持续更新中)

    前端面试题总结--HTML(持续更新中) 1.什么是HTML? HTML:HyperText Markup Language超文本标记语言 2.XHTML和HTML有什么区别 HTML是一种基本的WE ...

  9. 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

    Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...

随机推荐

  1. Could not connect to Redis at 127.0.0.1:6379: Connection refused

    启动redis:  redis-server ../redis.conf redis启动成功后 执行命令行redis-cli报:Could not connect to Redis at 127.0. ...

  2. GitLab-CI环境搭建与操作手册

    第一章 系统安装简介 1.1. 系统结构 GitLab-CI持续集成服务主要包括gitlab.runner 2个模块.Gitlab主要负责代码文件的管理:runner则负责版本编译.存储.推送等任务. ...

  3. loadrunner rtsp协议模拟

    在核心网做过3年的sip消息模拟,所以rtsp消息模拟只要知道信令消息交互就非常顺利了 RTSP 实时流传输协议, 是TCP/IP协议体系中的一个应用层协议, 该协议定义了一对多应用程序如何有效地通过 ...

  4. LAMP总四部分

    第一部分 1. 安装mysqlcd /usr/local/src/ 免安装编译二进制的包wget http://syslab.comsenz.com/downloads/linux/mysql-5.1 ...

  5. C#,一种简单的方式实现滚动鼠标缩放图片,平移

    1.缩放 private void ImageShow_Load(object sender, EventArgs e) { pictureBox1.Load(@"E:\SQ1.jpg&qu ...

  6. [NOI2003][bzoj1507] 文本编辑器 editor [splay]

    其实看明白了就是一道水题 毕竟模板 splay敲一发,插入一个串的时候先把它构建成一棵平衡树,再挂到原来的splay上面去即可 没别的了,上代码 #include<iostream> #i ...

  7. 【APIO 练习题】Lock Puzzle

    题意 你有一个长度为 $n$ 的字符串,你需要经过若干次操作将其变成目标串 $n'$. 一次操作:选择串 $n$ 的一个后缀,将其翻转,并放到串 $n$ 的最前面. 请你输出任意一种方案.当然,你达到 ...

  8. pat 甲级 1049. Counting Ones (30)

    1049. Counting Ones (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The tas ...

  9. MySQL数据库”mysql SQL Error:1146,SQLState:42S02 “解决方法

    项目在开发的时候在Mac平台下开发的,开发完了之后在LINUX环境上部署好之后,运行时MySQL数据库报错,提示为某个表不存在之类的错误信息,后来修改了MySQL的配置文件将大小写敏感去掉,问题解决. ...

  10. 知乎上的一些文章---leetcode【笔记1】

    张土汪 http://github.com/shawnfan Java{script}代码仔 42 人赞同 [1.19.2017] 更新: 2017年1月17日, 陪我征战多年的 2014 MackB ...