暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MongoDB分片实践

data之道 2017-01-25
296

  • 一、介绍

  • 二、架构

  • 三、集群配置

  • 四、添加分片

  • 五、Collection启用分片        

  • 六、Balance

  • 七、那些坑

  一、介绍

    sharding是指将一个collection根据一定的规则拆分,分散存储到多台服务器中,每台服务器只存储一个collection中的一部分数据。数据集分布式负载存储,可以减少单台服务器的存储压力、充分利用各个片的资源,提高整个数据库的系能。一个collection被分成多个chunk(数据块),每个chunk包含多个document。

二、架构

    mongos:请求路由,mongos隐藏分片细节,客户端不需要知道collection分布式存储在哪些片里。mongos根据config配置知道数据和片的对应关系,接收客户端发来的请求,把请求自动转分到对应的片上,然后汇集每个片的响应数据,最后把汇集结果返回给客户端

    config servers:配置服务器存储分片元数据、集群配置:collection的数据块、每个数据块包含的document范围、每个数据块存储在哪个分片上等

    shard:每个分片只包含分片collection的一部分数据。shard可以是单个mongodb也可以是一个复制集(replica),建议用复制集,提高分片的稳定性


三、集群配置

    为了简化操作,分片有三个mongodb:est1、test2、test3,生产建议每个分片都是用复制集)、一个路由mongos(test1)、一个配置服务(test1,3.4以上的版本必须使用复制集作为配置服务)

    1、shard:

    test1、test2、test3创建同样的mongodb.conf配置文件:


    然后在test1、test2、test3服务器上启动mongodb:

      mongod -f mongodb.conf

    2、config servers:

      test1服务器创建mongodbconf.conf配置文件:


    启动config server:

       mongod -f mongodbconf.conf

    3、mongos:

    test1服务器上启动mongos:


    configdb:指定配置服务器

    port:mongos端口

    fork:mongos后台运行

    logpath:mongos日志文件

四、添加分片 

    1、访问monogs:mongo test1:27037

    2、增加三个数据库分片实例

use admin;

db.runCommand({addShard: "test1:27017"});

db.runCommand({addShard: "test2:27017"});

db.runCommand({addShard: "test3:27017"});

    或者下面命令:

        sh.addShard("test3:27017");

    3、验证shard是否加到集群:

        方法一、sh.status()命令的输出结果可以看到

        方法二、配置数据库里查看:use config;db.shards.find()

五、Collection启用分片 

    1、对数据库启用分片

        use admin;

        db.runCommand( { enablesharding :"test_db"});

    2、创建索引,分片的片键有索引后才能分片

        user test_db;

        db.cl_test1.ensureIndex({"uid":1});

      查看创建的索引:db.cl_test1.getIndexes()

    3、对collection进行分片

        sh.shardCollection("test_db.cl_test1", {"uid" : 1})

        或者下面的命令:

        use admin;

        db.runCommand({shardcollection:"test_db.cl_test1",key:{"uid":1}})

    4、验证分片

    方法一:sh.status();输出结果能看到数据是分布在哪些分片上。

    或者直接查询chunks:   

六、Balance

    Balance是Mongo的负载均衡工具,负责拆分、合并、移动Chunks,保证分片集合的chunks负载均衡存储在整个集群中;Balance是一个后台进程,监控每一个shard中的块数量,当一个分片里的chunks文件超过了阀值,就会自动在集群内移动chunks,以到达每个分片中的chunks数据量相等。默认的块是64M。

    块的拆分是为了避免块增长太快,当块达到了块的大小或者达到了块中最大文档数;MongoDB根据片键的值拆分块,一个快可能拆分成多个块。

七、那些坑

    1、热点问题:如果片键选择不适当,分片后的数据可能会较集中,查询请求也会集中在一些特定chunks,会导致整个集群出现瓶颈。假设根据uid分片,如果一个用户有很多行为数据,当查询这个用户时,会引起单台shard热点问题,解决方法是可以根据多个键hash作为片键,如day+uid;Hash分片会把数据均匀分布

    2、如果块太大,balance就不能再拆分、移动chunk:块中的文档数超过250000个或者块的大小超过了集合平均文档大小的1.3倍。这样会导致负载不均衡,需要选择好片键

    3、balance执行时会影响集群工作效率,建议设定在请求量小的时间段内执行

文章转载自data之道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论