ermouth: (ang)
ermouth ([personal profile] ermouth) wrote2015-01-10 10:49 am

Что такое CouchDB

Прочитал на Хабре про успехи npm и решил написать пост. npm – это пакетный менеджер и публичный репозиторий для node.js, и успехи реально очень впечатляющие.

Снимок экрана 2015-01-10 в 7.04.56

Фишка в том, что этот репозиторий – база CouchDB. Не “веб-сервер плюс БД”, а именно просто БД. Кластер там, с обвесами – но основные функции выполняет CouchDB, вот на её мету прямой выход. И именно CouchDB там используется неспроста.

Доступность

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

По-хорошему, CouchDB сразу после установки становится веб-сервисом. Доступ к БД – только через http(s)-запросы, через REST-интерфейс, то-есть веб-сервер уже встроен в БД. Веб-приложение админки тоже встроено в БД, аж в двух версиях.

Система контроля доступа – простая, но совершенно железобетонная – тоже встроена в БД, как и механика авторизации.

БД умеет синхронизироваться в непрерывном режиме с другими экземплярами через http(s), в тч в режиме “мастер-мастер”. Протокол репликации хорошо документирован и основан на согласовании деревьев ревизий.

Последняя фича, например, значит, что можно иметь полную локальную “живую” копию npm. Можно даже в браузере, без установки CouchDB.

Хранение и запись

Сама по себе, как БД, CouchDB представляет из себя хранилище JSON-документов, но тут тоже есть целый ряд уникальных фич.

Операция записи/обновления – просто POST запрос, например, аяксом. Запись неблокирующая, это называется MVCC, и тут он честный, а не как в табличных БД.

У каждого дока есть ревизия, которая состоит из номера версии и случайного значения (типа 15-12efdab). При каждой записи в док версия инкрементится, а значение меняется. Записать в док можно только отправив значение предыдущей ревизии, причём если сохранённая ревизия не равна отправляемой, запись отменяется.

Запись идёт в режиме “append only”, ничего не пишется поверх. Это значит, что база помнит все ревизии документов до тех пор пока не будет выполнена операция очистки/оптимизации. Также это значит, что база выжимает из SSD-дисков всё, на что они способны – и при этом их бережёт.

И самое главное – к JSON-документам возможны файловые аттачи, примерно как к емэйлам. То-есть это не просто блобы, это блобы с именем и mime-типом.

Выборка по ключу

Нет ничего проще – GET-запрос типа domain/dbname/doc_id – например https://ermouth.couchappy.com/cwmanual/cw-Demo-Controls-4vx1 – сразу отдаст JSON-документ.

В этом документе есть приаттаченный файл – картинка. Она тоже доступна по прямой ссылке https://ermouth.couchappy.com/cwmanual/cw-Demo-Controls-4vx1/turing.jpg. Вот она, отображается прямо из CouchDB.

Выборка запросами

Любая выборка запросом из CouchDB – это выполнение map/reduce и выдача запрошенного диапазона ключей.

Именованные пары map/reduce функций, к которым выполняются запросы, хранятся в самой БД в специальных документах. Документ выглядит примерно так ermouth.couchappy.com/cloudwall/_design/cloudwall. Видно, что функция – javascript.

Снимок экрана 2015-01-10 в 8.50.45

Запрос к этой map/reduce паре (в которой reduce, правда, нет) выглядит примерно так:
ermouth.couchappy.com/cloudwall/_design/cloudwall/_view/info?startkey="cw"&endkey="cwz"

На выходе – краткая информация о документах в базе, подготовленная map-функцией. В диапазоне ключей cw…cwz.

Важнейшее отличие CouchDB от других БД – результаты вычислений map/reduce кэшируются и повторно map-функции не вычисляются, если документ не обновился.

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

Валидация записи и частичное обновление

POST-запросы на запись могут проверяться в БД функциями-валидаторами. Они тоже js и тоже хранятся прямо в БД как специальные документы. Например, вот эта функция не даст писать в БД, если вы не авторизованы:

Снимок экрана 2015-01-10 в 9.03.51

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

Ну то-есть например надо обновить в документе только таймстамп. Чтоб не гонять весь док по сети, можно вызвать на сервере сохранённую функцию, которая это сделает “не отходя от кассы”.

Применимость CouchDB

Везде, где reads>>writes и структура хранимых данных – более-менее сложная. Также в силу специфики http и сериализации как читать, так и писать лучше сразу помногу.

Табличка вот по кейсам, 0 – совсем не подходит, 5 – лучше не придумаешь.

Версионированные хранилища доков 5
Распределённые синхронизированные хранилища 4
Хранилища частично нормализованных связанных данных 1-4
Полностью нормализованные данные 0
Быстрые логи 2
Медленные логи / Агрегаторы логов для анализа 5
Вообще большие наборы данных для анализа 5
Необходимость транзакционной целостности 0
Сложные повторяющиеся “фигурные” выборки 4
Выборки сабсетов узлов документов (частей документов) 5
Подключенные клиенты хотят уведомлений, что база обновилась 4
Хранение файлов (типизированных блобов) 4
SSD диски как хранилище 5+++
Синхронизация / репликация по каналам с потерями и обрывами 5+++

CouchDB вместо сервера приложений

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

Так вот, жизнь показала, что в подавляющем большинстве случаев сервер приложений рядом с CouchDB не нужен вообще – хранимые функции прекрасно со всем справляются. То-есть получается связка из веб-приложения в браузере и БД на сервере, и между ними ничего, кроме сети и https-запросов.

Такая архитектура проста и надёжна, как железный лом – если в ней что-то и ломается (что почти невероятно), то мгновенно понятно что.

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

----

В общем, всем ребятам, кто в вебе или около, очень советую как минимум покрутить-попробовать. Тем более анонимные эксперты вот говорят, что эта технология – один из трендов 2015.

Есчо, на Винде тоже прекрасно работает.

[identity profile] tonsky.livejournal.com 2015-01-10 04:45 pm (UTC)(link)
У меня не везде получилось написать то, что я хотел написать (волновался), так что дополню:

1. Да, конечно, средствами CouchDB, я хотел немного другое сказать, про сам механизм:

http://docs.couchdb.org/en/1.6.1/maintenance/compaction.html

> During compaction of the target CouchDB creates new file with the .compact extension and transfers only actual data into. Because of this, CouchDB checks first for the available disk space - it should be twice greater than the compacted file’s data.

When all actual data is successfully transferred to the compacted file CouchDB replaces the target with the compacted file.

То есть минусы такие: затраты на компактификацию пропорциональны объему всех данных, а не только устаревших. Соответственно можно представить себе ситуацию когда не очень большой поток writes на очень большую базу приведет к тому, что компактификация не будет успевать отрабатывать.

Понятно, что можно много случаев придумать, когда это приемлимо. Я просто говорю, что это один из основных векторов критики CouchDB, думаю полезно его упомянуть, для целостности картины.

2. Хм, окей, а для чего предназначена? И что за инструменты?

4. Да, не требует, там append only + перезаписываемый заголовок с вершиной B-дерева в начале файла. Я скорее всего спутал с чем-то, возможно, с более ранней версией.

Забыл еще спросить про вот это:

> Запись идёт в режиме “append only”, ничего не пишется поверх. Это значит, что база помнит все ревизии документов до тех пор пока не будет выполнена операция очистки/оптимизации. Также это значит, что база выжимает из SSD-дисков всё, на что они способны – и при этом их бережёт.

Как связаны append only и SSD? Я понимаю, почему SSD хороши для random reads (в любых базах), но для append-only как бы без разницы, какой диск, HDD прекрасно справляются с последовательной записью.

[identity profile] Андрей Гаврилов (from livejournal.com) 2015-12-15 11:37 am (UTC)(link)
двух дней не прошло, как своими глазами видел/своими ушами слышал, как товарищ из одной американской конторы рассказывал, как они отказались из-за С. из за-того, что не могли позволить себе платить за террабайты "пустоты" на SSD (они чей-то С.-хостинг использовали). Т.е. сперва платили, а потом поняли, что "так жить нельзя". Но он честно признался - "это потому что мы использовали С. не так, как нужно" (хотя сперва они честно консультировались с перцами из того С.-хостинга). Проблема была в том, что их use case - много, более половины, удалений. При большом потоке записей, конечно.

Я, конечно, не настоящий С.-сварщик, но суть, полагаю, передал верно.

[identity profile] ermouth.livejournal.com 2015-12-15 12:30 pm (UTC)(link)
Использовать специализированные CouchDB-хостинги – серьёзное расточительство. Ценники абсолютно неадекватны.

[identity profile] Андрей Гаврилов (from livejournal.com) 2015-12-15 12:38 pm (UTC)(link)
я, как "не настоящий [С.-]сварщик" подумал, что там, что-то / кто-то "близкий к корням" использовался, то, что это С.-хостинг - это я додумал их контекста, там этого произнесено не было, ЕМНИП.

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