目录

前言

1. 什么是分片

2. 为什么使用分片

3. 分片的优缺点

二、 安装部署

3. 分片配置服务器

1.直接连接mongos

2.分片规则命令 

总结

1 分片注意点



 



前言

数据库?集合?文档?MongoDB分片集群推荐的模式是:分片集合,它是一种基于分片键的逻辑对文档进行分组,分片键的选择对分片非常重要,分片键一旦确定,mongoDB对数据的分片对应用是透明的。


一、mongodb分片

1. 什么是分片

分片是把大型数据集进行分区成更小的可管理的片,这些数据片分散到不同的mongoDB节点,这些节点组成了分片集群.

2. 为什么使用分片

当前海量数据的增长,比如我公司单表的增量为每天2亿数据,这个时候需要更大的读写吞吐量  

单台mongo服务的负载很高,导致读写效率的低下、内存、cup等资源存在瓶颈。就算是使用副本集也是复制主节点的数据再存储一份在另一台服务上。

3. 分片的优缺点

分片集群是个双刃剑,在提高系统可扩展性和性能的同时,增大了系统的复杂性,所以在实施之前请确定是必须的。好的分片键的选择,可以极大的提高系统的读写效率。分片服务的数据存储也要根据业务的需求设置相对应的分片存储方式。分片服务中 ,读写的链路会增长,不恰当的分片规则和存储方式会增加数据读写过程中返回结果的时间。


二、 安装部署

mongoDB服务器的安装可以参考以前写的副本集安装部署:MongoDB副本集安装部署

1. 安装部署的服务器一般需要大于3台服务器 本地是测试安装就使用一台服务

本次使用的服务器: 10.10.11.61

 

2. 分片节点配置 创建mgdb.conf 文件(具体位置自己设置 后面需要使用完整目录启动)

systemLog:
  destination: file
  path: /home/mongodb/burst/logs/mongod.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /home/mongodb/burst/db
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 13 # 内存的最大占用 默认为内存的50%
processManagement:
  fork: true
  pidFilePath: /home/mongodb/burst/db/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 20001 # 端口号
  bindIp: 127.0.0.1,10.10.11.61 # 对应本机的IP 
replication:
  oplogSizeMB:  3072 # 不设置会使用默认的大小 物理内存剩余的5%建议自行查询
  replSetName:  burst1 # 副本集名称 多个分片服务 修改这里的名称 三个分片名称: burst2 burst3
sharding:
  clusterRole: shardsvr # 对应分片名称 分片服务基于角色


安全启动方式: 
numactl --interleave=all mongod -f /home/mongodb/burst/mgdb.conf

2) burst1 分片副本集的添加

rs.initiate({_id:"burst1",version:1,members:[{_id:0,host:"10.10.11.61:20001"}]});
rs.add("10.10.11.62:20001"); //有几个节点就执行几次方法 我这里只有一个节点 只需要执行一次

3. 分片配置服务器

systemLog:
  destination: file
  path: /home/mongodb/config/logs/mongod.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /home/mongodb/config/db
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 13 
processManagement:
  fork: true
  pidFilePath: /home/mongodb/config/db/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 20002
  bindIp: 127.0.0.1,10.10.11.61
replication:
  oplogSizeMB:  3072 # 不设置会使用默认的大小 物理内存剩余的5%建议自行查询
  replSetName:  configCopy # 副本集名称 
sharding:
  clusterRole: configsvr # 对应分片名称

1) 配置服务器的启动

安全启动方式:
numactl --interleave=all mongod -f /home/mongodb/config/mgdb.conf

2) 配置服务器的副本集添加 mongo -port 20002 use admin 

rs.initiate({_id:"configCopy",version:1,members:[{_id:0,host:"10.10.11.61:20002"}]});
rs.add("10.10.11.61:20002"); //有几个节点就执行几次方法 只有一个 只执行初始化一次

4. 配置mongo路由服务器 mongos

systemLog:
  destination: file
  path: /home/mongodb/logs/mongod.log
  logAppend: true
processManagement:
  fork: true
net:
  port: 20000
  bindIp: 0.0.0.0
setParameter:
  enableLocalhostAuthBypass: false
sharding:
  configDB: configCopy/10.10.11.61:20002

1)路由服务 mongos的启动方式

mongos -f /home/mongodb/mgdb.conf &

2) 执行分片的添加

mongo -port 20000 #进入mongos服务
use admin # 切换 admin用户
sh.addShard("burst1/10.10.11.61:20001"); #多个分片执行多次
#执行分片添加 如果是副本集 后面为: replSetName/IP+Port,IP+Port
sh.addShard("burst2/10.10.11.62:20001");

3) 查看添加分片状态

mongodb分区分片 mongodb分片集群_服务器

 

三、使用步骤

1.直接连接mongos

@Bean(name="mongo")
    public MongoClient mongoClient() {

        WriteConcern wc = WriteConcern.W1.withJournal(true);
        MongoClientOptions mco = MongoClientOptions.builder()
                .writeConcern(wc)
                .connectionsPerHost(100)
                .readPreference(ReadPreference.secondary())
                .threadsAllowedToBlockForConnectionMultiplier(5)
                .readPreference(ReadPreference.secondaryPreferred())
                .maxWaitTime(120000).connectTimeout(10000).build();

        MongoClient client = new MongoClient(new ServerAddress("10.10.11.61", 20000), mco);
        return client;
    }

2.分片规则命令 

  • 必须进入mongos服务中,切换到admin用户下
  • sh.enableSharding("dbName")  对当前数据库执行分片操作
  • sh.shardCollection("dbName.collectionName",{"_id":"hash"}) 对当前数据库的集合按照_id hash分片规则 进行数据的存储(注: 该操作会导致集合中会存在两个_id索引 一个为顺序索引,一个为hash索引,建议自己选择符合自己业务的索引规则)

 


总结

1 分片注意点

  • 热点: 某些分片键会导致所有的读或者写请求都操作在单个数据块或者分片上,导致单个分片服务器严重不堪重负。自增长的分片键容易导致写热点问题。
  • 不可分割数据块: 过于粗粒度的分片键可能导致许多文档使用相同的分片键,这意味着这个些文档不能被分割为多个数据块,限制了mongoDB均匀分布数据的能力。
  • 查询障碍: 分片键与查询没有关联,造成糟糕的查询性能。
  • Mongo集合的分片键字段值一经设置,不可变更!
  • 对于有分片键的集合,更新操作(无论是单条,还是批量)优先使用分片键的排列组合作为更新条件。
  • 如果因业务特性,不能使用分片键作为更新条件, 并且要求{upsert:true}的场景,必须使用批量更新操作。
  • 对于mongos能够确定唯一记录的(主键),可以使用update等单条更新动作进行更新,否则必须使用批量更新操作。