Это первая статья в серии статей об интересных технологиях баз данных, которая вытесняет (нет) основной поток SQL. Я познакомлю вас с основными понятиями этих СУБД, поделюсь с вами некоторыми соображениями и расскажу, где можно найти дополнительную информацию.
Большая часть этого не предназначена для немедленного использования в вашем следующем проекте: скорее, я хочу дать вдохновение и рассказать о новых интересных взглядах на проблемы в этой области. Но если когда-нибудь один из этих проигравших станет статус-кво, вы можете сказать всем, что знали об этом до того, как это было круто…
Все шутки в стороне, я надеюсь, вам понравится. Давайте начнем.
обзор
Datomic — последнее детище Рича Хикки, создателя Clojure. Он был выпущен в начале этого года и представляет собой новый тип СУБД, который включает его идеи о том, как должны работать современные базы данных. Это эластично масштабируемая, основанная на фактах, чувствительная ко времени база данных с поддержкой транзакций ACID и JOIN.
Вот основные аспекты, вокруг которых вращается эта интересная технология:
- Новая архитектура. Сверстники, приложения и Transactor.
- Модель данных, основанная на фактах.
- Мощный декларативный язык запросов «Datalog».
Команда Datomic хочет, чтобы ее СУБД предоставила первую «реальную» реализацию записей: записи в до-компьютерном возрасте сохранили информацию о прошлом, тогда как в современных базах данных старые данные перезаписываются только новыми. Datomic изменяет это и сохраняет всю информацию, дифференцируя информацию, делая время неотъемлемой частью системы.
1. Новая архитектура
Единственной самой революционной вещью в Datomic была бы его архитектура. Datomic возвращает мозг вашего приложения обратно клиенту. В традиционной конфигурации сервер обрабатывает все, от запросов и транзакций до фактического хранения данных. С увеличением нагрузки добавляется больше серверов, и набор данных разделяется на них. Как показывает большинство современных баз данных NoSQL, этот метод работает очень хорошо, но за счет некоторых «мозгов», как утверждает г-н Хикки, он стоит. Потеря согласованности и / или мощности запросов является хорошо известным компромиссом для масштаба.
Для достижения распределенного хранилища, но с мощным языком запросов и согласованными транзакциями, Datomic использует существующие масштабируемые базы данных в качестве простых служб распределенного хранения. Вся сложная обработка данных обрабатывается самим приложением. Почти как в родном настольном приложении (если вы помните одно из них).
Это подводит нас к первому краеугольному камню инфраструктуры Datomic:
Приложение для сверстников
Пир создается путем встраивания библиотеки Datomic в ваш клиентский код. С этого момента каждый экземпляр вашего приложения сможет:
- ● общаться с Transactor и сервисами хранения
- ● выполнять запросы к данным, обращаться к данным и обрабатывать кэширование рабочего набора
Каждый узел управляет своим собственным рабочим набором данных в памяти и синхронизируется с «живым индексом» глобального набора данных. Это позволяет приложению выполнять очень гибкие запросы, не прибегая к обходным путям (подробнее об этом в разделе «Критика»).
Но пока у нас есть только обратный запрос. Кроме того, для повторного включения согласованных транзакций Datomic делает еще один шаг: делает службу хранения доступной только для чтения и выполняет все операции записи через новый тип архитектурного компонента — Transactor.
Транзактор
Transactor будет:
- ● обрабатывать ACID транзакции
- ● синхронная запись в избыточное хранилище
- ● сообщать об изменениях сверстникам
- ● индексирование вашего набора данных в фоновом режиме
Кажется, что команда Datomic изгнала все, что затрудняло масштабирование реляционной СУБД в отдельном модуле, и старалась не слишком беспокоиться об этом. Например, Datomic-Rationale заявляет:
«Когда чтение отделено от записи, запись никогда не задерживается запросами. В архитектуре Datomic транзактор предназначен для транзакций и вообще не нуждается в чтениях! »
и
«Размещение механизмов запросов в одноранговых сетях делает возможности запросов такими же гибкими, как и сами приложения. Кроме того, использование механизмов запросов в самих приложениях означает, что они никогда не будут ждать запросов друг друга ».
Первое утверждение верно для некоторых операций чтения, но я не смог найти подсказку о том, как Transactor обрабатывает операции чтения в транзакциях. Хотя упоминается, что «каждый узел и транзактор управляет своим собственным локальным кешем сегментов данных в памяти» , что потребовало бы идеальной синхронизации кеша. В противном случае согласованность гарантируется только для одного пира, что, откровенно говоря, бессмысленно. Надеемся, что эти издержки на управление не нейтрализуют многообещающие возможности ACID и прирост производительности операций в памяти.
Вторая цитата имеет первоначальный смысл, но все же вызывает некоторые опасения:
Что происходит, когда один Transactor сталкивается с слишком большой нагрузкой? Команда Datomic хотела бы избежать шардинга, но разве это не было бы необходимо в какой-то момент? Кроме того, даже если мы притворимся, что количество транзакций не увеличится с увеличением числа пиров, время, необходимое для передачи изменений всем им, обязательно возрастет.
В заключение, Transactor может быть удивительной вещью с меньшими наборами данных, но может стать потенциальным узким местом производительности или Единой точкой отказа.
Складские услуги
Эти сервисы обрабатывают распределенное хранилище данных. Некоторые возможности:
- ● Локальное хранилище Transactor (бесплатно, полезно для игры с Datomic на одной машине)
- ● Базы данных SQL (требуется Datomic Pro)
- ● DynamoDB (требуется Datomic Pro)
- ● Infinispan Memory Cluster (требуется Datomic Pro)
… плюс еще несколько. Поддержка сервиса хранилища может быть одной из главных причин попробовать Datomic, но, к сожалению, для пользователей Datomic Free доступно только временное локальное хранилище (то есть пользователи, которые не хотят платить более 3000 долларов за совершенно новую СУБД).
В общем и целом, архитектура Datomic обладает множеством инновационных идей и потенциальных преимуществ, но ее реальная применимость еще предстоит доказать.
Пожалуйста, ознакомьтесь с подробным обзором архитектуры в документации Datomic или посмотрите 20-минутное видео самого мистера Хики.
(Исходное изображение взято отсюда.)
2. Модель данных на основе фактов
Datomic не моделирует данные как документы, объекты или строки в таблице. Вместо этого данные представлены в виде неизменных фактов, называемых «Datoms». Они состоят из четырех частей:
- сущность
- атрибут
- Значение
- Метка времени транзакции
Datoms очень напоминают схему субъект-предикат-объект, используемую в RDF Triplestores.
Датом может быть чем угодно:
«Баланс Джона составляет $ 12 000» → [Джон: Баланс 12000 <отметка времени>]
Эти определения атрибутов являются единственным типом схемы, подразумеваемой в наборе данных.
В реляционной базе данных это будет представлено как 12000 в строке «john» в ячейке «balance» (данные ориентированы на место). Если сейчас, через месяц, баланс Джона изменится на 6 000, эта конкретная ячейка будет стерта, и будет введено новое значение. Тот факт, что Джон имел 12 000 на своем счете месяц назад, исчезнет навсегда.
Одной из основных причин создания Datomic было ощущение, что современное оборудование, наконец, способно хранить достоверные записи данных, что не делает ни одна другая популярная на сегодняшний день СУБД. Datomic никогда не обновляет данные, он просто записывает новые факты и сохраняет старые. Это открывает путь для множества интересных, чувствительных ко времени запросов.
Из-за своей неизменной, основанной на фактах природы, Datomic справится с новым балансом Джона, просто вставив новый факт:
[Джон: Баланс 6000 <timestamp2>]
Факты никогда не теряются. Если Джон интересуется его текущим балансом, он запрашивает самые последние данные. Но ничто не помешает ему в любой момент запросить свою полную историю баланса. Кроме того, Datoms являются, как следует из названия, атомарной, максимально возможной формой нормализации. Вы можете выразить свою модель данных в любом количестве сущностей, сколько хотите, более широкая картина автоматически создается с помощью неявных JOINS.
Другие преимущества
- ● Поддержка разреженных, нерегулярных или иерархических данных
○ Значения атрибута могут быть ссылками на другие объекты
- ● Встроенная поддержка многозначных атрибутов.
- ● нет принудительной схемы
- ● Нет необходимости хранить историю данных отдельно, время является неотъемлемой частью
Такая гибкость позволяет Datomic функционировать как что угодно, например, полный API-интерфейс для графов .
Некоторые недостатки этого подхода:
- ● Не подходит для больших динамических данных
○ Поскольку обновления всегда записываются в виде новых данных с более поздней отметкой времени, большие динамические блоки данных вскоре заняли бы совсем немного места.
- ● Гибкие схемы ведут к опрометчивости
○ Некоторое планирование все еще должно быть сделано на модели данных
- ● конфликты атрибутов
○ Пространство имен должно использоваться с самого начала
3. Даталог, поиск потерянных фактов
Двухатомные запросы состоят из предложений «ГДЕ», «НАЙТИ» и «В» и набора правил, применимых к фактам. Затем обработчик запросов находит все соответствующие факты в базе данных, принимая во внимание неявную информацию
Правила представляют собой «шаблоны фактов», с которыми сопоставляются все факты в базе данных.
Явные правила могут быть примерно такими:
[? лицо: возраст 42]
Неявные правила выглядят как привязки переменных:
[? сущность: возраст? a]
и может быть объединен с LISP / Clojure-подобными выражениями:
[(<? 30)]
Набор правил для клиентов старше 40 лет, которые купили продукт p, будет выглядеть следующим образом:
[? покупатель: возраст? а] [(>? 40)] [? покупатель: купил р]
Затем наборы правил встраиваются в базовый каркас запроса:
[: найти <переменные>: где <правила>]
<переменные> это просто набор переменных, которые вы хотите включить в свои результаты. Нас интересует только клиент, а не его возраст, поэтому наш запрос клиента будет выглядеть так:
[: найти? покупателя: где [? покупатель: возраст? а] [(>? 40)] [? покупатель: купил р]]
Теперь мы запустим это через:
Peer.q (запрос)
Этот синтаксис, вероятно, потребует некоторого привыкания (за исключением того, что вы знакомы с Clojure), но я считаю, что он очень удобочитаемый и, как обещает Datomic Rationale, «смысл очевиден».
Опрос прошлого
Чтобы выполнить ваши запросы в вашей истории фактов, никаких изменений в строке запроса не требуется:
Peer.q (запрос, db.asOf (<время>)
Вы также можете смоделировать ваш запрос на гипотетических, новых данных. Вроде как прогнозирующий запрос о будущем:
Peer.q (запрос, db.with (<data>))
Для получения дополнительной информации о синтаксисе запроса, пожалуйста, обратитесь к очень хорошей документации и этому видео .
Случаи использования
Datomic, конечно, здесь не для того, чтобы уничтожать все остальные СУБД, но это интересное совпадение для некоторых приложений. Сначала мне в голову пришла аналитика:
- ● Факты неизменны, записи без ACID должны быть быстрыми, поскольку аналитические системы обычно не требуют строгой согласованности
- ● Факты чувствительны ко времени. Это довольно интересно для аналитики.
Сообщения о статусе, твиты или цены могут также храниться более естественно с учетом их динамического характера. Кроме того, поскольку эта СУБД была явно создана для предоставления «реальных» записей, все, что связано с записями, должно быть очевидным соответствием.
В общем, чувствительный ко времени слой Datomic обеспечивает интересный поворот в существующем наборе данных. Его можно использовать как обычную СУБД с дополнительным аспектом понимания. Представьте себе свою базу данных электронной коммерции, включающую полную историю цен каждого товара и историю взаимодействия каждого клиента. Разве не было бы интересно получить быстрый ответ на сложные вопросы? «Когда этот продукт стал популярным? — О, это было после падения цены на 10 долларов. — Когда этот клиент начал использовать сайт каждый день? — Это было два месяца назад, вот график его ежедневного увеличения времени на странице ».
критика
Революционные идеи, подобные тем, на которых основывается Datomic, всегда должны цениться, но анализироваться с разных сторон. Технология слишком молода, чтобы выносить окончательное решение, но некоторые ранние критические замечания включают в себя:
- ● Разделение данных и обработка.
Все необходимые данные должны быть перемещены в клиентское приложение, прежде чем их можно будет обработать / запросить. Это может создать проблему, когда вы доберетесь до больших наборов данных. Локальный кеш также неизбежно будет сдерживать рост рабочего набора. После того, как эта верхняя граница пройдена, повторные обращения к серверному бэкенду снова будут необходимы, с еще большими потерями производительности. Команда Datomic ожидает, что его подход «работает для наиболее распространенных случаев использования», но это не может быть проверено на ранней стадии.
- ● Компонент Transactor как единая точка отказа и узкое место
- ● Для инфраструктуры, доступной только для чтения, может не потребоваться использование шардинга, но Transactor потребуется механизм шардирования определенного типа, как только он будет иметь дело с большими нагрузками.
- ● Цены на Datomic Pro довольно ограничены, и, учитывая, что Datomic Free не подходит для любого производственного использования, создание некоторых экспериментальных проектов будет довольно сложным для среднего разработчика.
Алекс Попеску написал отличный пост по Datomic, сосредоточив внимание на этих критических точках и некоторых других.
Вывод
Лично я считаю, что многие концепции и идеи Datomic, особенно превращающие время в первоклассного гражданина, велики и имеют большой потенциал. Но я не вижу, чтобы я использовал его в ближайшем будущем, потому что я хотел бы доказать некоторые из требований команды к производительности для себя, желание не соответствовать моим финансам относительно лицензии Pro.
В противном случае некоторые из продвинутых функций Datomic, таких как полнотекстовый поиск, несколько источников данных (помимо службы распределенного хранения) и возможность использовать систему только для локальной обработки данных, могут оказаться полезными.
Пожалуйста, поделитесь своими мыслями в комментариях!
Погружение глубже
○ Несколько отличных видео о Datomic
○ Datomic: начальный анализ (сравнение Datomic с другими СУБД)