|
Персональные инструменты |
|||
|
Сравнительный анализ хранилищ данных (Олег Царев и Кирилл Коринский на ADD-2010)Материал из CustisWiki(перенаправлено с «102-SQL-vs-NOSQL-add-2010»)
Короткая ссылка: 102-SQL-vs-NOSQL-add-2010 СодержаниеАннотация
Видео
Видео в HD-качестве, смотрите в полноэкранном режиме.
HTML-код включения <iframe src="http://player.vimeo.com/video/22753732?byline=0&portrait=0" width="720" height="405" frameborder="0"></iframe>
ПрезентацияСтенограмма
Постановка проблемы
Чтобы дать ответ на эти вопросы, нужно понять следующее.
В нашем докладе вы узнаете:
В первой части Олег опишет проблемы, вынуждающие нас использовать распределенные хранилища данных. А я расскажу, какие аспекты распределенных систем важны при выборе хранилища. После этого, мы вместе рассмотрим имеющиеся реализации. Друзья в социальной сетиДрузья в социальной сети Задача: получить список друзей.
Для начала давайте рассмотрим несколько популярных социальных сетей. Почему они интересны? Социальные сети имеют весьма жесткие характеристики по нагрузке на них, много пользователей, много показов в секунду, и требуется решить немало проблем, чтобы система работала удовлетворительно, без перебоев. Собственно, мы выбрали лишь часть из них, это Facebook и их российский аналог ВКонтакте, МойМир, социальная сеть Mail.Ru, и для сравнения, игрушечная сеть на десять пользователей, Toy net, просто как пример.
Матрица смежности — таблица:
Задача, которую мы будем исследовать, выглядит весьма просто. Нужно ограничить во-первых, пользователей, во-вторых, отношения между ними. Т.е. «кто с кем дружит?». Данные отношения представляются обычно в виде графов. Граф — это множество вершин, и ребер. Вершины у нас — это пользователи, Петя-Маша-Вася, а ребра — это отношения между ними, вершины соединены ребрами. Отношения бывают разные. Facebook, ВКонтакте, и наша игрушечная сеть ToyNet — это просто обычная связь, либо дружит, либо нет. А МойМир имеет более сложную структуру, связи детализированы — брат, родственник, дружит, ненавидит, т.е. там весьма сложные отношения возможны. И для хранения простых связей, ВКонтакте, Facebook, ToyNet нам требуется один бит, элементарная единица, а в МойМир требуется шесть байт. Информацию мы взяли из доклада на Highload, за 2009 год от Mail.ru. И представляется все это обычно в виде матрицы смежности. Т.е. у нас столбцы и строчки — это пользователи, а их ячейки на пересечении — это отношения.
Список смежных вершин каждый элемент:
Иным представлением является список смежных вершин. Это просто пара из двух идентификаторов пользователей, организованная в виде списка. Т.е. если у нас в списке есть элемент UserID Пети и UserID Маши, значит между ними есть отношения. Если этой пары в списке нету, значит отношения между ними нет. Ну, в случае МоегоМира нам требуется еще дополнительные шесть байт на описание собственно отношений. Что между Машей и Петей у нас есть — дружба, ненависть, родственные какие-то отношения. Генерация списка друзейКаждый элемент:
Давайте теперь рассмотрим, как для какого-то пользователя, например для Пети, получить список всех его отношений. Суммарный объем связи у нас в Facebook/ВКонтакте это два идентификатора пользователя, так как у пользователя берется четыре байта. Почему мы говорим про байты — это важно, об этом мы поговорим чуть позже. Тут все очевидно. ToyNet — нам достаточно одного байта. Матрица смежности:
Так вот, как выглядит генерация списка друзей для матрицы смежности. Напоминаю, это табличка, из столбцов-пользователей и строчек. Мы должны взять строчку из этой таблицы, например для Пети, и пройтись по всем ее ячейкам. Каждая ячейка относится к какому-то пользователю, и сообщает отношение Пети с этим пользователем.
Просто → Список смежных вершин:
В случае списка смежных вершин, напоминаю, это список из пар двух идентификаторов, требуется более сложный алгоритм. Каждый элемент списка, состоит из идентификатора «Кто?», идентификатора «С кем?», т.е. кто с кем имеет отношения. «Что?» у нас есть только в МоемМире. И для генерации списка мы должны взять полный список, и отфильтровать его по «Кто?». Если у Пети ID пользователя это какое-то число, то мы должны отфильтровать спосок по этой компоненте, по этому числу. Это самый простой алгоритм, и обратите внимание — он у нас требует перебрать все отношения между пользователями. Понятно, что это нам не интересно. Это слишком долго будет.
Сложно → Список смежных вершин:
МасштабыmemoryМатрица смежности:
Теперь давайте мы оценим, сколько потребуется памяти для этих представлений. Казалось бы, ничего сложного, список друзей. Цифры ошеломляющие. Фейсбук, 500 миллионов пользователей, даже если ячейка занимает один бит, занимает 30 тыщ петабайт. Мне страшно от этой цифры. И естественно, для современной техники это решение не представимо, они слишком дорогие. Т.е. мы еще на первом этапе, оценив объемы нашей системы, можем отсечь какие-то заведомо неверные решения. А эти решения, они достаточно напрямую отображаются на наши структуры данных.
Список смежных вершин (сложно):
В случае списка смежный вершин, сложный вариант, напоминаю, устройство через список, объемы уже более реальные. Точный расчет, если кому-нибудь будет интересно, возникнут сомнения, можно меня в конце попросить, я покажу, как это считалось. Ну, уже что-то похожее на реализуемую систему. Фейсбуку требуется 69 гигабайт, чтобы представить всех друзей, вКонтакте чуть поменьше, МойМир — чуть побольше, потому что там, связи сложные. А опять же, оценки делались исходя из цифры, что в среднем пользователи дружаться со 150 друзьями. Так как публичной информации нет, по поводу среднего числа друзей, и на этапе проектирования системы мы не можем эту цифру знать. Поэтому, приходится брать некоторую оценку. У кого-то друга, у кого-то пятьсот друзей, … такую оценку, иначе как с потолка, или из аналитических отчетов взять неоткуда.
latencyDDR3 ECC2 (DDR3-1066E):
Давайте теперь оценим, сколько будет стоить тема, которая в состоянии хранить эти данные, в рамках одной машины, не прибегая к распределенным системам. Мы взяли топовую память, по скорости, DDR3 ECC2, ее пропускная способность 8 гигабит, стоит модуль $1500-2000, ну и можете себе представить, сколько будет стоить сервак, который будет работать с этой памятью. Дальше идет важный такой момент, железного уровня. Когда мы говорим, что пропускная способность памяти восемь гигабит, т.е. один гигабайт в секунду, народ почему-то думает, что они могут эти восемь гигабит, получить при абсолютно хаотичном доступе, на то это и RAM, Random Access Memory, память со случайным доступом. К сожалению, это не так. При обращении к памяти мы не можем прочитать произвольный байт. Память всегда читается постранично, одна страничка это четыре килобайта. И на самом деле, вот эти восемь гигабит, это не значит, что мы прочитаем нам нужный гигабайт, это означает, что мы можем в секунду прочитать два миллиона страниц, по четыре килобайта[1]. Это очень важный момент, который сильно влияет на дальнейшие выкладки. Матрица смежности:
Давайте теперь представим, сколько запросов в секунду будет выдавать наш сервер. В случае матрицы смежности, допустим у нас есть сервер с таким объемом памяти, это получается… ну на такой памяти очень медленно. 16 запросов в секунду, 80, 40. Игрушечная сеть — два миллиона, ну в общем, один запрос — одна страницу. Это решение нам не интересно, оно слишком дорогое. Масштабы: memory/latency Список смежных вершин (просто)
Простой вариант со списком смежных вершин, где мы делаем полный скан всех отношений, нам тоже не интересен. Потому что он неэффективен.
Список смежных вершин (сложно):
А сложный вариант, где все отношения связаны с друг с другом, для каждого пользователя, они позволяют, они требуют сделать…
напоминаю цифру — 150 друзей в среднем, т.е. для каждого пользователя нам нужно сделать 150 чтений памяти, причем случайных.
И это означает, что мы не 150 элементов прочитаем, а прочитаем на самом деле 150 страниц памяти, т.е. не какие-то байты,
а Зачем я долго рассказывал вам про байты, странички и так далее? Обратите внимание, мы можем выжать на топовом железе 14тысяч запросов в секунду, а изначальные требования — пять миллионов запросов в секунду для фейсбука. Ну это все как бы очевидно, можно было так долго не говорить, но нужно было почувствовать порядок. Т.е. у нас производительность на топовом железе в пять тысяч раз не дотягивает до желаемого. Логичный вывод — нам придется строить распределенную систему, нам не избежать проблем, даже на такой простой задаче. Более сложные задачи требуют, естественно, еще более сложных решений. Я беру максимальную пропускную способность памяти, я беру минимально необходимый объем оперативной памяти, и все равно мы не укладываемся на порядки. Исходя из этого, кстати, можно оценить, например, сколько серверов стоит в mail.ru, или там у facebook-а, в лучшем случае. Оптимизация матрицы смежности
Давайте рассмотрим еще паручку простых оптимизаций. Матрица смежности — это таблица «пользователи/пользователи», ячейка — отношения между ними. Она у нас сильно разряжена. Потому что мы храним по сути, отношения пользователя для каждого с каждым, а он дружит естественно не со всеми, а с каким-то подмножеством, в среднем — 150 человек. Это означает, что у нас очень большие элементы матрицы — пустые, и мы можем делать сжатие, т.е. пустые регионы выкидывать. Памяти у нас потребуется меньше, но появляется проблема фрагментации, код сильно усложняется. Т.е. для оптимизации, чтобы уменьшить объем потребляемой памяти, нам приходится идти на уступки. С усложнением кода. Вместо простой структуры, мы имеем что-то сложное. Чем сложнее код, тем дольше его разрабатывать и отлаживать. Тем больше с ним проблем, тем более непредсказуемо он себя ведет.
Оптимизация списка смежных вершин
Оптимизация списка смежных вершин, ну вот, мы уже одну применили, связали все в список, можно еще сделать группировку данных. Когда для пользователя Пети, все его связи лежат рядышком. Проблемы те же самые. У нас возрастет потребление памяти, потому что для каждого пользователя придется резервировать место для его новых друзей. Нам придется производить какую-то переупаковку данных, т.е. возникает проблема, это становится тоже сильно сложнее. А тогда можно будет не хранить информацию о следующих связях
Кирилл Коринский: А давайте вопросы в конце? Олег Царев: Информацию о следующей связи конечно хранить не придется, однако нам придется резервировать место, посколько для одного пользователя нужно хранить связи рядышком, а у одного пользователя много друзей, а у другого — мало. А если не поместилось? А если осталось пустое пространство? Это очень большая проблема в разработке. Лучше не станет, если хотите, можем посмотреть более подробно в конце. Ну, с друзьями все понятно, мы имеем классическую проблему выбора между памятью и задержками. Т.е. либо мы имеем большую память и какие-то задержки, иногда приемлимые, иногда не очень. Либо мы памяти тратим меньше, но все равно у нас есть проблема задержек. Memory и Latency это две первые такие точки экстремума, между которыми надо выбирать. И третья, неявно рассмотренная — это сложность кода. У нас здесь компромисс — потребляемая память, задержки, сложность кода. ВидеоПостановка задачи
Можно рассмотреть другую задачу. Видео. YouTube. Пользователь загружает данные на сервер, они там должны хранится, и раздаваться ему по требованию. Потом будет доклад Макса Лапшина, кстати, это один из разработчиков ErlyVideo, кстати, с ним можно будет еще на эту тему поговорить, какие там возникают проблемы. Мы рассмотрим крайне упрощенную ситуацию. У нас есть различные кодеки. Кодеки — это алгоритмы сжатия видео. И эти кодеки, имеют опять же, отличные характеристики. У нас снова встает проблема выбора, между тем, сколько ролик будет занимать, сколько он будет конвертироваться, сколько вычислений потребуется сделать, для конвертации. Он может конвертировать долго, но мало потреблять, с другой стороны мы можем конвертировать быстро, но потреблять процессор гораздо больше. Видео: решение
Мы рассмотрим два самых простых случая. Это несжатое видео, это просто 24 кадра в секунду, и один из новых кодеков, весьма эффективный, H.264. Видео: «Экстремумы»
И снова у нас возникает та же самая проблема. Проблема выбора. H.264 требует весьма трудоемких вычислений, т.е. каждое загружаемое пользователем видео придется конвертировать. Т.е. нам требуются процессорные мощности, нам недостаточно просто памяти, нам нужен еще быстрый процессор. Но с другой стороны, несжатое видео требует очень много памяти для хранения. И в зависимости от используемого кодека у нас будет совершенно разное железо. Совершенно разный бюджет. Но помимо этих двух аспектов, CPU и Memory, у нас снова возникает проблема Latency, это задержки. В случае несжатого видео, у нас будет проблема чтения, загрузки роликов с сайта. Чем больше занимает ролик, тем дольше пользователь его загружает, у него может быть маленький канал, и так далее. Но в случае H.264 потребуется больше времени на конвертацию. Мы снова сталкиваемся с проблемой компромиссов — что мы хотим? Если у нас, например, идет какая-то обработка, рендеринг видео на кластере, фильм например, у нас сеть очень быстрая, и мы можем работать с несжатым видео. Если у нас именню YouTube, то раздача видео по тонким каналам конечным пользователям, то нам, конечно, естественно, чтобы видео кушало поменьше. Видео: выводы В задаче с видео тоже есть «экстремумы»
А выводы вполне очевидны. Нам приходится опять выбирать, и нет идеального решения. Каждое решение зависит от вашей задачи. И в зависимости от вашей задачи, меняется требование к аппаратуре.
Основные оси
Если это все подытожить, мы видим следующую картинку. У нас есть несколько ресурсов. Процессор, память и задержки. Еще важный критерий — для конкретно разработчиков, для инженеров сложных систем — это сложность кода. Чем сложнее в нем разбираться, дольше исправлять ошибки, дольше разработатывать какие-то новые фьючерсы, ну и собственно, проект становится менее управляемым, риски управления возникают.
Производные оси
С другой стороны, здесь есть оси, которые я называют производные, производные с точки зрения инженеров, для менеджмента они наоборот первичны. Это собственно бюджет проекта, от него зависит, какую мы можем нанять команду, насколько она много будет уметь, это опыт разработчика на этом слайде. От этого зависят сроки разработки, чем более крутых разработчиков мы нанимаем, тем быстрее они делают систему. От этого зависит опять же аппаратура. Если сделать решение влоб, которое работает опять таки на десяти друзьях, — для этого и пример приведен («У нас все работает быстро»). Когда пользователей становится несколько тысяч, требуется уже мощный сервер. Для миллионов пользователей это решение не работает вообще. Ну и очень важным момент в нашем докладе, какие у нас есть инструменты, чем они нам помогут. Эта первая часть подводит к очень важному вопросу — не бывает универсальних хранилищ, не бывает универсальных решений. Серебрянной пули нет. Вам всегда придется искать и думать, какая у вас задача, и какие взять решения. Выводы
Можно сформулировать тезис, один из ключевых тезисов доклада. Задача инженера сложных систем, это найти компромисс, между всеми требованиями. Это также задача и менеджмента, и также задача инвестора, это задача всей команды, которая разрабатывает систему. Это нужно у себя держать в голове. Самое главное — это конечно, цель. И надо понимать — иногда мы не можем разработать Фейсбук на старом дедушкином сервере. Это не будет работать. Я и в сетевых дискуссиях, и на докладе своем как-то наблюдал, что люди почему-то не задумываются про эти моменты. Не понимают их важность. Именно поэтому я рассмотрел «проблему с друзьями». Ключевые факторы, влияющие на выбор решения, я упомянул. Мы поняли, что нам придется строить систему распределенную, и искать компромисс. Дальше в следующей части Кирилл рассмотрит, чем эти системы характеризуются, и на что нужно обращать внимание, при выборе хранилища под ваши задачи.
Вопрос, скорее замечание. h264 на самом деле быстрый кодек, только он конвертируется специализированным железом.
Олег Царев: Я охотно допускаю… Повторите пожалуйста…
Было высказано замечание, что кодек h264 конвертирует достаточно быстро. Я охотно верю. Я не разбираюсь в видео вообще. Я это взял просто как пример, в качестве иллюстрации. Это игрушечный совершенно пример, его цель — познакомить с проблемами. Есть небольшая ошибочка в оценке скорости, использовался метод полного перебора, полный поиск. На самом деле, если построить на B-дереве или на 2/3-дереве там достаточно возрастет скорость
Во-первых, я хочу спросить, сколько попросит разработчик, который знает, что такое BTree-дерево? Ну это достаточно стандартный алгоритм
Это стандартный алгоритм, но я знаю очень немного людей, которые понимают, что такое btree. Для примера — в аналитической базе, которую я разрабатывал два года назад, BTree-деревья писались четыре года. И спустя четыре года мы в них находили ошибки. Кирилл Коринский: А к вам такой вопрос — вы сами пробовали реализовать btree-дерево? Олег Царев: Я собственно реализовывал btree-дерево. Было дело, только не такое большое по объему данных
Ну объемы данных были 200-300 Гигабайт. У меня были поменьше…
Еще вопросы? Действительно ли память считывается по четыре килобайта? Мне казалось там по 64-128 байт там все считывается.
Эти 64-128 это на самом деле немного другие цифры. Это ассоциативность кеша процессора, а я говорю про шину памяти. Что, память в одной транзакции считывает 4Кб и все тут? Т.е. random-access в 4000 раз медленнее, чем последовательный?
Нет, естественно мы вычитываем один и тот же объем. Просто когда мы последовательно вычитываем данные, мы всегда в рамках одной страницы вычитываем четыре килобайта. В случае random access доступа, нам придется выкидывать большую часть этих данных. Нет, я понимаю. Но следует ли из этого, что считывать память хаотично, это будет в 4096 раз медленнее, чем считывать ее последовательно.
Если вы читаете по одному байту из каждой страницы, то да, это будет в 4000 раз медленнее. … я это проверю…
Есть такая хорошая книжка Криса Касперского, «Техника оптимизации программ. Эффективное использование памяти», там это рассматривается. … я понимаю, что random access намного медленнее, просто в это не верится…
Давайте я это обсуждение на потом отложу. Еще вопросы?
Олег Царев: Я бы хотел немного процитировать этот момент. Я взял естественно ограниченный случай, нас очевидно интересует не страница памяти, 4Кб, она попала в кеш процессора, дальше мы работаем с кешом процессора и…
Олег Царев: Давайте мы рассмотрим этот тест отдельно, если останется время. Сейчас Кирилл начинает к сожалению. Андрей Аксенов: … Твои оценки неправильные, в две сотни раз. Олег Царев: Это мы обсудим после доклада. Что такое распределенные хранилищаВиды партицирования
Так вот, кончились всякие теоретические вещи, в смысле рассуждения, теперь начинаются достаточно сложные и теоретические вещи. Во-первых, кто-то знает в зале, что такое партицирование? Ладно. Поехали. Партицирование можно делать несколькими способами. Первый — это функциональная декомпозиция. Олег Царев: Кирилл, расскажи пожалуйста, что такое партицирование. Знает достаточно мало народу, что это такое. Кирилл Коринский: Фактически, это распределение данных, когда ты разрезаешь свои куски данных, каким бы то ни было образом, по узлам твоего кластера. Для примера можно представить базу данных, когда данные не влезают в одну таблицу, по объему на сервере. Или если они влезут в одну таблицу performance будет падать, соответственно, делаешь горизонтальное партицирование, раскидывая разные строчки. Также можно делать вертикальное партицирование, раскидывая просто по колонкам. Олег Царев: Ну тут наверное, я немного прокомментирую все-таки, партицирование — это просто разделение данных, а не страшное слово, в результате, партицирование — это когда мы разделяем данные на части. Кирилл Коринский: Именно горизонтальное, именно целостные данные, куски, именно строчки. В базе данных мы будем разделять именно строчки. Олег Царев: Да, горизонтальное партицирование — это разделение отдельных компонент. В случае с друзьями, можно сказать, что горизонтальное партицирование, это у нас половина наших связей, а вертикальное партицирование, это когда мы «Кто?» и «С кем дружит?» разносим на разные узлы. Кирилл Коринский: Также есть функциональная декомпозиция, это когда партицирования, как такового нет, но вы это делаете просто руками, тем или иным образом.
Manual partitioning
приложения
Что такое разделение руками? Это разделение данных на уровне приложения, мы пишем некую систему, которая каким-либо образом определяет в какое из нескольких хранилищ будут направлятся наши данные. Есть такое понятие, distributed artifaction, вот он фактически и есть.
Automatic partitioning
Иные аспекты партицирования
Репликация
Транзакции
после исполнения на текущем узле текущем узле.
после исполнения на всех узлах всех узлах.
выдавал различные данные.
Пример:
Обычная СУБД данные которой лежат на одном сервере. Она не может стать неконсистентной, а данные читает только с одного storage к которому она имеет монопольный доступ. Пример:
Система с несколькими мастер-базами, которые обновляются синхронно. Она всегда корректна, потому что транзакция отрабатывает, только если изменения удалось распространить по всем серверам БД. Она продолжает корректно работать по крайней мере на чтение, если один из серверов падает. А вот попытки записи будут обрываться или сильно задерживаться, пока система не убедится в своей консистентности.
Пример:
Система переживает падения части серверов, но когда они входят в строй, они будут выдавать пользователям старые данные.
CAP Solution
Первый вариант, пожертвовать, например, Consistency. Тем самым в случае потери комментариев, за последние пару минут, мы не получим, какой-то сильной проблемы. Мы можем развить этот вариант и составить систему, которая будет кускам удоволетворять разным свойствам CAP теоремы. Например, комментарии будут жить в +A+P-C, а финансы -A+P+C. Но наиболее интересным вариантом является понимание, что CAP теорема накладывает на систему ограничения в определенный момент времени. В другой момент она может иметь отличные свойства. Interface: access
Олег Царев: Один из самых важных моментов, это интерфейс…
Олег Царев: Ну тут у нас будет запись, интересующиеся смогут посмотреть. Лицо базы — это ее интерфейс. Способ, которым мы получаем данные, или делаем поиск, запускаем запросы. И именно вокруг этого потом ломаются копья. SQL или NOSQL? Это одна из причин, по которой мы делам совместный доклад. Чтобы не было ангажированности в пользу того или иного решения. Интерфейс у нас грубо говоря можно разделить на четыре части. Это некоторые клиентские библиотеки, фактически все базы их имеют. Это стандарт ODBC, который для Microsoft SQL-сервера, потом для других баз. Embedded базы, встраиваемые, т.е. в которой движок базы напрямую интегрируется в ваше приложение. И некоторый простой текстовый протокол. Telnet. Вплоть до того, что можно к хранилищу… Кирилл Коринский: Маленькая ремарка, есть базы, например тот же memcache, к которому по другому просто не прицепишься. Или тебе надо использовать сторонние какие-то клиенты, база сама предоставляет только один простой протокол (citilog?). Олег Царев: Ну да, прицепились telnet-клиентом, посылаем обычные текстовые команды, получаем читаемый текстовый ответ. Interface: method
Помимо, собственно, способов подключения, у нас есть еще вопрос, как собственно выглядит взаимодействие с базой. Т.е. это может быть API, это может быть некоторый набор функций, куча классов для работы с базой, это может быть какой-то специализированный язык. Эти языки называются Domain Specific Language, DSL. Языки разработаны под какую-то конкретную задачу. Т.е. мы на SQL-е не можем сделать отдельное вычисление, объявляет ли он себя как Тьюринг-полный? — это хороший вопрос. Мы не можем на нем написать произвольную программу. Но мы на нем можем сделать любую выборку данных. Именно поэтому, … кастомизированы. Самый популярный — SQL, остальные все языки достаточно местечковые. Следующий вопрос — это то, насколько полно мы работаем с данными. Одни данные позволяют делать нам только поиск, такие как Sphinx, другие позволяют делать полноценные запросы.
Interface: abstraction level
Мы не просто просим из достать какие-то данные, мы просим их сделать с ними какие-то вычисления. Зачем нам это нужно? Во-первых, для удобства. Мы написали один запрос и получили обработанный результат, например, статистику. Во-вторых, часто это быстрее. Если нам например нужна сумма в какой-то колонке, движки умеют оптимизировать такие вычисления. При этом вычислять ее во время добавления данных. Обзор доступных хранилищInterface: реализации
У нас тут есть обзор, я думаю, лучше просмотреть слайды. Мы свели все реализации воедино, у популярных баз, и вы можете под ваши задачи выбрать, что вам интересно. Т.е. какой-нибудь критерий, упомянутый ранее. В частности, это еще интересно при интеграции между базами данных.
Storage
Следующий вопрос — это storage, где данные находятся. Это очень сильно влияет как на эффективность работы, так и на другие характеристики, такие как консистентность. Тут достаточно все просто. Оперативная память, файловая система, и голый раздел на диске. Сетевые хранилища мы не рассматриваем, потому что они описываются как распределенная система в нашем обзоре. А для них тоже самое верно. Storage: реализации
Большинство баз у нас умеет работать с файловой системой, отдельные базы живут только в памяти.
Persistent
Следующий важный вопрос — это persistence, это как данные хранятся, насколько долго они хранятся. Например, для кеша root-сервера, мы можем данные терять, это последняя строчка, когда persistence отсутствует, нам не страшно потерять данные. Полный persistence, это когда мы считаем денежные транзакции, мы не имеем права терять деньги клиентов. И есть еще такое понятие, как частичный persistence, он может применятся в системах, когда мы можем потерять несколько последних записей. Зачем он нужен? Ну потому, что он работает быстрее, чем полный persistence.
Persistent: реализации
Тут у нас есть сводная таблица, большинство поддерживают либо loose, либо полный persistence. Только Oracle поддерживает все три части одновременно.
Динамическая типизация
И следующий, очень важный вопрос, это типизация. Типизация — это некоторые типы, некоторые свойства наших данных. Мы либо указываем явно, например, мы указываем в SQL время колонок, либо типы сопоставляются во время вычисления. Т.е. мы создали таблицу и описали — здесь у нас числа, а здесь у нас строки. А в Javascriptе мы работаем с данными исходя из контекста. Вот динамическая типизация, это как раз случай, когда мы не знаем заранее, типы данных, с которыми мы работаем. Они могут быть любые. Из плюсов это то, что мы можем в одной таблице[2] хранить и тексты и строчки и все подряд. Это например, интересно для блогов, для постов. У нас там могут лежать и картинки, могут лежать тексты, а может быть там какая-то очень сложная структура даже. Например, либо HTML, либо Plain-текст. И удобно это тем, что у нас, в принципе, обработчик всегда один. Мы обрабатываем данные и всегда проверяем, какой у нас здесь тип. Если это строка, то мы ее выводим, если это картинка, то мы ее рисуем. Статическая типизация
У статической типизации, за которую часто ругают SQL, где нам нужно явно указывать типы, у табличек, у колонок, у индексов, — у них есть другие, очень важные плюсы. Во-первых, это целостность данных. Если мы знаем, что число — всегда число, база нам не даст записать строчку… Например, пользователь вместо номера паспорта при покупке билета указал имя и фамилию. Понятно, мы проверяем это еще при вводе, но если вдруг, программист сделал ошибку, мы все равно не сможем все это записать. Система проверяет это автоматически. И на самом деле, система со статической типизацией более производительна. Нам не нужно сохранять информацию о типе, в каком-то виде, мы ее знаем заранее. Она описана сбоку, как схема базы. Кирилл Коринский: Маленькая ремарка. Почти все nosql-базы, которые мы рассматриваем здесь и сейчас, имеют динамическую типизацию. И они имеют только один тип — строка. И вам приходится жить с этой строкой, и самим сериализовать в нее структуры данных, ну и возращать их назад. Олег Царев: И самим вам делать обработку ошибок. Кирилл Коринский: Десериализацию и сериализацию вы делаете сами. Олег Царев: … Запись и чтение. Вам приходится проверять ошибки самостоятельно, на уровне приложения. Кирилл Коринский: Какие ошибки? Олег Царев: Ну, например, у нас вместо строки оказалось число. Если нам нужна смешанная типизация, для половины данных статическая, для половины — динамическая, то придется выбирать между ними. Либо вообще брать разные движки, для разных частей системы. Реализации
Тут в принципе рассмотрены почти все SQL-базы … Cost/license
Следующий важный вопрос — это стоимость и лицензии. Лицензии нам важны при разработке нашего софта, чтобы у нас не было каких-то проблем в суде… Кирилл Коринский: … они важны, когда ты хочешь понимать, хочешь ли ты вводиться эту базу, и на каких условиях ты хочешь в нее вводиться, что последует после этого. Если ты хочешь например, взять Postgres, и сделать его embedded — пожалуйста. А если он сменит лицензию на GPL, как MySQL, то после того, как ты его сделаешь embedded, и встроишь к себе, тебе придется открывать свое решение. Не все люди на это согласны и способны. Олег Царев: Да, например, тот продукт, который я разрабатываю, это сервер, который сделан на базе MySQL, весь наш исходный код доступен на сайте, именно по причине лицензий. И если мы включаем патчи с другими лицензиями, например, BSD, мы вынуждены указывать сopyright, что этот патч имеет другую лицензию. Если мы обмениваемся с Oracle какими-то патчами, то опять же, приходится эти вопросы улаживать. Может быть в России народ не очень с этим знаком, а на западе это очень важный вопрос. Ну и естественно, что важна цена. Сколько нам будет стоить решение. Кирилл Коринский: И еще маленький вопрос, даже ремарка. Есть такая база BerkleyDB. Вообще она бесплатна. В большинстве своем случаев. Но есть такие вкусные вещи, как репликация, и цена этой репликации — десять тысяч долларов. Если посмотреть на этот слайд, на TimesTen за сорок тысяч долларов, которая работает, и на Berkley Database, который еще надо допиливать, возникает вопрос… Олег Царев: Да, если у нас есть время, можно допилить BerkleyDB… если времени нет, берем TimesTen, и как говорится, не паримся. Это опять же, насколько решение готово, от этого зависит цена. Насчет MondoDB и AGPL. Правильно я понимаю, что если я использую, если я делаю… Affero GPL заставляет меня открывать код всего, что «трогает» MongoDB?
Да. Т.е. если я беру какой-то платный продукт, котором нет сорсов, но я договорился с его хозяевами, об его продаже. Я беру, пишу к нему драйвер для MongoDB, …
Кирилл Коринский: А теперь смотри, если используешь какой-то код из MongoDB, заголовочный или еще что-то такое, ты должен открывать и исходный код своего приложения, с которым ты слинковал. У меня нет исходного кода, я не его владелец…
Тогда я тебя приветствую. Тогда ты пойдешь в суд, ты или твой… Олег Царев: Есть еще способ сделать это в виде загружаемой библиотеки, но это вообще говоря, хороший вопрос к лицензиям. Разные лицензии требуют по-разному интегрировать ваши продукты.
Олег Царев: Не будем отвлекаться, но вопрос лицензий он на самом деле очень интересный и важный.
Второй вопрос — у MySQL лицензия GPL2.0 или JustCall. Т.е. хозяева, которые держать MySQL могут продать его не под GPL2?
Кирилл Коринский: Они могут продать тебе по той цене, о которой ты договоришься, и на нужных тебе условиях. Я вопрос не задал до конца. Вот если я сделал патч к MySQL, я отправляю его держателем MySQL, они его принимают, авторское право, оно…
Олег Царев: Oracle требует передачи авторских прав, перед передачей патча. Это потому, что… Не авторских прав наверно, а имущественное право…
Авторское право. Совместный копирайт, shared contribution, …
Когда ты работаешь наемным сотрудником, ты же передаешь все права на свой код работадателю? Не передаю. Но имущественные права остаются целиком и полностью за компанией. Авторское право остается мое.
Да, действительно… Oracle выпускает две версии MySQLа, первая — это open-source, GPL-версия, вторая — это закрытая версия, с некоторыми дополнительными фичами. Продукты производные, такие как MariaDB, или PerconaServer, они базируются на GPL-версии, и работают через патчи. А закрытая версия — это собственность только Oracle, он имеет право делать все, что угодно, любые изменения, не открывая исходный код. Счастья нет
Теперь перейдем собственно к выводам, подытожим. Сначала Кирилл скажет свои выводы, потом я еще дополню. Кирилл Коринский: Выводы на самом деле простые. У каждой задачи свои требования. Вполне очевидно, что требования у нас разные, от разных задач.
Олег Царев: Деньги мы считаем — у нас одни требования по надежности, когда мы показываем картинки вКонтакте или на Фишки, у нас другие совершенно требования.
Олег Царев: Реально приходится искать компромисс. Нет универсального хранилища. Кирилл Коринский: Стоит понимать, что у каждого хранилища свои плюсы и минусы, есть некоторое окружение, в котором тебе приходится выбирать, что тебе хватит денег, что тебе позволит включить юридически… Олег Царев: Все аспекты, которые мы рассматривали, работают одновременно.
Олег Царев: Надеюсь наш доклад отвечает на один простой вопрос, какое хранилище выбирать? Счастья нет. И требуется привлекать менеджмент, требуется привлекать аналитиков, юристов и разработчиков, чтобы выбрать решение под вашу задачу. И именно поэтому, у нас есть работа. Именно поэтому, IT — востребованная специальность на рынке труда, нужны люди, которые умеют решать такие задачи, находить этот компромисс. Серебрянная пуля — это компромисс. ВопросыСм. видеозапись с 43:54.
Примечания
Внимание! Данная статья выбрана для репликации во внешнюю базу знаний компании. Пожалуйста, не допускайте в этой статье публикацию конфиденциальной информации, ведения обсуждений в теле статьи, и более ответственно относитесь к качеству самой статьи — проверяйте орфографию, пишите по-русски, избегайте непроверенной вами информации. |
|||||