Chinaunix首页 | 论坛 | 博客
  • 博客访问: 308582
  • 博文数量: 35
  • 博客积分: 825
  • 博客等级:
  • 技术积分: 913
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-11 09:44
文章分类

全部博文(35)

文章存档

2013年(10)

2012年(24)

2010年(1)

我的朋友

分类: NOSQL

2013-01-25 15:13:56

重新配置了shard cluster 另外看了《scaling mongodb》这本书的前两章 回头来再读这篇文档 感觉容易理解很多 顺便把它给翻译了吧 


Shard Keys

Shard keys 是collection中的一个字段 Mongo DB用这个keys来对数据进行分片存放到集群中的各个存储节点上去


Cardinality

Cardinality 在这里的意思指 系统对数据分片的能力 举个例子吧 存储地址簿:

  • 用州这个字段作为shard key
    state州,这个字段存放地址簿中美国州的名称 用state作为shard key 那么相应的cardinality会比较小 因为州名相同的地址必须存放在相同的shard中 这可能导致分片后 某个州的地址超过了chunk最大值
    另外 州这个字段可能的值是一定的 美国就只有50来个州 MongoDB有可能把所有的数据不均匀地存放到少量的chunk中 导致的后果是: 
    • MongoDB无法对某个chunk分片 迁移这些不可分割的chunk的代价可能很高 万一某个chunk有2-5GB 那么做这样一次迁移的代价可想而知
    • state这样一个字段所可能的值很有限 想多添加shard来增加集群的吞吐是不肯完成的任务 mission impossible
  • zipcode邮政编码作为shard key
    全国范围内的邮政编码的可能值比州要多很多 相比state作为shard key 用zipcode的cardinality会高一些 当然如果记录的地址都是某个特定的地区 那么死的惨烈状况和用state一样 但是记录全国范围内的地址 它还是比较理想的shard key

  • phone-number电话号码作为shard key
    用这个字段 比之上的两个字段都要棒 可能的值更多 MongoDB会按需要对数据进行分片

较高的cardinality对于均匀地分布数据是有好处的 但是这并不能保证读写的效率会相应地增加


写的伸缩性

下面这个例子用ObjectID作为shard key

ObjectID 在document创建的时候确定 和存储的document是一一对应的 但是这个值往往和时间戳相关 也就意味着 我们可以预计这个值的变化情况 尽管用它作为shard key可以获得较高的cardinality 但是这种单调增长的值作为shard key 那么某一个时间段的数据都会存放到同一个chunk中 也就会在同一个shard里 从而这个shard就会直接影响到集群的写效率 如果插入数据的比例很低 那么用它是没有问题的 并不会影响性能 但是 总的来说 尽可能选择那些既可以获得高cardinality 又能把写分散到整个集群的字段作为shard key 可以选择那些比较随即的字段 或者计算出document的hash值作为shard key 看起来这样对写来说是足够理想了 但是考虑到读的性能 哎 


查询

mongos隐藏了整个集群的信息 应用发送查询请求到mongos monos向config server请求metadata 然后把应用查询导向到某个mongod实例  从这个过程中 我们也可以看出shard key对查询性能的影响


查询隔离性

效率最高的查询是 mongos利用shard key 还有config server的metadata 发送到一个特定的shard上  如果查询中没有包含shard key mongos必须询问所有的shard 然后等待它们响应 如果你的请求包含了shard key的一部分 mongos就可以依赖这些信息把查询转给特定的shard 或者少数的几个shard 这样查询效率也会相应地提高


如何选择理想的shard key:

  • 研究一下哪些字段是应用在查询时 通常会被包含在请求中
  • 哪些操作最影响性能

如果单一的字段作为shard key导致cardinality很低 那么你可以再添加一个字段作为shard key 这种复合的shard key对于MongoDB来说更好


排序

mongos会对shard返回的查询结果合并排序


可靠性

在选择shard key时 最需要考虑的因素:

  • 确保MongoDB可以把数据均匀地分布到整个集群
  • 把写操作分布到整个集群
  • 确保mongos可以把查询请求 转到一个明确的shard上 而不是询问所有的shard

其它:

  • 每一个shard最好是一个replica set 如果这个replica set中的某一个server 挂了 那么其它的server可以投票选择一个新的shard作为primary shard继续提供服务 如果这个shard replica set中的所有server都挂了 那么大声说拜拜吧 game over
  • 如果shard key可以让mongos的请求转到特定的shard上去 那么这个shard的故障 只会影响一部分数据
  • 如果你选择的shard key 让所有的请求都需要通过整个集群的处理才能得到响应 那么shard挂了 整个集群也就挂了


Choosing a Shard Key

通常很难选择一个shard key 达到理想化的成都 但是这里还是有三点建议提供给大家:

  1. 在应用层设法获取一个比较理想的shard key 并且在每条记录里都存这个字段 可以是_id字段
  2. 使用复合的shard key 用两到三个字段 这样有助于读写效率的提高 MongoDB也更加容易对数据进行分片
  3. 对比一下如果选择了一个稍微差一点的shard key 对性能的影响, 可以从一下几点出发:
    • 写性能,
    • 预期的数据大小
    • 请求的特点 还有需求
阅读(6010) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~