Базы данных. MongoDB

Post on 14-Jan-2015

847 views 3 download

description

Обсуждаем здесь: http://incubos.org/posts/2013/10/07/db-mongodb/

Transcript of Базы данных. MongoDB

MongoDB is a web-scaleКурс «Базы данных»

Антон Волохов

Yandex

7 октября 2013 г.

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 1 / 51

Содержание

1 Введение

2 API

3 Storage internals

4 Replication

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 2 / 51

Содержание

5 Sharding

6 Секретный ингредиент

7 Заключение

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 3 / 51

Введение Терминология

Терминология

Документ - Ряд в RDBMSКоллекция - Таблица в RDBMSБаза данных - Базы данных в MySqlПространство имён - Пара <база данных,коллекция>Нода - Процесс базы данных, осуществляющийхранение и поиск пользовательских данных надискеРеплика - Множество Node, обладающееполной копией одних и тех же данныхШард - Единица масштабирования БД

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 4 / 51

Введение Disclaimer

Disclaimer

Если есть вопрос, меня можно и нужно перебиватьНе на каждый вопрос я смогу ответить по ходулекцииНе на каждый вопрос я смогу ответить

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 5 / 51

API Декларированные цели

Декларированные цели

ПроизводительностьПростота использованияГоризонтальное масштабированиеОбработка эволюционирующих данныхКонкуренция с RDBMS

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 6 / 51

API MongoDB features

MongoDB features

BSON протоколJS консольХранимые процедурыMaster-slave репликацияШардирование без даунтаймаСистема хранения файлов GridFS

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 7 / 51

API MongoDB features

API

Хранимые процедуры> db.system.js.insert ({"_id" : "inc", "value" : f unc t i on (x)

{ re tu rn x+1}})> db.eval("inc(1)")2

ИндексыMapReduceУникальный первичный ключ> db.books.insert({foo:"bar"})> db.books.find(){ "_id" : ObjectId("5251664b629201a4d4164ec0"), "foo" : "bar" }

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 8 / 51

API Querying

Примеры запросов

Документыisbn = {_id: "0-321-34960-1",author: "B. Goetz",title: "Java Concurrency In Practice",ISBN :{"ISBN-10": "0-321-34960-1","ISBN-13": "978-0-321-34960-6"},"authors-list":["Brian Goetz", "Tim Peierls", "Doug Lea", "Joseph

Bowbeer", "David Holmes"]}

Запросыdb.test.insert(isbn)db.test.find({ "title" : /Java/ })db.test.update(isbn, { $push : { "authors-list" : "Joshua Bloch" }})db.test.insert({ "foo" : "bar" })db.test.find({ "title" : { $gte : "Java" }, "title" : { $lt : "Python"

}})

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 9 / 51

API Querying

Вложенные документы> db.items.insert({ foo : "foo", "bar" : { "first" : 1, "second" : 1 }})> db.items.insert({ foo : "foo", "bar" : { "first" : 1, "second" : 2 }})> db.items.insert({ foo : "foo", "bar" : { "first" : 2, "second" : 1 }})

Запрос на точное совпадение> db.items.find({ bar:{ "first" : 1 , "second" : 1 }})

{ "_id" : ObjectId("52517090629201a4d4164ec1"), "foo" : "foo","bar" : { "first" : 1, "second" : 1 } }

Запрос на диапазон значений> db.items.find({ bar : { $gte : { "first" : 1, "second" : "" }},"bar" : { $lt : { "first" : 2, "second" : "" }}})

{ "_id" : ObjectId("52517090629201a4d4164ec1"), "foo" : "foo","bar" : { "first" : 1, "second" : 1 } }

{ "_id" : ObjectId("5251709e629201a4d4164ec2"), "foo" : "foo","bar" : { "first" : 1, "second" : 2 } }

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 10 / 51

Storage internals Работа с файловой системой

Работа с файловой системой

Аллокейтим файлы на диске отдельно для каждойбазы данных-rw------- 1 mongodb nogroup 16M test.ns-rw------- 1 mongodb nogroup 64M test.0-rw------- 1 mongodb nogroup 128M test.1...-rw------- 1 mongodb nogroup 2.0G test.5-rw------- 1 mongodb nogroup 2.0G test.6

Создаём служебную базу данных (∼ 5% дисковогопространства)

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 11 / 51

Storage internals Работа с файловой системой

Кеширование

Не in-memory databaseНе занимаемся memory managementMemory-mapped filesFile system cache

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 12 / 51

Storage internals Работа с файловой системой

Файлы данных

ЭкстентУказатели на первую и последнюю записьПоложениеДлинаПространство имён

ЗаписьДлинаСмещение внутри экстентаСмещения предыдущей и последующей записейДокументPadding

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 13 / 51

Storage internals Advanced querying

В свете этого

УдалениеПомечаем пространство как свободноеНе пишем на диск

ДобавлениеЛенивоВ первый найденный свободный блок

ОбновлениеДокумент увеличился?Влезает ли обновлённый элемент в свой блок?

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 14 / 51

Storage internals Advanced querying

Администрирование

Проблемы1 Фрагментация данных2 Параллельное изменение одних и тех же файлов3 Неконтролируемое разрастание файлов данных

Решения1 compact2 глобальные блокировки на уровне базы данных3 repair базы

РезюмеНи одного адекватного решения

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 15 / 51

Storage internals Advanced querying

Пространство имён

ИндексыКоллекцииЭкстентыСтатистика

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 16 / 51

Storage internals Индексы

Индексы

B-ДеревоКомпозитный индексПо массиву и поддокументуЗапоминаем оптимальный план запроса.explain()

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 17 / 51

Replication Replication

Master - Slave

Запись только на одну машинуЧтение со всех машинНастраиваемая консистентность

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 18 / 51

Replication Replication

КонсистентностьНе проверяем, удалась ли записьОшибки записи в текущем соединении

getLastError()Ждёт, когда W машин запишут все изменения втекущем соединении с момента предыдущегоgetLastError()По-сути, точка синхронизации

Не верьте бенчмаркам!Если не вызывать getLastError(), клиент будет писать вмонгу, не зная, прошла ли запись. Результат - over9000rps, при неопределённом числе удачных записей.

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 19 / 51

Replication Replication

Replication internals

Лог операцийПростейшие преобразования запросовТранзитивность репликацииТекущий мастер выбирается голосованием

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 20 / 51

Replication Replication

Replication internals: oplog polling

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 21 / 51

Replication Replication

Replication internals: voting

Все машины реплики знают друг о другеМастер пингует все машины своей репликиЕсли мастер не видит кворум, он снимает с себяполномочияПроцесс голосования инициирует машина,которая не может найти мастераГолосование начинается в случае, если мастер невиден кворумом

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 22 / 51

Replication Replication

Replication internals: Rollback andRecovery

1 Откатываются все изменения, которых нет намастере

2 Накатываются все изменения нового мастера

NB!Нет автоматического разрешения конфликтовНет внятного оповещения о существованииконфликтов

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 23 / 51

Sharding Overview

Overview

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 24 / 51

Sharding Overview

Overview

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 25 / 51

Sharding Sharding meta

Sharding meta

Точечные запросы по шардамАвтоматическая балансировкаЛокализация данных

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 26 / 51

Sharding Sharding meta

Sharding metaА что внутри?

Где хранить метаданные?Как обеспечить надёжность?Как сгруппировать данные для шардирования?

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 27 / 51

Sharding Sharding meta

Configuration Server

Нет репликацииСинхронная записьTwo phase commitRead-Only при отказе одной из машин

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 28 / 51

Sharding Sharding in a Nutshell

Шардируем

1 Объявляем коллекцию как шардированную2 Выбираем поле, по которому будут строится чанки

ЧанкНачало диапазонаКонец диапазонаОбъемПринадлежность к шарду

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 29 / 51

Sharding Sharding in a Nutshell

Балансируем

Периодичный бэкграунд процесс роутера

Workflow1 Пытаемся взять lock2 Если удалось, опрашиваем каждое пространство

имён3 Смотрим на распределение и заполненность

чанков4 Определяем, нужно ли делить или перемещать

чанки5 Осуществляем миграцию

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 30 / 51

Sharding Sharding in a Nutshell

Решаем проблемы

ПлохоХодить на каждый запрос в амстердам с западногопобережья - не комильфо.

Кеширование на стороне роутера

Всё ещё плохоПосле каждой миграции, кешированная информациястановится протухшей.

Оповещаем роутеры, они обновляют кеш

На хлеб уже мажется.А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 31 / 51

Sharding Sharding in a Nutshell

Решаем проблемы

Но ещё пахнетНе можем контролировать распределение чанков; нетзаявленной локализации данных

ТэгиСвойство шардаОтображение из диапазона ключей в тэг

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 32 / 51

Sharding Sharding in a Nutshell

Тэги

{ ns : "test.books", minKey : { date : 01.01.2013 }, maxKey : {date : $MaxKey}, tag : "ssd" }

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 33 / 51

Sharding Sharding in a Nutshell

Не решаем проблем

Не предусмотренноеDDL-убивашкаНельзя так просто взять и поменять ключшардированияЕсли поздно объявить коллекцию шардированной,все существующие данные навсегда окажутся водном чанкеЧанки не умеют склеиваться и не умирают приопустении

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 34 / 51

Sharding Ключ шардирования

Выбираем ключ шардированияСхема:

100 000 000 записей{url: "http://www.imdb.com/title/tt0795176/", domain : 1, title:

"Planet Earth", "air date": 2007, seasons:[1], rating:9.5cast:<...>, similar:<...>, description:<...> }

Полный урл уникаленНекоторые домены могут содержать десятки тысячдокументовСписок доменов меняется редко, информация по урламменяется часто, домены имеют возрастающийидентификатор

ЗапросыДостать одну сущность по урлуДостать 1000 сущностей по урламДостать всё из www.imdb.comОтгрузить всю базу

Как правильно выбрать ключ шардирования?А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 35 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (0)

Возможные вариантыObjectId()Поле с рандомным значениемУрлХеш от урлаПара <хеш от домена, хеш от урла>

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 36 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (1)

ObjectId

ПреимуществаМонотонно возрастает - легко собрать чанк

НедостаткиМонотонно возрастает - запись в один шардМонотонно возрастает - пустые чанкиНевозможно поддержать уникальность урлов вразных шардах

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 37 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (2)Случайное значение

ПреимуществаРавномерная распределённость - запись во всешардыРавномерная распределённость - нет пустыхчанков

НедостаткиРавномерная распределённость - очень долгаямиграция, стынет кешНевозможно поддержать уникальность урлов вразных шардах

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 38 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (3)

Урл

ПреимуществаУникальность урловЛокализация запросовЗапись во все шардыМало пустых чанков

НедостаткиТяжеловесный индексСложно собрать чанк - долгая миграция чанка

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 39 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (4)

Пара id домена- хеш от урла

ПреимуществаТе же, что и от урлаПлюс бесплатный индекс по доменуБыстрая миграция, если обновления по доменуприходят батчамиЛегковесный индекс

НедостаткиДолгая миграция, если гипотеза о батчах невернаИногда чанки пустеют

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 40 / 51

Sharding Ключ шардирования

Выборы ключа шардирования (5)

РезюмеНа какие запросы хотим отвечать?Монотонно возрастающий ключ - плохоПолностью рандомный ключ - плохоШардовый ключ участвует в запросе -дополнительный профит

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 41 / 51

Sharding Ключ шардирования

Выборы ключа шардирования. ИтогиСтудент! Помни!

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 42 / 51

Секретный ингредиент Почему MongoDB не production-ready?

Почему MongoDB не production-ready?

Писалась исходя из того, что она работаетТолько SocketException в логахСовершенно не описано поведение внеблагоприятных условияхНекачественные мониторинги

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 43 / 51

Секретный ингредиент Почему MongoDB не production-ready?

Кстати о мониторингах

db.serverStatus()

Возвращает кучу данных о базеВсе показатели - в миллисекундах от старта сервераМониторинг дёргает serverStatus

А теперь представим, что система перегружена1 Дёргаем serverStatus2 Через 20 секунд получаем ответ3 Через минуту дёргаем ещё раз4 Через 20 секунд получаем ответ5 Разность значений может быть статистикой за любой

промежуток времени от 40 до 80 секунд

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 44 / 51

Секретный ингредиент Почему MongoDB не production-ready?

Кстати о мониторингах

А теперь делим разность из предыдущего слайда на 60И получается, что за последнюю минуту половина базбыла заблокирована на чтение в течение не меньшечем 90 секунд.

Не вся статистика разделена по пространствамимёнНе знаем, какие именно запросы перегружаютбазу

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 45 / 51

Секретный ингредиент Почему MongoDB не production-ready?

WAT?

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 46 / 51

Секретный ингредиент Эксплуатация

Если действительно нужен функционал

1 Предельно уяснить, какие запросы важные2 Описать ограничения уникальности3 Построить ключ шардирования4 Не выполнять DDL на боевых базах без крайней

необходимости5 Всегда вручную передёргивать роутеры после DDL6 Заблаговременно масштабировать7 Не тянуть с шардированием

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 47 / 51

Заключение Сухой остаток

Сухой остаток

Почему MongoDB - это действительно крутоОднокнопочные шардирование и репликацияБогатый язык запросовВторичные индексы

Почему нужно трижды подуматьНечитаемые логиНепонятно, где у монги болитПри неосторожном обращении, легко превратитьвсё в тыквуНе жмутся названия полей

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 48 / 51

Заключение Осталось за кадром

Осталось за кадром

http://www.kchodorow.com/blog/2010/08/23/history-of-mongodb/ - История созданияпродуктаАвторизацияGridFSПрофилированиеAggregation frameworkMapReduce

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 49 / 51

Заключение Осталось за кадром

Литература

http://www.amazon.com/MongoDB-Definitive-Guide-Kristina-Chodorow/dp/1449344682http://docs.mongodb.org/manual/http://www.kchodorow.com/blog/index.php?s=mongodb

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 50 / 51

Вопросы?

Вопросы?

Почта a.v.volokhov@gmail.com

А. В. Волохов (Yandex) MongoDB 7 октября 2013 г. 51 / 51