Статьи

Настройка сегментированного кластера mongodb на локальном хосте

Я играл с MongoDb, благодаря курсу M101J, предлагаемому Университетом Mongodb. Эти хранилища данных NoSQL набирают популярность по ряду причин, одной из которых является простота масштабирования, например горизонтальное масштабирование. Это горизонтальное масштабирование в MongoDB может быть достигнуто путем создания сегментированного кластера экземпляров mongodb. Возможно, вы захотите понять концепцию разделения, прежде чем продолжить. Ссылка MongoDB имеет очень четкое объяснение того же здесь .

Для закрытой установки mongodb требуется следующее:

  • Сервер конфигурации Mongodb — хранит метаданные кластера
  • Экземпляр mongos — это маршрутизатор, который направляет запросы разным шардам на основе ключа шардинга.
  • Отдельные экземпляры mongodb — они действуют как осколки.

Ниже приведена схема архитектуры примера установки shonged mongodb (Источник: MongodDB Reference )

sharded-кластер производства, архитектура

Давайте создадим все вышеперечисленные компоненты в одном экземпляре, т.е. на вашем локальном хосте.

Создание Mongodb Config Server

1
2
$ mkdir \data\configdb
$ mongod --configsvr --port 27010
  1. Сначала создается каталог данных для хранения метаданных кластера.
  2. Второй запускает сервер конфигурации deamon на порт 27010. Порт по умолчанию 27019, но я переопределил с помощью параметра командной строки —port.

Настройка Query Routers (экземпляры mongos)

Это служба маршрутизации для сегментирующего кластера, где он принимает запросы от приложения и получает данные от определенных сегментов. Маршрутизаторы запросов можно настроить с помощью команды mongos как показано ниже:

1
$ mongos -configdb localhost:27010 --port 27011

Это выводит на консоль ряд вещей, начиная со следующей строки:

1
2015-02-01T18:51:35.606+0300 warning: running with 1 config server should be done only for testing purposes and is not recommended for production

Рекомендуется запускать с 3-мя серверами configdb для производства, чтобы избежать единой точки отказа. Но для нашего тестирования 1 сервер configdb вполне подойдет.

--configdb командной строки --configdb используется, чтобы сообщить маршрутизатору запросов о серверах конфигурации, которые мы настроили. Он принимает запятую: значения, такие как –configdb host1: port1, host2: port2. В нашем случае у нас всего 1 конфиг-сервер.

Бегущие осколки mongodb

Теперь нам нужно запустить реальные экземпляры mongodb, которые хранят общие данные. Мы создадим 3 закрытых экземпляра mongodb и запустим все это на локальном хосте в разных портах и ​​предоставим каждому экземпляру mongodb свой собственный --dbpath как показано ниже:

Осколок Монгодб — 1

1
$ mongod --port 27012 --dbpath \data\db

Осколок Монгодб — 2

1
$ mongod --port 27013 --dbpath \data\db2

Осколок Монгодб — 3

1
$ mongod --port 27014 --dbpath \data\db3

Теперь у нас есть три осколка mongodb, работающих на localhost. Для базы данных я буду использовать базу данных students имеющую оценочные grades . Структура документов по grades приведена ниже:

1
2
3
4
5
6
{
  "_id" : ObjectId("50906d7fa3c412bb040eb577"),
  "student_id" : 0,
  "type" : "exam",
  "score" : 54.6535436362647
}

Вы можете выбрать любую базу данных на ваш выбор.

Регистрация осколков с помощью монго

Теперь, когда мы создали два шарда mongodb, работающих на localhost: 27012 и localhost: 27013 соответственно, мы продолжим и зарегистрируем эти шарды на нашем маршрутизаторе запросов mongos, также определим, какую базу данных нам нужно шардировать, а затем включим шардинг в коллекции, которую мы заинтересованы, предоставив ключ шарда. Все это должно быть выполнено путем подключения к маршрутизатору запросов mongos, как показано в следующих командах:

01
02
03
04
05
06
07
08
09
10
$ mongo --port 27011 --host localhost
mongos> sh.addShard("localhost:27012")
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard("localhost:27013")
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> sh.enableSharding("students")
{ "ok" : 1 }
mongos> sh.shardCollection("students.grades", {"student_id" : 1})
{ "collectionsharded" : "students.grades", "ok" : 1 }
mongos>

В sh.shardCollection мы указываем коллекцию и поле из коллекции, которая должна использоваться в качестве ключа шарда.

Добавление данных в сегментированный кластер mongodb

Позволяет подключиться к Монго и запустить некоторый код для заполнения данных в коллекцию оценок в базе данных студентов.

1
2
3
4
5
6
for ( i = 200; i < 10000; i++ ) {
  db.grades.insert({student_id: i, type: "exam", score : Math.random() * 100 });
  db.grades.insert({student_id: i, type: "quiz", score : Math.random() * 100 });
  db.grades.insert({student_id: i, type: "homework", score : Math.random() * 100 });
}
WriteResult({ "nInserted" : 1 })

После вставки данных мы заметили некоторую активность в демоне mongos, утверждающую, что он перемещает некоторые чанки для определенного шарда и т. Д., Т.е. балансировщик будет в действии, пытаясь сбалансировать данные между шардами. Вывод будет примерно таким:

1
2
3
4
5
6
7
2015-02-02T18:26:26.770+0300 [Balancer] moving chunk ns: students.grades moving
( ns: students.grades, shard: shard0000:localhost:27012, lastmod: 1|1||000000000000000000000000, min: { student_id: MinKey }, max: { student_id: 200.0 })
shard0000:localhost:27012 -> shard0001:localhost:27013                                                   
 
2015-02-02T18:31:12.314+0300 [Balancer] moving chunk ns: students.grades moving
( ns: students.grades, shard: shard0000:localhost:27012, lastmod: 2|2||000000000000000000000000, min: { student_id: 200.0 }, max: { student_id: 2096.0 })
shard0000:localhost:27012 -> shard0002:localhost:27014

Давайте посмотрим на состояние осколков, подключившись к монго. Это может быть достигнуто с помощью команды sh.status() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ mongo --port 27011 --host localhost
mongos> sh.status()
--- Sharding Status ---
sharding version: {
  "_id" : 1,
  "version" : 4,
  "minCompatibleVersion" : 4,
  "currentVersion" : 5,
  "clusterId" : ObjectId("54cf95d9d9309193f5fa0780")
}
shards:
  "_id" : "shard0000""host" : "localhost:27012" }
  "_id" : "shard0001""host" : "localhost:27013" }
  "_id" : "shard0002""host" : "localhost:27014" }
databases:
  "_id" : "admin""partitioned" : false"primary" : "config" }
  "_id" : "blog""partitioned" : false"primary" : "shard0000" }
  "_id" : "course""partitioned" : false"primary" : "shard0000" }
  "_id" : "m101""partitioned" : false"primary" : "shard0000" }
  "_id" : "school""partitioned" : false"primary" : "shard0000" }
  "_id" : "students""partitioned" : true"primary" : "shard0000" }
    students.grades
      shard key: { "student_id" : 1 }
      chunks:
          shard0001       1
          shard0002       1
          shard0000       1
      { "student_id" : { "$minKey" : 1 } } -->> { "student_id" : 200 } on : shard0001 Timestamp(2, 0)
      { "student_id" : 200 } -->> { "student_id" : 2096 } on : shard0002 Timestamp(3, 0)
      { "student_id" : 2096 } -->> { "student_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(3, 1)
  "_id" : "task-db""partitioned" : false"primary" : "shard0000" }
  "_id" : "test""partitioned" : false"primary" : "shard0000" }

Приведенный выше вывод показывает, что база данных students отбрасывается, а разбитая коллекция является коллекцией grades . Он также показывает различные доступные шарды и диапазон ключей шарда, распределенных по разным шардам. Таким образом, для shard0001 у нас есть student_id от минимума до 200, затем для shard0002 у нас есть student_id от 200 до 2096, а остальные в shard0000.

Мы также можем подключиться к отдельным осколкам и выполнить запрос, чтобы узнать максимальные и минимальные доступные идентификаторы учащихся.

На шард0000

1
2
3
4
5
6
7
8
9
$ mongo --host localhost --port 27012
MongoDB shell version: 2.6.7
connecting to: localhost:27012/test
> use students
switched to db students
> db.grades.find().sort({student_id : 1}).limit(1)
{ "_id" : ObjectId("54cf97295a23cc67efa848c8"), "student_id" : 2096, "type" : "exam", "score" : 6.7372970981523395 }
> db.grades.find().sort({student_id : -1}).limit(1)
{ "_id" : ObjectId("54cf973b5a23cc67efa8a567"), "student_id" : 9999, "type" : "homework", "score" : 60.64519872888923 }

На шард0001

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
C:\Users\Mohamed>mongo --host localhost --port 27013
MongoDB shell version: 2.6.7
connecting to: localhost:27013/test
> use students
switched to db students
> db.grades.find().sort({student_id:1}).limit(1).pretty()
{
        "_id" : ObjectId("54cf97d05a23cc67efa8a568"),
        "student_id" : 1,
        "type" : "exam",
        "score" : 5.511052813380957
}
> db.grades.find().sort({student_id:-1}).limit(1).pretty()
{
        "_id" : ObjectId("54cf97d15a23cc67efa8a7bc"),
        "student_id" : 199,
        "type" : "homework",
        "score" : 51.78457708097994
}

На шард0002

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
$ mongo --host localhost --port 27014
MongoDB shell version: 2.6.7
connecting to: localhost:27014/test
> use students
switched to db students
> db.grades.find().sort({student_id:1}).limit(1).pretty()
{
  "_id" : ObjectId("54cf971f5a23cc67efa83292"),
  "student_id" : 200,
  "type" : "homework",
  "score" : 79.56434232182801
}
> db.grades.find().sort({student_id:-1}).limit(1).pretty()
{
  "_id" : ObjectId("54cf97295a23cc67efa848c7"),
  "student_id" : 2095,
  "type" : "homework",
  "score" : 62.75710032787174
}

Давайте выполним тот же набор запросов на маршрутизаторе запросов mongos и увидим, что на этот раз результаты будут включать данные всех сегментов, а не только отдельные сегменты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
$ mongo --port 27011 --host localhost
MongoDB shell version: 2.6.7
connecting to: localhost:27011/test
mongos> use students
switched to db students
mongos> db.grades.find().sort({student_id:-1}).limit(1).pretty()
{
  "_id" : ObjectId("54cf973b5a23cc67efa8a567"),
  "student_id" : 9999,
  "type" : "homework",
  "score" : 60.64519872888923
}
mongos> db.grades.find().sort({student_id:1}).limit(1).pretty()
{
  "_id" : ObjectId("54cf97d05a23cc67efa8a568"),
  "student_id" : 1,
  "type" : "exam",
  "score" : 5.511052813380957
}
mongos>

Таким образом, это завершает настройку кластера shong mongodb на локальном хосте. Надеюсь, это было информативно и полезно!