Главная > Java - язык и технологии, Open Source, Высокопроизводительная архитектура, СУБД > Марш против RDBMS или проекты распределенных хранилищ (key-value stores)

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

20 марта 2009

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, и лишь в редких случаях базируется на собственных разработках на С/С++.

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

  1. Андрей
    21 марта 2009 в 18:57 | #1

    Я бы к Вашему списку добавил еще Tokyo Cabinet (http://tokyocabinet.sourceforge.net/index.html)

    • 21 марта 2009 в 19:02 | #2

      ага, спасибо, да там «за бортом» осталось еще много интересных, мне на хабре уже подсказали несколько, одну штуку я уже пробовал, буду на ней чат писать, чуть позже опишу в статье

  2. 22 марта 2009 в 23:29 | #3

    Спасибо за статью. Но есть маленький вопрос: а стоит ли вообще уравнивать (т.е. ставить на один уровень) документоориентированные бд и хранилища данных «ключ-значение»?

    Просто, например, в той же CouchDB можно производить более сложные выборки данных чем просто «выборка по ключу»…

  3. 23 марта 2009 в 05:04 | #4

    FX Poster, да, конечно возможности CouchDB намного шире, но все это просто расширения самой базовой возможности — хранения и работы с абстракцией ключ-значение, где значение это любой поддерживаемый тип данных, от чисел и строк до документов и объектов.
    Так что здесь скорее не уравнено, а обобщено, так как документоориентированные системы это расширение простейшего варианта

  4. Марк
    2 сентября 2009 в 15:36 | #5

    Изобретение велосипедов. После этого, чтобы оптимизировать выборку, придем к необходимости наряду с базовой таблицей хранить таблицу, оптимизирующую поиск по заданному полю (например есть у нас хранилище книг, а нам надо по-бырому сделать выборку книг Шолом-Алейхема, и в ходе оптимизации делаем хранилище вида:
    «Author»=>»Author’s Books»
    —————————
    ‘Шолом-Алейхем’=>’2545,5475,00455’
    ‘Эдуард Лимонов’=>’6578,687,6412’
    )

    Что это такое? Правильно — индексы. То есть подобные разработки приведут историю на новый виток развития хорошо забытых реляционных СУБД.
    Я не говорю, что key-value это плохо. Я просто считаю, что это подмена терминов. Это частный случай СУРБД.

  5. Марк
    5 сентября 2009 в 07:36 | #7

    Но ведь, как не назови, все равно принципиально ничего не поменялось. Два колеса, педали^H^H^H таблицы, индексы…

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

    да, нет никаких фильтров, выборок, сортировки, самый максимум — система тегов для выборки одним запросом всех связанных записей.

    Как можно на таком построить что-либо полезное? Я понимаю, что автор «не фанатик» одной технологии, и выступает за разумный компромисс и т.д., но ведь есть такие облачные платформы, которые не оставляют другого выбора (например Google Appengine). Возможно ли на таком движке написать что-либо, использующее аггрегацию (сисема анализа статистики, складской учет и т д)?

  6. 5 сентября 2009 в 10:48 | #8

    Марк, а что, в определение «что-то полезное» — входят только системы класса анализа статистики и учет? Больше программ нет? Это частные случаи только, да и внутри той же CRM-системы модуль анализа данных и вывода статистики это также частный случай. Полностью на kv-базе сделать возможно и сложнее (но не нереально), обычно используют совместно с СУБД. Например, есть веб-система анализа логов, там во фронт-енде используется Redis, дальше вполне можно использовать для углубленного анализа СУБД.

  7. Марк
    5 сентября 2009 в 12:13 | #9

    Это я для примера.
    Всё это просто навеяно размышлениями о том, что GAE не предоставляет реляционных баз, но позиционируется как платформа для разработки веб-приложений.
    Однако за все время его существования еще не было замечено ни одной более-менее работоспособной CMS… Есть ли в нём вообще смысл?

  8. Марк
    5 сентября 2009 в 12:14 | #10

    ?

  9. Иван
    19 января 2012 в 16:51 | #11

    а кто-нибудь слышал об Oracle NoSQL?

    • Александр Лозовюк
      19 января 2012 в 16:55 | #12

      да, они выпустили такую систему и сейчас включаются в тему NoSQL. 
      детальнее: http://www.oracle.com/technetwork/database/nosqldb/overview/index.html

      И даже есть доступна версия Community Edition

Комментирование отключено.
Developers.org.ua