Как пишут базы данных на C#: RavenDb

от автора

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

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

Быстрые переходы:

Предыстория

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

Однажды он поделился этими наработками с коллегой Senior разработчиком — и тот даже на базовом уровне не понимал, как устроены индексы. Вроде бы можно ответить просто: «используй Dictionary». Да, можно подойти к вопросу серьёзно и начать изучать реальные движки — тот же Elasticsearch, Neo4j на Java, или хотя бы посмотреть, как это делают зрелые системы, но стоял вопрос о самой простой реализации и человек ответить не смог.

Со временем я заметил, что многие мои знакомые из крупных компаний сталкиваются с тем же: глубину вещей почти никто не понимает. И часто — не потому что не хотят, а потому что это не требуется. Собеседования превратились в скрипты: выучил — прошёл. А если в реальной задаче что‑то непонятно, можно разобраться по ходу дела и в этом нет ничего плохого, однако до боли забавно.

Все пересказывают одни и те же заученные ответы. А особо щепетильные интервьюеры придумывают искусственные проблемы и ждут, что кандидат угадает их внутреннее решение — чтобы найти «того, кто мыслит так же». Ничего нового, и уж точно ничего вдохновляющего. P.S: это подводка к моей ранее опубликованной статье.

Чет от о всех и везде Клоунада

Чет от о всех и везде Клоунада

И вот на фоне всех этих разговоров у меня возник вопрос: неужели на такой мощной платформе, как C# и .NET, нет собственной базы данных?

Оказалось — есть. И имя ей RavenDB.

С этого момента у меня появилась цель: написать материал о RavenDB, но постоянно сталкивался с дилеммой — одна большая статья получается слишком тяжёлой, а серия статей рискует превратиться в бесконечное дописывание.

Полного объёма материала я пока не собрал, но уже успел неплохо разобраться в этой базе данных. Чтобы двигаться дальше, я заранее публикую свои заметки(может таким образом появятся люди, что тоже начнут делиться своим опытом) — и они будут постепенно расширяться. RavenDB мне действительно понравилась: работать с ней интересно, а возможности впечатляют. Я хотел бы видеть её чаще в production‑средах, особенно в Российских компаниях, где она могла бы занять достойное место среди современных решений для хранения данных. С полной уверенностью могу сказать: эта база данных прочно вошла в мой кругозор и я не собираюсь выпускать её из поля внимания. Сам создатель и его детище RavenDB настолько запали мне в душу, что стали для меня не просто инструментом, а настоящим источником вдохновения

Oren Eini, что создал RavenDb, уже много лет ведёт свой блог на собственном портале ayende.com — это его личная площадка, где он документирует технические идеи, эксперименты, архитектурные решения и собственный профессиональный путь. Мой рассказ о нём во многом основан именно на его статьях, опубликованных на этом сайте: они дают редкую возможность увидеть, как он мыслит и какие инженерные принципы считает важными.

Что такое RavenDB?

RavenDb

RavenDb

RavenDB — это высокопроизводительная документно-ориентированная/многомодельная NoSQL‑база данных с открытым исходным кодом, созданная как распределённая платформа для обработки онлайн‑транзакций, хоть и основное предназначение быть документной-ориентированной. Cпециализирующая на обработке онлайн-транзакций (OLTP). С момента своего первого запуска в 2009 году система полностью основана на транзакциях (ACID, а не BASE). С самого начала RavenDB была задумана как система, где целостность данных и надёжность транзакций являются не дополнительной опцией, а фундаментом архитектуры.

RavenDB используется для хранения критически важных бизнес‑данных, таких как медицинская информация и финансовые транзакции

Одним из сильных сторон RavenDB является её отсутствие жёсткой схемы — и это касается не только хранения данных. RavenDB обладает мощными возможностями для работы с динамическими данными и пользовательским контентом.

Если вы когда-либо работали с MongoDb — то RavenDb вам покажется очень удобным и знакомым по методике работы. Те же коллекции, документы, базовый метод моделирования в том числе строится вокруг корневых агрегатов.

Поскольку RavenDB написана на C#, её документация и примеры в первую очередь ориентированы на разработчиков, работающих с C# и .NET. Это делает изучение внутреннего устройства базы особенно увлекательным: вы не только сможете глубже понять, как она устроена, но и получите удовольствие от её использования в повседневных бизнес‑задачах. Работа с RavenDB ощущается естественно и органично для экосистемы .NET, что превращает её применение в практичное и приятное занятие.

C#

C#

Если вы хотите познакомиться с RavenDB без установки и настройки, можно открыть живую демонстрационную версию, развёрнутую самими разработчиками — полноценный интерфейс RavenDB Studio, доступный прямо в браузере.

UI RavenDb

UI RavenDb

Хотите почитать книгу? Держите

RavenDb Inside

RavenDb Inside

Хотите почитать документацию? Держите

Хотите изучить, как выглядит интегрированная RavenDb в приложение? Смотрите примеры

Путь и история создателя RavenDB: от создателя до учителя

Просматривая интервью — я неожиданно узнал, что RavenDB весьма популярна в Америке: как в Северной, так и в Южной. Об этом прямо говорит её создатель, Oren (Oli) Eini. В Европе и Азии она тоже встречается, пусть и не так массово. Причём используется RavenDB давно и в самых разных сферах — включая банковский сектор.

Если посмотреть рейтинг на DB‑Engines, RavenDB находится примерно на 100‑м месте. И это действительно впечатляет, учитывая, что в списке более 400 систем управления базами данных. Для продукта, который не является массовым, но ориентирован на сложные корпоративные задачи, это очень достойная позиция. RavenDB предлагает богатые возможности, зрелую архитектуру и вполне конкурентные преимущества — ей есть что предложить разработчикам и бизнесу.

RavenDb в DbEngines

RavenDb в DbEngines

Сам Oren Eini — человек с необычной биографией. В его профессиональном пути были не только годы работы программистом, но и совершенно неожиданные профессии, например служба в тюремной системе. Программированием он увлёкся давно, знает множество языков и всегда стремился разбираться в технологиях глубже, чем большинство.

Oren Eini

Oren Eini

И важно начать с того, что RavenDB была далеко не его первым проектом. До неё он был активным контрибьютором в NHibernate — одном из самых известных ORM в .NET‑мире. Кроме того, он создал целую линейку инструментов под брендом Rhino. Например:

NHibernate

NHibernate
  • Rhino Mocks — один из первых фреймворков для моков в .NET, появившийся задолго до Moq и NSubstitute.

  • Rhino Service Bus — лёгкая шина сообщений для распределённых систем, созданная до массового распространения MassTransit и NServiceBus.

  • RaccoonBlog — собственная платформа для его блога Ayende, которая служила живым примером использования RavenDB.

И это лишь часть его проектов — многие из них стали фундаментом, на котором позже выросла RavenDB.

Если в наших краях RavenDB пока не получила широкой известности и о самом Oren Eini знают немногие, то в других частях света его экспертиза ценится настолько, что его просят рецензировать книги . Один из примеров — просьба оценить книгу и он написал рецензию на данную просьбу: Review: Getting Started with LevelDB.

Getting Started with LevelDB

Getting Started with LevelDB

Oren Eini — не просто создатель базы данных, он активно делится своим опытом и показывает, как устроены БД изнутри. На GitHub у него есть полноценная книга‑проект, где он шаг за шагом обучает созданию собственной базы данных на языке C.

Этот проект называется libgavran — и в нём вы буквально создаёте минималистичную БД с поддержкой WAL, транзакций, страничного хранения и других фундаментальных механизмов. Это не просто учебник: это практическая мастерская, где каждая глава — новый слой реального сторедж‑движка.

libgavran project-book

libgavran project-book

Особенно интересно то, что многие идеи в книге выросли из его более ранних статей о внутреннем устройстве БД. Поэтому, читая libgavran, можно увидеть знакомые концепции, которые он подробно разбирал в своём блоге — от структуры страниц до реализации журналирования.

Статьи на Ayende

Статьи на Ayende

🔗 Репозиторий для тех, кто хочет понять, как работает движок хранения, это один из лучших практических ресурсов.

Так же в своей книге о RavenDb, Oli Eini четко подчеркивает, что все же впервую очередь в душе он остается разработчиком. Он прекрасно понимает все проблемы таких ребят, как мы дорогие читатели.

Как личность автора отражается в архитектуре

Если внимательно читать его материалы, становится очевидно: Oren — сторонник чистого объектно‑ориентированного кода и последовательный противник триггеров и хранимых процедур. В нескольких статьях он прямо называет подобные конструкции “evil code”, подчёркивая, насколько неприятно ему работать с логикой, спрятанной внутри базы данных. Это хорошо видно в его постах

Красота даже в самом репозитории

Красота даже в самом репозитории

Из книги о RavenDB мы узнаём, что Oren Eini, пришедший из мира, ориентированного на Microsoft, начал написание книги о RavenDb ещё в 2014 году и многократно переписывал её.

Первоначальная цель в разработке RavenDb заключалась в создании системы, которая сочетала бы ACID‑гарантии с отсутствием жёстких ограничений реляционных схем, но при этом сохраняла привычные модели работы с данными.

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

На дизайн RavenDB сильное влияние оказала книга Release It!, которую Oren Eini настоятельно рекомендует — именно она помогла сформировать подход к надёжности и устойчивости системы.

Release It!

Release It!

Эти взгляды позже напрямую повлияли на архитектуру RavenDB, где он сознательно отказался от скрытой серверной логики в пользу прозрачных механизмов — патчей, ETL и подписок.

В видео‑интервью c Rodrigo Branas создатель RavenDB Oren Eini рассказывает, сколько времени команда вложила в создание качественного пользовательского интерфейса. По его словам, работа над UI заняла годы — и это заметно: интерфейс RavenDB действительно один из лучших, что мне доводилось видеть среди баз данных.

UI RavenDb

UI RavenDb

Причина проста: Oren Eini ставит удобство разработчика в центр всей философии RavenDB. Он много раз писал, что если у базы данных нет хороших инструментов, то она останется нишевой и неудобной. В одной из статей он критикует SQL Management Studio за перегруженность и неудобство — “SQL Management Studio”. И это хорошо объясняет, почему RavenDB получила современный, продуманный UI, который снижает порог входа и делает работу с документной БД интуитивной.

UI Sql Management Studio

UI Sql Management Studio

Говоря о том, как Oren Eini относится к конкурентам, то здесь заметен не фанатизм и не попытка «топить» другие технологии, а вполне здравый, инженерный подход. Например, есть статья, которая на первый взгляд выглядит как критика MongoDB, но внутри оказывается совсем другим — это попытка защитить саму идею документной модели и показать, как люди неправильно используют NoSQL‑базы. Речь о статье

В ней он объясняет, что проблема не в MongoDB как продукте, а в том, что разработчики не умеют применять её. То есть он критикует не конкурента, а неправильные архитектурные решения.

Бестолковость

Бестолковость

Такой же подход заметен и в интервью с Rodrigo Bananas: Oren прямо говорит, что уважает создателей PostgreSQL. Это важный момент — он не противопоставляет RavenDB другим базам, не пытается доказать, что «его БД лучше всех». Он подчёркивает, что разные системы решают разные задачи, и уважение к чужой работе — часть профессиональной культуры.

Уважение

Уважение

Путь к созданию RavenDb

Вдохновение на создание собственной БД он черпал из CouchDB, что не скрывается и открыто видно в его статье

  • Designing a document database В статье поднимается список архитектурных вопросов, которые нужно решить при создании документной базы данных; он показывает, что простая идея документного хранилища скрывает множество сложных инженерных решений.

CouchDb

CouchDb

Интересно, что RavenDB изначально имела другое название и начиналась как экспериментальный проект DivanDB. Ранние прототипы создавались на разных языках (точной информации нет), а в качестве движка хранения использовался ESENT. Именно DivanDB стал отправной точкой, на которой Oren Eini проверял идеи документной модели, прежде чем они эволюционировали в RavenDB.

ESENT (Extensible Storage Engine) — это встроенный в Windows низкоуровневый транзакционный сторедж‑движок, который Microsoft использует во множестве систем: Active Directory, Windows Search, Exchange, Windows Update и других.

Если коротко: ESENT — это полноценная ACID‑база данных уровня key‑value/record‑store, встроенная прямо в Windows.

Designing A Document Database Storage

Hidden Windows Gems Extensible Storage Engine

ESENT Engine

ESENT Engine

Этот движок использовался в RavenDB довольно долго, пока проект не дорос до момента, когда ESENT перестал удовлетворять требованиям. Потребовалась кроссплатформенность, возможность глубокой модификации, масштабирование и более высокая производительность — а такие задачи невозможно решить, оставаясь внутри ограничений чужого движка. Логичным шагом стало создание собственного сторедж‑движка, и так появился Voron.

Voron Engine

Voron Engine

На дворе 2009-2010 года. Oren Eini выбрал C# не случайно: ему нужна была высокая скорость разработки, современная экосистема и удобный язык, который позволяет быстро строить сложные системы. При этом он неоднократно писал, что продукты Microsoft ему не всегда нравились, а решения Oracle вызывали у него откровенное раздражение. На фоне всех доступных вариантов C# оказался наименее проблемным и наиболее продуктивным выбором, сочетая мощь платформы .NET с комфортом разработки.

Собственного текстового поискового движка Corax тогда ещё не существовало, поэтому на ранних этапах было принято практичное решение — интегрировать Lucene.NET в качестве индексатора

Apache Lucene .NET Logo

Apache Lucene .NET Logo

Из каких слоёв состоит RavenDB

Если открыть исходный код RavenDB, можно увидеть девять ключевых слоёв, из которых состоит вся система:

SRC проекта RavenDb

SRC проекта RavenDb
  1. Corax — исходный код нового поискового движка Corax, который RavenDB разработала как замену Lucene.

  2. Raven.Client — это клиентская библиотека RavenDB, которая позволяет .NET‑приложению подключаться к серверу RavenDB, выполнять запросы, работать с документами, индексами, патчингом, потоками, операциями и всем API базы данных.

  3. Raven.Embedded — встроенная (embedded) версия RavenDb, предназначенная для запуска RavenDB внутри вашего приложения, без отдельного сервера, без установки, без сети и без администрирования. Raven.Embedded удобен для WPF, Avalonia и тд тому подобное.

  4. Raven.PAL — это Platform Abstraction Layer RavenDb. Он нужен, чтоб RavenDb могла работать кросплатформенно с Windows, Linux, MacOS. Там описана работа с файловой системой и инструментами OC, чтобы БД корректно отрабатывала везде. Используется язык “C” в нем и через [DllImport] импортируются функции в язык “C#” в разных слоях приложения.

  5. Raven.Server — это основной сервер RavenDB, то есть полноценная серверная СУБД. Принимает запросы от клиентов, обрабатывает их и тд.

  6. Raven.Studio — веб‑интерфейс администрирования RavenDB, написанный на React. Позволяет управлять базой данных визуально.

  7. Sparrow — содержит базовые структуры данных, низкоуровневые оптимизации(SPAN, Memory, SIMD, Hashing), парсеры, сериализаторы. Их использует RavenDb для работы и в особенности они используются в Corax/Voron. Это фундамент.

  8. Sparrow.Server — серверное расширение Sparrow, содержащее утилиты и примитивы, которые нужны именно Raven.Server для выполнения тяжёлых системных операций, как пример подойдут криптографические примитивы.

  9. Voron — собственный движок хранения данных. Он отвечает за все, что связано с физическим хранением данных на диске, управления страницами, журналированием, транзакционностью и durabillity.

Зависимость проектов RavenDb, сделано через NDepend

Зависимость проектов RavenDb, сделано через NDepend
Зависимость проектов RavenDb, сделано через NDepend

Зависимость проектов RavenDb, сделано через NDepend

По сути, часть внутренних слоёв RavenDB названа в едином стиле — в честь птиц, что создаёт собственную “орнитологическую” экосистему имен:

  1. Corax — латинское название рода воронов.

  2. Sparrow — воробей.

  3. Raven — ворона по‑английски.

Такая архитектура выбрана не случайна и имеет объяснение. Чтоб лучше понять эти слои я вам настоятельно рекомендую почитать его книгу по созданию БД, ведь она нацелена на практическое понимание осуществляемых работ Базы данных. Вконце-концов она не большая.

В качестве небольшого примера я сделаю отсылку на книгу.

Для чего нужен PAL?

3тья глава книги про libgavran

При создании движка хранения нам нужно очень хорошо понимать, как работать с файлами. Как выясняется, существует множество вещей, которые мы неправильно себе представляем, когда думаем о файлах. В статье “All File Systems Are Not Created Equal: On the Complexity of Crafting Crash-Consistent Applications” исследовали десять приложений (от SQLite до Git и PostgreSQL), чтобы выяснить, корректно ли они записывают данные в файлы. Эту работу обычно называют статьёй ALICE (Application-Level Intelligent Crash Explorer) — по имени инструмента, созданного для изучения ошибок в использовании файловых систем.

Если вы тестируете ошибки файловой системы, но сама файловая система не проверяет ошибки блочного устройства, вы можете оказаться в забавном состоянии. И в 99.999% случаев это не имеет значения, но однажды вы попадёте на тот самый шанс один к миллиарду — и получите сломанную систему.

Статья ALICE обнаружила множество проблем в проектах, которые прошли долгую боевую эксплуатацию. Несколько лет назад произошёл случай потери данных в PostgreSQL, который был отслежен до того, что разработчики не проверяли возвращаемое значение вызова fsync(). Эта статья на LWN хорошо описывает инцидент. Если мы стремимся создать надёжную систему, мы должны предполагать, что любой вызов может завершиться ошибкой — и реагировать соответствующим образом. …

Для чего нужен Voron?

4тья глава книги про libgavran

Нам нужно решить, как мы будем читать и писать данные. Существует несколько распространённых подходов:

  1. Append-only — только добавление в конец файла Мы всегда пишем в конец файла, а формат данных гарантирует, что новые значения считаются актуальными. ….

  2. Фиксированные записи Мы заранее определяем размер записи (например, 64 байта), и файл становится массивом таких записей. ….

  3. Модель страниц (paging) Файл делится на страницы фиксированного размера (обычно 4 КБ – 4 МБ). Каждая страница — независимый буфер, который читается и записывается атомарно. ….

Движок Corax

Corax — это внутренний компонент RavenDB. Он не поставляется отдельно, не имеет собственного логотипа, бренда, сайта

Если вы когда‑то работали с Lucene, то появление Corax не должно сбивать вас с толку — базовые принципы у этих движков очень похожи. Я не собираюсь глубоко погружаться во внутренности Corax, но хочу объяснить фундаментальные вещи, чтобы вы понимали, как он работает и почему он появился.

И прежде чем говорить о Corax, нужно разобраться с вопросом: что такое Lucene?
Lucene — это поисковый движок для работы с текстом. Его верхнеуровневый принцип работы достаточно прост, и лучше всего он раскрывается на примере Elasticsearch, который построен поверх Lucene и демонстрирует весь его потенциал. Да, Lucene используется и в других системах — например, в Neo4j, но именно Elasticsearch показывает, насколько мощным может быть движок, когда вокруг него выстроена специализированная архитектура.

Lucene — это официальный проект Apache Software Foundation, распространяемый под лицензией Apache 2.0.

Логотип Apache Lucene

Логотип Apache Lucene

Lucene и Corax используют принцип Pipeline — он фундаментален для всех движков полнотекстового поиска. В процессе работы активизируется цепочка фильтров, где каждый шаг преобразует текст в более структурированную форму, пока он не станет частью inverted index.

1 Токенизация — первый шаг т.е задача тут превратить строку текста в последовательность токенов.

Пример: "Corax is a fast search engine"Результат: ["Corax", "is", "a", "fast", "search", "engine"]Токенизация не просто split по пробелам, она включает: удаление пунктуации, выделение чисел, выделение составных слов и тд.

2 Анализаторы — нормализация, фильтры, стемминг

После токенизации токены проходят через цепочку анализаторов.Примером нормализации могут служить:[1] приведение к нижнему регистру, допустим "Hello" -> "hello"[2] Стемминг т.е приведение слова к основе(корню), допустим: "running" -> "run"[3] Удаление часто встречающихся слов: the, a, an, is, on, at, of

3 Построения термов — превращение токенов в термы.

После анализа токены становятся термами - нормализованными единицами поиска.Пример: "Corax is a faster engine than Lucene"Результат: ["corax", "fast", "engine", "lucene"]

4 Формирование постинг‑листов — связь термов с документами

Постинг‑лист - это структура вида:term → [docId1, docId7, docId42, ...]

5 Запись в Inverted Index — финальная структура поиска.

Inverted index - это структура term -> posting listПример:"corax" → [docId 1, docId 5]"engine" → [docId 1, docId 7, docId 42]"fast" → [docId 1, docId 9]"lucene" → [docId 1, docId 42]
Работа Apache Lucene

Работа Apache Lucene

В отличие от Lucene, который вычисляет и хранит структуры данных в памяти, Corax хранит их на диске. В результате Corax использует значительно меньше памяти и устраняет длительное время выполнения «холодных» запросов.

Движок Voron

Voron не является самостоятельным продуктом. Он полностью интегрирован в RavenDB и существует только как её внутренний движок хранения.

Voron Engine

Voron Engine

Как отмечает Oli Eini, создание движка хранения данных — одна из самых простых частей в разработке СУБД. Если вы понимаете, как работает B‑Tree, то вы уже знаете 60–70% того, как устроена база данных. Алгоритм B‑Tree был описан ещё в 1970‑х, и с тех пор его фундаментальные свойства остаются неизменными.

B-Tree

B-Tree

Но настоящая сложность базы данных — не в хранении, а в том, как она используется. Эини подчёркивает, что ключевыми качествами хорошей БД являются:

  • удобные инструменты,

  • прозрачное использование,

  • минимизация когнитивной нагрузки на разработчика,

  • и главное — создание ценности для бизнеса, а не необходимость разбираться в том, как работает система внутри.

Именно поэтому движок хранения — лишь фундамент. Настоящая инженерная сложность начинается там, где база данных должна быть удобной, предсказуемой, надёжной и простой в использовании.

При этом B‑Tree остаётся невероятно мощной структурой: она позволяет эффективно работать с сотнями и тысячами терабайт данных, обеспечивая логарифмическое время доступа и устойчивость к росту объёма данных.

Сам Voron имеет 250 .cs файлов и 68_000 строк кода т.е изучить его на первый взгляд не сложно. Однако… Создание движка хранения на “C” и “C#” не одно и тоже.

У Орена Эини действительно была экспериментальная архитектура Naver — небольшой учебный сторедж‑движок, который он писал в блоге, пытаясь воспроизвести идеи LMDB в C#. Первоначально он рассматривал Naver как возможную основу для будущего движка хранения RavenDB, но довольно быстро стало ясно, что это лишь экспериментальная площадка, а не реальный кандидат на продакшен‑использование.

Подробной документации по Naver нет: это не продукт, а серия блог‑постов, где Орен исследовал низкоуровневые техники работы с памятью, layout страниц, указатели, B‑Tree и MVCC. Однако именно в этих экспериментах он столкнулся с тем, насколько непросто реализовать низкоуровневое управление страницами в C#, особенно если пытаться повторить модель LMDB, где всё основано на прямом доступе к памяти через mmap.

В итоге многие идеи из Naver — такие как memory‑mapped доступ, работа со страницами, copy‑on‑write и структура B‑Tree — действительно легли в основу Voron, но сам Naver в RavenDB не используется. Это был шаг на пути к созданию полноценного движка хранения.

LMDB — минималистичный, транзакционный, memory‑mapped движок хранения, построенный на B‑Tree и MVCC. Он невероятно быстрый и надёжный, и стал архитектурным вдохновением для Voron в RavenDB.

Движки хранения

Движки хранения

Орен подробно описывает этот переход в статье: Voron’s implementation: Managed memory mapped database–getting to C memory model

Встроенный движок хранения RavenDB Voron — был создан специально для повышения производительности при росте конкурентности. Он использует архитектуру MVCC, чтобы писатели не блокировали читателей и наоборот. При конкурентных записях RavenDB может объединять несколько параллельных операций в одну дисковую операцию, значительно снижая затраты на I/O и существенно повышая производительность. RavenDB была ACID‑совместимой по умолчанию с самого начала — целостность данных всегда была ключевой ценностью RavenDB.

MVCC

MVCC

Для чтения RavenDB масштабируется прямо пропорционально количеству узлов в системе, поскольку нет необходимости в блокировках или других механизмах управления конкурентностью, которые тратят ресурсы.

RavenDB использует технологию Write Ahead Log и MVCC для обеспечения полной ACID‑защиты. Она хранит дублирующиеся версии изменённых данных только до тех пор, пока существуют активные транзакции, которым может понадобиться доступ к старым данным. Как только такие транзакции завершаются, пространство, занимаемое старыми значениями, может быть немедленно перераспределено. Нет необходимости в VACUUM или постоянном обслуживании. Объём пространства, используемого под метаданные, минимален и обеспечивает хороший баланс между производительностью и использованием диска.

Write Ahead Log

Write Ahead Log

Архитектурная модель и принципы

В основе RavenDB лежит архитектура, ориентированная на устойчивость, предсказуемость и отсутствие простоев. Мульти‑мастер‑кластер позволяет каждому узлу принимать записи и реплицировать их другим узлам, обеспечивая непрерывную работу даже при отказе части инфраструктуры. В документе это сформулировано так: «постоянный нулевой простой для клиентов, даже если один из серверов выходит из строя, благодаря высокой доступности в мульти-мастер‑кластере».

Multi Master System

Multi Master System

Транзакции в RavenDB работают как внутри одного узла, так и между узлами кластера. Это означает, что изменения нескольких документов могут быть выполнены в одной транзакции, и RavenDB гарантирует, что они либо полностью попадут на диск, либо будут полностью откатаны. Более строгий режим — кластерные транзакции, использует консенсус Raft, обеспечивая повышенную согласованность, хотя и с большей задержкой. Стандартный режим транзакций выполняется на предпочтительном узле, после чего изменения асинхронно и атомарно реплицируются на остальные узлы группы.

Системы RavenDB основаны на кооперативном взаимодействии клиентов и серверов. Сбой сервера не вызывает никаких специальных действий в кластере — клиенты уже знают список узлов‑преемников и немедленно переключаются на следующий сервер. Временные ошибки просто перенаправляют трафик на другие узлы, и конечное приложение не замечает ничего, кроме нескольких запросов, которые могут быть немного медленнее обычного.

За кулисами RavenDB отслеживает состояние узла и его восстановление. Опыт показывает, что полная потеря узла — редкость, поэтому RavenDB по умолчанию стремится обеспечить живучесть системы и дождаться возвращения узла.

RAFT

RAFT

Сбой узла RavenDB не рассматривается как приоритетная операция, что позволяет DevOps бесшовно выполнять поочерёдные обновления узлов. Обновление кластера — рутинная операция, где узлы отключаются по одному, чтобы команды DevOps могли выполнить обслуживание, а затем вернуть узел в кластер.

RavenDB ожидает, что узлы будут выходить из строя, и обрабатывает это спокойно и прозрачно. Превращая сбой узла в «не‑событие», RavenDB даёт операционным командам возможность рассматривать узлы как горячие резервные. Вы можете отключить узел в любой момент, по любой причине, и ничего серьёзного не произойдёт.

Производительность и оптимизация RavenDB

RavenDB демонстрирует выдающуюся производительность «из коробки». В документе приводится показатель: «150K записей / 1M чтений в секунду на обычном железе». Это достигается благодаря сочетанию нескольких ключевых технологий.

Источник

Источник

Первая — нативный формат хранения Blittable JSON. Он был создан специально для RavenDB, чтобы минимизировать накладные расходы на обработку документов. Blittable позволяет RavenDB не десериализовать JSON‑объекты при чтении из постоянного хранилища, что экономит огромное количество памяти и CPU. В книге сказано: «Blittable может обрабатывать данные без полного парсинга документа в объектную форму, что значительно снижает стоимость большинства операций».

Вторая — использование страничного кеша операционной системы вместо собственных подсистем кеширования. RavenDB обращается к документам так, чтобы максимально эффективно использовать поведение ядра ОС, которое лучше знает состояние всей системы. Это делает RavenDB «командным игроком», который делит ресурсы системы, а не конкурирует за них.

Третья — само‑оптимизация. RavenDB адаптируется под нагрузку и характеристики оборудования, автоматически выбирая оптимальные стратегии выполнения запросов, обновления индексов и распределения данных.

Само-оптимизация

Само-оптимизация

RavenDB подходит для работы на маломощных устройствах. На сайте приводится показатель: «около 20K запросов/сек на Raspberry Pi или ARM64». Это делает RavenDB подходящей для IoT‑систем, распределённых сенсорных сетей и автономных устройств.

Rasberry PI

Rasberry PI

Индексы и интеллектуальная обработка запросов

Все запросы в RavenDB выполняются через интеллектуальные индексы. Когда поступает запрос, оптимизатор определяет, можно ли ответить на него с помощью существующего индекса, и при необходимости модифицирует и оптимизирует определение индекса на лету. Если подходящего индекса нет, RavenDB автоматически создаёт его. Если индекс не используется, RavenDB удаляет его через определённое время: «30 минут до idle, 72 часа до удаления».

Авто‑индексы RavenDB обучаются на поведении запросов и адаптируются под реальные сценарии использования. Это освобождает разработчиков и администраторов от необходимости вручную проектировать индексы для каждого возможного случая. Когда индекс создан, RavenDB использует предварительно вычисленные результаты, что снижает время выполнения запросов более чем на 99,9%.

Индексы

Индексы

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

Разработчики могут создавать статические индексы, которые выполняют сложные вычисления над данными при каждом их изменении. Такие индексы особенно полезны для AI/ML‑моделей и тяжёлых агрегатов. В отличие от авто‑индексов, статические индексы не удаляются автоматически. RavenDB предоставляет механизм Index Cleanup, который анализирует использование индексов и предлагает объединить или удалить те, что не нужны.

Indexing Perfomance

Indexing Perfomance

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

В RavenDb хорошо поддерживаются пространственные(на основе географических данных) запросы. Так же можно находить документы не по их собственным данным, а по данным связанных документов.

Безопасность данных как встроенная характеристика

RavenDB безопасна по умолчанию. Она использует индустриальные стандарты защиты: шифрование данных «в транзите» и «на диске», сертификаты X.509, TLS 1.2+, а также механизмы предотвращения неправильных конфигураций. В документе подчёркивается: «Индустриальный стандарт безопасности, включая шифрование данных «на диске» и «в транзите», которое относительно просто применять… встроенные постоянные резервные копии».

TLS

TLS

Если база данных настроена так, что принимает внешние подключения без корректной конфигурации безопасности, RavenDB блокирует запуск и требует от администратора исправить ситуацию. Это предотвращает случайное открытие данных в интернет. При этом разработчик может спокойно работать локально без сложной настройки безопасности — RavenDB позволяет запускать систему на loopback‑интерфейсе без аутентификации, пока база не выходит наружу.

По умолчанию RavenDB в незашищённом режиме слушает только localhost. Это сделано для безопасности, чтобы администраторы случайно не выставили RavenDB в сеть без аутентификации. Если попытаться настроить URL, отличный от localhost, при отключённой аутентификации, RavenDB вернёт страницу ошибки с объяснением и инструкциями. Можно явно указать RavenDB, что это осознанное решение (например, если сеть изолирована и безопасна). Для этого требуется дополнительный шаг подтверждения.

RavenDB использует X509 клиентские сертификаты для аутентификации. Преимущество сертификатов в том, что они не привязаны к конкретному пользователю. Они представляют доступ, предоставленный приложению или роли. Обычно сертификаты выдаются именно на уровне приложения/роли, что делает модель аутентификации более естественной.

X.509 Certificate

X.509 Certificate

Настроить RavenDB безопасно — просто (хотя сделать это простым было совсем непросто). После настройки RavenDB сама заботится обо всех аспектах защиты данных. Данные в транзите шифруются, клиенты и серверы проходят взаимную аутентификацию.

RavenDB шифрует все данные и индексы с использованием 256‑битного шифрования. Данные расшифровываются «на лету» по мере необходимости и хранятся в памяти только на время активной транзакции.

256 bit Encryption

256 bit Encryption

Интеграции и гибридные архитектуры

RavenDB интегрируется с широким спектром технологий: реляционные базы данных, OLAP‑решения, Kafka, RabbitMQ, PowerBI, Grafana, Elasticsearch.

Для реляционных систем RavenDB предоставляет мастер миграции SQL, который создаёт шаблон документов на основе таблиц. Автоматические ETL‑процессы позволяют реплицировать данные из RavenDB в SQL‑базы и обратно. RavenDB часто используется как write‑behind cache для реляционных систем или как часть полиглотной микросервисной архитектуры.

Для аналитических задач RavenDB имеет родной OLAP‑ETL, который автоматически передаёт изменения данных в дата‑лейки и OLAP‑хранилища.

ETL

ETL

Интеграция с Kafka и RabbitMQ двунаправленная: RavenDB может получать события из очередей и преобразовывать их в документы, а также публиковать события, сформированные из документов.

PowerBI может выполнять RQL‑запросы напрямую, что позволяет строить отчёты на основе интеллектуальных индексов RavenDB.

Power BI

Power BI

Elasticsearch может использоваться как внешний поисковый кластер, и RavenDB предоставляет ETL для передачи данных в него, включая возможность отправлять только релевантные поля или агрегированные данные.

Клиентский API

Клиентский API, как и вся RavenDB, стремится «просто работать». Для этого он основан на конвенциях — заранее принятых политик. Они определяют, например, какое свойство хранит идентификатор документа или как сериализовать сущность в документ.

RavenDb Conventions

RavenDb Conventions

В большинстве случаев вам не придётся менять конвенции. Создатели RavenDb вложили много усилий, чтобы это было редко нужно. Но предугадать все сценарии невозможно, поэтому API допускает кастомизацию.

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

Масштабирование, шардинг и распределённость

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

Особенность RavenDB — возможность «якорения» документов через символ $ в идентификаторе. «Хеш‑функция использует только часть после $… документы окажутся в одном бакете». Это позволяет хранить связанные документы вместе, что ускоряет запросы, индексирование и работу с агрегатами.

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

Исходя из книги Inside RavenDb пишется система использует одновременно протокол консенсуса и протокол gossip, создавая два уровня коммуникации между узлами кластера.

gossip Protocol

gossip Protocol

Богатый встроенный функционал

RavenDB поставляется с обширным набором встроенных возможностей, которые в других системах требуют сторонних компонентов: быстрые агрегирования, ETL, Hub/Sink‑репликация, полнотекстовый поиск, тайм‑серии, ревизии документов, event sourcing, управление памятью, автоматическое кеширование, шаблоны Identity Map и Unit of Work.

«Функции, которые обычно приходится подключать извне… уже являются частью RavenDB». Это снижает сложность инфраструктуры, уменьшает количество точек отказа и экономит время разработчиков.

ETL RavenDb

ETL RavenDb

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

RavenDB использует два вида кэширования: автоматическое и агрессивное. Автоматическое кэширование позволяет клиенту сообщать серверу, что у него есть закэшированная версия запроса. Если данные не изменились, RavenDB возвращает подтверждение, и клиент использует кэш.

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

Конкурентность обеспечивается движком хранения Voron, который использует MVCC. Писатели не блокируют читателей, а RavenDB объединяет несколько операций записи в одну дисковую операцию. Это значительно снижает I/O‑нагрузку и повышает производительность при высокой параллельности.

Caching RavenDb

Caching RavenDb

Применение в индустрии и масштаб реальных систем

RavenDB используется компаниями из Fortune 100, работает на нескольких континентах и применяется в системах с огромным количеством узлов. В документах упоминается: «крупная сеть с более чем 1,5 миллионами экземпляров POS‑терминалов».

RavenDB развёртывается как локально, так и в облаке — через RavenDB Cloud DBaaS на AWS, Azure и Google Cloud. Конфигурации варьируются от односерверных установок до глобальных гео‑распределённых кластеров.

Что такое Fortune 100?

Что такое Fortune 100?

RavenDB vs MongoDB — архитектурные различия, транзакции, индексы, производительность и эксплуатация

Сравнение RavenDB и MongoDB — это не просто сопоставление двух документных баз данных. Это сопоставление двух философий, двух подходов к архитектуре, двух способов думать о данных, транзакциях, индексации, репликации и эксплуатации. RavenDB и MongoDB появились в разное время, решали разные задачи и развивались под влиянием разных инженерных традиций. Поэтому их различия не поверхностны — они фундаментальны.

В этой главе мы подробно разберём ключевые отличия, опираясь на документы, включая такие фрагменты, как: «RavenDb изначально была ACID транзакционной БД, а MongoDb стала транзакционной в 2018 году…» и «индексы MongoDB оптимизируются под определённые шаблоны запросов». Мы также рассмотрим реальные кейсы, включая опыт Rakuten Kobo, который сравнивал Couchbase, MongoDB и RavenDB в условиях реальной нагрузки.

MongoDb VS RavenDB

MongoDb VS RavenDB

RavenDB vs MongoDB — ACID как фундамент VS ACID как надстройка

RavenDB была спроектирована как ACID‑транзакционная система с самого первого дня. Это означает, что транзакции над несколькими документами, строгая целостность данных и предсказуемое поведение при сбоях встроены в архитектуру. Подчёркивается: «RavenDb изначально была ACID транзакционной БД…».

MongoDB же пришла к транзакциям значительно позже — только в 2018 году. До этого она поддерживала лишь атомарные операции над одним документом. Даже сегодня транзакции в MongoDB имеют цену: они снижают производительность, требуют явного включения и сопровождаются рекомендациями документации избегать их, если возможно, изменяя модель данных.

Это различие определяет всё остальное. В RavenDB транзакции — естественная часть системы. В MongoDB — компромисс между скоростью и целостностью.

ACID

ACID

RavenDB vs MongoDB — оптимистичная модель VS многоуровневых блокировок

RavenDB использует оптимистичное управление конкурентностью. Это означает, что операции чтения и записи не блокируют друг друга, а движок хранения Voron объединяет несколько изменений в одну дисковую операцию.

MongoDB использует многоуровневую систему блокировок — на уровне сервера, базы данных, коллекции и документа. В документах подчёркивается: «Блокировки могут составлять более 30% общей стоимости операций.»

Под нагрузкой это различие становится критическим. RavenDB масштабируется линейно по числу узлов. MongoDB начинает терять производительность из‑за роста количества блокировок и затрат на их управление.

Optimistic VS Pessimistic Locking

Optimistic VS Pessimistic Locking

RavenDB vs MongoDB — master‑to‑master VS primary–secondary

RavenDB использует архитектуру master‑to‑master. Запись может происходить на любом узле, узлы реплицируют изменения друг другу, и каждый узел содержит полную копию данных. Это обеспечивает нулевой простой при сбоях.

MongoDB использует модель primary–secondary. Запись идёт только на primary, а вторичные узлы получают данные через OpLog. Это создаёт узкое место и приводит к задержкам при выборе нового primary.

В документе подчёркивается: «сбой первичного узла может остановить всю систему…» и «RavenDB — 0 downtime» в тестах Chaos Monkey.

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

Переведено всё тут с этой книги

RavenDB vs MongoDB — автоматическая адаптация VS ручной настройки

Индексирование — одна из областей, где различия между системами наиболее заметны.

MongoDB не поддерживает автоматические индексы. MongoDB Atlas предлагает Index Autopilot, но он лишь создаёт индексы по рекомендациям и не умеет удалять ненужные. Это приводит к накоплению индексов, снижению производительности и необходимости постоянного участия DBA.

MongoDb Atlas

MongoDb Atlas

В документе это описано так: «MongoDB Performance Advisor лучше, чем ничего, но это похоже на то, как если бы вы отвезли свой фургон на ремонт после того, как он уже сломался.»

RavenDB, напротив, создаёт индексы автоматически, оптимизирует их на основе реальных запросов, объединяет релевантные индексы и удаляет неиспользуемые. Индексы RavenDB способны обслуживать широкий спектр запросов, тогда как индексы MongoDB оптимизируются под конкретный шаблон — порядок полей, порядок сортировки, структуру запроса.

Это фундаментальное различие: RavenDB адаптируется под приложение, MongoDB требует адаптации приложения под базу.

RavenDb, как из персонажей DC Comics: Думсдэй

RavenDb, как из персонажей DC Comics: Думсдэй

RavenDB vs MongoDB — предвычисление VS постоянного пересчёта

MongoDB предоставляет два механизма агрегирования — MapReduce и Aggregation Pipeline. Оба требуют обработки всех подходящих документов при каждом запросе. Это приводит к обходным решениям: сохранению результатов во временные коллекции, их периодическому обновлению, планированию обновлений в нерабочие часы и значительным затратам на поддержку.

RavenDB выполняет агрегирование заранее и постоянно поддерживает результаты в актуальном состоянии. В документе подчёркивается: «агрегирующие запросы выполняются за миллисекунды, а не за минуты — и без какого‑либо операционного оверхеда.»

Это превращает RavenDB в систему, где аналитические запросы не создают нагрузку на продакшен, а MongoDB — в систему, где аналитика требует отдельной инфраструктуры.

RavenDB vs MongoDB — Blittable JSON VS BSON

MongoDB использует BSON — формат, который требует десериализации при каждом чтении. Это увеличивает использование памяти и CPU.

RavenDB использует Blittable JSON — формат с нулевыми накладными расходами, который позволяет обращаться к документам напрямую в страничном кеше ОС.

В документе подчёркивается: «Blittable может обрабатывать данные без полного парсинга документа… что значительно снижает стоимость операций.»

Это одно из ключевых преимуществ RavenDB: система работает в тандеме с операционной системой, а не поверх неё.

Виды JSON

Виды JSON

RavenDB vs MongoDB — Шардинг и простота VS сложности

Шардинг MongoDB требует настройки нескольких серверов, mongos‑роутеров и config‑серверов. Выбор shard key критически важен, и его нельзя изменить без выгрузки и перезагрузки данных. Неправильный выбор приводит к неравномерному распределению данных и «горячим точкам».

RavenDB использует сегментирование по идентификатору документа и скрывает все детали реализации. Перешардирование выполняется без остановки системы. Это делает масштабирование RavenDB предсказуемым и безопасным.

Sharding

Sharding

RavenDB vs MongoDB — Интеграции и ETL; встроенные возможности VS сторонних решений

MongoDB предлагает коннекторы, но большинство ETL‑сценариев требует сторонних инструментов. MongoDB BI Connector не поддерживает выполнение запросов. Коннекторы не позволяют добавлять трансформационные скрипты.

RavenDB предоставляет встроенные ETL‑механизмы для SQL, OLAP, Kafka, RabbitMQ, Elasticsearch. Это полноценные, нативные инструменты, которые работают в реальном времени и не требуют внешних компонентов.

RavenDB vs MongoDB — Полнотекстовый поиск; встроенный движок VS интеграции с Elastic

MongoDB предлагает полнотекстовый поиск только в MongoDB Atlas. Типичные развёртывания интегрируются с Elasticsearch, что удваивает операционный оверхед.

RavenDB предоставляет полнотекстовый поиск из коробки. В документе подчёркивается: «RavenDB предоставляет полноценный полнотекстовый поиск из коробки… отсутствие необходимости покупать, интегрировать и мониторить отдельный продукт.»

Corax

Corax

RavenDB vs MongoDB — Безопасность; простота VS сложности

MongoDB не является безопасной по умолчанию. Конфигурация рассматривает каждого пользователя как администратора, что удобно для разработки, но опасно в продакшене. В документе приводится факт: «За последние годы было скомпрометировано более 100 000 баз данных MongoDB.»

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

Encryption RavenDb

Encryption RavenDb

RavenDB vs MongoDB — Практический опыт; Rakuten Kobo

Rakuten Kobo провели масштабное сравнение Couchbase, MongoDB и RavenDB. Импорт данных, нагрузочные тесты, отказоустойчивость и эксплуатация показали, что RavenDB обеспечивает стабильную производительность, нулевой простой, предсказуемую архитектуру и удобство разработки и эксплуатации.

Trevor Hunter подчёркивает: обновления RavenDB проходят легко, тесты пишутся просто, разработчики довольны, DevOps довольны, отказоустойчивость впечатляет, производительность стабильна, архитектура предсказуемая.

Rakuten Kobo

Rakuten Kobo

RavenDB vs MongoDB — Итоговое различие философий

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

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

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

RavenDb

RavenDb

RavenDB vs Couchbase — архитектура, производительность и опыт Rakuten Kobo

История Rakuten Kobo — это не просто пример выбора между двумя документными базами данных. Это история компании с капитализацией 12–13 миллиардов долларов, которая ежедневно обслуживает десятки миллионов устройств, генерирующих нагрузку, сравнимую с постоянной DDoS‑атакой.

Rakuten Kobo — один из крупнейших мировых продавцов цифровых книг. Компания принадлежит японской корпорации Rakuten и базируется в Торонто. Миллионы пользователей покупают книги, делают выделения, оставляют заметки, синхронизируют свои устройства — и всё это требует стабильной, быстрой и предсказуемой инфраструктуры хранения данных.

Когда руководство Kobo решило модернизировать инфраструктуру, они столкнулись с вопросом: какая база данных выдержит их реальный продакшен‑трафик?
Couchbase уже использовалась в компании, но её поведение под нагрузкой вызывало вопросы. RavenDB же обещала высокую производительность, низкие задержки и устойчивость к сбоям.

Чтобы получить объективный ответ, команда под руководством CTO Тревора Хантера провела масштабное исследование, создала огромный тестовый набор данных и сравнила обе системы в условиях, максимально приближённых к реальности.

CTO Rakuten Kobo - Trevor Hunter

CTO Rakuten Kobo — Trevor Hunter

RavenDB vs Couchbase — что значит обслуживать десятки миллионов устройств?

Для большинства компаний даже несколько тысяч одновременных запросов — серьёзная нагрузка. Для Rakuten Kobo обычный день выглядит как непрерывная атака: миллионы устройств синхронизируются автоматически, независимо от действий пользователей.

Каждый ридер периодически отправляет данные о новых книгах, выделениях, заметках. Если запросы начинают тормозить, устройства получают тайм‑ауты и повторяют попытку позже, создавая лавинообразный эффект. Инфраструктура должна выдерживать:

  • постоянный поток запросов,

  • редкие, но тяжёлые операции (полная синхронизация нового устройства),

  • всплески нагрузки,

  • сбои узлов,

  • обновления кластера.

Именно поэтому выбор базы данных стал критически важным.

RavenDb VS CouchDb

RavenDb VS CouchDb

RavenDB vs Couchbase — подготовка тестового набора данных: 1.35 миллиарда документов

Чтобы сравнение было честным, Kobo совместно с RavenDB создали воспроизводимый набор данных, максимально похожий на реальный.

В итоговую базу вошли:

  • 69.38 млн пользователей,

  • 63 510 книг,

  • 734.22 млн связей «пользователь-книга»,

  • 497.03 млн выделений,

  • десятки миллионов документов о произведениях, авторах и изданиях.

Общий объём 1.35 миллиарда документов, экспорт 108 ГБ, итоговый размер базы 985 ГБ.

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

Это не синтетический тест. Это модель реальной нагрузки крупного мирового сервиса

HighLoad Results

HighLoad Results

RavenDB vs Couchbase — Загрузка данных

Загрузка 1.35 млрд документов — сама по себе серьёзный стресс‑тест.

RavenDB справилась менее чем за сутки, используя машину с 8 ядрами и 32 ГБ RAM.

Couchbase потребовала почти четыре дня, и это был только первый тревожный сигнал.

Причина — архитектура Couchbase:

  • она хранит метаданные всех документов в оперативной памяти,

  • каждый ключ документа занимает длину ID + 56 байт,

  • при длинных идентификаторах это приводит к огромному потреблению RAM.

Для 1.35 млрд документов Couchbase потребовала 162 ГБ RAM только для хранения ключей, тогда как RavenDB работала со всем набором данных, используя 32 ГБ.

Даже узлы с 128 ГБ RAM падали из‑за нехватки памяти, уходили в page faults, становились недоступными. Приходилось снижать скорость загрузки, делать паузы, отключать механизмы Couchbase, увеличивать диски до 6 ТБ.

Минимальная конфигурация, которая смогла завершить загрузку в Couchbase, — 3 узла по 32 ядра и 128 ГБ RAM каждый.

Это в 12 раз больше, чем требовалось RavenDB.

Вот это обгон в 12 раз!

Вот это обгон в 12 раз!

RavenDB vs Couchbase — почему Couchbase требует терабайты?

RavenDB хранила полный набор данных на каждом узле: 985 ГБ данных + 120 ГБ индексов. На дисках 2 ТБ оставалось достаточно места.

Couchbase же столкнулась с несколькими проблемами:

[1] Шардинг без репликации Каждый документ хранился только на одном узле. Это снижало надёжность и увеличивало риск потери данных.

[2] Модель append‑only Каждая запись добавляется в конец файла. При изменениях старые версии остаются, а новые записываются снова. Это приводит к:

  • огромному росту файлов,

  • необходимости компакции,

  • временным скачкам использования диска.

[3] Компакция

Компакция Couchbase — тяжёлая операция:

  • может длиться часы,

  • иногда более 12 часов,

  • требует огромного количества IOPS,

  • может удваивать или утраивать размер файлов.

Один вторичный индекс занимал 450 ГБ, а во время компакции до 2.5 ТБ.

Чтобы завершить тест, узлы Couchbase пришлось увеличить до 6 ТБ диска каждый.

CouchDb

CouchDb

RavenDB vs Couchbase — производительность запросов

[1] Доступ по ключу При доступе по ключу Couchbase показывает хорошие результаты — пока данные находятся в памяти. Но есть нюанс: узел Couchbase не может обслуживать запросы, пока не загрузит все ключи в память. Это занимает 10–20 минут.

RavenDB начинает обслуживать запросы через несколько секунд после запуска, даже если данные ещё не прогреты.

[2] Запросы по пользователю и книге

Это основной сценарий Kobo: получить выделения пользователя или выделения пользователя в конкретной книге.

RavenDB обрабатывала:

  • 15 000 запросов/сек до достижения порога 200 мс,

  • 93% запросов — быстрее 200 мс,

  • 85% — быстрее 50 мс.

Couchbase достигла порога 200 мс уже при 250 запросах/сек.

[3] Префиксные запросы

RavenDB позволяет выполнять префиксные запросы по ID, минуя индекс. Это даёт огромный выигрыш в производительности.

Couchbase пыталась повторить этот подход, но:

  • CPU взлетал до 80%+,

  • задержки росли,

  • кластер не выдерживал даже 100 запросов/сек.

RavenDB vs Couchbase — Отказоустойчивость

Rakuten Kobo уделяет особое внимание отказоустойчивости.

[1] Поведение Couchbase при сбое узла

Сбой узла вызывает:

  • перебалансировку,

  • огромную нагрузку на кластер,

  • длительное время восстановления,

  • необходимость загрузки всех ключей в память,

  • задержку в 10–20 минут до начала обслуживания запросов,

  • задержку индексов до 30 минут.

Некоторые операции Couchbase (например, смена hostname) требуют удаления узла из кластера и повторного присоединения — что вызывает перебалансировку, которая может длиться 40 часов.

[2] Поведение RavenDB при сбое узла

RavenDB:

  • мгновенно переключает клиентов на другой узел,

  • не вызывает перебалансировку,

  • не требует загрузки ключей,

  • восстанавливается за секунды,

  • использует write‑ahead log,

  • реплицирует только новые записи.

Обновление узла RavenDB занимает менее минуты и является «не‑событием».

Отказоустойчивость

Отказоустойчивость

RavenDB vs Couchbase — Стоимость инфраструктуры

Эталонный кластер Couchbase — минимальная конфигурация без репликации. Но в продакшене так работать нельзя.

Согласно документации Couchbase, для реальной нагрузки Kobo требуется:

  • 5 узлов по 192 ГБ RAM,

  • коэффициент репликации 3,

  • тип узлов m5a.12xlarge,

  • общий объём дисков около 30 ТБ.

Годовая стоимость — огромная.

RavenDB же:

  • работает на кластере из 3 узлов m5a.xlarge,

  • может работать даже на ARM‑узлах,

  • выдерживает 10 000 запросов/сек на узле с 2 ядрами и 8 ГБ RAM,

  • выдерживает 500 запросов/сек на Raspberry Pi 4.

Разница в стоимости — порядки величины.

Price of Infrastructure and Requests

Price of Infrastructure and Requests

RavenDB vs Couchbase — Почему Rakuten Kobo выбрала RavenDB

Rakuten Kobo пришла к однозначному выводу:

  • RavenDB быстрее,

  • RavenDB стабильнее,

  • RavenDB дешевле,

  • RavenDB проще в эксплуатации,

  • RavenDB выдерживает реальные нагрузки,

  • RavenDB не требует внешних систем для запросов,

  • RavenDB не падает при сбоях,

  • RavenDB не требует терабайтов диска,

  • RavenDB не требует сотен гигабайт RAM.

Couchbase же:

  • не выдерживает запросы под нагрузкой,

  • требует огромных ресурсов,

  • долго восстанавливается,

  • вызывает перебалансировки,

  • нуждается в Elasticsearch для запросов,

  • не подходит для инфраструктуры Kobo.

Итог

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

Любопытно, что когда‑то RavenDB вдохновлялась идеями CouchDB, но сегодня сама опережает его по уровню зрелости и функциональности. MongoDB, несмотря на популярность, также заметно уступает RavenDB по качеству предоставляемых возможностей и стабильности работы.

Даже если эти факты не производят сильного впечатления, они демонстрируют важный принцип: там, где есть конкуренция, рождаются лучшие продукты. Конкуренция остаётся ключевым двигателем прогресса.

Конкуренция ключ прогресса

Конкуренция ключ прогресса

ссылка на оригинал статьи https://habr.com/ru/articles/1067642/