Обновить

Марш против RDBMS или проекты распределенных хранилищ (key-value stores)

Высокая производительность
candybar2Вот вы часто создаете проекты? И, наверное, везде применяете базу данных, в частности, MySQL (а кто-то и PostgreSQL). Но вот что интересно, по опыту да и просто после чтения описания различных архитектур видно, что далеко не везде в проекте нужны ключевые особенности баз данных, во многих случаях базу используют просто как некоторое хранилище обычных данных. Например, в системах кеширования базы обычно не применяются, более того, кеширование как раз используют для того, чтобы избежать лишних запросов. А что используют для кеширования наиболее часто? Memcached. А что это такое? Это распределенная система хранения данных на основе хеш-таблицы. В общих чертах, это просто хранилище пар ключ-значение, над которыми можно производить только основные операции — запись, чтение, удаление и проверку на присутствие. Да-да, нет никаких фильтров, выборок, сортировки, самый максимум — система тегов для выборки одним запросом всех связанных записей. И во многих случаях такого функционала вполне достаточно.

Я отнюдь не фанатик, и в реальных проектах лучшей будет комбинация из обычной, реляционной базы и специализированного хранилища данных. Более продвинутые системы, хранящие не просто пары ключ-значение, а и дополнительную мета-информацию об объекте, уже приближаются по возможностям к базам данных, их иногда называют документ-ориентированными базами (хранилищами), так как единицей информации, над которой происходит работа, является документ и ассоциированные с ними данные.

Вторым критерием или особенностью является распределённость. Для СУБД это часто решается достаточно сложно или при помощи сторонних средств. Хранилища данных строятся на основе DHT (Distributed Hash Table) и изначально готовы к распределенной работе, обеспечивая масштабируемость и устойчивость к отказам отдельных узлов. В одних системах это решается за счет среды (например, если хранилище работает поверх Erlang VM), вторые используют встроенные средства распределенной работы (например, JGroups для систем на Java), либо собственные решения, как Memcached.

Немаловажна и полная готовность таких систем для работы в Cloud-среде, не даром именно такое хранилище работает у Amazon (S3 и SimpleDB). Всем известный BigTable от Google также, по большей части, как раз система хранения и обработки пар ключ/значение. Из-за простоты и даже тривиальности API (но не всегда и внутреннего устройства, хотя оно и проще чем у стандартных SQL DB) решения отлично масштабируются (как на чтение, так и на запись), в том числе и динамически, без перерыва в работе. Так что если у вас есть или будет кластер, присмотритесь к таким решениям. Но есть один момент, о котором стоит упомянуть — очень часто такие системы работают только с хранением данных в памяти, если же требуется постоянное хранение, используются бек-енд системы, в том числе и хранение в обычной реляционной базе данных, хотя это часто может налагать ограничения на данные и их параметры (а также замедляет работу).

Для чего же можно такое применить? Да везде, где у вас есть потребность хранить большое (практически неограниченное) количество данных, которые могут быть разбиты на отдельные независимые блоки. Это могут быть отдельные статьи, фотографии, видео или другие большие бинарные объекты, записи в логе, профайлы пользователей, сессионные данные (кстати, мы раньше анонсировали свою экспериментальную открытую разработку, сессионный сервер на Java для распределенного хранения сессий РНР приложений, аналогичное решение есть в промышленном Zend Platform). В большинстве случаев все ограничивается либо набором бинарных данных, либо текстовой строкой с данными или кодом в сериализированном виде, поэтому данные можно как использовать дальше в программе обработки, либо сразу отдать клиенту — именно так делает плагин для Nginx, который смотрит в Memcached и, если там есть запрашиваемый контент, отдает напрямую, минуя вообще обращение к вашему скрипту. Сейчас я, к примеру, проектирую чат-сервер, там как раз в качестве основного хранилища данных будет использован распределенный кеш (Java-система, использующая кеш с репликацией через JGroups), который по сути такое же хранилище данных в виде ключ и значение.

Ладно, хватит теории, посмотрим, какие существуют системы хранения на рынке (конечно, open source).
  • Project Voldemort — один из интереснейших проектов (планирую рассказать о нем как то подробнее). Написан на Java, реализован шардинг (partitioned) и репликация данных. Если требуется постоянное хранение, используется BerkleyDB или MySQL, можно и свое хранилище дописать, система хранения основана на плагинах, потому это достаточно просто. К сожалению, похоже, что есть только API для Java-приложений (либо использование Facebook Thrift протокола для других клиентов). Из данных можно хранить структурированные данные (массивы), blob (двоичные пакеты данных) и обычный текст. Определенные сложности есть при горячем масштабировании, добавление новых нод в кластер не самое простое действие.
  • Scalaris — транзакционная система хранения, основанная на Erlang, при этом работает только с данными в памяти, не используя постоянного хранения на диске. Для отказоустойчивости используют шардинг и репликацию, а также «non-blocking Paxos commit protocol» (надо будет подробнее изучить, что это такое). Сервер имеет API для Java, Erlang и встроенный JSON RPC для взаимодействия с другими клиентами. Может масштабироваться достаточно легко и в любое время (платформа Erlang-а прекрасно для этого приспособлена).
  • MemcacheDBмы уже писали ранее об этой системе, использует только репликацию и хранилище на диске с использованием BerkeleyDB. Наверное, простейший из всех проектов, как в установке так и в использовании, а если мы и так используете инфраструктуру на основе Memcached, то это система идеально в нее вписывается.
  • ThruDB — проект, основанный на Apache Thrift framework (открытом проекте развития протокола Thrift, разработанного Facebook). На самом деле это даже не один проект, а целое семейство сервисов для построения инфраструктуры (которые, в свою очередь, базируются на других открытых разработках) — собственно, сам сервис хранения данных с бекендами на MySQL, Amazon S3, BerkeleyDB, а также сервис очередей сообщений, сервис масштабирования, система хранения документов и даже сервис индексирования и поиска данных (использует CLucene, порт Java Lucene на С). Клиентские библиотеки есть для разных языков, в принципе, достаточно порта протокола Thrift. Очень интересное решение, если вам необходимы многие из перечисленных функций сразу.
  • Apache CouchDB — документо-ориентированная система хранения данных на базе Erlang, использующая RESTful HTTP/JSON API для взаимодействия с клиентами. Для распределённости используется инкрементная двухсторонняя репликация и автоматическое разрешение конфликтов. Кстати, может использовать JavaScript в качестве языка запросов документов. Для устойчивости используется хранение данных на диске (собственный формат) и репликации на других нодах. Исходя из сетевой природы протокола, база может работать с любым клиентом и платформой, которая может сформировать JSON HTTP запрос, включая напрямую запросы от веб-страницы (JS).

В список не вошли ещё несколько систем — например, Hadoop HBase, Cassandra, Hypertable, Dynomite, Kai, Ringo.

Интересно заметить, что в основном для такого рода систем используют или специализированные языки и платформы (Erlang здесь почти вне конкуренции) или уже ставшие классикой и мейнстримом серьезные системы вроде Java, и лишь в редких случаях базируется на собственных разработках на С/С++.

Разрабатываете высокопроизводительную систему, не обязательно веб? Нуждаетесь в специфическом хранении данных, при этом хотите получать их самым простым способом, масштабировать «в шырь и ввысь», даже не останавливая ни на секунду работы? При этом данных может быть много, но все они простые и сводятся к строкам или сериализированным структурам и двоичным блокам? Надо надежное хранение данных, распределённое и устойчивое к сбоям? Если хоть на один из этих вопросов ответ «да», вам стоит посмотреть хоть пару проектов из списка, возможно именно они позволят вашему проекту выдержать нагрузки и уверенно развиваться.

P.S. Оригинальная статья, которая подтолкнула меня на написание — там хорошая сравнительная таблица систем.
Теги:DBDTHframeworkhash tableJavaJSONkey-value storageopen sourceвебстартап
Хабы: Высокая производительность
Рейтинг +46
Количество просмотров 14,4k Добавить в закладки 84
Комментарии
Комментарии 31

Похожие публикации

Факультет Java-разработки
10 марта 2021180 000 ₽GeekBrains
Java Developer. Professional
11 марта 202160 000 ₽OTUS
Веб-дизайнер
16 марта 202183 000 ₽GeekBrains

Лучшие публикации за сутки