【MongoDB】副本集 & 分片集群

MongoDB 副本集 & 分片集群

1. 副本集 – Replica Sets

1.1 简介

MongoDB 中的副本集(Replica Sets)是一组维护相同数据集的MongoDB服务。副本集可提供冗余和高可用性,是所有生产部署的基础。

也可以说,副本集类似于有自动故障恢复功能的主从集群 。通俗的讲就是用 多台机器进行同一数据的异步同步,从而使多台及其拥有同一数据的多个副本,并且当主库宕掉时在不需要用户干预的情况下自动切换其他服务器做主库。而且还可以利用副本服务器做只读服务器,实现读写分离,提高负载。

(1)冗余和数据可用性

复制提供冗余并提高数据可用性。通过在不同数据库服务器上提供多个数据副本,复制可提供一定级别的容错功能,以防止丢失单个数据库服务器。

(2)MongoDB中的复制

副本集是一组维护相同数据集的MongoDB实例。副本集包含多个数据承载节点和可选的一个仲裁节点。在承载数据的节点中,一个且仅一个成员被视为主节点,而且他节点被视为次要(从)节点。

主节点接受所有读写操作。副本集只能由一个主要能够具有{w: “most”}写入关注的写入;虽然在某些 情况下,另一个MongoDB实例可能暂时认为自己也是主要的。主要记录其操作日志中的数据集的所有更改,即oplog。
《【MongoDB】副本集 & 分片集群》

辅助(副本)节点复制主节点的oplog并将操作应用于其数据集,以便辅助节点的数据集反映主节点的数据集。如果主要人员不在,则在符合条件中举行选举选出新的主要人员。

(3)主从复制和副本集区别

主从集群和副本集最大的区别就是副本集没有固定的“主节点”;整个集群会选出一个“主节点”,当其宕掉后,又在剩下的从节点中选中其他节点为“主节点”,副本集总有一个活跃点(主、primary)和一个或多个备份节点(从、secondary)。

1.2 副本集的三个角色

副本集有两种类类型三种角色

两种类型:

  • 主节点(Primary)类型:数据操作的主要连接点,可读写。
  • 次要(辅助 、从)节点(Secondaries)类型:数据冗余备份节点,可以读/选举。

三种角色:

  • 主要成员(Primary):主要接收所有写操作。就是主节点。

  • 副本成员(Replicate):从节点通过复制操作以维护相同的数据集,即备份数据,不可泄操作,但可以读操作(需要配置)。是默认的一种从节点类型。

  • 仲裁者(Arbiter):不保留任何数据的副本,只具有投票选举作用。当然也可以将仲裁服务器维护作为副本集的一部分,即副本成员同也可以是仲裁者。也是一种从节点类型。

1.3 副本集架构目标

一主一副本一仲裁

《【MongoDB】副本集 & 分片集群》

1.4 副本集的创建

1.4.1 第一步:创建主节点

建立存放数据和日志的目录

#---------myrs
#主节点
mkdir -p /mongodb/replica_sets/myrs_27017/log \ &
mkdir -p /mongodb/replica_sets/myrs_27017/data/db

新建/修改配置文件

vim /mongo/replica_sets/myrs_27017/mongod.conf

myrs_27017:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/replica_sets/myrs_27017/log/mongod.log"
	logAppend: true
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
storage: 
	dbPath: "/mongodb/replica_sets/myrs_27017/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27017
relication: 
	#副本集的名称
	replSetName: myrs

启动节点服务:

[root@localhost replica_sets]# /usr/local/mongodb/bin.mongo -f /mongod/replica_sets/myrs_27017/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 54257
child process started sucessfully, parent exiting

1.4.2 第二步:创建副本节点

建立存放数据和日志的目录

#---------myrs
#副本节点
mkdir -p /mongodb/replica_sets/myrs_27018/log \ &
mkdir -p /mongodb/replica_sets/myrs_27018/data/db

新建/修改配置文件:

vim /mongo/replica_sets/myrs_27018/mongod.conf

myrs_27018

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/replica_sets/myrs_27018/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/replica_sets/myrs_27018/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/replica_sets/myrs_27018/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27018
relication: 
	#副本集的名称
	replSetName: myrs

启动节点服务:

[root@localhost replica_sets]# /usr/local/mongodb/bin.mongo -f /mongod/replica_sets/myrs_27018/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 54361
child process started sucessfully, parent exiting

1.4.3 第三步:创建副本节点

建立存放数据和日志的目录

#---------myrs
#仲裁节点
mkdir -p /mongodb/replica_sets/myrs_27019/log \ &
mkdir -p /mongodb/replica_sets/myrs_27019/data/db

新建/修改配置文件:

vim /mongo/replica_sets/myrs_27019/mongod.conf

myrs_27019

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/replica_sets/myrs_27018/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/replica_sets/myrs_27019/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/replica_sets/myrs_27019/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27019
relication: 
	#副本集的名称
	replSetName: myrs

启动节点服务:

[root@localhost replica_sets]# /usr/local/mongodb/bin/mongo -f /mongod/replica_sets/myrs_27019/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 54410
child process started sucessfully, parent exiting

1.4.4 第四步:初始化配置副本集和主节点

使用客户端命令连接任意一个节点,但这里尽量要连接主节点(27017节点):

/usr/local/mongdb/bin/mongo --host=[IP地址] --port=27017

结果,连接上后,发现很多命令无法使用,比如show dbs等,必须进行初始化副本集才行

准备初始化新的副本集

语法:

rs.initiate(configuration)

选项:

ParameterTypeDescription
configurationdocumentOptional. A document that specifies configuration for the new replica set. If a configuration is not specified, MongoDB uses a default replica set configuration.

【示例】

使用默认的配置来初始化副本集:

rs.initiate()

双击回车,成为主节点(一次回车→SECONDARY,两次回车→PRIMARY)

执行结果:

> rs.initiate()
{ 
    "info2" : "no configuration specified. Using a default configuration for the set",
    "me": "[ip地址]:27017",
    "ok" : 1,
    "operationTime" : Timestamp(1565760476, 1),
    "$clusterTime" : { 
        "clusterTime" : TimeStamp(1565760476, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
myrs:SECONDARY>
myrs:PRIMARY>

提示:

  1. “ok”的值为1,说明创建成功。
  2. 命令行提示符发生变化,变成了一个从节点角色,此时默认不能读写。稍等片刻,回车,变成主节点。

1.4.6 第五步:查看副本集的配置内容

说明:

返回包含当前副本集配置的文档。

语法:

rs.conf(configuration)

提示:
rs.config()是该方法的别名。

configuration:可选,如果没有配置,则使用默认主节点配置。

说明

  1. "_id : "myrs":副本集的配置数据存储的主键值,默认为副本集的名字
  2. "members":副本集成员数组,此时只有一个:"host" : "[ip地址]:port",该成员不是仲裁节点:"arbiterOnly" : false,优先级(权重值):"priority" : 1
  3. "settings":副本集的参数配置

提示:副本集配置的查看指令,本质是查询的是system.replset的表中的数据:

myrs:PRIMARY> use local
switched to db local
myrs:PRIMARY> show collections
oplog.rs
replset.election
replset.minvalid
replset.oplogTruncateAfterPoint
startup_log
system.replset

1.4.6 第六步:查看副本集状态

检查副本集状态。

说明:

返回包含状态信息的文档。此输出使用从副本集的其他成员发送的心跳包中获得的数据反映副本集的当前状态。

语法:

rs.status()

1.4.7 第七步:添加副本从节点

在主节点添加从节点,将其他成员加入副本集

语法:

rs.add(host, arbiterOnly)

选项:

ParameterTypeDescription
hoststring or document要添加到副本集的新成员。指定为字符串或配置文档:1)如果是一个字符串,则需要指定新成员的主机名和可选的端口号;2)如果是一个文档,请指定在members数组中找到的副本集成员配置文档。您必须在成员配置文档中指定主机字段。
arbiterOnlyboolean可选。仅在<host>值为字符串时适用。如果为true,则添加的主机时仲裁者。

主机成员的配置文档:

{ 
    _id:<int>,
    host:<string>,	//required
    arbiterOnly: <boolean>,
    buildIndexes: <boolean>,
    hidden: <boolean>,
    priority: <number>,
    tags: <document>,
    slaveDelay: <int>,
    votes: <number>
}

【示例】

将27018的副本节点添加到副本集中:

myrs:PRIMARY> rs.add("[ip地址]:27018")
{ 
	"ok" : 1,
    "operationTime" : Timestamp(1565761757, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp((1565761757, 1),
        "signature" : { 
       	 	"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NuberLong(0)
        }
    }
}

说明:

  • "ok" : 1:说明添加成功

1.4.8 第八步:添加仲裁从节点

添加一个仲裁节点到副本集

语法:

rs.addArb(host)

将27019的仲裁节点添加到副本集中:

myrs:PRIMARY> rs.add("[ip地址]:27019")
{ 
	"ok" : 1,
    "operationTime" : Timestamp(1565761757, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp((1565761757, 1),
        "signature" : { 
       	 	"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NuberLong(0)
        }
    }
}

说明:

  • "ok" : 1:说明添加成功

1.5 副本集的数据读写操作

目标:测试三个不同角色的节点的数据读写情况。

登录主节点27017,写入和读取数据:

[root@localhost ~]# /usr/lcoalhost/mongodb/bin/mongo --host=[ip地址] --port=27017

myrs:PRIMARY> use articledb
switched to db articledb
myrs:PRIMARY> db
articledb
myrs:PRIMARY> db.comment.insert({ "articleid":"10001","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime":new Date()})
writeResult({ "nInserted" : 1})
myrs:PRIMARY> db.comment.find()
{ "_id" : ObjectId("5d4d2ae3068138b4570f53bf"),"articleid":"10001","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime": ISODate("2019-08-09T08:12:19.427z")}

登录节点27018

[root@localhost ~]# /usr/lcoalhost/mongodb/bin/mongo --host=[ip地址] --port=27018

myrs:SECONDARY> show dbs;
2019-09-10T10:56L51.953+0800 E QUERY	[js] Error: listDatabases failed: { 
    "operationTime" : Timestamp(1568084204, 1),
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 12345,
    "codeName" : "NotMasterNoSlaveOk",
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1568084204, 1),
        "signature" : { 
            "hash" : BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:139:1
shellHelper.show@src/mongo/utils.js:882:13
shellHelper@src/mongo/utils.js:776:15
@(shellhelp2):1:1

发现,不能读取集合的数据。当前从节点只是一个备份,不是隶属节点,无法读取数据,写更不行。

因为默认情况下,从节点是没有读写权限的,可以增加读的权限,但需要进行设置。

设置读操作权限:

说明:

设置为隶属节点,允许在从成员上运行读的操作

语法:

rs.slaveOk()
#或
rs.slaveOk(true)

提示:

该命令是db.getMongo().setSlaveOk()的简化命令。

现在实现了读写分离,让主插入数据,让从来读取数据。

如果要取消作为隶属节点的读权限:

rs.slaveOk(false)

仲裁者节点,不存放任何业务数据,可以登陆查看

[root@localhost ~]# /usr/lcoalhost/mongodb/bin/mongo --host=[ip地址] --port=27018

myrs:ARBITER> rs.slaveOk()
myrs:ARBITER> show dbs
local 0.000GB

1.6 主节点选举选择

MongoDB在副本集中,会自动进行主节点的选举,住系欸但选举的触发条件:

  1. 主节点故障
  2. 主节点网络不可达(默认心跳信息为10秒)
  3. 人工干预(rs.stepDown(600))

一旦触发选举,就要根据一定规则来选主节点。

选举规则是根据票数来决定谁获胜:

  • 票数最高,且获得了”大多数“成员的投票支持的节点获胜。

    “大多数”:假设复制集内存活成员数量为N,则大多数为N/2 + 1。例如:3个投票成员,则大多数的值为2。当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。

  • 若票数相同,却都获得了“大多数”成员的投票支持的,数据新的节点获胜。

    数据的新旧是通过操作日志oplog来对比的。

在获得票数的时候,优先级(Priority)参数影响重大。

可以通过设置优先级(Priority)来设置额外票数。优先级即权重,取值为0~1000,相当于可额外增0~1000的票数,优先级的值越大,就越可能获得多数成员的投票(votes)数。指定较高的值可使成员更有资格成为主要成员,更低的值可使成员更不符合条件。

默认情况下,优先级值为1

myrs:PRIMARY> rs.conf()
{ 
    "_id" : "myrs",
    "version" : 3,
    "protocolVersion" : NumberLog(1),
    "writeConcernMajorityJournalDefault" : true,
    "members" : [
        { 
            "_id" : 0,
            "host" : "IP地址:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : { 
                
            },
            "salveDelay" : NumberLong(0),
            "votes" : 1
        },
        { 
            "_id" : 1,
            "host" : "IP地址:27018",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : { 
                
            },
            "salveDelay" : NumberLong(0),
            "votes" : 1
		},
        { 
            "_id" : 2,
            "host" : "IP地址:27019",
            "arbiterOnly" : true,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 0,
            "tags" : { 
                
            },
            "salveDelay" : NumberLong(0),
            "votes" : 1
		}
    ],
    "settings" : { 
        "chainingAllowed" : true,
        "heartbeatIntervalMills" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMills" : 10000,
        "catchUpTimeoutMills" : -1,
        "catchUpTaskoverDelayMills" : 30000,
        "getLastErrorModes" : { 
            
		},
        "getLastErrorDefaults" : { 
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId{ "5df4aba91d0400a87dff834d"}
    }
}

1.7 故障测试

1.7.1 副本节点故障测试

关闭27018副本节点:

发现,主节点和仲裁节点对27018的心跳失败。因为主节点还在,因此没有触发投票选举。

如果此时,在主节点写入数据:

db.comment.insert({ "_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水,幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatatime":new Date("2019-08-05T22:08:15.522z"),"likenum":NumberInt(1000),"state":"1"})

再启动从节点,会发现,主节点写入的数据,会自动同步给从节点。

1.7.2 主节点故障测试

关闭27017节点:

发现,从节点和仲裁节点对27017的心跳失败,当失败超过10秒,此时因为没有主节点了,会自动发起投票。

而副本节点只有27018,因此,候选人只有一个就是27018,开始投票。

27019向27018投了一票,27018本身自带一票,因此共两票,超过了“大多数”

27019是仲裁节点,没有选举权,27018不向其投票,其票数是0

最终结果,27018成为主节点,具备读写功能。

在27018写入数据查看:

db.comment.insert({ "_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水,幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatatime":new Date("2019-08-05T22:08:15.522z"),"likenum":NumberInt(1000),"state":"1"})

再启动27017节点,发现27017节点变成了从节点,27018仍保持主节点。

登录27017系欸但,发现是从节点了,数据自动从27018同步。

从而实现了高可用。

1.7.3 仲裁节点和主节点故障

先关闭仲裁节点27019,再关闭现在的主节点27018(投票后)

登录27017后,发现,27017仍然是从节点,副本集中没有主节点,导致此时副本集为只读状态,无法写入。

为什么不选举?因为27017的票数,没有获得大多数(即≥2),它只有默认的一票(优先级是1)

如果要触发选举,随便加入一个成员即可。

  • 如果只加入27019仲裁成员,则主节点一定是27017(没得选),仲裁节点不参与选举,但参与投票。

  • 如果只加入27018节点,会发起选举。因为27017和17018都是两票,则谁数据新,谁当主节点。

1.7.4 仲裁节点和从节点故障

先关掉仲裁节点27019,再关闭现在的副本节点27018(投票后)

大约10秒后,27017主节点自动降级为副本节点(服务降级)

副本集不可写数据,发生故障

1.8 Compass连接副本集

如果使用云服务器需要修改配置中的主节点ip

var config = rs.config();
config.members[0].host="ip地址:27017";
rs.reconfig(config);

Compass连接:

连接主节点:

《【MongoDB】副本集 & 分片集群》

连接从节点:

《【MongoDB】副本集 & 分片集群》

1.9 SpringDataMongoDB连接副本集

只能使用uri方式连接:

mongodb://host1,host2,host3/数据库名称?connect=replicaSet&slaveOk=true&replicaSet=副本集名字

其中:

  • slaveOk=true:开启副本节点读的功能,可实现读写分离。
  • connect=replicaSet:自动到副本集中选择读写的主机。如果slaveOK是打开的,则实现了读写分离。

【示例】

连接 replica set 三台服务器(端口 27017,27018,27019),直接连接第一个服务器无论是replica set一部分/主服务器/从服务器,写入操作应用在主服务器,并且分布查询到到从服务器。

修改配置文件 application.yaml

spring: 
	#数据源配置
	data:
		#主机地址
		#host: [ip地址]
		#数据库
		#database: articledb
		#默认端口号是27017
		#port: 27017
		#也可以使用url连接
		#副本集连接的字符串
		uri: mongodb://[ip地址]:27017,[ip地址]:27018,[ip地址]:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs

注意:

主机必须是副本集中所有的主机,包括主节点、副本节点、仲裁节点。

2. 分片集群-Sharded Cluster

2.1 分片概念

分片(sharding)是一种跨多台机器分布数据的方法,MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。

换句话说:分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以储存更多的数据,处理更多的负载。

具有大型数据集活高吞吐量的应用程序的数据库系统可以会挑战单个服务器的容量。例如,高查询率会耗尽服务器的CPU容量。工作集大小大于系统的RAM会强调磁盘驱动器的I/O容量。

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

垂直扩展意味着增加单个服务器的容量,例如使用更强大的CPU,添加更多RAM或增加存储空间量。可用技术的局限性可能会限制单个机器对于给定工作负载而言足够强大。此外,基于云的提供商基于可用的硬件配置具有硬性上限。结果,垂直缩放具有实际的最大值。

水平扩展意味着划分系统数据集并加载多个服务器,添加其他服务器根据需要增加容量。虽然单个机器的总体速度或容量可能不高,但每台机器处理整个工作负载的子集,可能提供比单个告诉大容量服务器更高的效率。扩展部署容量只需要根据需要添加额外的服务器,这可能比单个机器的高端硬件的总体成本更低。权衡使基础架构和部署维护的复杂性增加。

2.2 分片集群包含的组件

MongoDB分片集群包含以下组件:

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

下图描述了分片集群中组件的交互:

《【MongoDB】副本集 & 分片集群》

Mongo DB 在集合级别对数据进行分片,将集合数据分布在集群中的分片上。

2.3 分片集群架构目标

两个分片节点副本集(3+3)+一个配置节点副本集(3)+两个路由节点(2),共11个服务节点。

《【MongoDB】副本集 & 分片集群》

2.4 分片(存储)节点副本集的创建

所有的配置文件都直接放到sharding_cluster的相应的子目录下面,默认配置文件名字:mongo.conf

2.4.1 第一套副本集

准备存放数据和日志的目录

#--------------myshardrs01
mkdir -p /mongodb/sharded_cluster/myshardrs01_27018/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27018/data/db \ &

mkdir -p /mongodb/sharded_cluster/myshardrs01_27118/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27118/data/db \ &

mkdir -p /mongodb/sharded_cluster/myshardrs01_27218/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27218/data/db \ &

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27018/mongod.conf

myshardrs01_27018:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs01_27018/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27018
relication: 
	#副本集的名称
	replSetName: myshardrs01
sharding: 
	#分片角色
	clusterRole: shardsvr

sharding.clusterRole:

ValueDescription
configsvrStart this instance as a config server. The instance starts on port 27019 by default.
shardsvrStart this instance as a shard. The instance starts on port 27018 by default.

注意:

设置sharding.clusterRole需要mongod实例运行复制。要将实例部署为副本集成员,请使用replSetName设置并指定副本集名称。

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27118/mongod.conf

myshardrs01_27118:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs01_27118/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs01_27118/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27118/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27118
relication: 
	#副本集的名称
	replSetName: myshardrs01
sharding: 
	#分片角色
	clusterRole: shardsvr

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

myshardrs01_27218:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs01_27218/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs01_27218/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27218/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27218
relication: 
	#副本集的名称
	replSetName: myshardrs01
sharding: 
	#分片角色
	clusterRole: shardsvr

启动一主一副本一仲裁

依次启动三个mongod服务:

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27018/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123223
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27118/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123292
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27218/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123326
child process started sucessfully, parent exiting

(1)初始化副本集和创建主节点

使用客户端命令连接任意一个节点,但这里尽量要连接主节点:

/usr/local/mongodb/bin/mongo --host [ip地址] --port 27018

执行初始化副本集命令:

> rs.initiate()
{ 
    "ingo2" : "no configuration specified. Using a deafult configuration for the set",
    "me" : "ip地址:27018",
    "ok" : 1,
    "operationTime" : Timestamp(1545933449, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933449, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
"me" : "localhost.localdomain:27018"

查看副本集情况

rs.status()

(2)主节点配置查看:

rs.conf()

(3)添加副本节点:

mushardrs01:PRIMARY> rs.add("ip地址:27118")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545933501, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933501, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

(4)添加仲裁节点:

mushardrs01:PRIMARY> rs.add("ip地址:27218")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545933676, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933676, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

2.4.2 第二套副本集

准备存放数据和日志的目录

#--------------myshardrs01
mkdir -p /mongodb/sharded_cluster/myshardrs01_27318/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27018/data/db \ &

mkdir -p /mongodb/sharded_cluster/myshardrs01_27418/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27118/data/db \ &

mkdir -p /mongodb/sharded_cluster/myshardrs01_27518/log \ &
mkdir -p /mongodb/sharded_cluster/myshardrs01_27218/data/db \ &

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27018/mongod.conf

myshardrs01_27318:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs02_27318/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs02_27318/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27318/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27318
relication: 
	#副本集的名称
	replSetName: myshardrs02
sharding: 
	#分片角色
	clusterRole: shardsvr

sharding.clusterRole:

ValueDescription
configsvrStart this instance as a config server. The instance starts on port 27019 by default.
shardsvrStart this instance as a shard. The instance starts on port 27018 by default.

注意:

设置sharding.clusterRole需要mongod实例运行复制。要将实例部署为副本集成员,请使用replSetName设置并指定副本集名称。

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27418/mongod.conf

myshardrs01_27118:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs02_27418/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs02_27418/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27418/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27418
relication: 
	#副本集的名称
	replSetName: myshardrs02
sharding: 
	#分片角色
	clusterRole: shardsvr

新建/修改配置文件:

vim /mongodb/sharded_cluster/myshardrs01_27218/mongod.conf

myshardrs01_27518:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myshardrs02_27518/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myshardrs02_27518/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myshardrs02_27518/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27518
relication: 
	#副本集的名称
	replSetName: myshardrs02
sharding: 
	#分片角色
	clusterRole: shardsvr

启动一主一副本一仲裁

依次启动三个mongod服务:

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27318/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123332
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27418/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123368
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27518/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123423
child process started sucessfully, parent exiting

(1)初始化副本集和创建主节点

使用客户端命令连接任意一个节点,但这里尽量要连接主节点:

/usr/local/mongodb/bin/mongo --host [ip地址] --port 27318

执行初始化副本集命令:

> rs.initiate()
{ 
    "ingo2" : "no configuration specified. Using a deafult configuration for the set",
    "me" : "ip地址:27318",
    "ok" : 1,
    "operationTime" : Timestamp(1545934449, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545934449, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
"me" : "localhost.localdomain:27318"

查看副本集情况

rs.status()

(2)主节点配置查看:

rs.conf()

(3)添加副本节点:

mushardrs02:PRIMARY> rs.add("ip地址:27418")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545934501, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933501, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

(4)添加仲裁节点:

mushardrs02:PRIMARY> rs.add("ip地址:27518")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545934676, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933676, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

2.5 配置节点副本集的创建

准备存放数据和日志的目录

#--------------configs
mkdir -p /mongodb/sharded_cluster/myconfigs_27019/log \ &
mkdir -p /mongodb/sharded_cluster/myconfigs_27019/data/db \ &

mkdir -p /mongodb/sharded_cluster/myconfigs_27119/log \ &
mkdir -p /mongodb/sharded_cluster/myconfigs_27119/data/db \ &

mkdir -p /mongodb/sharded_cluster/myconfigs_27219/log \ &
mkdir -p /mongodb/sharded_cluster/myconfigs_27219/data/db \ &

新建/修改配置文件:

vim /mongodb/sharded_cluster/myconfigs_27019/mongod.conf

myconfigs_27019:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myconfigs_27019/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myconfigs_27019/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myconfigs_27019/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27019
relication: 
	#副本集的名称
	replSetName: myconfigs
sharding: 
	#分片角色
	clusterRole: configsvr

sharding.clusterRole:

ValueDescription
configsvrStart this instance as a config server. The instance starts on port 27019 by default.
shardsvrStart this instance as a shard. The instance starts on port 27018 by default.

注意:

设置sharding.clusterRole需要mongod实例运行复制。要将实例部署为副本集成员,请使用replSetName设置并指定副本集名称。

新建/修改配置文件:

vim /mongodb/sharded_cluster/myconfigs_27119/mongod.conf

myconfigs_27119:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myconfigs_27119/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myconfigs_27119/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myconfigs_27119/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27119
relication: 
	#副本集的名称
	replSetName: myconfigs
sharding: 
	#分片角色
	clusterRole: shardsvr

新建/修改配置文件:

vim /mongodb/sharded_cluster/myconfigs_27219/mongod.conf

myconfigs_27219:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/myconfigs_27219/log/mongod.log"
	logAppend: true
storage: 
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
	dbPath: "/mongodb/sharded_cluster/myconfigs_27219/data/db"
	joural:
		#启用或禁用持久性日志以确保数据文件保持有效和可恢复。
		enabled: true
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/myconfigs_27219/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27219
relication: 
	#副本集的名称
	replSetName: myconfigs
sharding: 
	#分片角色
	clusterRole: shardsvr

启动一主一副本一仲裁

依次启动三个mongod服务:

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27019/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123332
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27119/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123368
child process started sucessfully, parent exiting

[root@localhost bin]# /usr/local/mongodb/bin/mongo -f /mongod/sharded_cluster/myrs_27219/mongod.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123423
child process started sucessfully, parent exiting

(1)初始化副本集和创建主节点

使用客户端命令连接任意一个节点,但这里尽量要连接主节点:

/usr/local/mongodb/bin/mongo --host [ip地址] --port 27019

执行初始化副本集命令:

> rs.initiate()
{ 
    "ingo2" : "no configuration specified. Using a deafult configuration for the set",
    "me" : "ip地址:27318",
    "ok" : 1,
    "operationTime" : Timestamp(1545934449, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545934449, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
"me" : "localhost.localdomain:27019"

查看副本集情况

rs.status()

(2)主节点配置查看:

rs.conf()

(3)添加副本节点:

mushardrs01:PRIMARY> rs.add("ip地址:27119")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545934501, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933501, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}
mushardrs01:PRIMARY> rs.add("ip地址:27219")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1545934676, 1),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1545933676, 1),
        "signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

2.6 路由节点的创建和操作

2.6.1 第一个路由节点的创建

准备存放数据和日志的目录

#--------------mongos01
mkdir -p /mongodb/sharded_cluster/mymongos_27017/log

mymongos_27017:

新建/修改配置文件:

vim /mongodb/sharded_cluster/mymongos_27017/mongos.conf

mongos.conf:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/mymongos_27017/log/mongod.log"
	logAppend: true
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/mymongos_27017/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27219
sharding: 
	#指定配置 节点副本集
	configDB: myconfigrs/[ip地址]:27019,[ip地址]:27119,[ip地址]:27219

启动mongos:

[root@localhost bin]# /usr/local/mongodb/bin/mongos -f /mongod/sharded_cluster/mymongos_27017/mongos.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123332
child process started sucessfully, parent exiting

提示:启动如果 失败,可以查看log目录下的日志,查看失败原因。

客户端登录mongos,

/usr/local/mongod/bin/mongo --host [ip地址] --port 27017

此时,写不进去数据,如果写数据就会报错:

mongos> use aadb
switch tp db aadb
mongos> db.aa.insert({ aa:"aa"})
writeCommandError({ 
    "ok" : 0,
    "errmsg" : "unable to initialize targeter for write op for collection aa.aa :: cause by :: Database aa not found :: cause by :: No shards found",
    "code" : 70,
    "codeName" : "ShardNotFound",
    "operationTime" : Timestamp(1564600123, 2),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564600123, 2),
    	"signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
})

2.6.2 在路由节点上进行分片配置操作

使用命令添加分片:

(1)添加分片:

语法:

sh.addShard("IP:Port")

将第一套分片副本集添加进来:

mongos>
sh.addShard("myshardrs01/192.168.0.2:27018,[ip地址]:27118,[ip地址]:27218")
{ 
    "shardAdded" : "myshardrs01",
    "ok" : 1,
    "operationTime" : Timestamp(1564600226, 4),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564600226, 4),
    	"signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

查看分片情况:

mongos> sh.status()

将第二套分片副本集添加进来:

mongos>
sh.addShard("myshardrs02/192.168.0.2:27318,[ip地址]:27418,[ip地址]:27518")
{ 
    "shardAdded" : "myshardrs02",
    "ok" : 1,
    "operationTime" : Timestamp(1564600276, 5),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564600276, 5),
    	"signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

查看分片情况:

mongos> sh.status()

提示:如果添加分片失败,需要先手动移除分片,检查添加分片的信息的正确性后,再次添加分片。

移除分片:

use admin
db.runCommand({ removeShard : "myshardrs02"})

注意:如果只剩下最后一个shard,是无法删除的

移除时会自动转移分片数据,需要一个时间过程。

完成后,再次执行删除分片命令才能真正删除。

(2)开启分片功能:sh.enableSharding(“库名”)、sh.enableSharding(“库名.集合名”,{“key”:1})

在mongos上的articledb数据库配置sharding:

mongos> sh.enableSharding("articledb")
{ 
    "ok" : 1,
    "operationTime" : Timestamp(1564600336, 5),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564600336, 5),
    	"signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

查看分片状态:

mongos> sh.status()

(3)集合分片

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

语法:

sh.shardCollection(namespace, key, unique)

参数:

ParameterTypeDescription
namespacestring要(分片)共享的目标集合的命名空间,格式<database>.<collection>
keydocument用作分片键的索引规范文档。shard键决定MongoDB如何在shard之间分发文档。除非集合为空,否则索引必须建立在shard collection命令之前存在。如果集合为空,则MongoDB在对集合进行分片之前创建索引,前提是支持分片键的索引不存在。简单地说:由包含字段和该字段的索引遍历方向的文档组成。
uniqueboolean当值为true情况下,片键字段上会限制为确保是唯一索引。哈希策略片键不支持唯一索引。默认是false。

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

用什么字段当片键都可以,如:nickname作为片键,但一定是必填字段。

分片规则一:哈希策略

对于 基于哈希的分片,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块。【适用于数据不确定的情况】

在使用基于哈希分片的系统中,拥有 “相近” 片键的文档 很可能不会 存储在同一个数据块中,因此数据的分离性更好一些。

使用 nickname 作为片键,根据其值的哈希值进行数据分片:

mongos> sh.shardCollection("articledb.comment",{ "nickname":"hashed"})
{ 
    "collectionsharded" : "articledb.comment",
    "colelctionUUID" : UUID("ddea6ed8-ee61-4693-bd16-19acc3a45e8"),
    "ok" : 1,
    "operationTime" : Timestamp(1564602840, 28),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564602840, 28),
    	"signature" : { 
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

分片规则二:范围策略

对于 基于范围的分片,MongoDB按照片碱的范围把数据分成不同部分。假设有一个数字的片键:想象一个从负无穷到正无穷的直线,每一个片键的值都在直线上画了一个点。MongoDB把这条直线划分为更短的不重叠的片段,并称之为数据块,每个数据块包含了片键在一定范围内的数据。【适用于范围查询较多情况】

在使用片键做范围划分的系统中,拥有“相近”片键的文档很可能存储在同一个数据块中,因此也会存储在同一个分片中。

如使用作者年龄字段作为片键,按照点赞数值进行分片:

mongos> sh.shardCollection("articledb.author",{ "age":1})
{ 
    "collectionsharded" : "articledb.author",
    "colelctionUUID" : UUID("9a47bdaa-213a-4039-9c18-e70bfc369df7"),
    "ok" : 1,
    "operationTime" : Timestamp(1564602867, 13),
    "$clusterTime" : { 
        "clusterTime" : Timestamp(1564602867, 13),
    	"signature" : { 
            "hash" : BinData(0,"eE9QT5yESSL1Tyr7+3U8GRy5+5Q="),
            "keyId" : NumberLong("6732061237309341726")
        }
    }
}

查看分片状态:

mongos> sh.status(0)

2.6.3 分片后插入数据测试

测试一(哈希规则):登录mongos后,向comment循环插入1000条数据做测试:

mongos> use articledb
switched to db articledb
mnogos> for(var i=1;i<1000;i++){ db.comment.insert({ _id:i+"",nickname:"Hello"+i})}
writeResult({  "nInserted" : 1 })
mongos> db.comment.count()
1000

提示:js的语法(mongo的shell是一个JavaScript的shell)

注意:从路由上插入的数据,必须包含片键,否则无法插入。

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

第一个分片副本集:

/usr/local/mongodb/bin/mongo --host [ip地址] --port 27018
myshardrs01:PRIMARY> use articledb
switched to db articledb
myshardrs01:PRIMARY> db.comment.count()
508

第二个分片副本集:

/usr/local/mongodb/bin/mongo --host [ip地址] --port 27318
myshardrs02:PRIMARY>use articledb
switched to db articledb
myshardrs02:PRIMARY>db.comment.count()
492

可以看到,1000条数据近似均匀分布到了2个shard上。是根据片键的哈希值分配的。

这种分配方式非常易于水平扩展:一旦数据存储需要更大的空间,可以直接再增加分片即可,同时提高了性能。

使用db.comment.status()查看单个集合的完整情况,mongos执行该命令可以查看该集合的数据分片情况。

使用sh.status()查看本库内所有集合的分片信息。

测试二(范围测试):登录mongos后,向comment循环插入1000条数据做测试:

mongos> use articledb
switched to db articledb
mongos> for(var i=1;i<=20000;i++){ db.author.save({ "name":"Hello"+i,"age":NumberInt(i%120)})}
writeResult({  "nInserted" : 1 })
mongos> db.comment.count()
20000

插入成功后,仍要分别查看两个分片副本集的数据情况。

db.author.count()

提示:

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

1)系统繁忙,正在分片中

2)数据块(chunk)没有填满,默默人的数据块尺寸(chunksize)是64M,填满后才会考虑向其他片的数据块填充数据,因此,为了测试,可以将其改小,这里改为1M,操作如下:

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

测试完改回来:

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

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

2.6.4 再增加一个路由节点

文件夹:

#------------mongos02
mkdir -p /mongodb/sharded_cluster/mymongos_27117/log

mymongos_27117:

新建/修改配置文件:

vim /mongodb/sharded_cluster/mymongos_27117/mongos.conf

mongos.conf:

systemLog:
	#发送所有日志输出的目标指定为文件
	destination: file
	#mongod或mongos应向其大宋所有诊断日志记录信息的日志文件的路径
	path: "/mongodb/sharded_cluster/mymongos_27117/log/mongod.log"
	logAppend: true
	#mongod实例存储其数据的目录。storage.dbpath设置仅适用于mongod。
processManagement:
	#启用在后台运行mongos或mongod进程的守护进程模式
	fork: true
	#指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将其写入其PID
	pidFilePath: "/mongodb/sharded_cluster/mymongos_27117/log/mongod.pid"
net:
	#服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
	#bindIpAll: true
	#服务实例绑定ip
	bindIp: localhost,192.168.0.2
	#bindIp
	#绑定的端口
	port: 27219
sharding: 
	#指定配置 节点副本集
	configDB: myconfigrs/[ip地址]:27019,[ip地址]:27119,[ip地址]:27219

启动mongos2:

[root@localhost bin]# /usr/local/mongodb/bin/mongos -f /mongod/sharded_cluster/mymongos_27117/mongos.conf
about to fork child process, waiting until serve is ready for connections.
fork process: 123336
child process started sucessfully, parent exiting

使用mongo客户端登录27117,发现,第二个路由无需配置,因为分片配置都保存到了配置服务器中了。

2.7 Compass 连接分片集群

Compass连接:

《【MongoDB】副本集 & 分片集群》

2.8 SpringDataMongoDB连接分片集群

Java客户端常用的是SpringDataMongoDB,其连接的是mongos路由,配置和单机mongod的配置是一样的。

多个路由时候的SpringDataMongoDB的客户端配置参考如下:

spring:
	#数据库配置
	data: 
		mongodb: 
		#连接路由字符串
		uri: mongodb://[ip地址]:27017,[ip地址]:27117/articledb

通过日志发现,写入数据的时候,会选择一个路由写入。

    原文作者:L Jiawen
    原文地址: https://blog.csdn.net/Bitter_Li/article/details/121309545
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞