• MongoDB——分片片键的选择 (转)


    转自:

    https://www.cnblogs.com/cmt/p/14580194.html?from=https%3A%2F%2Fwww.cnblogs.com%2Fcwane%2Fp%2F5519830.html&blogId=281155&postId=5519830 

    1.分片

          分片是什么?分片就是将数据存储在多个机器上。当数据集超过单台服务器的容量,服务器的内存,磁盘IO都会有问题,即超过单台服务器的性能瓶颈。此时有两种解决方案,垂直扩展和水平扩展(分片)。

          垂直扩展就是增加CPU,增加容量,但高性能系统的CPU和容量不成比例,这样扩展成本大,并且有上限。

          水平扩展分片,将数据分发到多个服务器,每个服务器是一个单独的数据库,各个服务器加起来组成一个逻辑数据库,把写压力和操作分流到不同服务器,提高容量和吞吐量。

          MongoDB的文档是无模式的,不固定结构,因此只能进行水平分片。当块超过指定大小或者文档数超过最大文档数,MongoDB尝试分割这个块,若分割成功,把它标记为一个大块避免重复分割。拆分块的关键就是片键,下面介绍常见片键的种类。

    2.片键种类

          片键是文档的一个属性字段或者一个复合索引字段,一旦建立不能改变。片键是分片拆分数据的关键,片键的选择直接影响集群的性能。

          MongoDB首先根据片键划分块chunks当块超过指定大小(默认64M),然后把块分到其他的分片上,片键类型主要有以下几种:

          注意:片键也是查询时常用的一个索引。

    (1) 递增片键

          这类片键比较常见,比如使用时间戳,日期,自增的主键,ObjectId,_id等,此类片键的写入操作集中在一个分片服务器上,写入不具有分散性,这会导致单台服务器压力较大,但分割比较容易,这台服务器可能会成为性能瓶颈。

    递增片键的创建,对foo数据库的bar集合使用timestamp时间戳分片

    mongos> use foo
    mongos> db.bar.ensureIndex({"timestamp":1})
    mongos> sh.enableSharding("foo")
    { "ok" : 1 }
    mongos> sh.shardCollection("foo.bar",{"timestamp":1})
    { "collectionsharded" : "foo.bar", "ok" : 1 }

     (2) 哈希片键

          使用一个哈希索引字段作为片键,优点是使数据在各节点分布比较均匀,数据写入可随机分发到每个分片服务器上,把写入的压力分散到了各个服务器上。但是读也是随机的,可能会命中更多的分片,一般具有随机性的片键(如密码,哈希,MD5)查询隔离性能比较差。

    哈希片键的创建,对GridFS的chunks集合使用files_id哈希分片

    mongos> db.bar.ensureIndex({"files_id":"hashed"})
    mongos> sh.enableSharding("foo")
    { "ok" : 1 }
    mongos> sh.shardCollection("foo.fs.chunks",{"files_id":"hashed"})
    { "collectionsharded" : " foo.fs.chunks ", "ok" : 1 }

     (3) 组合片键

          数据库中没有比较合适的片键供选择,或者是打算使用的片键基数太小(即变化少如星期只有7天可变化),可以选另一个字段使用组合片键,甚至可以添加冗余字段来组合。一般是粗粒度+细粒度进行组合。

    组合片键的创建,对GridFS的chunks集合使用files_id和n组合分片

    mongos> sh.enableSharding("foo")
    { "ok" : 1 }
    mongos> sh.shardCollection("foo.fs.chunks",{"files_id":1, "n":1})
    { "collectionsharded" : " foo.fs.chunks ", "ok" : 1 }

    (4) 标签分片

          数据存储在指定的分片服务器上,可以为分片添加tag标签,然后指定相应的tag,比如让10.*.*.*(T)出现在shard0000上,11.*.*.*(Q)出现在shard0001或shard0002上,就可以使用tag让均衡器指定分发。

    标签分片的创建

    mongos > sh.addShardTag("shard0000", "T")
    mongos > sh.addShardTag("shard0001", "Q")
    mongos > sh.addShardTag("shard0002", "Q")
    mongos> sh.addTagRange("foo.ips",{ "ip": "010.000.000.000 ", … , "ip": "011.000.000.000 "}}, "T")
    mongos> sh.addTagRange("foo.ips",{ "ip": "011.000.000.000 ", … , "ip": "012.000.000.000 "}}, "Q")

     3片键选择策略

          大致了解了片键的种类,那么怎么选择片键呢?无非从两个方面考虑,数据的查询和写入,最好的效果就是数据查询时能命中更少的分片,数据写入时能够随机的写入每个分片,关键在于如何权衡性能和负载

    如何选择片键主要从下面几个问题考虑:

    (1)首先确定一个经常性查询的字段

    (2)找到影响这些操作性能的关键点

    (3)如果选的字段基数比较小,添加一个粒度细的字段

  • 相关阅读:
    本人作品
    转本笔记计算机理论
    markdown
    javascript的原型链解析(相信你也可以)
    思考 | 执行 delete from t1 where id = 10;MySQL会加什么锁?
    ORA00439: 未启用功能: Deferred Segment Creation
    思考 | select…for update会锁表还是锁行?
    DMS迁移MySQL源限制
    属性文件加载
    视频流推送到公网播放
  • 原文地址:https://www.cnblogs.com/xingchong/p/14703949.html
Copyright © 2020-2023  润新知