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

对集合进行分片时,要选择一个或者两个字段拆分数据,这个键叫做片键 一旦拥有对个分片,在修改片键几乎是不肯能的事情,因此选择合适的片键是非常重要的.
对集合分片之前要问自己集合问题
  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. Struts2请求流程

    1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionContextCleanUp过滤器,其为可 ...

  2. UVALive 6609 Minimal Subarray Length(RMQ-ST+二分)

    题意:给定长度为N的数组,求一段连续的元素之和大于等于K,并且让这段元素的长度最小,输出最小长度即可,若不存在这样的元素集合,则输出-1 题目链接:UVAlive 6609 做法:做一个前缀和pref ...

  3. [SDOI2011][bzoj2245] 工作分配 [费用流]

    题面 传送门 思路 数据范围n,m<=250 分配任务问题 这是典型的"看到数据范围就知道算法"类型 而且我们发现我们要保证一定产出的情况下最小化花费 这句话等价于保证一定流 ...

  4. 三叉神经树 ( neuron )

    三叉神经树 ( neuron ) 题目描述 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物SHTSC 的密切联系引起了人们的极大关注. S ...

  5. Codeforces Round #315 (Div. 2) B 水题强行set

    B. Inventory time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  6. duilib入门简明教程 -- 第一个程序 Hello World(3) (转)

    原文转自 http://www.cnblogs.com/Alberl/p/3343579.html 小伙伴们有点迫不及待了么,来看一看Hello World吧: 新建一个空的win32项目,新建一个m ...

  7. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---57

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  8. 把握linux内核设计思想系列【转】

    转自:http://blog.csdn.net/shallnet/article/details/47734053 版权声明:本文为博主原创文章,未经博主允许不得转载.如果您觉得文章对您有用,请点击文 ...

  9. JavaScripts广告轮播图以及定时弹出和定时隐藏广告

    轮播图: 函数绑定在body标签内 采用3张图,1.jpg   2.jpg  3.jpg  利用定时任务执行设置图片属性 src  利用for循环可以完成3秒一次 一替换. 定时弹出广告: 由于bod ...

  10. 2016百度之星资格赛 Round1(2,3,4题)

    Problem B Accepts: 2515 Submissions: 9216 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...