zoukankan      html  css  js  c++  java
  • MongoDB-分片片键

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/1182994018.html

    1.分片

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

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

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

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

    2.片键种类

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

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

    注意:片键也是查询时常用的一个索引。
    原文作者: xingguang
    原文链接:https://www.tiance.club/post/1182994018.html

    (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 }
    

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/1182994018.html

    (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)如果选的字段基数比较小,添加一个粒度细的字段

    怎么选择,如何权衡,跟具体的业务以及数据类型都有关系,具体问题具体分析。

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/1182994018.html

  • 相关阅读:
    老鼠走迷宫
    堆栈的应用 问题还未解决
    计数排序与基数排序
    C++类的描述
    选择排序 冒泡排序 插入排序
    计算名次
    多项式求值 n维多项式 Horner解法
    003_sublime如何实时预览markdown
    002_git下载的源码怎么打成jar包呢?
    001_idea常用插件
  • 原文地址:https://www.cnblogs.com/yizhidaozuihou/p/12830176.html
Copyright © 2011-2022 走看看