MongoDB 入门专栏



MongoDB 副本集



复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性,同时 还允许从硬件故障和服务中断中恢复数据。




mongodb 的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据,主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。






mongo 副本集 如何负载均衡 mongo副本集 分片_分片



这样一个数据冗余系统中,主节点和所有从节点组成一个副本集,mongodb 的副本集拥有以下特点:


  • N 个节点的集群
  • 任何节点可作为主节点
  • 所有写入操作都在主节点上
  • 自动故障转移
  • 自动恢复



mongodb 副本集的设置


副本集的启动,和从节点加入到副本集的操作,只能在主节点上完成,但是主节点随时否可以转移到其他从节点;



启动一个副本集系统的基本步骤如下:


  • 在主节点启动 mongod 服务时,可以使用 --replSet 启动副本集,同时指定副本集名称;
  • 连接主节点,初始化新的副本集;
  • 启动各个从节点 mongod 服务,同时这些从从节点也创建和必须初始化副本集,使用同一个副本集 id;
  • 在主节点将这些从节点加入主节点副本集;



以下演示 3 个 mongodb 创建一个副本集系统


1)主节点启动 mongod 服务:


 


# 启动 mongodb 服务,设置副本集 rs0


$ mongod --port 27017 --dbpath "/var/run/mongodb/data" --replSet rs0


2) 2 个从节点分别启动 mongod 服务


 


$ mongod --port 27017 --dbpath "/var/run/mongodb/data" --replSet rs0


3)连接到主节点 mongodb,进行副本集的初始化和配置


 


$ mongo


> rs.initiate()      # 启动一个新的副本集


> rs.add("233.76.45.12:27107")   # 加入从节点,该节点为 233.76.45.12 主机 27107 端口上的 mongod 服务


> rs.add("45.76.45.18:27107")    # 加入从节点,该节点为 45.76.45.18 主机 27107 端口上的 mongod 服务



此时一个副本系统已经完成,所有操作直接面向主节点,实际操作由整个副本集集群提供,默认是从主节点读取;


从副本集中删除节点如下:


 


> rs.remove("45.76.45.18:27107")  # 删除 45.76.45.18:27107 上的从节点



查看副本集信息


可以使用以下命令参看整个副本集的信息:


 


> rs.conf()      # 查看副本集的配置


> rs.status()    # 查看副本集状态


> rs.isMaster()  # 查看该主机节点是否为副本集主节点



设置从节点读写策略


在从节点可以设置该从节点的读写测策略:


 


> rs.getMongo().setReadPref(STRATEGY)


其中策略参数如下:


  • Primary                      - 从主节点读取;
  • secondary                 - 从从节点读取;
  • nearest                      - 从网络延迟最小的节点读取;
  • primaryPreferred       - 基本上从主节点读取,主节点不可用时,从从节点的读取;
  • secondaryPreferred  - 基本上从从节点读取,从节点不可用时,从主节点读取;








MongoDB 分片


在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求,当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量,此时就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据;




mongo 副本集 如何负载均衡 mongo副本集 分片_MongoDB_02




在以上这个典型的分片模型中,存在以下 3 种角色:


  • Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障;
  • Config Server:mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息;
  • Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用;




mongodb 分片系统创建示例


以下创建一个 mongodb 分片系统,使用 1 个 Router,1 个 Config Server,2 个 Shard,它们的端口情况如下:


 


Reouter: 23.23.23.23:27017


Config Server: 23.23.23.24:27017


Shard 1:23.23.23.25:27017


Shard 2:23.23.23.26:27017




1) 启动 Shard Server 


分别启动 shard server 1,shard server 2;


 


$ mongod --port 27017 --dbpath /var/run/mongodb/shard/ --fork


2)启动 Config Sevrer


 


$ mongod --port 27017  --dbpath /var/run/mongodb/shard/ --fork


3)启动 Router Server,并绑定 Config Server 和 Shard Server


 


$ mongod --port 27017 --fork --logpath=/var/run/mongo/route.log --configdb 23.23.23.24:27017 --chunkSize 500


※此处需要设置 configdb 参数,用于设置指想的 config server,chunkSize 用于设置 chunk 大小,单位为 MB,默认 200MB;


登陆到 Router mongodb,进行进一步设置


 


# 登陆到 router mongodb


$ mongo


> use admin



# 添加 shard 分片


> db.runCommand( {addShard("23.23.23.25:27017")} )


> db.runCommand( {addShard("23.23.23.26:27017")} )



# 开启分片,设置分片储存的数据库名称,以下为 testdb


> db.runCommand( {enablesharding:"testdb"} )



# 设置集合的分片形式,以下对 testdb.students 集合使用 hash 模式分片,对 testdb.address 使用 range 模式分片


> db.runCommand( {shardCollection:"testdb.students",key:{_id:"hashed"}} )


> db.runCommand( {shardCollection:"testdb.address",key:{name:1}} )





之后程序在连接这个分片系统时候,只需要连接 Router Server (23.23.23.23:27017) 即可,分片过程对应用程序时透明的;