docker-compose创建mongodb分片集群

参考:
分布式NoSQL数据库MongoDB初体验-v5.0.5 - itxiaoshen - 博客园 (cnblogs.com)

MongoDB–副本集

MongoDB 数据库高级进阶 - 集群和安全

1、mongodb基础

1.1 mongodb特点?

  • 面向文档,具有动态ddl能力,更为灵活;
  • 完全的分布式、高可用、高性能,基于内存的数据查询;
  • 容易扩展,基于分片可以进行海量数据存储,实现自动分片和水平扩展;
  • API丰富,支持索引、管道聚合、地理空间数据、事务、join等;
  • 支持多种语言;

1.2 bson和json区别?

bson是一种二进制形式的存储格式,采用了相似于C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具备轻量性、可遍历性、高效性的特色,能够有效描述非结构化数据和结构化数据,有点相似于Google的Protocol Buffer。

  • 更快的遍历速度:对json格式来讲,太大的json结构会导致数据遍历变慢;在json中要跳过一个文档进行数据读取,须要对此文档进行扫描匹配比如括号的匹配,而bson将每个元素的长度存在元素的头部,这样就可快速读到指定位置。
  • 操做更简易:对json来讲数据存储是无类型的,比如你要修改值9为10这样就从一个字符变成了两个字符,也即是后面的内容都要后移一位因此增加开销。而使用bson可以指定这个列为数字类型,那么数字从9改为10甚至是10000,这样都只是在存储数字上修改,不会致使数据总长度变化。当时在MongoDB中若是数字从整形增大到长整型那仍是会致使数据总长度变大的。
  • 增加额外的数据类型:json是一个很方便的数据交换格式,可是其类型比较有限;bson在其基础上增长了“byte array”数据类型,这使得二进制的存储再也不需要先base64转换后再存成json,大大减小了计算开销和数据大小。下图为bson支持数据类型

1.3 和关系型数据库区别?

  • database-数据库,与关系型数据库(database)概念相同,一个数据库包含多个集合(表)。
  • collection-集合,相当于关系型数据库中的表(table),一个集合可以存放多个文档(行)。不同之处就在于集合的结构(schema)是动态的,不需要预先声明一个严格的表结构。更重要的是默认情况下MongoDB 并不会对写入的数据做任何schema的校验。
  • document-文档,相当于关系型数据库中的行(row),一个文档由多个字段(列)组成,并采用bson(json)格式表示。
  • field-字段,相当于关系型数据库中的列(column),相比普通column的差别在于field的类型可以更加灵活比如支持嵌套的文档、数组,区分大小写。
  • 其他说明
    • id-主键,MongoDB 默认生成id 字段来保证文档的唯一性。
    • reference-引用,勉强可以对应于外键(foreign key) 的概念,但reference 并没有实现任何外键约束,只是由客户端(driver)自动进行关联查询、转换的一个特殊类型。
    • view-视图,MongoDB 3.4 开始支持视图,这个和关系型数据库的视图没有什么差异,视图是基于集合之上进行动态查询的一层对象,可以是虚拟的,也可以是物理的(物化视图)。
    • index-索引,与关系型数据库的索引相同。
    • $lookup-聚合操作符,可以用于实现类似关系型数据库-join连接的功能。
    • transaction-事务,从 MongoDB 4.0 版本开始,提供了对于事务的支持。
    • aggregation-聚合,MongoDB 提供了强大的聚合计算框架,group by是其中的一类聚合操作。

1.4 什么是复制集?

复制集是一组拥有相同数据的mongodb节点,由两台及以上的mongodb实例组成的集群,包括primary主节点(读写能力)、secondary从节点(读能力)、投票节点3种角色。
复制集提供了数据冗余、备份能力,提高了数据的可用性,保证了数据的安全性。

1.5 复制集原理?

MongoDB副本集同步原理

primary主节点记录所有操作到oplog中,该文件存储在local数据库中。
全量同步:第一次加入或者secondary落后的数据超过了oplog的大小
复制:拉取和重放oplog采用不同线程完成

1.6 什么是分片?

将大量数据,对于mongodb来说就是大数据量的collection按照一定规则切分后存放到不同服务器上,通过更多的服务器提升对数据的处理能力。

1.7 为什么要分片?

  • 单机磁盘容量有限,无法存放更多数据;
  • 单机处理能力有限,无法有效处理更多请求;
  • 单机内存有限,导致较多请求从磁盘查询数据、效率低下;
  • 副本集具有数量限制

1.8 分片原理?

分片集群由3部分组成:

  • config server:配置服务器,存储所有的数据库元数据(分片、路由)信息;可以配置副本;
  • shard server:分片服务器,由一个或多个mongod进程组成,存储数据;可以配置副本;
  • router server:路由服务器,分片集群的入口,所有的请求都由router(mongos)路由到指定的shard服务器上;可以配置副本;

分片键(shard key):

  • 为了在多个shard server中分片,使用分片键进行分割数据,分片键必须是每个记录都包含的字段、且是建立了索引的单个或者多个字段。
  • 一旦集合设置了分片键,那么插入数据后,分片键和分片键的值都是不可改变的。如若修改,必须先删除文档,然后重新设置分片键,再插入数据。
  • 分片键不支持地理空间索引、全文索引、数组索引。

分片算法:

  • 基于范围:

    • 定义:基于范围的分片键是根据分片键值把数据分成一个个邻接的范围,如果没有指定特定的分片类型,则基于范围的分片键是默认的分片类型。

    • 特点:基于范围的分片键对于范围类型的查询比较高效,给定一个片键的范围,分发路由可以很简单地确定哪个数据块存储了请求需要的数据,并将请求转发到相应的分片中。

    • 使用场景:建议在分片键基数较大,频率较低,并且分片键值不是单调变化的情况下使用基于范围的分片键。

    • 操作:

      #基于范围的分片键设置,使用如下命令,开启数据库分片开关,参数database表示要开启分片集合的数据库
      sh.enableSharding(database)
      #设置分片键,参数namespace表示需要进行分片的目标集合的完整命名空间<database>.<collections>,key表示要设置分片键的索引,如果需要进行分片的目标集合是空集合,可以不创建索引直接进行下一步的分片设置,该操作会自动创建索引,如果需要进行分片的目标集合是非空集合,则需要先创建索引key。然后使用如下命令设置分片键。
      sh.shardCollection(namespace, key)
      
  • 基于hash:

    • 定义:基于哈希的分片键是指MongoDB数据库计算一个字段的哈希值,并用这个哈希值来创建数据块。

    • 特点:保证了集群中数据的均衡。哈希值的随机性使数据随机分布在每个数据块中,因此也随机分布在不同分片中。

    • 使用场景:如果分片键值的基数较大,拥有大量不一样的值,或者分片键值是单调变化的,则建议使用基于哈希的分片键。

    • 操作:

      然后再使用如下命令创建基于哈希的分片键#基于范围的分片键设置,使用如下命令,开启数据库分片开关,参数database表示要开启分片集合的数据库
      sh.enableSharding(database)
      #设置基于哈希的分片键,其中numInitialChunks值的估算方法是:db.collection.stats().size / 10*1024*1024*1024。
      sh.shardCollection("<database>.<collection>", { <shard key> : "hashed" }* , false, {numInitialChunks: 预置的chunk个数})
      #如果集合已经包含数据,则需要先使用如下命令对需要创建的基于哈希的分片键先创建哈希索引
      db.collection.createIndex()
      #然后再使用如下命令创建基于哈希的分片键
      sh.shardCollection()
      

1.9 限制

  • mongodb的bson数据嵌套不超过100层;
  • 32位系统只能寻址4GB内存,意味着数据集包含元数据和存储达到4GB,Mongodb就无法存储额外的数据了
  • 由于数据库名称在MongoDB中不区分大小写,因此数据库名称不能仅因字符的大小写而不同。
  • 命名
    • 数据库 名称也不能包含空字符。数据库名称不能为空,并且必须少于64个字符。
    • 集合 名称应以下划线或字母字符开头,并且不能包含$、不能包含空字符串、不能以system.前缀开头。集合名称空间的最大长度为120个字节,其中包括数据库名称,点(.)分隔符和集合名称(即.)
    • 字段 名称不能包含null字符,顶级字段名称不能以美元符号($)字符开头。
    • 在Mongodb3.0中 副本集 成员最最多支持50个,也就是说副本集做大支持50个节点,副本集每个节点数据支持32T,副本集每个实例建议数据不要超过4T,数据量大备份恢复时间会很长。
    • 我们通常 分片 会使用默认的chunk大小为64M,如果我们的分片key (片键)values值是512字节,分片节点支持最大32768个也就是最大支持数据量为32768TB。一个片键大小不能超过512字节。
    • 从MongoDB 3.6开始,服务器允许存储包含点(即.)和美元符号(即$)的字段名称

2、使用docker编排文件创建mongodb分片集群

mongo分片集群结构:
  • config
    • config0
    • config1
    • config2
  • shard
    • shard0
      • shard00
      • shard01
      • shard02
    • shard1
      • shard10
      • shard11
      • shard12
  • mongos
docker挂载文件结构(宿主机):

docker-compose.yaml
mongo
|-- config
|-- |-- config0
|-- |-- |-- data
|-- |-- |-- log
|-- |-- config1
|-- |-- |-- data
|-- |-- |-- log
|-- |-- config2
|-- |-- |-- data
|-- |-- |-- log
|-- |-- conf
|-- |-- |-- mongod.conf
|-- shard
|-- |-- conf0
|-- |-- |-- mongod.conf
|-- |-- conf1
|-- |-- |-- mongod.conf
|-- |-- shard00
|-- |-- |-- data
|-- |-- |-- log
|-- |-- shard01
|-- |-- |-- data
|-- |-- |-- log
|-- |-- shard02
|-- |-- |-- data
|-- |-- |-- log
|-- |-- shard10
|-- |-- |-- data
|-- |-- |-- log
|-- |-- shard11
|-- |-- |-- data
|-- |-- |-- log
|-- |-- shard12
|-- |-- |-- data
|-- |-- |-- log
|-- mongos
|-- |-- conf
|-- |-- |-- mongod.conf
|-- |-- data
|-- |-- log

2.1 生成keyFile

  • MongoDB使用keyfile认证,副本集中的每个mongod实例使用keyfile内容作为认证其他成员的共享密码。mongod实例只有拥有正确的keyfile才可以加入副本集。
  • keyFile的内容必须是6到1024个字符的长度,且副本集所有成员的keyFile内容必须相同。
  • 有一点要注意是的:在UNIX系统中,keyFile必须没有组权限或完全权限(也就是权限要设置成X00的形式)。Windows系统中,keyFile权限没有被检查。
  • 可以使用任意方法生成keyFile。例如,如下操作使用openssl生成复杂的随机的1024个字符串。然后使用chmod修改文件权限,只给文件拥有者提供读权限。
# 400权限是要保证安全性,否则mongod启动会报错
openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key

2.2 mongodb配置文件

配置服务器的配置文件(config/conf/mongod.conf)

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /data/db
  journal:
    enabled: true
  directoryPerDB: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 0.25
      directoryForIndexes: true

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

security:
  keyFile: /etc/key.key
  clusterAuthMode: "keyFile"
  authorization: enabled

# network interfaces
net:
  port: 27019
  bindIp: 0.0.0.0

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#replication:
replication:
   oplogSizeMB: 256
   replSetName: cfg

sharding:
  clusterRole: configsvr

分片服务器0的配置文件(shard/conf0/mongod.conf)

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  #mongod实例存储其数据的目录
  dbPath: /data/db
  journal:
    #启用或禁用持久性日志已确保数据文件保持有效和可恢复 
    enabled: true
  directoryPerDB: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 0.25
      directoryForIndexes: true

# where to write logging data.
systemLog:
  #日志输出的目标指定为文件
  destination: file
  #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  logAppend: true
  #日志存放目录
  path: /var/log/mongodb/mongod.log

security:
  keyFile: /etc/key.key
  clusterAuthMode: "keyFile"
  authorization: enabled

# network interfaces
net:
  port: 27018
  bindIp: 0.0.0.0

# how the process runs
processManagement:
  #启用在后台运行mongos或mongod进程的守护进程模式
  #fork: true
  #指定用于保存mongos或mongod进程的进程ID的文件位置
  #pidFilePath: "/data/replica_sets/myrs_27018/log/mongod.pid"
  timeZoneInfo: /usr/share/zoneinfo

#replication:
replication:
   oplogSizeMB: 256
   #副本集的名称
   replSetName: rs0

sharding:
  clusterRole: shardsvr

分片服务器1的配置文件(shard/conf1/mongod.conf)

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /data/db
  journal:
    enabled: true
  directoryPerDB: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 0.25
      directoryForIndexes: true

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

security:
  keyFile: /etc/key.key
  clusterAuthMode: "keyFile"
  authorization: enabled

# network interfaces
net:
  port: 27018
  bindIp: 0.0.0.0

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#replication:
replication:
   oplogSizeMB: 256
   replSetName: rs1

sharding:
  clusterRole: shardsvr

路由服务器的配置文件(mongs/conf/mongod.conf)

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/


# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

security:
  keyFile: /etc/key.key
  clusterAuthMode: "keyFile"

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

sharding:
  configDB: cfg/mongo-config0:27019,mongo-config1:27019,mongo-config1:27019

2.3 docker编排文件

创建docker-compose.yaml编排文件。
首先要定义网络,docker network create basenetwork --subnet=172.18.0.0/16
所有容器在同一网络,互连互通。

version: "3.9"  # optional since v1.27.0
services:
  # mongodb开始************************
  # https://www.cnblogs.com/ricklz/p/13237419.html
  # 
  # sharding--->
  # docker-compose部署单机版本分片mongo  https://cloud.tencent.com/developer/article/1717360
  # docker部暑mongodb_4.4.8 sharding集群(arm64和amd64),mongodb_consistent_backup备份与恢复  https://blog.csdn.net/u010533742/article/details/119754119
  # 分布式NoSQL数据库MongoDB初体验-v5.0.5 https://www.cnblogs.com/itxiaoshen/p/15728782.html 
  # https://docs.mongodb.com/manual/

###### 配置服务器,存储数据库的元数据(路由、分片)。副本配置。
  mongo-config0:
    image: mongo:latest
    privileged: true
    hostname: mongo-config0
    container_name: mongo-config0
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/config/config0/data:/data/db # 挂载数据目录
      - ./mongo/config/config0/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/config/conf:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.30

  mongo-config1:
    image: mongo:latest
    privileged: true
    hostname: mongo-config1
    container_name: mongo-config1
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/config/config1/data:/data/db # 挂载数据目录
      - ./mongo/config/config1/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/config/conf:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.31

  mongo-config2:
    image: mongo:latest
    privileged: true
    hostname: mongo-config2
    container_name: mongo-config2
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/config/config2/data:/data/db # 挂载数据目录
      - ./mongo/config/config2/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/config/conf:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.32


  mongo-shard0-0:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard0-0
    container_name: mongo-shard0-0
    # depends_on:
    #   - "mongo-shard0-1"
    #   - "mongo-shard0-2"
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard00/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard00/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf0:/etc/mongod
      # - ./mongo/shard/scripts:/scripts
      # - ./mogon/shard/initdb:/docker-entrypoint-initdb.d # 需要初始化的数据库脚本存放文件夹,容器启动后会自动执行。
    command: -f /etc/mongod/mongod.conf
    # entrypoint: [ "/scripts/setup.sh" ]
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.33

  mongo-shard0-1:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard0-1
    container_name: mongo-shard0-1
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard01/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard01/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf0:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.34

  mongo-shard0-2:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard0-2
    container_name: mongo-shard0-2
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard02/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard02/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf0:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.35




  mongo-shard1-0:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard1-0
    container_name: mongo-shard1-0
    # depends_on:
    #   - "mongo-shard1-1"
    #   - "mongo-shard1-2"
    # environment:
    #   - MONGO1=mongo-shard1-0
    #   - MONGO2=mongo-shard0-1
    #   - MONGO3=mongo-shard0-2
    #   - RS=rs1
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard10/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard10/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf1:/etc/mongod
      # - ./mogon/shard/initdb:/docker-entrypoint-initdb.d # 需要初始化的数据库脚本存放文件夹,容器启动后会自动执行。
      # - ./mongo/shard/scripts:/scripts
    command: -f /etc/mongod/mongod.conf
    # entrypoint: [ "/scripts/setup.sh" ]
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.36

  mongo-shard1-1:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard1-1
    container_name: mongo-shard1-1
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard11/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard11/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf1:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.37

  mongo-shard1-2:
    image: mongo:latest
    privileged: true
    hostname: mongo-shard1-2
    container_name: mongo-shard1-2
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/shard/shard12/data:/data/db # 挂载数据目录
      - ./mongo/shard/shard12/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/shard/conf1:/etc/mongod
    command: -f /etc/mongod/mongod.conf
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.38


  mongos:
    image: mongo:latest
    privileged: true
    hostname: mongos
    container_name: mongos
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - ./mongo/mongos/log:/var/log/mongodb
      - ./mongo/key.key:/etc/key.key
      - ./mongo/mongos/conf:/etc/mongod
    command: mongos -f /etc/mongod/mongod.conf
    ports:
      - "27017:27017"
    #定义IP网络
    networks:
      basenetwork:
        ipv4_address: 172.18.0.39

      
#定义网络。 docker network create basenetwork --subnet=172.18.0.0/16
networks:
  basenetwork:
    external: true


执行 docker-compose -f docker-compose.yaml up -d命令,根据编排文件创建容器。

2.4 初始化配置服务器、分片服务器

####初始化配置服务器副本集群
# 1、进入到任一config容器中
# 2、登录mongo
mongo --port 27019
# 3、初始config化副本集(https://www.cnblogs.com/ricklz/p/13237419.html)
rs.initiate({
     _id: "cfg",
     members: [
         { _id : 0, host : "mongo-config0:27019" },
         { _id : 1, host : "mongo-config1:27019" },
         { _id : 2, host : "mongo-config2:27019" }
     ]
});
####初始化两个分片服务器副本集群
# 1、进入到分片服务器集群0的任一容器中
# 2、登录mongo
mongo --port 27018
# 3、初始分片副本集(https://www.cnblogs.com/ricklz/p/13237419.html)
rs.initiate({
     _id: "rs0",
     members: [
        { _id : 0, host : "mongo-shard0-0:27018" },
        { _id : 1, host : "mongo-shard0-1:27018" },
        { _id : 2, host : "mongo-shard0-2:27018" }
     ]
});

# 1、进入到分片服务器集群1的任一容器中
# 2、登录mongo
mongo --port 27018
# 3、初始分片副本集(https://www.cnblogs.com/ricklz/p/13237419.html)
rs.initiate({
     _id: "rs1",
     members: [
         { _id : 0, host : "mongo-shard1-0:27018" },
         { _id : 1, host : "mongo-shard1-1:27018" },
         { _id : 2, host : "mongo-shard1-2:27018" }
    ]
});

2.5 添加用户、分片等操作

# 1、进入mongos容器并连接mongos。端口号与mongos配置文件中设定一致。
docker exec -i mongos mongo --port 27017 #可以执行docker exec -it mongos /bin/bash进入容器,再执行mongo连接mongo。因为使用了默认端口27017,所以登录mongo的时候可以不设置端口号。

# 2、创建用户,
use admin
db.createUser(
  {
    user: "root",
    pwd: "123456",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" , {role: 'root', db: 'admin'}]
  }
);
# 验证用户。不验证的话无法执行mongo命令。
db.auth('root','123456')


# 3、将分片加入到集群。
sh.addShard("rs0/mongo-shard0-1:27018,mongo-shard0-2:27018,mongo-shard0-3:27018");
sh.addShard("rs1/mongo-shard1-1:27018,mongo-shard1-2:27018,mongo-shard1-3:27018");
# 查看分片状态。
sh.status();

# 4、创建库并设置分片
# 切换数据库(会自动创建库)
use springboot
# 创建该库的操作用户
db.createUser(
   {
     user: "admin",
     pwd: "123456",
     roles: [ { role: "dbOwner", db: "springboot" } ]
   }
);
db.auth('admin','123456')
#指定要分片的数据库
sh.enableSharding("springboot")
#指定集合的分片规则
#这里表示指定springboot库下的user集合的_id字段(也就是主键,每个集合都有这个字段)按hash散列进行分片,{ id : 1 }表示按字段id进度范围分片,这里id必须是整型
#要分片存储的集合都需要指定分片规则,分片规则一经创建不可修改,只能删除集合再重新设置
sh.shardCollection("springboot.user", { _id : "hashed" } )
#查询user的集合状态
db.user.stats()

# 5、测试分片效果。
use springboot
# 尝试写入数据,并观察数据分块
# 插入5百万个简单的文档,耐心等待插入结束
for(var i=1;i<=1000;i++){
    db.user.insert({
        name:i,
        age:Math.round(Math.random() * 100),
        score1:Math.round(Math.random() * 100),
        score2:Math.round(Math.random() * 100),
        score3:Math.round(Math.random() * 100),
        score4:Math.round(Math.random() * 100),
        score5:Math.round(Math.random() * 100)
    });
}
#查询user的集合状态
db.user.stats()

2.6 其他命令参考

###################################  注意 #################################################
# 在分片的主节点也可以同样步骤创建用户并验证,然后可以执行其他命令。
# 之后,可以在分片副本上用上一步创建的用户并验证,但是show dbs 会出现错误uncaught exception: Error: listDatabases failed:
## 当前从节点只是一个备份,不是奴隶节点,无法读取数据,写当然更不行。因为默认情况下,从节点是没有读写权限的,可以增加(删除)读的权限,rs.secondaryOk()/rs.secondaryOk(false)。
# 仲裁节点不会放任何业务数据,可以登陆查看.仲裁节点不能进行数据的查看。


#### https://www.cnblogs.com/cy0628/p/15175428.html
# 查看副本集的配置:返回包含当前副本集配置的文档。rs.conf()/rs.config()是该方法的别名。
# 查看副本集的状态:返回包含状态信息的文档,次输出结果从副本集的其他成员发送的心跳包中获得的数据反映副本集的当前状态。rs.status()
# 添加副本从节点:在主节点添加从节点,将其他成员加入到副本集。rs.add(host, arbiterOnly)
# 查看全局所有账户:db.system.users.find().pretty()
# 查看当前库下的账户:use test; show users;



#数据库 命令
db.serverStatus().connections; //连接数查看
show collections  //查看表信息
db.test_shard.find().count() //查看table1数据长度
db.test_shard.remove({}) //删除数据表
db.stats()   //查看所有的分片服务器状态
db.adminCommand( { listShards: 1 } ) //分片列表
db.test_shard.find({ age: 36 }).explain()   //精确查询
db.test_shard.find({ age: { $gte : 36 ,$lt : 73 } }).explain() //范围查询

#分片 操作命令
sh.enableSharding('testdb')                //开启数据库testdb分片
sh.shardCollection('testdb.users',{uid:1})    //按testdb.users的uid字段分片
sh.shardCollection("testdb.test_shard",{"age": 1})     //按ranged分片
sh.shardCollection("testdb.test_shard2",{"age": "hashed"}) //按hash分片
sh.status()   //查看分片节点
sh.addShard() //向集群中添加一个 shard
sh.getBalancerState()   //查看平衡器
sh.disableBalancing()   //禁用平衡器
sh.enableBalancing()    //启用平衡器
db.runCommand( { removeShard: "mongodb0" } ) //删除分片mongodb0,迁移数据查看命令
db.runCommand( { movePrimary: "test", to: "mongodb1" })   //将数据库test未分片mongodb0的数据,迁移到mongodb1主分片。
db.adminCommand("flushRouterConfig") //处理分片后,刷新路由数据。

use config 
db.databases.find()  //查看所有数据库使用分片
db.settings.save({_id:"chunksize",value:1}) //将 chunk 的大小调整为 1MB
db.serverStatus().sharding


#副本集 操作命令
rs.status()   //查看成员的运行状态等信息
rs.config()    //查看配置信息
rs.slaveOk()  //允许在SECONDARY节点上进行查询操作,默认从节点不具有查询功能
rs.isMaster()  //查询该节点是否是主节点
rs.add({})   //添加新的节点到该副本集中
rs.remove()   //从副本集中删除节点
rs.stepDown //降级节点
db.printSlaveReplicationInfo()  //查看同步情况
rs.addArb("172.20.0.16:27038") //添加仲裁节点

#强制加入仲裁节点:
config=rs.conf()
config.members=[config.members[0],config.members[1],{_id:5,host:"127.0.0.1:27023",priority:5,arbiterOnly:"true"}]
rs.reconfig(config,{force:true})

#强制主节点:
cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 0.5
cfg.members[2].priority = 1
rs.reconfig(cfg)

#备份/恢复
mongodump -h 127.0.0.1:27017 -d test -o /data/backup/
mongorestore -h 127.0.0.1:27017 -d test --dir /data/db/test
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐