Научите, как создать набор реплик mongodb

задняя часть база данных сервер MongoDB

Создайте набор реплик mongodb

1. Что такое набор реплик

Набор реплик — это кластер экземпляров MongoDB, состоящий из основного сервера и нескольких резервных серверов. С помощью репликации обновления данных передаются из первичного экземпляра в другие экземпляры.После определенной задержки каждый экземпляр MongoDB поддерживает одну и ту же копию набора данных. Поддерживая избыточные копии базы данных, можно добиться удаленного резервного копирования данных, разделения чтения и записи и автоматического аварийного переключения.
В более ранних версиях MongoDB использовался главный-ведомый, один главный и один подчиненный, как в MySQL, но в этой архитектуре подчиненный доступен только для чтения.Когда главная база данных выходит из строя, подчиненная база данных не может автоматически переключаться на главную. В настоящее время режим «ведущий-ведомый» упразднен и заменен набором реплик, в этом режиме есть один первичный (основной) и несколько вторичных (вторичный), которые доступны только для чтения. Поддерживается установка для них весов, когда мастер выходит из строя, слейв с наибольшим весом переключается на мастера. В этой архитектуре также может быть установлена ​​роль арбитра, который отвечает только за вынесение решений и не хранит данные. В этой архитектуре все данные чтения и записи находятся на главном сервере.Для достижения цели балансировки нагрузки необходимо вручную указать целевой сервер библиотеки чтения. Выше цитата из(blog.51CTO.com/zero01/2059…

2. Начните строить

Набор реплик предназначен для непрерывного предоставления услуг и безопасного удаленного резервного копирования данных.Как правило, каждый узел экземпляра будет храниться на узле сервера.Здесь не так много серверов, поэтому они будут построены на одном сервере и созданы используя разные порты.

1. Выполните три команды последовательно
```
mongod --dbpath=/home/mongodb/db/testReplPrim   --logpath=/home/mongodb/logs/mongolog_testReplPrim   --logappend --fork --port=27017 --replSet=testRepl  
```

```
mongod --dbpath=/home/mongodb/db/testReplSec1     --logpath=/home/mongodb/logs/mongolog_testReplSec1     --logappend --fork --port=27018 --replSet=testRepl  
```

```
mongod --dbpath=/home/mongodb/db/testReplSec2   --logpath=/home/mongodb/logs/mongolog_testReplSec2   --logappend --fork --port=27019 --replSet=testRepl
```
2. Выберите экземпляр mongodb в качестве основного узла, здесь мы выбираем 27017.

подключиться к этому экземпляру

```
mongo --port 27017
```

 ```
 use admin
 ```
3. Создайте пользователя под администратором
```
db.createUser({
 user:"test01",
 pwd:"abc123",
 roles:[{
 role:"userAdminAnyDatabase",db:"admin"
 },{
 role:"clusterAdmin",db:"admin"
 }]})
 ```

```
db.auth('test01','abc123')
```
4. Инициализируйте набор реплик
 ```
rs.initiate({"_id":"testRepl","members":[{"_id":0,"host":"10.10.10.10:27017",priority:3},{"_id":1,"host":"10.10.10.10:27018",priority:2},{"_id":2,"host":"10.10.10.10:27019",priority:0,slaveDelay:86400}]})
```

ip是随机写的,此时我们已经初始化好了mongodb副本集,其中27017是primary节点,27018和27019位secondary节点,20179实例会延时60秒同步数据。
5. Создайте новую базу данных
```use testdb```
6. Создайте пользователя
```db.createUser({"user":"testdb01","pwd":"abc123",roles:[{role:"readWrite",db:"testdb"}]})```
7. Добавьте коллекцию клиентов и добавьте документ
```db.customers.insert({"name":"wang"})```

此时,27017实例中,testdb库下的customer集合会有一条文档,在其他两个实例中也会有相同的数据
8. Подключитесь к экземпляру 27018
 ```mongo --port 27018```

 ```use testdb```

```show collections```
9. Это отобразит:
```
2018-11-08T16:50:10.122+0800 E QUERY    [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:773:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:785:19
DB.prototype.getCollectionNames@src/mongo/shell/db.js:796:16
shellHelper.show@src/mongo/shell/utils.js:753:9
shellHelper@src/mongo/shell/utils.js:650:15
@(shellhelp2):1:1
```

由于我们是在secondary节点,需要执行如下命令

```rs.slaveOk()```

```show collections```

10. Видно, что вторичный узел синхронизировал данные, пока что мы завершили построение базового набора реплик, но очевидно, что мы не добавили опцию --auth при запуске инстанса базы данных, т.е. Скажем, мы можем работать с базой данных без какой-либо аутентификации, что невозможно в производственной среде, поэтому нам нужно добавить параметр --auth, затем мы сначала отключим три экземпляра службы.
```
mongod --dbpath=/home/mongodb/db/testReplPrim --logpath=/home/mongodb/logs/mongolog_testReplPrim --logappend --fork --port=27017 --replSet=testRepl   --shutdown
```

```
    mongod --dbpath=/home/mongodb/db/testReplSec1 --logpath=/home/mongodb/logs/mongolog_testReplSec1 --logappend --fork --port=27018 --replSet=testRepl --shutdown
```
    
```
mongod --dbpath=/home/mongodb/db/testReplSec2 --logpath=/home/mongodb/logs/mongolog_testReplSec2 --logappend --fork --port=27019 --replSet=testRepl 
--shutdown
```
11. Затем запустите три экземпляра по отдельности
  ```
mongod --dbpath=/home/mongodb/db/testReplPrim --logpath=/home/mongodb/logs/mongolog_testReplPrim --logappend --fork --port=27017 --replSet=testRepl --auth
```

```
    mongod --dbpath=/home/mongodb/db/testReplSec1 --logpath=/home/mongodb/logs/mongolog_testReplSec1 --logappend --fork --port=27018 --replSet=testRepl --auth
    ```
  
  ```
    mongod --dbpath=/home/mongodb/db/testReplSec2 --logpath=/home/mongodb/logs/mongolog_testReplSec2 --logappend --fork --port=27019 --replSet=testRepl 
    --auth
    ```
12. Подключитесь к основному узлу экземпляра
  ```mongo --port 27017```

  ```use admin```
  
  ```db.auth('test01','abc123')```
  
  ```rs.status()```
  
 会看到如下状态
 
  ```
    {
	"set" : "testRepl",
	"date" : ISODate("2018-11-08T10:36:32.750Z"),
	"myState" : 3,
	"term" : NumberLong(6),
	"heartbeatIntervalMillis" : NumberLong(2000),
	"members" : [
		{
			"_id" : 0,
			"name" : "10.10.10.10:25231",
			"health" : 1,
			"state" : 3,
			"stateStr" : "RECOVERING",
			"uptime" : 1002,
			"optime" : {
				"ts" : Timestamp(1541671316, 2),
				"t" : NumberLong(6)
			},
			"optimeDate" : ISODate("2018-11-08T10:01:56Z"),
			"infoMessage" : "could not find member to sync from",
			"configVersion" : 1,
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "10.10.10.10:25232",
			"health" : 0,
			"state" : 6,
			"stateStr" : "(not reachable/healthy)",
			"uptime" : 0,
			"optime" : {
				"ts" : Timestamp(0, 0),
				"t" : NumberLong(-1)
			},
			"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
			"lastHeartbeat" : ISODate("2018-11-08T10:36:30.447Z"),
			"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
			"pingMs" : NumberLong(0),
			"authenticated" : false,
			"configVersion" : -1
		},
		{
			"_id" : 2,
			"name" : "10.10.10.10:25233",
			"health" : 0,
			"state" : 6,
			"stateStr" : "(not reachable/healthy)",
			"uptime" : 0,
			"optime" : {
				"ts" : Timestamp(0, 0),
				"t" : NumberLong(-1)
			},
			"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
			"lastHeartbeat" : ISODate("2018-11-08T10:36:30.452Z"),
			"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
			"pingMs" : NumberLong(0),
			"authenticated" : false,
			"configVersion" : -1
		}
	],
	"ok" : 1
}
```

说明主节点无法建立与其他节点互访认证,那如何建立互访认证呢,就需要用到Keyfile

3. Используйте контроль доступа к ключевым файлам, чтобы установить механизм аутентификации между узлами.

1. Сгенерировать ключевой файл
 `openssl rand -base64 100 > /usr/local/keyfile/mongodb_keyfile`
2. Изменить права доступа к файлам
 `chmod 600 /usr/local/keyfile/mongodb_keyfile`
3. Скопируйте сгенерированный ключевой файл на машины каждой ноды, обратите внимание, что путь должен совпадать с путем, указанным при запуске mongodb.
4. Завершите работу трех экземпляров службы.
   `mongod --dbpath=/home/mongodb/db/testReplPrim --logpath=/home/mongodb/logs/mongolog_testReplPrim --logappend --fork --port=27017 --replSet=testRepl --shutdown`

   `mongod --dbpath=/home/mongodb/db/testReplSec1 --logpath=/home/mongodb/logs/mongolog_testReplSec1 --logappend --fork --port=27018 --replSet=testRepl --shutdown`
   
   `mongod --dbpath=/home/mongodb/db/testReplSec2 --logpath=/home/mongodb/logs/mongolog_testReplSec2 --logappend --fork --port=27019 --replSet=testRepl --shutdown`
5. Перезапустите три экземпляра службы.
   `mongod --dbpath=/home/mongodb/db/testReplPrim --logpath=/home/mongodb/logs/mongolog_testReplPrim --logappend --fork --port=27017 --replSet=testRepl keyFile=/usr/local/keyfile/mongodb_keyfile --auth`

   `mongod --dbpath=/home/mongodb/db/testReplSec1 --logpath=/home/mongodb/logs/mongolog_testReplSec1 --logappend --fork --port=27018 --replSet=testRepl keyFile=/usr/local/keyfile/mongodb_keyfile --auth`
   
   `mongod --dbpath=/home/mongodb/db/testReplSec2 --logpath=/home/mongodb/logs/mongolog_testReplSec2 --logappend --fork --port=27019 --replSet=testRepl keyFile=/usr/local/keyfile/mongodb_keyfile--auth`
6. Порт подключения — экземпляр 21071.
   `mongo --port 27017`

   `use admin`
   
   `db.auth('test01','abc123')`
   
   `rs.status()`

Готово. На данный момент, когда мы добавляем данные на первичный узел, они могут отображаться синхронно на вторичном узле. Узел 27019 имеет задержку 60 секунд, и мы не будем ее здесь демонстрировать. хорошо, почему так много команд размещено без особых объяснений?Это интуитивно (лениво), просто следуйте командам и понятно это, и конкретные детали кажутся легкими.