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] ermouth.livejournal.com 2015-01-13 04:16 pm (UTC)(link)
О чём я рассуждаю, я обозначил – распределённые системы. Я не понял, почему сразу два человека решили, что я про кластер (условно) – но феномен этот отметил.

Ни денеженые расчёты, ни покупка-продажа, ни цифровые подписи и идентификация не требуют транзакций. С транзакциями просто удобнее и в некотором смысле "надёжнее".

Это диковато звучит, но я это тщательно обдумал, и не раз. Чтоб сразу обозначить канву рассуждений и основные поинты, просто два кейворда: 1) биткоины 2) чековые расчёты в докомпьютерную эпоху.

То, что ты назвал P2P сетями образуется и в бизнесе, и чаще, чем кажется. Скажем, модель hq + филиалы. Зачастую системы, которые получаются, вовсе никакие не одноранговые (не P2P).

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

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

А если ещё чуть глубже копнуть, проблема тут в скорости света, она конечна – и именно это и есть гарантия невозможности произвольного роста транзакционных систем.

[identity profile] morfizm.livejournal.com 2015-01-14 09:40 am (UTC)(link)
Теперь понятно, да. Возражений у меня нет, но я не настолько много об этом думал, что бы конструктивно вести диалог.

Насчёт P2P - это, скорее, не удачно выбранный пример, лучше подойдёт понятие "децентрализованные". Для децентрализованных систем в общем случае транзакции невозможны как раз по причине невозможности контроля количества нодов онлайн. Биткоин реализует делает очень хорошее приближение к транзакциям: ты ждёшь достаточно времени и вероятность ошибки быстро уменьшается (но не становится равной нулю).

Почему я сначала решил, что ты про кластер: контекст постом задан компьютерный, а не философско-социальный.

Я всё ещё считаю, что контролируемые распределённые системы всегда способны на транзакции. Скорость света не помеха:
1) Во-первых, всё, что в пределах земного шара - это константа. За 100 мс можно облететь вокруг по самому длинному пути.
2) Во-вторых, ты не уточнял, хочешь ли ты иметь возможность сохранять скорость операций для транзакций. Мне естественным образом думать, что при расширении системы допускается постепенное замедление транзакций (не ограниченное константой) - если так, то пусть хоть на всю галактику разрастётся.
3) У меня нет уверенности, что скорость света - фактор, гарантирующий замедление. Как минимум потому, что нет физически ограничивающих факторов на плотность вещества. Может быть, можно увеличивать её бесконечно? Тогда бесконечно большую распределённую систему можно будет разместить компактно :)

[identity profile] ermouth.livejournal.com 2015-01-14 10:25 am (UTC)(link)
Если исключить из рассмотрения транзакции, которые занимают больше, скажем, 4 поколений – 100 лет – получится, что ограничения есть по здравому смыслу.

Также я бы исключил распределённые длинные транзакции, которые выполняются через чейн координаторов и журнал отката – типа заказов с отложенным исполнением/подтверждением (букинг, предзаказы и тп). Их транзакциями называют по недоразумению. При ближайшем рассмотрении это оказываются логи с той или иной формой хранения истории ревизий.

Теперь про физику.

Бесконечно сжимать нельзя – получится чёрная дыра, которая обязательно взорвётся. Энергетика процесса – как у термоядерной бомбы сопоставимой массы )

Ну и конечно гораздо раньше ты получишь такую ситуацию, что тепловые флуктации не дадут тебе просто ничего оттуда считать.

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

У меня нет уверенности, что в галактике есть столько вещества, чтобы построить такую конструкцию.

Я допускаю, правда, что при межзвёздных, кхгм, путешествиях на кораблях будет банка с какими-то entangeled particles, и именно с помощью них будет осуществляться связь с базой (там тоже банка с такими частицами). Можно даже сюда транзакции прикрутить межзвёздные, но это всё равно надо сначала делать специальное вещество, а потом его везти куда-то. Так что быстрее скорости света в результате не получается.

Такие дела. Похоже, транзакции – это больше земная технология )

[identity profile] morfizm.livejournal.com 2015-01-15 08:53 am (UTC)(link)
Уточню, что журнал ревизий есть возможная реализация настоящих транзакций. Только букинги через чейн координаторов транзакциями не являются по другой причине - потому что они читают нетранзакционно - у них копия, скажем, свободных мест, которые в результате могут оказаться несвободными из-за коллизий (кто-то забукал тот же билет через другого координатора) и букинг становится недействительным. Что делает его действительность на момент букинга некоторой вероятностной величиной.

По остальному - жутко интересно, но сказать мне, пожалуй, нечего :)

[identity profile] ermouth.livejournal.com 2015-01-15 09:36 am (UTC)(link)
А мне, кажется, есть что. Я тут комменты перечитал и, действительно, насчёт скорости света погорячился.

Я, кажется, знаю, как всё же организовать идеальную транзакционную базу любого масштаба.

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

Вещество (связанные частицы) тут – расходный материал.

Тянет на пост дичайшего гона )

[identity profile] morfizm.livejournal.com 2015-01-15 10:31 am (UTC)(link)
Хм, подгонять связанные частицы придётся тоже быстрее скорости света. Хотя, конечно, если раздобыть где-нибудь бесконечную энергию для разгона, то, наверное, можно как-то будет хакнуть теорию относительности :)

С другой стороны, если хакнуть скорость света, то транзакции можно реализовать тупо путешествием во времени: синхронизируем "запись транзакции" со всеми нодами настолько долго, сколько нам надо, пусть даже годы, и пусть даже всё увеличивающиеся отрезки времени, потом смотрим, в какие моменты времени кто-то сделал "read", трогающий те же данные, что транзакция записала, и пишем напрямую в прошлое результат "read"-а. С точки зрения пользователя будет работать очень шустро! :)

[identity profile] ermouth.livejournal.com 2015-01-15 10:59 am (UTC)(link)
Нет, не обязательно их быстрее скорости света везти. Их можно везти заранее, если не пытаться через них _передавать_ информацию.

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

Мы всё время везём какое-то количество связанных частиц и их расходуем для синхронизации реплик баз, которые устроены "классически".

Атомарная операция, которую мы будем делать – это флип бита.

Чтобы передать адрес этого флипнутого бита, надо израсходовать примерно (n+1) пар связанных кубитов, где 2^n – общее к-во бит в базе.

Передаём мы очень просто – выполняем на источнике передачи алгоритм Гровера, который нам "найдёт" флипнутый бит. Кубиты в приёмнике выполнят то-же самое одновременно. Значит, в итоге на приёмнике будет содержаться указатель на бит, который надо флипнуть.

Наверное, можно проще. Главное, обойтись без передачи информации.
Edited 2015-01-15 11:02 (UTC)

[identity profile] ermouth.livejournal.com 2015-01-14 10:30 am (UTC)(link)
Кстати, мне вот в голову пришло, что нервная система человека – это сеть с optimistic репликацией. Синапсы там, небыстро, то-сё.

А вот нервная система Чужого – это транзакции. Говорят, у Чужих прямая иннервация )