美文网首页
MongoDB Sharding

MongoDB Sharding

作者: geekpy | 来源:发表于2018-02-03 13:14 被阅读93次

    介绍

    Sharding Key

    • Sharding key必须是在对应的collection当中所有的文档都存在的field,比如我要sharding我的user collection,我就可以找nick_name这种所有documents中都存在的field来做为sharding key,当然还要考虑其它因素,但是这个是一个必要条件。
    • sharding key可以一个或者多个fields组成,还以user document为例,除了可以使用nick_name还可以加一个created time一起作为sharding key。当然具体使用什么field要根据系统的实际情况来综合考虑。
    • sharding只能有一个,而且设定后不可更改
    • 针对已经有数据的collections做sharding时,原collections必须有以sharding key开头的索引;如果是空的collection,则MongoDB会自动创建对应的索引

    Sharding的优势

    读写效率

    由于我们可以将相应的写操作分布在不同的shard上,可以更加均匀分担写压力,因此写的性能一般情况下会得到提高。
    读取操作时,如果query中包含shard key对应的field,或者以这个field为prefix的compound index key

    存储容量

    由于是水平分割,因此几乎可以无限扩容,不需要担心某个collection过大而无法单机存储的问题

    高可用

    从MongoDB3.2开始,config server已经支持replicaset模式,这样的话sharding节点和config节点均可以通过replicaset来保证高可用。

    关于Sharding的考虑

    由于sharding的不可逆性,所以最好是先不使用sharding,在业务运行一段时间后,根据业务的情况来做决定,这主要需要考虑如下因素:

    • 某个collection的数据是否非常大,达到未来可能一台机器的存储容量都无法解决该collection的存储。
    • 是否有些collection存在性能问题,希望通过sharding来解决
    • 由于具有不可逆性,我们可以只针对需要做sharding的collection做sharding,而其它collection不需要sharding。不做sharding的collection会存储于primary shard之上(所以可见这个shard应该有更大的容量)
    • 针对需要分片的collection,需要确定满足以下几个条件:
      • 选取的key可以使得collection的数据能均衡地分布在不同的shard上
      • 写请求的时候也能均匀分布,比如时间戳作为key时,虽然也能将key均匀分布到不同的shard上,但是同一时间段,写请求就会持续在一个shard上,这样就不是均匀写了
      • 我们针对该collection的查询主要是使用哪个field来作为查询条件,那么这个field最好是作为shard key
      • 作为sharding key的field需要有索引,或者是作为compound索引的prefix。
      • 尽量避免会导致jumbo chunk的key,比如通过age来作为key,同一个age的数据均会放到同一个chunk,这就可能导致chunk不断变大,当超过chunk size时,就会变成jumbo chunk

    Sharding策略

    Sharding有两种策略:一种是ranged sharding; 另一种是hashed sharding。

    • 如果选择的key,其值域非常接近,尤其是单调递增或者递减(increase or decrease monotonically, 也可以翻译成单向递增递减),就会导致所有的新增操作都会集中在最大的range的shard上(如果是递增);或者集中在最小range的那个shard上(如果是递减)。这就导致无法均匀地进行写操作(因为所有的写操作都集中在一个shard甚至一个chunk上)。而那个最大或最小range的shard将成为系统的瓶颈。具体参考shard-key-monotonic。在这种情况下,我们应当选择hashed sharding.
    • hashed sharding。MongoDB通过hash算法(MD5)来计算key的hash值,然后将数据存储于对应范围的chunk上。由于算法的原因,即使非常"近"的key通过hash之后的值可能会有很大的差异,从而可以更加均匀的分布在不同的chunk之上。hashed sharding的缺点在于当我们的业务有很多范围查询时,(比如uid 5~20),此时由于可能分布在很多不同的chunk上,所以就必须进行广播时操作,即要求所有的shard都进行查询,看是否有在这个范围内的数据,如果有就会交给mongos,mongos再负责将这些数据组合成一个完整的答案给客户端。这种情况下,势必会影响到查询性能。所以具体使用什么样的策略,需要综合考虑很多因素。

    Splitting and Migration

    Splitting

    splitting就是当chunk中存储的数据量超过设定的chunk size时(默认64M),将其分裂成两个chunk,具体参考chunk split

    Splitting

    Migration

    数据迁移,是将某一个shard中的chunk数据迁移到另一个shard上。迁移有两种方式,一种是手动迁移,一种自动迁移。大部分时候,MongoDB会通过balancer进行自动迁移,以保持chunk在shard上能够均匀分布。手动迁移仅用于某些特定场景如bulk insert。

    关于balancer

    balancer是一个后台进程,它会自动判断含有最多chunk的shard和最少chunk的shard之间的chunk数量差达到了设定的threshold,如果达到了,就会自动进行数据迁移。


    Balancing

    相关文章

      网友评论

          本文标题:MongoDB Sharding

          本文链接:https://www.haomeiwen.com/subject/aqruzxtx.html