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

对集合进行分片时,要选择一个或者两个字段拆分数据,这个键叫做片键 一旦拥有对个分片,在修改片键几乎是不肯能的事情,因此选择合适的片键是非常重要的.
对集合分片之前要问自己集合问题
  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. 【Luogu】P4172水管局长(LCT)

    题目链接 有个结论是x到y的路径上最长边权值等于最小生成树上最长边权值,于是问题转化为最小生成树. 再考虑把问题反过来,删边变成加边. 于是变成动态维护最小生成树,LCT可以做到. #include& ...

  2. ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  3. 完美匹配(matching)

    完美匹配(matching) 题目描述 给定nn个点,mm条边的无向图G=(V,E)G=(V,E),求出它的完美匹配数量对106+3106+3取模的值. 一个完美匹配可以用一个排列ϕ:V→Vϕ:V→V ...

  4. Hibernate逆向工程生成代码

    编辑此文章,其目的是方便以后根据表生成相应的代码,然而并非所有的代码都是如此.这里的Hibernate 即响应题目的ssh框架中的“h”. 如图所示,点击右上角,在myeclipse之中.再点击Mye ...

  5. ajax跨域两个方法

    1在后端转换,调用API. ajax瀑布流: <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  6. linux之stat

    stat指令:文件/文件系统的详细信息显示: 使用格式:stat 文件名 stat命令主要用于显示文件或文件系统的详细信息,该命令的语法格式如下: -f 不显示文件本身的信息,显示文件所在文件系统的信 ...

  7. spring boot 运行jsp原理分析

    Spring-boot运行jsp原理分析   结论: 启动server的时候会创建临时目录 在浏览器中访问jsp文件的时候通过内置Tomcat将jsp转换为java,保存在临时目录中 然后编译为cla ...

  8. 【转】利用ScriptManager实现Javascript调用WebService中的方法

    原文发布时间为:2009-07-01 -- 来源于本人的百度文章 [由搬家工具导入] 前台调用后台方法,或者后台调用前台方法。ScriptManager实现 开发过程中,总想在前台直接调用后台的met ...

  9. ubuntu php编译安装配置

    安装参考:http://ilanni.blog.51cto.com/526870/1569322/ 加载扩展的一些参数参考:http://java-er.com/blog/nginx-php-fpm/

  10. angular 右击事件的写法

    .directive('ngRightClick', function ($parse){ return function (scope, element, attrs){ var fn = $par ...