11 декабря 2009 в 11:49

Обзор NoSQL систем

Беспрецедентные объемы данных заставляют разработчиков и бизнес приглядываться к альтернативам реляционных баз данных, используемым вот уже более тридцати лет. В совокупности все эти технологии известны как «NoSQL базы данных».


Основной проблемой является то, что реляционные базы данных не могут справляться с нагрузками актуальными в наше время (мы говорим о high-load проектах). Есть три конкретные проблемных области:
  • горизонтальное масштабирование при больших объемах данных, например как в случае Digg (3 терабайта для зеленых значков, отображаемых, если ваш друг сделал dugg на статье) или Facebook (50 терабайт для поиска по входящим сообщениям) или eBay (2 петабайта в целом)
  • производительность каждого отдельного сервера
  • не гибкий дизайн логической структуры.
Многие компании нуждаются нахождении новых путей для хранения и масштабирования огромных массивов данных. Я недавно писал перевод статьи про не реляционное хранилище RIAK. В этой статье мы рассмотрим основную часть не реляционных баз данных и систем, под которыми и подразумевается движение NoSQL.

Термин NoSQL был придуман Эриком Эвансом (Eric Evan / Racker), когда Джоан Оскарсон (Johan Oskarsson) из Last.fm хотел организовать мероприятие для обсуждения распределенных баз данных с открытым исходным кодом.

Некоторые люди относятся неодобрительно к термину NoSQL так как он звучит как основанный на том что мы не хотим делать, а не на том кем мы являемся. Движение NoSQL это не движение против реляционных баз данных. NoSQL — это «Не только SQL» (Not Only SQL), а не «Нет SQL» (No SQL at all).

Под термином NoSQL скрывается большое количество продуктов с абсолютно разными дизайнами и иногда при обсуждении разговор может идти о разных системах. Так что я предлагаю использовать три оси для сравнения этих систем: масштабируемость, модель данных и запросов, система хранения данных.

Я выбрал 10 NoSQL баз данных для примеров. Это не весь список, но их достаточно для оценки.

Масштабируемость


Под масштабируемостью, некоторые могут подразумевать репликацию, так что когда мы говорим о масштабируемости в данном контексте — мы имеем в виду автоматическое распределение данных между несколькими серверами. Такие системы мы называем распределенные базы данных. В них входят Cassandra, HBase, Riak, Scalaris и Voldemort. Это ваш единственный выбор, если вы используете объем данных который не может быть обработан на одной машине или если вы не хотите управлять распределением вручную.

Есть две вещи, на которые нужно смотреть в распределенной базе данных: поддержка нескольких датацентров и возможность добавления новых машин в работающий кластер прозрачно для ваших приложений.


Не распределенные базы данных включают в себя CouchDB, MongoDB, Neo4j, Redis и Tokyo Cabinet. Данные системы могут служить прослойкой для хранения данных для распределенных систем; MongoDB предоставляет ограниченную поддержку шардинга (sharding), так же как и отдельный проект Lounge для CouchDB, и Tokyo Cabinet может использоваться как система хранения файлов для Voldemort.

Модель данных и запросов


Существует огромное многообразие моделей данных и API запросов в NoSQL базах данных.


(Соответствующие ссылки Thrift, Map/Reduce, Thrift, Cursor, Graph, Collection, Nested hashes, get/put, get/put, get/put)

Система семейства столбцов (columnfamily) используется в Cassandra и HBase и ее идея была привнесена в них из документов описывающих устройство Google Bigtable (Cassandra правда немного ушла от идей Bigtable и ввела supercolumns). В обеих системах, у вас есть строки и столбцы, как вы привыкли видеть, но количество строк не велико: каждая строка имеет больше или меньше столбцов, в зависимости от необходимости и столбцы не должны быть определены заранее.

Система ключ/значения сама по себе простая, и не сложная для реализации, но не эффективна, если вы заинтересованы только в запросе или обновлении части данных. Так же трудно реализовать сложные структуры поверх распределенных систем.

Документо-ориентированные базы данных это по существу следующий уровень систем ключ/значение, позволяющие связывать вложенные данные с каждым ключом. Поддержка таких запросов более эффективна, чем просто возвращение всего BLOB каждый раз.

Neo4J обладает поистине уникальной моделью данных, храня объекты и связи в качестве узлов и ребер графа. Для запросов, которые соответствуют этой модели (например, иерархических данных) они могут быть в тысячу раз быстрее, чем альтернативные варианты.

Scalaris уникальна в использовании распределенных транзакций между несколькими ключами. Обсуждение компромиссов между последовательностью и наличием свободных мест выходит за рамками этого поста, но это другой аспект, который необходимо учитывать при оценке в распределенных системах.

Система хранения данных


Под системой хранения данных я имею в виду, как данные хранятся внутри системы.


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

Базы данных хранящие данные в памяти очень, очень быстрые (Redis может выполнять до 100,000 операций в секунду), но не могут работать с данными превышающими размер доступной оперативной памяти. Долговечность (сохранение данных в случае сбоя на сервере или отключения питания) так же может быть проблемой (в новых версиях будет поддержка append-only log). Количество данных которые могут ожидать записи на диск потенциально велико. Другая система с хранением данных в оперативной памяти — Scalaris, решает проблему долговечности с помощью репликации, но она не поддерживает масштабирования на несколько датацентров, так что потеря данных вероятна и тут — в случае отключения питания.

Memtables и SSTables буферизируют запросы на запись в памяти (memtable), после записи в commit лог для сохранности данных (объяснить это трудно, но можно подробнее почитать в wiki Cassandra — http://wiki.apache.org/cassandra/ArchitectureOverview). После накопления достаточного количества записей, Memtable сортируется и записывается на диск, уже как SSTable. Это дает производительность близкую к производительности памяти, в тоже время система лишена проблем актуальных при хранении только в памяти. (Эта процедура описана более подробно в разделах 5.3 и 5.4, так же как слияние деревьев на основе лога — The log-structured merge-tree)

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

Интересным вариантом является использование в CouchDB B-деревьев, только с функцией добавления (append-only B-Trees — бинарное дерево которое не нужно перестраивать при добавлении элементов), что позволяет получить не плохую производительность при записи данных на диск.

Заключение


Движение NoSQL резко выросло в 2009 году, благодаря увлечению количества компаний связанных с использованием больших объемов данных. Появляется все больше систем позволяющих организовывать и прозрачно поддерживать огромные массивы данных, обрабатывать и контролировать эти данные. Я надеюсь благодаря этой небольшой статье, вы узнаете о некоторых сильных сторонах NoSQL систем и возможно внесете свой вклад в развитие данного движения.

Andy One @SilenceAndy
карма
198,5
рейтинг 0,0
Пользователь
Самое читаемое Разработка

Комментарии (67)

  • +2
    > Движение NoSQL это не движение против реляционных баз данных.
    > NoSQL — это «Не только SQL» (Not Only SQL), а не «Нет SQL» (No SQL at all).

    Тогда разумнее записывать эту аббревиатуру как NOSQL.
    • +2
      Возможно, но уже как-то принято писать именно так — en.wikipedia.org/wiki/NoSQL
      • 0
        там любой желающий может написать что угодно)) можно хоть сейчас взять и исправить))
        З.Ы. мня очень бесит когда многие меня тыкают фактами из википедии)) тогда как она для меня вообще не авторитетна.
  • +4
    Хороший краткий обзор, спасибо.

    Жаль, что Эванс своим предложением хранить моделей предметной области не в РСУБД нажил себе врагов — как среди читателей книг-приверженцев реляционизма :) Это сразу сузило его аудиторию. Радует то, что таких остается все меньше и меньше.
    • 0
      Их потихоньку убирают?
      • +3
        :)
        Не, до них потихоньку доходит, что не SQLем единым живы данные. Ну и естественный процесс помогает — зоказчег часто понимает, что ему нужно как можно более подходящее решение, а не «о, у вендора X есть отличная РСУБД, запилим на ней» отсылка к дедам-авторитетам, что мы «всю жись на foxpro рубили, SQL рулит и бибикает»
  • –2
    Хороший вариант хранилищ данных для онлайновых браузерных игр в реалтайме, баннерных систем и тому подобного.
  • 0
    в js-kit.com используется файловая система для хранения информации
    • 0
      Вы случаем не из этой компании? Интересно было бы увидеть обзор и какие хранилища используются при их объемах данных, так сказать из первых рук =)
      Кое какая информация есть тут — lionet.livejournal.com/, но её мало.
      • 0
        работал там. насколько я помню, обычная фс. выборка данных идёт по пути к файлу. всё гениальное — просто.
        насчёт вопроса железа, не знаю.
        • 0
          Периодически пользуюсь аналогичной схемой. Но при первой возможности отказываюсь.
          Основной минус — сильно ест диск. Если много небольших блоков данных — приличный объем съедается впустую.
          Удобство — когда постоянно нужно модифицировать отдельные блоки. В одном проекте перешел на файлы, дисковые расходы терплю, пока не нашел достойной альтернативы.
          В другом проекте, где несколько индексов ежедневно обновлялись целиком и по-новой разворачивались в кучу мелких файлов ушел от кучи к одному большому файлу с индексом. Сэкономил не только диск, но и время развертывания данных.
          • 0
            Разворачивание данных в файл происходит в несколько раз быстрее, чем закачка того-же массива в SQLite. 2-3 часа, вместо 10-12
          • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    >Интересным вариантом является использование в CouchDB B-деревьев, только с функцией добавления (append-only B-Trees), что позволяет избежать накладных расходов на позиционировании головки.

    тут больше скорости при записи изза того что не нужно перестраивать индекс, а не изза головки которая и так ездиет за шелскриптами/апачами (if any), etc

    Ну и сама фраза несколько не понятно написана, AoBT — бинарное дерево которое не нужно перестраивать при добавлении элементов. соответственно в CouchDB элементы не удаляются, лишь добавляются записи об удалении, что поидее должно хорошо сказываться на перформансе при записи :)
    • 0
      Спасибо, поправил.
  • +2
    Хотелось бы почитать про стабильность упомянутых решений.
    А то есть негативный опыт с repcached — так и не удалось добиться стабильной работы на солярисе.
    • 0
      Честно сказать, я тоже. Дело в том, что эти системы достаточны молодые и из них работает в большом продакшене только одна — Cassandra (используется на Facebook для хранения индекса для поиска по входящим сообщениям). Но если я найду исследования по стабильности других решений, конечно же выложу.
    • 0
      CouchDB полностью защищена от поломки базы, там даже нет отдельной команды для выключения сервиса, его убивают kill`ом :) Т.е. на диске при любых условиях целостная база

      MongoDB наоборот, требует специального шатдауна, и при аварийном завершении нужно чинить базу, в результате чего могут полаться OID объектов и сломать связи между объектами если вы их используете. Сответсвенно авторы советуют для защиты базы использовать кластер из >1 интсанса монго.
      • 0
        Кластеры вообще-то штука требующая достаточно высокой квалификации и опыта работы с ней.
        И уж тем более следует относится с недоверием к кластерам из нового, не испытанного годами большого продакшна, софта. Особенно в горизонтально масштабирующихся системах.

        Причем потеря данных — это лишь одна из угроз. Нужно еще поизучать, насколько софт терпим к потерям в сети, выходам из строя и временным выпадениям отдельных узлов, а в наших условиях еще и к неожиданному отключению всего кластера по питанию.
        • 0
          дада, с couch это by design так

          • 0
            For higher availability and more concurrent users, CouchDB is designed for “shared nothing” clustering. In a “shared nothing” cluster, each machine is independent and replicates data with its cluster mates, allowing individual server failures with zero downtime. And because consistency scans and fix-ups aren’t needed on restart, if the entire cluster fails – due to a power outage in a datacenter, for example – the entire CouchDB distributed system becomes immediately available after a restart.
          • 0
            хабра схела копипасту :)
    • 0
      Кассандра — вполне стабильна. Думаю, через пару месяцев напишем на хабре подробнее, как будут весомые нагрузки. А пока что полет более чем нормальный на тестах.
  • 0
    Neo4J чем-то напомнил Cerebrum( www.shuklin.com/ai/ht/ru/cerebrum/ )
    • 0
      Чего минусуем?
      • +1
        Содержательный получается диалог)
  • 0
    представление данных, имхо, очень удобно хранить в графовых структурах, поскольку именно этот способ очень схож с устройством человеческой памяти, подходит для тэгирования и категоризации данных, хранения знаний. вообще не понимаю, почему такие системы не развивались как альтернатива sql.
    • 0
      Кто сказал, что не развивались? Есть, но они не очень популярны…
  • 0
    Хотелось бы отметить, что Redis поддерждивает репликацию.
    • 0
      да, пока только мастер->слейв, распределение ключей пока на уровне клиентских библиотек. В след версии (1.2) по моему, обещается слейв с режимом рид онли, что позволит работать с двумя серверами сразу
  • 0
    Немного не понял про масштабируемость Redis — вроде читал, что такая классная и быстрая, масштабируемая система, а тут оказывается не так. Можете прокомментировать немного подробнее?

    И еще про возможность потери данных в Redis — он хранит большое количество данных для записи долгое время?
    Учитывая его асинхронную работу с файловой системой, мне кажется вполне возможно, что записывает он очень часто и даже при непредвиденном сбое может потеряться минимум данных. Да и то, такие сбои, что сервер не успеет записать данные, мне кажется, довольно редки.
    • 0
      Конечно могу. Тут не сказано, что Redis не такая как вы сказали. Redis как написано в третьей таблице использует для хранения оперативную память с периодическими снэпшотами которые записываются на диск, и есть возможность, что вы запишите в систему данные которые вы потеряете в случае сбоя или отключения питания — снэпшот не будет сохранен.

      Да, хранит. Как я уже сказал используются снэпшоты памяти. Потеря данных, вне зависимости от количества — это плохо. Например очень большие объемы данных в банковском секторе, согласитесь, вы бы не хотели, чтобы система потеряла пару нолей в вашем счету?

      … мне кажется вполне возможно, что записывает он очень часто...

      Все зависит от объема данных. А если их много, и нужна минимальная потеря данных, для меня предпочтительней идеи BigTable и Cassandara с Memtable и SSTable.
      • 0
        там еще есть append.log который постоянно писаться может и сбрасываться на диск после каждой записи. ПРи восстановлении можно по логу восстановиться вместо снапшота.
      • +1
        Понял, спасибо.
      • +1
        Создатели самого Редиса прямо не рекомендуют на данный момент использовать эту систему в секторах, где потеря небольшого количества недавних изменений данных критична.
        • +1
          Точнее, не рекомендовали. Новая фича — append-only log — позволяет восстанавливать все данные после сбоя. Хотя, справедливости ради надо отметить, использование этой возможности требует много места на диске, и, кроме того, в «самом надежном» режиме она плохо сказывается на производительности. Здесь можно посмотреть кое-какие тесты: www.mysqlperformanceblog.com/2009/12/10/redis-benchmarks-on-fusionio-round-1/
      • 0
        Так же интересно отметить, что можно настроить как часто «Редиска» сбрасывает кэш на диск. В текущей реализации сделана комплексная проверка — снэпшот каждые ХХ секунд при наличии УУ операций с базой. Таких «лимитов-условий» можно завать целый список.
    • 0
      Redis, как и Tokyo {Tyrant, Cabinet}, может масштабироваться путём хэширования ключей (в простейшем случае, чётные в правый сервер, нечётные в левый).

      Просто стандартного метода хэширования Redis в своё API довольно долгое время не предлагал, но это не значит, размазать Redis по многим серверам сложно. Наоборот, запросто.
    • +2
      Информация о Redis в табличке несколько устарела. Действительно, Redis поддерживает репликацию данных (Master-Slave).

      Некоторые проблемы с масштабируемостью пока есть, и раскидать данные по множеству серверов без бубна не получится. Это связано с тем, что некоторые операции работают с несколькими ключами сразу (например, тип данных set поддерживает операции union, difference, intersection; sort может сортировать данные не в алфавитном порядке, а используя список «весовых» значений, хранящихся по другому ключу; атомарная операция msetnx может устанавливать значения сразу для множества ключей; и т.п.). Такие операции (пока) невозможны, если ключи хранятся на разных серверах. Автор обещает внедрить поддержку Redis-Cluster в будущих версиях, тогда эта проблема будет решена.
      Что касается сохранности данных и записи их на жесткий диск, уже сейчас реализована такая фича как append-only log: в фоновом режиме Redis может сохранять историю всех изменений данных. В случае сбоя по этому логу можно восстановить все потерянные данные.
      • 0
        Думаю автору стоит дополнить пост полученной от вас информацией.
        • 0
          Какой именно? В статье нет информации о том, что Redis не поддерживает репликацию. К тому же пока репликация не очень стабильно работает судя по словам birukoff и количеству задач связанных с репликацией на странице проекта на code.google.com.

          Фича с append-only log добавлена только в версии 1.1, которая на данный момент находится в стадии beta, поэтому фича и не упомянута в статье.
          • 0
            Да, вы правы. Хотя может быть стоит добавить в качестве примечания, про append-only log.
            • 0
              Добавил.
      • +1
        Последние тесты Redis с append-only log
        www.mysqlperformanceblog.com/2009/12/10/redis-benchmarks-on-fusionio-round-1/
  • 0
    Обзор интересный. Вообще по моему мнению NoSQL будет и дальше набирать обороты, нужно только популизировать его.
    К пример — системы статистики, аггрегаторы — это идеальный вариант для них.
    Также в статье можно указать на ссылку на сам блог — www.rackspacecloud.com/blog/category/development/ и статью — www.rackspacecloud.com/blog/2009/11/09/nosql-ecosystem/. Действительно увлекательное чтиво, периодически появляются шикарные статьи.
    • 0
      Вот вы не поверите, это перевод именно этой статьи.
      • 0
        К тому же я покапался в исходниках Riak и узнал как у него хранятся данные внутри, в оригинальной статье автор этого не указал.
      • 0
        Измините, а почему в статье не указано, что это перевод? Почему нет ссылки на оригинал?
        • 0
          Я хотел сказать «Извините»
  • 0
    После прочтения этой статьи, вашу прошлую о Riak было читать особенно интересно.
    • 0
      Спасибо :)
  • 0
    А про Berkeley DB почему не упомянули?

    Все перечисленные вместе имеют меньше инсталляций чем она одна :-)
    • 0
      Не увидел, что это перевод :-(
  • 0
    Огромное спасибо… обзор на высоте!
  • 0
    Статья отличная!
    А насчёт нереляционных баз, так они ещё старше чем реляционные.
    Да, несомненно, у хешей и B-tree скорость отличная.
    Однако создавая более менее сложную систему вы неприменимо придёте к реляционности.
    Вот посмотрите пример создание клона Twitter на Redis, уже с первых строк пошла реляционность, конечно это потому что такая задача, но ведь большинство именно таких.
    А поиск по разным полям?
    Тут конечно документо-ориентированные базы рулят по сравнению с простыми ключ-значение,
    но в них появляется надобность создавать индексы =)
    В общем, нереляционные базы быстры, но они не панацея, и следует обдумано подходить к вопросу, даже не смотря что это так модно нынче.
  • 0
    Основной проблемой является то, что реляционные базы данных не могут справляться с нагрузками актуальными в наше время (мы говорим о high-load проектах) — Ларри Элиссон плачет каждый раз, когда Вы это говорите :)

    Кстати, а он миллиард баксов так ведь и не проиграл? Его никто не уделал на Hi-load проектах? А?
  • 0
    А где Mnesia?
    • 0
      В этой статье не рассматривались встраиваемые СУБД. Mnesia и Berkeley DB именно к такому типу и относятся.
      • 0
        Брррр Berkeley DB — встраиваемая????

        Вы шутите. Наличие слова «embeddable» на главной странице говорит только о том, что ее можно встраивать, а не о том, что только встраивать.

        Она более полноценная БД чем многие из обзора. К примеру поддержка репликации мастер-мастер.

        • +2
          Да, возможно я ошибся, так как мало знаком с данной базой данных. В описании к Berkeley DB написано:
          For example, like SQLite, it does not provide support for network access — programs access the database using in-process API calls.

          Насколько я понимаю этот текст, для организации структуры для хранения больших объемов данных и распределенной структуры которая необходима для этого, нам придется самим дописывать поверх системы дополнительный функционал.

          Основные цели систем приведенных в статье — работа с большими объемами данных и высокой нагрузкой. Примеров high-load проектов с использованием Berkeley DB как основного хранилища, я не нашел. Если вы приведете ссылки на такие проекты, я был бы крайне признателен.
          • 0
            Пожалуй был не совсем прав.

            Просто в свое время рассматривалась возможность ее использования и нашлись разработки для доступа к ней по сети.
            Отказались по причине снижения требований к надежности хранения данных.
            По памяти нашлось только это
            www.interface.ru/home.asp?artId=19187

            В принципе ничто не мешает организовать собственный типа сервер доступа. API у Berkeley DB очень пристойное. Транзакции и развод кроликов при паралельном доступе реализованы там достаточно неплохо.

            Естественно затраты на разработку резко растут. Смысл имеет если Вам необходимо максимально надежное хранилище при очень высокой производительности.

            Мы остановились на Tokyo Cabinet.
            По большому счету Tokyo Tyrant является прокладкой для доступа из сети к Tokyo Cabinet.

            Чем подкупил Tokyo Cabinet, так это возможностью выбора режима. Если мне нестрашно потерять какие то из последних данных — могу его разогнать как ракету, если небходима надежность — за счет производительности имею ее.

            Как то комфортней себя чувствую если сам подобными вещами рулю :-)

      • 0
        tokyo cabinet встраиваемая
  • +1
    Парадокс :-)

    Тема NoSQL.

    Если залезть в потроха MySQL Cluster увидите — там в основе обычное хранилище key-value :-)

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

    Если посмотреть производительность — все как и во всех key-value, ракета по получению key-value, задница при каком нибудь join'е.

    В принципе, конечной точкой навертывания функционала на перечисленные в статье системы нечто подобное и является.

    По сути все они — промежуточные точки между memcached и чем то подобным MySQL Cluster.
  • 0
    redis умеет append-only
    tokyo cabinet умеет + table и fixed length string в on-disk и hash и b-tree (кстати очень хорошо настраиваемые) в on-memory
    кроме того используя скрипты lua можно легко смастерить еще модели, коллекции, например, как в редисе
  • 0
    А почему нет указания что эта статья перевод?
  • 0
    Есть еще такая СУБД как InterSystems Caché. На их сайте написано, что она «World's fastest object database». Впрочем на больших объемах проверять не приходилось. Используется исторически в медицинских учреждениях.
  • 0
    маленькая поправочка: Tokyo Cabinet. не является распределенной БД, это всего лишь АПИ к разного вида key/value таблиц. источник fallabs.com/tokyocabinet/
    на базе Токио можно уже построить что-то своё.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.