MongoDB从入门到实战(十四):分片集群(水平扩展)

x33g5p2x  于2021-12-25 转载在 Go  
字(19.2k)|赞(0)|评价(0)|浏览(621)

一:分片简介

分片(sharding)是一种跨多台机器分布数据的方法, MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。换句话说:分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以储存更多的数据,处理更多的负载。

有两种解决系统增长的方法:垂直扩展和水平扩展

  • 垂直扩展意味着增加单个服务器的容量,例如使用更强大的CPU,添加更多RAM或增加存储空间量。可用技术的局限性可能会限制单个机器对于给定工作负载而言足够强大。此外,基于云的提供商基于可用的硬件配置具有硬性上限。结果,垂直缩放有实际的最大值。
  • 水平扩展意味着划分系统数据集并加载多个服务器,添加其他服务器以根据需要增加容量。虽然单个机器的总体速度或容量可能不高,但每台机器处理整个工作负载的子集,可能提供比单个高速大容量服务器更高的效率。扩展部署容量只需要根据需要添加额外的服务器,这可能比单个机器的高端硬件的总体成本更低。权衡是基础架构和部署维护的复杂性增加。MongoDB支持通过分片进行水平扩展。

二:MongoDB分片群集组件

  • 分片(存储):每个分片包含分片数据的子集。 每个分片都可以部署为副本集。
  • mongos(路由):mongos充当查询路由器,在客户端应用程序和分片集群之间提供接口。
  • config servers(“调度”的配置):配置服务器存储群集的元数据和配置设置。 从MongoDB 3.4开
    始,必须将配置服务器部署为副本集(CSRS)。

三:单机分片搭建

  • 2套分片节点副本集,每套3个mongod服务。
  • 1套配置节点副本集。
  • 2个路由节点。

将mongod-4.4.5 复制多份并重命名。注意:每个mongod-4.4.5下面都要创建config、log和data/db目录。

3.1 Primary1 副本集搭建

3.1.1 为每个Primary1配置配置文件

mongodb-primary1-27018/config/mongod.conf

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary1-27018/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: "/Users/mengday/Mongo/mongodb-primary1-27018/data/db"
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary1-27018/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27018
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs01
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr

mongodb-primary1-27118/config/mongod.conf

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary1-27118/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: "/Users/mengday/Mongo/mongodb-primary1-27118/data/db"
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary1-27118/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27118
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs01
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr

mongodb-primary1-27218/config/mongod.conf

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary1-27218/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: "/Users/mengday/Mongo/mongodb-primary1-27218/data/db"
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary1-27218/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27218
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs01
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr

3.1.2 启动第一套副本集:一主一副本一仲裁

  1. cd Mongo/mongodb-primary1-27018
  2. ./bin/mongod -f ./config/mongod.conf
  3. cd Mongo/mongodb-primary1-27118
  4. ./bin/mongod -f ./config/mongod.conf
  5. cd Mongo/mongodb-primary1-27218
  6. ./bin/mongod -f ./config/mongod.conf
  7. # 查看是否启动成功
  8. ps -ef |grep mongod

3.1.3 初始化Primary1副本集

  1. mongodb-primary1-27018 ./bin/mongo --host 127.0.0.1 --port 27018
  2. // 初始化副本集
  3. > rs.initiate()
  4. > rs.status()
  5. // 主节点配置查看
  6. > myshardrs01:PRIMARY> rs.conf()
  7. // 添加副本节点
  8. > myshardrs01:PRIMARY> rs.add("127.0.0.1:27118")
  9. // 添加仲裁节点
  10. > myshardrs01:PRIMARY> rs.addArb("127.0.0.1:27218")
  11. // 查看副本集的配置情况
  12. myshardrs01:PRIMARY> rs.conf()

3.2 Primary2 副本集搭建

3.2.1 为每个Primary2配置配置文件

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary2-27318/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-primary2-27318/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary2-27318/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27318
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs02
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr
  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary2-27418/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-primary2-27418/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary2-27418/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27418
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs02
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr
  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-primary2-27518/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-primary2-27518/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-primary2-27518/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27518
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myshardrs02
  30. sharding:
  31. #分片角色
  32. clusterRole: shardsvr

3.2.2 启动第二套副本集:一主一副本一仲裁

  1. cd ~/Mongo/mongodb-primary2-27318
  2. ./bin/mongod -f ./config/mongod.conf
  3. cd ~/Mongo/mongodb-primary2-27418
  4. ./bin/mongod -f ./config/mongod.conf
  5. cd ~/Mongo/mongodb-primary2-27518
  6. ./bin/mongod -f ./config/mongod.conf
  7. ps -ef | grep mongod

3.2.3 初始化Primary2副本集

  1. mongodb-primary2-27318 ./bin/mongo --host 127.0.0.1 --port 27318
  2. > rs.initiate()
  3. > myshardrs02:SECONDARY> rs.status()
  4. > myshardrs02:PRIMARY> rs.conf()
  5. > myshardrs02:PRIMARY> rs.add("127.0.0.1:27418")
  6. > myshardrs02:PRIMARY> rs.addArb("127.0.0.1:27518")
  7. > myshardrs02:PRIMARY> rs.conf()
  8. > myshardrs02:PRIMARY> rs.status()

3.3 配置节点搭建

3.3.1 为每个配置节点配置配置文件

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-configserver-27019/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-configserver-27019/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-configserver-27019/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27019
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myconfigrs
  30. sharding:
  31. #分片角色
  32. clusterRole: configsvr
  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-configserver-27119/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-configserver-27119/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-configserver-27119/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27119
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myconfigrs
  30. sharding:
  31. #分片角色
  32. clusterRole: configsvr
  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-configserver-27219/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: /Users/mengday/Mongo/mongodb-configserver-27219/data/db
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Mongo/mongodb-configserver-27219/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27219
  25. setParameter:
  26. enableLocalhostAuthBypass: false
  27. replication:
  28. #副本集的名称
  29. replSetName: myconfigrs
  30. sharding:
  31. #分片角色
  32. clusterRole: configsvr

3.3.2 启动配置节点副本集:一主一副本一仲裁

  1. cd ~/Mongo/mongodb-configserver-27019
  2. ./bin/mongod -f ./config/mongod.conf
  3. cd ~/Mongo/mongodb-configserver-27119
  4. ./bin/mongod -f ./config/mongod.conf
  5. cd ~/Mongo/mongodb-configserver-27219
  6. ./bin/mongod -f ./config/mongod.conf
  7. ps -ef | grep mongod

3.3.3 初始化配置节点副本集

  1. cd Mongo/mongodb-configserver-27019
  2. ./bin/mongo --host 127.0.0.1 --port 27019
  3. > rs.initiate()
  4. > myconfigrs:SECONDARY> rs.status()
  5. > myconfigrs:PRIMARY> rs.conf()
  6. // 添加两个副本节点
  7. > myconfigrs:PRIMARY> rs.add("127.0.0.1:27119")
  8. > rs.add("127.0.0.1:27219")
  9. > myconfigrs:PRIMARY> rs.conf()
  10. > myconfigrs:PRIMARY> rs.status()

3.4 路由节点的创建和操作

3.4.1 配置路由节点配置文件

mongodb-mongos-27017/config/mongos.conf

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-mongos-27017/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. processManagement:
  9. #启用在后台运行mongos或mongod进程的守护进程模式。
  10. fork: true
  11. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  12. pidFilePath: "/Users/mengday/Mongo/mongodb-mongos-27017/log/mongod.pid"
  13. net:
  14. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  15. #bindIp: 127.0.0.1
  16. #绑定的端口,默认是27017
  17. port: 27017
  18. setParameter:
  19. enableLocalhostAuthBypass: false
  20. sharding:
  21. #指定配置节点副本集
  22. configDB: myconfigrs/127.0.0.1:27019,127.0.0.1:27119,127.0.0.1:27219

3.4.2 启动路由节点客户端

  1. cd Mongo/mongodb-mongos-27017
  2. # 启动mongos
  3. ./bin/mongos -f ./config/mongos.conf

3.4.3 为路由添加分片

  1. // 连接
  2. ./bin/mongo --host 127.0.0.1 --port 27017
  3. // 将第一套副本集加入进来
  4. mongos>sh.addShard("myshardrs01/127.0.0.1:27118,127.0.0.1:27218")
  5. // 将第二套副本集加入进来
  6. mongos> sh.addShard("myshardrs02/127.0.0.1:27418,127.0.0.1:27518")
  7. mongos> sh.status()
  8. --- Sharding Status ---
  9. sharding version: {
  10. "_id" : 1,
  11. "minCompatibleVersion" : 5,
  12. "currentVersion" : 6,
  13. "clusterId" : ObjectId("60781f0e70d3d8115984e85a")
  14. }
  15. shards:
  16. { "_id" : "myshardrs01", "host" : "myshardrs01/127.0.0.1:27118,localhost:27018", "state" : 1 }
  17. { "_id" : "myshardrs02", "host" : "myshardrs02/127.0.0.1:27418,localhost:27318", "state" : 1 }
  18. active mongoses:
  19. "4.4.5" : 1
  20. autosplit:
  21. Currently enabled: yes
  22. balancer:
  23. Currently enabled: yes
  24. Currently running: no
  25. Failed balancer rounds in last 5 attempts: 0
  26. Migration Results for the last 24 hours:
  27. 30 : Success
  28. databases:
  29. { "_id" : "config", "primary" : "config", "partitioned" : true }
  30. config.system.sessions
  31. shard key: { "_id" : 1 }
  32. unique: false
  33. balancing: true
  34. chunks:
  35. myshardrs01 994
  36. myshardrs02 30
  37. too many chunks to print, use verbose if you want to force print

3.4.5 为数据库开启分片

  1. // 开启数据库分片
  2. mongos> sh.enableSharding("articledb")
  3. mongos> sh.status()
  4. --- Sharding Status ---
  5. sharding version: {
  6. "_id" : 1,
  7. "minCompatibleVersion" : 5,
  8. "currentVersion" : 6,
  9. "clusterId" : ObjectId("60781f0e70d3d8115984e85a")
  10. }
  11. shards:
  12. { "_id" : "myshardrs01", "host" : "myshardrs01/127.0.0.1:27118,localhost:27018", "state" : 1 }
  13. { "_id" : "myshardrs02", "host" : "myshardrs02/127.0.0.1:27418,localhost:27318", "state" : 1 }
  14. active mongoses:
  15. "4.4.5" : 1
  16. autosplit:
  17. Currently enabled: yes
  18. balancer:
  19. Currently enabled: yes
  20. Currently running: no
  21. Failed balancer rounds in last 5 attempts: 0
  22. Migration Results for the last 24 hours:
  23. 166 : Success
  24. databases:
  25. { "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("f2e6b495-cf22-4ce9-b6ad-52ed1ebd78e3"), "lastMod" : 1 } }
  26. { "_id" : "config", "primary" : "config", "partitioned" : true }
  27. config.system.sessions
  28. shard key: { "_id" : 1 }
  29. unique: false
  30. balancing: true
  31. chunks:
  32. myshardrs01 858
  33. myshardrs02 166
  34. too many chunks to print, use verbose if you want to force print

3.4.6 集合分片

对集合分片,你必须使用 sh.shardCollection() 方法指定集合和分片键。sh.shardCollection(namespace, key, unique)

对集合进行分片时,你需要选择一个 片键(Shard Key) , shard key 是每条记录都必须包含的,且建立了
索引的单个字段或复合字段,MongoDB按照片键将数据划分到不同的 数据块 中,并将 数据块 均衡地分布
到所有分片中.为了按照片键划分数据块,MongoDB使用 基于哈希的分片方式(随机平均分配)或者基
于范围的分片方式(数值大小分配) 。
用什么字段当片键都可以,如:nickname作为片键,但一定是必填字段。

分片规则一:哈希策略

对于 基于哈希的分片 ,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块.
在使用基于哈希分片的系统中,拥有”相近”片键的文档 很可能不会 存储在同一个数据块中,因此数据的分
离性更好一些.使用nickname作为片键,根据其值的哈希值进行数据分片

  1. mongos> sh.shardCollection("articledb.comment",{"nickname":"hashed"})
  2. mongos> sh.status()
  3. --- Sharding Status ---
  4. sharding version: {
  5. "_id" : 1,
  6. "minCompatibleVersion" : 5,
  7. "currentVersion" : 6,
  8. "clusterId" : ObjectId("60781f0e70d3d8115984e85a")
  9. }
  10. shards:
  11. { "_id" : "myshardrs01", "host" : "myshardrs01/127.0.0.1:27118,localhost:27018", "state" : 1 }
  12. { "_id" : "myshardrs02", "host" : "myshardrs02/127.0.0.1:27418,localhost:27318", "state" : 1 }
  13. active mongoses:
  14. "4.4.5" : 1
  15. autosplit:
  16. Currently enabled: yes
  17. balancer:
  18. Currently enabled: yes
  19. Currently running: yes
  20. Collections with active migrations:
  21. config.system.sessions started at Thu Apr 15 2021 19:52:25 GMT+0800 (CST)
  22. Failed balancer rounds in last 5 attempts: 0
  23. Migration Results for the last 24 hours:
  24. 325 : Success
  25. databases:
  26. { "_id" : "articledb", "primary" : "myshardrs02", "partitioned" : true, "version" : { "uuid" : UUID("f2e6b495-cf22-4ce9-b6ad-52ed1ebd78e3"), "lastMod" : 1 } }
  27. articledb.comment
  28. shard key: { "nickname" : "hashed" }
  29. unique: false
  30. balancing: true
  31. chunks:
  32. myshardrs01 2
  33. myshardrs02 2
  34. { "nickname" : { "$minKey" : 1 } } -->> { "nickname" : NumberLong("-4611686018427387902") } on : myshardrs01 Timestamp(1, 0)
  35. { "nickname" : NumberLong("-4611686018427387902") } -->> { "nickname" : NumberLong(0) } on : myshardrs01 Timestamp(1, 1)
  36. { "nickname" : NumberLong(0) } -->> { "nickname" : NumberLong("4611686018427387902") } on : myshardrs02 Timestamp(1, 2)
  37. { "nickname" : NumberLong("4611686018427387902") } -->> { "nickname" : { "$maxKey" : 1 } } on : myshardrs02 Timestamp(1, 3)
  38. { "_id" : "config", "primary" : "config", "partitioned" : true }
  39. config.system.sessions
  40. shard key: { "_id" : 1 }
  41. unique: false
  42. balancing: true
  43. chunks:
  44. myshardrs01 699
  45. myshardrs02 325
  46. too many chunks to print, use verbose if you want to force print
  47. mongos>
分片规则二:范围策略

对于 基于范围的分片 ,MongoDB按照片键的范围把数据分成不同部分.假设有一个数字的片键:想象一个
从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点.MongoDB把这条直线划分为更短的不
重叠的片段,并称之为 数据块 ,每个数据块包含了片键在一定范围内的数据.
在使用片键做范围划分的系统中,拥有”相近”片键的文档很可能存储在同一个数据块中,因此也会存储在同
一个分片中.如使用作者年龄字段作为片键,按照点赞数的值进行分片:

  1. mongos> sh.shardCollection("articledb.author",{"age":1})

注意的是:
1)一个集合只能指定一个片键,否则报错。
2)一旦对一个集合分片,分片键和分片值就不可改变。 如:不能给集合选择不同的分片键、不能更新
分片键的值。
3)根据age索引进行分配数据。

基于范围的分片方式与基于哈希的分片方式性能对比:
基于范围的分片方式提供了更高效的范围查询,给定一个片键的范围,分发路由可以很简单地确定哪个数
据块存储了请求需要的数据,并将请求转发到相应的分片中.
不过,基于范围的分片会导致数据在不同分片上的不均衡,有时候,带来的消极作用会大于查询性能的积极
作用.比如,如果片键所在的字段是线性增长的,一定时间内的所有请求都会落到某个固定的数据块中,最终
导致分布在同一个分片中.在这种情况下,一小部分分片承载了集群大部分的数据,系统并不能很好地进行
扩展.
与此相比,基于哈希的分片方式以范围查询性能的损失为代价,保证了集群中数据的均衡.哈希值的随机性
使数据随机分布在每个数据块中,因此也随机分布在不同分片中.但是也正由于随机性,一个范围查询很难
确定应该请求哪些分片,通常为了返回需要的结果,需要请求所有分片.
如无特殊情况,一般推荐使用 Hash Sharding。
而使用 _id 作为片键是一个不错的选择,因为它是必有的,你可以使用数据文档 _id 的哈希作为片键。
这个方案能够是的读和写都能够平均分布,并且它能够保证每个文档都有不同的片键所以数据块能够很
精细。
似乎还是不够完美,因为这样的话对多个文档的查询必将命中所有的分片。虽说如此,这也是一种比较
好的方案了。理想化的 shard key 可以让 documents 均匀地在集群中分布:

  1. // 显示集群的详细信息:
  2. mongos> db.printShardingStatus()
  3. // 查看均衡器是否工作(需要重新均衡时系统才会自动启动,不用管它):
  4. mongos> sh.isBalancerRunning()
  5. false
  6. // 查看当前Balancer状态
  7. mongos> sh.getBalancerState()
  8. true

3.5 分片后插入数据测试

3.5.1 测试一

  1. mongos> use articledb
  2. // 注意:从路由上插入的数据,必须包含片键,否则无法插入。
  3. mongos> for(var i=1;i<=1000;i++) {db.comment.insert({_id:i+"",nickname:"BoBo"+i})}
  4. WriteResult({ "nInserted" : 1 })

分别登陆两个片的主节点,统计文档数量

3.5.2 测试二

  1. mongos> for(var i=1;i<=20000;i++) {db.author.save({"name":"monday"+i, "age":NumberInt(i%120)})}
  2. mongos> db.author.count()
  3. 20000

如果查看状态发现没有分片,则可能是由于以下原因造成了:

  • 系统繁忙,正在分片中。
  • 数据块(chunk)没有填满,默认的数据块尺寸(chunksize)是64M,填满后才会考虑向其他片的数据块填充数据,因此,为了测试,可以将其改小,这里改为1M,操作如下:
  1. use config
  2. db.settings.save( { _id:"chunksize", value: 1 } )

测试完改回来:

  1. db.settings.save( { _id:"chunksize", value: 64 } )

注意:要先改小,再设置分片。为了测试,可以先删除集合,重新建立集合的分片策略,再插入数据测试即可。

3.6 增加第二个路由节点

3.6.1 为第二个路由配置配置文件

mongodb-mongos-27117/config/mongos.conf

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Mongo/mongodb-mongos-27117/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. processManagement:
  9. #启用在后台运行mongos或mongod进程的守护进程模式。
  10. fork: true
  11. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  12. pidFilePath: "/Users/mengday/Mongo/mongodb-mongos-27117/log/mongod.pid"
  13. net:
  14. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  15. #bindIp: 127.0.0.1
  16. #绑定的端口,默认是27017
  17. port: 27117
  18. setParameter:
  19. enableLocalhostAuthBypass: false
  20. sharding:
  21. #指定配置节点副本集
  22. configDB: myconfigrs/127.0.0.1:27019,127.0.0.1:27119,127.0.0.1:27219

3.6.2 启动路由节点客户端

  1. cd Mongo/mongodb-mongos-27117
  2. ./bin/mongos -f ./config/mongos.conf
  3. # 使用mongo客户端登录27117,发现,第二个路由无需配置,因为分片配置都保存到了配置服务器中
  4. 了。
  5. ./bin/mongo --host 127.0.0.1 --port 27117
  6. mongos> sh.status()

3.7 Compass连接分片集群

3.8 SpringDataMongDB连接分片集群

  1. spring: #数据源配置
  2. data:
  3. mongodb: #连接路由字符串
  4. uri: mongodb://127.0.0.1:27017,127.0.0.1:27117/articledb

相关文章