SlideShare ist ein Scribd-Unternehmen logo
1 von 51
MongoDB в 
продакшене – миф 
или реальность? 
Алексей Токарь 
руководитель группы разработки в 
направлении медиасервисов
2 
Наш самый обычный сервис – это… 
• 1 500 000 000 хитов в месяц 
• 2 000 000 уникальных пользователей в сутки 
• 4 000 RPS в пике 
• <70мс среднее время ответа 
• 15 обслуживающих серверов
3 
Выбор СУБД для веб-сервисов
4 
Как представляют себе MongoDB 
Уиииии!!! 
elcaracol.kiev.ua
5 
А так MongoDB обычно работает… 
Эмм? 
care2.com
6 
Иногда получается даже так 
:’( 
reddit.com
7 
Как увеличить производительность? 
помоги маленькой ламе повысить 
производительность 
bestclipartblog.com
8 
Можно вырасти вертикально 
если есть запас процессора/памяти/дисков 
bestclipartblog.com
9 
Можно вырасти горизонтально 
если в ДЦ еще остались свободные сервера 
bestclipartblog.com
Рецепты на данных 
структуры данных
11 
JSON и BSON документы 
{ 
"_id" : 1, 
"value" : "text", 
"array" : [ { 
"data" : 14 
} ] 
} 
44 00 00 00 01 5f 69 64 00 00 00 00 00 00 00 f0 
3f 02 76 61 6c 75 65 00 05 00 00 00 74 65 78 74 
00 04 61 72 72 61 79 00 1b 00 00 00 03 30 00 13 
00 00 00 01 64 61 74 61 00 00 00 00 00 00 00 2c 
40 00 00 00
12 
Структура BSON документа 
документ 
размер поля [] терминатор 
тип ключ терминатор значение 
1byte 
x01 (double) 
1byte 
x00 
1byte 
x00 
4byte 
18 
3byte 
_id 
8byte 
1 
{ _id : 1 }
13 
Поиск документа на диске (skip : 2) 
read size 
skip 
n = 3 
O(n)
14 
Индексное дерево. B-tree 
O(log n) 
wikipedia.org
Рецепты на данных 
сохранение или изменение?
16 
Доменный объект 
public class MyObject { 
private long id; 
private String title; 
... 
public long getId() { 
return id; 
} 
public String getTitle() { 
return title; 
} 
public void setTitle( String newTitle ) { 
title = newTitle; 
} 
}
public class TitleCommand extends Command { 
private String newTitle; 
private String oldTitle; 
public TitleCommand( MyObject o, String newTitle ) { 
super( o ); 
this.newTitle = newTitle; 
} 
@Override 
public void apply() { 
oldTitle = o.getTitle(); 
o.setTitle( newTitle ); 
} 
@Override 
public void undo() { 
o.setTitle( oldTitle ); 
} 
} 
17 Класс для изменения названия объекта
public class MyObjectService { 
@Autowired 
private MongoCommandsDao commandsDao; 
@Autowired 
private MongoMyObjectDao objectDao; 
public void updateTitle( MyObject o, String title ) { 
Command c = new TitleCommand( o, title ); 
c.apply(); 
commandsDao.save( c ); 
objectDao.save( o ); 
} 
} 
18 Сервис изменения заголовка объекта
public class MongoMyObjectDao { 
@Autowired 
private MongoOperations mongo; 
public void save( MyObject o ) { 
mongo.save( o ); 
} 
} 
19 Простейшая реализация репозитория
20 
Обновление объекта целиком 
• изменение всех деревьев индексов 
• блокировка всей БД на время записи 
документа 
• размещение объекта целиком на диске 
• добавление документа в oplog целиком 
– а значит еще раз запись на диск 
– передача объекта по сети для репликации
21 
public class TitleCommand extends Command { 
private String newTitle; 
private String oldTitle; 
public TitleCommand( MyObject o, String newTitle ) { 
super( o ); 
this.newTitle = newTitle; 
} 
@Override 
public Update getUpdate() { 
return Update.update( "title", newTitle ); 
} 
@Override 
public void apply() { 
oldTitle = o.getTitle(); 
o.setTitle( newTitle ); 
} 
@Override 
public void undo() { 
o.setTitle( oldTitle ); 
} 
}
public class MyObjectService { 
@Autowired 
private MongoCommandsDao commandsDao; 
@Autowired 
private MongoMyObjectDao objectDao; 
public void updateTitle( MyObject o, String title ) { 
Command c = new TitleCommand( o, title ); 
c.apply(); 
commandsDao.save( c ); 
objectDao.updateFromCommand( c ); 
} 
} 
22 Рефакторинг сервиса под новую идею
public class MongoMyObjectDao { 
@Autowired 
private MongoOperations mongo; 
public void updateFromCommand( Command c ) { 
Query query = new Query( 
Criteria.where( "_id" ) 
.is( c.getObject().getId() ) 
); 
mongo.updateFirst( 
query, 
c.getUpdate(), 
MyObject.class 
); 
} 
} 
23 Рефакторинг репозитория под новую идею
24 
Изменение поля объекта 
• изменение только одного дерева индекса 
(если поле было проиндексировано) 
• запись небольшого объема данных на диск 
• передача лишь изменяемой части 
документа по сети
25 
Результаты для 10К документов 
.save() .update() 
----------------------- 
ms Task name 
----------------------- 
47768 create 
10653 read 
40214 save 
----------------------- 
ms Task name 
----------------------- 
44667 create 
11199 read 
02472 update
Рецепты на данных 
выбор между вложенными и 
самостоятельными документами
27 
Коллекция отдельных документов 
{ 
"eventId" : 1, 
"author" : "Alice", 
"text" : "I like JavaDay 2014” 
"date" : "2014-10-17" 
} 
{ 
"eventId" : 1, 
"author" : "Bob", 
"text" : "I enjoy JavaDay 2014” 
"date" : "2014-10-18" 
}
28 
Коллекция отдельных документов 
• Плюсы: 
– если нужно вывести один документ, то поиск 
займет O(log n) времени 
– время записи документов O(1), так как он 
полностью размещается в конце файла данных
29 
Список вложенных документов 
{ 
"eventId" : 1, 
"comments" : [ { 
"author" : "Alice", 
"text" : "I like JavaDay 2014", 
"date" : "2014-10-17” 
}, { 
"author" : "Bob", 
"text" : "I enjoy JavaDay 2014", 
"date" : "2014-10-18” 
} ] 
}
30 
Список вложенных документов 
• Плюсы: 
– маленькое индексное дерево 
– меньше чтений с диска, если нужно вывести сразу 
все 
• Минусы: 
– можно достигнуть лимита документа в 16МиБ и 
все перестанет работать. Сразу. 
– …
31 
Добавление элемента в список 
• появление фрагментированного участка 
• запись объекта целиком в конец 
• перестроение индекса
Растём вертикально 
• обновляйте поля, а не документы, когда это 
возможно 
• храните документы в массивах, если это 
допустимо и они не будут значительно 
расти
Рецепты на кластерах 
репликация или шардирование?
34 
Репликация данных 
throughput 
= 400%? 
master 
replica 
replica 
replica
35 
Репликация данных 
• Плюсы: 
– растем линейно на чтение 
• Минусы: 
– нет выигрыша для операций записи 
– неизвестно какие данные получаем
36 
Шардирование 
shard1 
shard2 
. . . . . . 
shardN
37 
Шардирование 
• Плюсы: 
– растем линейно на чтение* 
– растем линейно на запись* 
– всегда актуальные данные 
• Минусы: 
– нужен правильный индекс и схема
Рецепты на кластерах 
выбор ключа и схемы для 
шардирования
39 
Монотонный шардирующий ключ 
Шардируем по date, userId или orderNum 
Все записи попадут на самый новый шард 
t
40 
Монотонный шардирующий ключ 
• hash-ключ или равномерно распределенное 
значение 
• Каждая запись на произвольный шард 
t
Рецепты на кластерах 
проблема рассеивания (scatter/gather)
42 
Граф друзей в приложении 
1 
2 
4 
3
43 
Очевидное решение 
{ user : 1, friend : 2 } 
{ user : 1, friend : 3 } 
{ user : 1, friend : 4 } 
{ user : 2, friend : 1 } 
{ user : 2, friend : 4 } 
{ user : 3, friend : 1 } 
Мои друзья: 
db.friends.find( { user : 1 } ); 
Мои фолловеры: 
db.friends.find( { friend : 1 } );
44 
Очевидное решение 
{ user : 1, friend : 2 } 
{ user : 1, friend : 3 } 
{ user : 1, friend : 4 } 
{ user : 2, friend : 1 } 
{ user : 2, friend : 4 } 
{ user : 3, friend : 1 } 
Мои друзья: 
db.friends.find( { user : 1 } ); 
Мои фолловеры: 
db.friends.find( { friend : 1 } ); 
shard 1 
shard 2 
shard 3
45 
scatter / gather problem 
latency 
shard 3 
{ user : 3, friend : 1 } 
shard 2 
{ user : 2, friend : 1 } 
{ user : 2, friend : 4 } 
shard 1 
{ user : 1, friend : 2 } 
{ user : 1, friend : 3 } 
{ user : 1, friend : 4 } 
mongos 
• запросить данные 
• объединить 
• отсортировать 
1ms 
3ms 
0ms 
total query
46 
Производительное решение 
{ user : 1, friend : 2 } 
{ user : 1, friend : 3 } 
{ user : 1, friend : 4 } 
{ user : 2, friend : 1 } 
{ user : 2, friend : 4 } 
{ user : 3, friend : 1 } 
{ user : 1, follower : 2 } 
{ user : 1, follower : 3 } 
{ user : 2, follower : 1 } 
{ user : 3, follower : 1 } 
{ user : 4, follower : 1 } 
{ user : 4, follower : 2 } 
Followers 
Friends
47 
Хороший ключ 
• высокое разнообразие значений 
• равномерное распределение по всему 
допустимому диапазону 
• попадание читающих запросов на один 
сервер
Растём горизонтально 
• для масштабирования – шардирование 
• хороший ключ для шардов не монотонен и 
разнообразен 
• дублирование может значительно повысить 
производительность
Бонус-трек
50 
writeConcern и readPreference – сила в 
балансе 
• writeConcern: 
– unacknowledged { w : 0 } 
– acknowledged { w : 1 } 
– replica-safe { w : >1 } 
– majority { w : “majority” } (n/2+1) 
• readPreference: 
– primary 
– primaryPreferred 
– secondary 
– secondaryPreferred 
– nearest
Алексей Токарь 
руководитель группы 
разработки 
azazeltap@yandex-team.ru 
Спасибо :)

Weitere ähnliche Inhalte

Was ist angesagt?

ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
Ontico
 
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
NoSQL внутри SQL: приземленные вопросы практического применения /  Дмитрий До...NoSQL внутри SQL: приземленные вопросы практического применения /  Дмитрий До...
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
Ontico
 
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.42014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
Nikolay Samokhvalov
 
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
Ontico
 
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
Ontico
 
Алексей Чумаков. Apache Cassandra на реальном проекте
Алексей Чумаков. Apache Cassandra на реальном проектеАлексей Чумаков. Apache Cassandra на реальном проекте
Алексей Чумаков. Apache Cassandra на реальном проекте
Volha Banadyseva
 
Redis: возможности, выгоды, примеры использования
Redis: возможности, выгоды, примеры использованияRedis: возможности, выгоды, примеры использования
Redis: возможности, выгоды, примеры использования
Alexey Kachayev
 
Cassandra: быстрая запись данных в высоконагруженных системах
Cassandra: быстрая запись данных в высоконагруженных системахCassandra: быстрая запись данных в высоконагруженных системах
Cassandra: быстрая запись данных в высоконагруженных системах
Alexander Mezhov
 

Was ist angesagt? (20)

ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
ClickHouse: очень быстро и очень удобно / Виктор Тарнавский, Алексей Миловидо...
 
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
NoSQL внутри SQL: приземленные вопросы практического применения /  Дмитрий До...NoSQL внутри SQL: приземленные вопросы практического применения /  Дмитрий До...
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
 
Анализируем данные с Clickhouse
Анализируем данные с  ClickhouseАнализируем данные с  Clickhouse
Анализируем данные с Clickhouse
 
ClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий КузьминClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
 
Обзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновОбзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий Насретдинов
 
Поиск наизнанку
Поиск наизнанкуПоиск наизнанку
Поиск наизнанку
 
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
 
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
 
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.42014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
 
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
Переезжаем на Yandex ClickHouse / Александр Зайцев (LifeStreet)
 
Mysql vs postgresql
Mysql vs postgresqlMysql vs postgresql
Mysql vs postgresql
 
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
Apache Cassandra. Ещё одно NoSQL хранилище (Владимир Климонтович)
 
2014.10.15 блиц-доклад PostgreSQL kNN search
2014.10.15 блиц-доклад PostgreSQL kNN search2014.10.15 блиц-доклад PostgreSQL kNN search
2014.10.15 блиц-доклад PostgreSQL kNN search
 
История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)
История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)
История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)
 
Алексей Чумаков. Apache Cassandra на реальном проекте
Алексей Чумаков. Apache Cassandra на реальном проектеАлексей Чумаков. Apache Cassandra на реальном проекте
Алексей Чумаков. Apache Cassandra на реальном проекте
 
2014.09.24 история небольшого успеха с PostgreSQL (Yandex)
2014.09.24 история небольшого успеха с PostgreSQL (Yandex)2014.09.24 история небольшого успеха с PostgreSQL (Yandex)
2014.09.24 история небольшого успеха с PostgreSQL (Yandex)
 
Redis: возможности, выгоды, примеры использования
Redis: возможности, выгоды, примеры использованияRedis: возможности, выгоды, примеры использования
Redis: возможности, выгоды, примеры использования
 
NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)
NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)
NewSQL: SQL никуда не уходит / Константин Осипов (tarantool.org)
 
Cassandra: быстрая запись данных в высоконагруженных системах
Cassandra: быстрая запись данных в высоконагруженных системахCassandra: быстрая запись данных в высоконагруженных системах
Cassandra: быстрая запись данных в высоконагруженных системах
 
Введение в Apache Cassandra
Введение в Apache CassandraВведение в Apache Cassandra
Введение в Apache Cassandra
 

Andere mochten auch

16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
IT-Portfolio
 
Couchbase, что за зверь и на что способен.
Couchbase, что за зверь и на что способен.Couchbase, что за зверь и на что способен.
Couchbase, что за зверь и на что способен.
Alexey Rusnak
 
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
IT-Portfolio
 
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Ontico
 

Andere mochten auch (10)

16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Строим N...
 
Couchbase, что за зверь и на что способен.
Couchbase, что за зверь и на что способен.Couchbase, что за зверь и на что способен.
Couchbase, что за зверь и на что способен.
 
NoSQL - World IT Planet, Saint Petersburg 2015
NoSQL - World IT Planet, Saint Petersburg 2015NoSQL - World IT Planet, Saint Petersburg 2015
NoSQL - World IT Planet, Saint Petersburg 2015
 
Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...
Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...
Применение в Enterprise-приложении графовой базы данных Neo4j - Антон Максимо...
 
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Оптимиза...
 
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
16 декабря, DEV {highload} - конференция о Highload веб-разработке, "Эксплуат...
 
Преимущества NoSQL баз данных на примере MongoDB
Преимущества NoSQL баз данных на примере MongoDBПреимущества NoSQL баз данных на примере MongoDB
Преимущества NoSQL баз данных на примере MongoDB
 
Вадим Шашенко, 2ГИС
Вадим Шашенко, 2ГИСВадим Шашенко, 2ГИС
Вадим Шашенко, 2ГИС
 
NoSQL thumbtack experience, Анатолий Никулин
NoSQL thumbtack experience, Анатолий НикулинNoSQL thumbtack experience, Анатолий Никулин
NoSQL thumbtack experience, Анатолий Никулин
 
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
Как выбрать In-memory NoSQL базу данных с умом. Тестируем производительность ...
 

Ähnlich wie MongoDB в продакшен - миф или реальность?

Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
Technopark
 
OpenResty: превращаем NGINX в полноценный сервер приложений / Владимир Прота...
OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Прота...OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Прота...
OpenResty: превращаем NGINX в полноценный сервер приложений / Владимир Прота...
Ontico
 
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON
 

Ähnlich wie MongoDB в продакшен - миф или реальность? (20)

Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
Дмитрий Прокопцев "Memory-mapped storage: ещё один подход к сериализации данных"
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
Nosql and Mongodb
Nosql and MongodbNosql and Mongodb
Nosql and Mongodb
 
CSS глазами машин
CSS глазами машинCSS глазами машин
CSS глазами машин
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
 
OpenResty: превращаем NGINX в полноценный сервер приложений / Владимир Прота...
OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Прота...OpenResty: превращаем NGINX в полноценный сервер приложений  / Владимир Прота...
OpenResty: превращаем NGINX в полноценный сервер приложений / Владимир Прота...
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
MongoDB@addconf
MongoDB@addconfMongoDB@addconf
MongoDB@addconf
 
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart GammaMongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma
 
LDAP in infrastructure (RootConf 2009)
LDAP in infrastructure (RootConf 2009)LDAP in infrastructure (RootConf 2009)
LDAP in infrastructure (RootConf 2009)
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
 
Basis.js - Production Ready Framework
Basis.js - Production Ready FrameworkBasis.js - Production Ready Framework
Basis.js - Production Ready Framework
 
Basis.js - Production Ready SPA Framework
Basis.js - Production Ready SPA FrameworkBasis.js - Production Ready SPA Framework
Basis.js - Production Ready SPA Framework
 
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
 
Tdd php
Tdd phpTdd php
Tdd php
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Куда уходит память?
Куда уходит память?Куда уходит память?
Куда уходит память?
 
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 

Mehr von Alexey Tokar

Mehr von Alexey Tokar (9)

Graph theory basics
Graph theory basicsGraph theory basics
Graph theory basics
 
Fantastic caches and where to find them
Fantastic caches and where to find themFantastic caches and where to find them
Fantastic caches and where to find them
 
Conway's transformation
Conway's transformationConway's transformation
Conway's transformation
 
Bug prediction + sdlc automation
Bug prediction + sdlc automationBug prediction + sdlc automation
Bug prediction + sdlc automation
 
Bots on guard of sdlc
Bots on guard of sdlcBots on guard of sdlc
Bots on guard of sdlc
 
Bug prediction based on your code history
Bug prediction based on your code historyBug prediction based on your code history
Bug prediction based on your code history
 
Extend your REST API
Extend your REST APIExtend your REST API
Extend your REST API
 
Найти иглоку в стоге сена
Найти иглоку в стоге сенаНайти иглоку в стоге сена
Найти иглоку в стоге сена
 
когда тексты не только слова
когда тексты не только словакогда тексты не только слова
когда тексты не только слова
 

MongoDB в продакшен - миф или реальность?

  • 1. MongoDB в продакшене – миф или реальность? Алексей Токарь руководитель группы разработки в направлении медиасервисов
  • 2. 2 Наш самый обычный сервис – это… • 1 500 000 000 хитов в месяц • 2 000 000 уникальных пользователей в сутки • 4 000 RPS в пике • <70мс среднее время ответа • 15 обслуживающих серверов
  • 3. 3 Выбор СУБД для веб-сервисов
  • 4. 4 Как представляют себе MongoDB Уиииии!!! elcaracol.kiev.ua
  • 5. 5 А так MongoDB обычно работает… Эмм? care2.com
  • 6. 6 Иногда получается даже так :’( reddit.com
  • 7. 7 Как увеличить производительность? помоги маленькой ламе повысить производительность bestclipartblog.com
  • 8. 8 Можно вырасти вертикально если есть запас процессора/памяти/дисков bestclipartblog.com
  • 9. 9 Можно вырасти горизонтально если в ДЦ еще остались свободные сервера bestclipartblog.com
  • 10. Рецепты на данных структуры данных
  • 11. 11 JSON и BSON документы { "_id" : 1, "value" : "text", "array" : [ { "data" : 14 } ] } 44 00 00 00 01 5f 69 64 00 00 00 00 00 00 00 f0 3f 02 76 61 6c 75 65 00 05 00 00 00 74 65 78 74 00 04 61 72 72 61 79 00 1b 00 00 00 03 30 00 13 00 00 00 01 64 61 74 61 00 00 00 00 00 00 00 2c 40 00 00 00
  • 12. 12 Структура BSON документа документ размер поля [] терминатор тип ключ терминатор значение 1byte x01 (double) 1byte x00 1byte x00 4byte 18 3byte _id 8byte 1 { _id : 1 }
  • 13. 13 Поиск документа на диске (skip : 2) read size skip n = 3 O(n)
  • 14. 14 Индексное дерево. B-tree O(log n) wikipedia.org
  • 15. Рецепты на данных сохранение или изменение?
  • 16. 16 Доменный объект public class MyObject { private long id; private String title; ... public long getId() { return id; } public String getTitle() { return title; } public void setTitle( String newTitle ) { title = newTitle; } }
  • 17. public class TitleCommand extends Command { private String newTitle; private String oldTitle; public TitleCommand( MyObject o, String newTitle ) { super( o ); this.newTitle = newTitle; } @Override public void apply() { oldTitle = o.getTitle(); o.setTitle( newTitle ); } @Override public void undo() { o.setTitle( oldTitle ); } } 17 Класс для изменения названия объекта
  • 18. public class MyObjectService { @Autowired private MongoCommandsDao commandsDao; @Autowired private MongoMyObjectDao objectDao; public void updateTitle( MyObject o, String title ) { Command c = new TitleCommand( o, title ); c.apply(); commandsDao.save( c ); objectDao.save( o ); } } 18 Сервис изменения заголовка объекта
  • 19. public class MongoMyObjectDao { @Autowired private MongoOperations mongo; public void save( MyObject o ) { mongo.save( o ); } } 19 Простейшая реализация репозитория
  • 20. 20 Обновление объекта целиком • изменение всех деревьев индексов • блокировка всей БД на время записи документа • размещение объекта целиком на диске • добавление документа в oplog целиком – а значит еще раз запись на диск – передача объекта по сети для репликации
  • 21. 21 public class TitleCommand extends Command { private String newTitle; private String oldTitle; public TitleCommand( MyObject o, String newTitle ) { super( o ); this.newTitle = newTitle; } @Override public Update getUpdate() { return Update.update( "title", newTitle ); } @Override public void apply() { oldTitle = o.getTitle(); o.setTitle( newTitle ); } @Override public void undo() { o.setTitle( oldTitle ); } }
  • 22. public class MyObjectService { @Autowired private MongoCommandsDao commandsDao; @Autowired private MongoMyObjectDao objectDao; public void updateTitle( MyObject o, String title ) { Command c = new TitleCommand( o, title ); c.apply(); commandsDao.save( c ); objectDao.updateFromCommand( c ); } } 22 Рефакторинг сервиса под новую идею
  • 23. public class MongoMyObjectDao { @Autowired private MongoOperations mongo; public void updateFromCommand( Command c ) { Query query = new Query( Criteria.where( "_id" ) .is( c.getObject().getId() ) ); mongo.updateFirst( query, c.getUpdate(), MyObject.class ); } } 23 Рефакторинг репозитория под новую идею
  • 24. 24 Изменение поля объекта • изменение только одного дерева индекса (если поле было проиндексировано) • запись небольшого объема данных на диск • передача лишь изменяемой части документа по сети
  • 25. 25 Результаты для 10К документов .save() .update() ----------------------- ms Task name ----------------------- 47768 create 10653 read 40214 save ----------------------- ms Task name ----------------------- 44667 create 11199 read 02472 update
  • 26. Рецепты на данных выбор между вложенными и самостоятельными документами
  • 27. 27 Коллекция отдельных документов { "eventId" : 1, "author" : "Alice", "text" : "I like JavaDay 2014” "date" : "2014-10-17" } { "eventId" : 1, "author" : "Bob", "text" : "I enjoy JavaDay 2014” "date" : "2014-10-18" }
  • 28. 28 Коллекция отдельных документов • Плюсы: – если нужно вывести один документ, то поиск займет O(log n) времени – время записи документов O(1), так как он полностью размещается в конце файла данных
  • 29. 29 Список вложенных документов { "eventId" : 1, "comments" : [ { "author" : "Alice", "text" : "I like JavaDay 2014", "date" : "2014-10-17” }, { "author" : "Bob", "text" : "I enjoy JavaDay 2014", "date" : "2014-10-18” } ] }
  • 30. 30 Список вложенных документов • Плюсы: – маленькое индексное дерево – меньше чтений с диска, если нужно вывести сразу все • Минусы: – можно достигнуть лимита документа в 16МиБ и все перестанет работать. Сразу. – …
  • 31. 31 Добавление элемента в список • появление фрагментированного участка • запись объекта целиком в конец • перестроение индекса
  • 32. Растём вертикально • обновляйте поля, а не документы, когда это возможно • храните документы в массивах, если это допустимо и они не будут значительно расти
  • 33. Рецепты на кластерах репликация или шардирование?
  • 34. 34 Репликация данных throughput = 400%? master replica replica replica
  • 35. 35 Репликация данных • Плюсы: – растем линейно на чтение • Минусы: – нет выигрыша для операций записи – неизвестно какие данные получаем
  • 36. 36 Шардирование shard1 shard2 . . . . . . shardN
  • 37. 37 Шардирование • Плюсы: – растем линейно на чтение* – растем линейно на запись* – всегда актуальные данные • Минусы: – нужен правильный индекс и схема
  • 38. Рецепты на кластерах выбор ключа и схемы для шардирования
  • 39. 39 Монотонный шардирующий ключ Шардируем по date, userId или orderNum Все записи попадут на самый новый шард t
  • 40. 40 Монотонный шардирующий ключ • hash-ключ или равномерно распределенное значение • Каждая запись на произвольный шард t
  • 41. Рецепты на кластерах проблема рассеивания (scatter/gather)
  • 42. 42 Граф друзей в приложении 1 2 4 3
  • 43. 43 Очевидное решение { user : 1, friend : 2 } { user : 1, friend : 3 } { user : 1, friend : 4 } { user : 2, friend : 1 } { user : 2, friend : 4 } { user : 3, friend : 1 } Мои друзья: db.friends.find( { user : 1 } ); Мои фолловеры: db.friends.find( { friend : 1 } );
  • 44. 44 Очевидное решение { user : 1, friend : 2 } { user : 1, friend : 3 } { user : 1, friend : 4 } { user : 2, friend : 1 } { user : 2, friend : 4 } { user : 3, friend : 1 } Мои друзья: db.friends.find( { user : 1 } ); Мои фолловеры: db.friends.find( { friend : 1 } ); shard 1 shard 2 shard 3
  • 45. 45 scatter / gather problem latency shard 3 { user : 3, friend : 1 } shard 2 { user : 2, friend : 1 } { user : 2, friend : 4 } shard 1 { user : 1, friend : 2 } { user : 1, friend : 3 } { user : 1, friend : 4 } mongos • запросить данные • объединить • отсортировать 1ms 3ms 0ms total query
  • 46. 46 Производительное решение { user : 1, friend : 2 } { user : 1, friend : 3 } { user : 1, friend : 4 } { user : 2, friend : 1 } { user : 2, friend : 4 } { user : 3, friend : 1 } { user : 1, follower : 2 } { user : 1, follower : 3 } { user : 2, follower : 1 } { user : 3, follower : 1 } { user : 4, follower : 1 } { user : 4, follower : 2 } Followers Friends
  • 47. 47 Хороший ключ • высокое разнообразие значений • равномерное распределение по всему допустимому диапазону • попадание читающих запросов на один сервер
  • 48. Растём горизонтально • для масштабирования – шардирование • хороший ключ для шардов не монотонен и разнообразен • дублирование может значительно повысить производительность
  • 50. 50 writeConcern и readPreference – сила в балансе • writeConcern: – unacknowledged { w : 0 } – acknowledged { w : 1 } – replica-safe { w : >1 } – majority { w : “majority” } (n/2+1) • readPreference: – primary – primaryPreferred – secondary – secondaryPreferred – nearest
  • 51. Алексей Токарь руководитель группы разработки azazeltap@yandex-team.ru Спасибо :)

Hinweis der Redaktion

  1. стабильность данных операции записи операции чтения
  2. размер нашего документа film около 10КиБ
  3. …но есть два существенных минуса
  4. дефрагментировать - дорого