ermouth: (ang)
[personal profile] ermouth

Прочитал на Хабре про успехи 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.

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

Date: 2015-01-12 09:09 am (UTC)
From: [identity profile] ermouth.livejournal.com
У тебя айфон 4. Там внутренняя механика хранения – SQLite, так что хрена с два это терминал, это ещё как нод.

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

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

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

Это же очевидно.

Это вообще повседневная ситуация.

Почему-то понятие "распределённая система" часто воспринимается как кластер – а эт шире понятие. Генерализовано это многослойный фрагментарный кэш.

Date: 2015-01-12 09:28 am (UTC)
From: [identity profile] morfizm.livejournal.com
Я не понимаю, к чему аргумент. Описанный тобой функционал (отложенная синхронизация получения и отправления писем) не транзакционен по сути, и его реализация не требует и не использует транзакций. О чём мы спорим вообще?

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

Date: 2015-01-12 09:52 am (UTC)
From: [identity profile] ermouth.livejournal.com
А я, кажется, понимаю, о чём.

Дай определение понятия "достаточно большой распределённой системе" – в терминах функции связности от времени и функции количества узлов от времени.

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

Поэтому тебе надо обеспечивать обновление данных на узлах каким-то другим способом.

Технически, конечно, можно утверждать, что 100% отклонённых транзакций обеспечивают транзакционную целостность системы, но это будет лукавством, нет?

Date: 2015-01-13 09:04 am (UTC)
From: [identity profile] morfizm.livejournal.com
Мне кажется, мы размышляем о разных вещах. Ты про естественным образом образующиеся P2P сети (вроде "PC всех пользователей" или "телефоны всех пользователей"), а я про контролируемый environment, где ты говоришь, сколько бросить железа, а я его определённым образом располагаю и управляю им.

В первого типа системах транзакции невозможны, это почти очевидно.
Во вторых - мне совсем неочевидно, что в каком-то обозримом будущем количества нодов и сопутствующие эффекты достигнут такого состояния, как ты описываешь, которое невозможно контролировать. С другой стороны, если суммарный computing power, доступный в частных руках, вдруг многократно превысит доступные коммерческие объёмы, которые можно организовать как ты хочешь, то да, возможно, то, что ты говоришь, будет правдой. Будет computing почти без транзакций. Но транзакции всё равно будут, т.к. есть приложения, которые фундаментально требуют транзакций. Например, денежные расчёты и покупка-продажа-резервация товаров, цифровые подписи, идентификация личности и т.п.

Date: 2015-01-13 04:16 pm (UTC)
From: [identity profile] ermouth.livejournal.com
О чём я рассуждаю, я обозначил – распределённые системы. Я не понял, почему сразу два человека решили, что я про кластер (условно) – но феномен этот отметил.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Profile

ermouth: (Default)
ermouth

November 2021

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 16th, 2025 02:41 pm
Powered by Dreamwidth Studios