Выбор типа базы данных для проекта децентрализованного календаря - PullRequest
0 голосов
/ 04 июня 2019

Я занимаюсь разработкой календарной системы, которая децентрализована. Он должен сохранять данные на каждом устройстве и синхронизировать, если они оба подключены к Интернету. Моя первая идея состояла в том, чтобы просто использовать реляционную базу данных и попытаться синхронизировать данные после подключения. Но теория говорит о другом. CAP-теорема Брюерса ​​ описывает лежащую в ее основе теорию, но я не уверен, что эта теорема устарела. Если я использую эту теорему, у меня есть «AP [доступность / разделение] системы». «A», потому что в любой момент мне нужны данные для моего календаря, и «P», потому что может случиться так, что между устройствами нет соединения, и данные не могут быть синхронизированы. Примерами баз данных являются CouchDB, RIAK или Cassandra. Я работал только с реляционными базами данных и не знаю, как дальше работать. Разве плохо использовать реляционную базу данных для моего проекта?

Это для моей дипломной работы. Я просто хотел начать использовать Postgres, но потом я нашел эту теорему ... Весь проект основан на Java.

1 Ответ

0 голосов
/ 05 июня 2019

Я думаю, что теорема CAP не очень помогает вашему сценарию.Распределенные системы, которые работают с разделами, должны решить, что делать, когда одна часть хочет внести изменения в данные, но не может достичь другой части.Одно из решений состоит в том, чтобы заставить запись ждать - и это отказывается от «доступности» из-за «раздела», одной из опций, представленных в теореме CAP.Но есть и более полезные варианты.Наиболее полезный (высокодоступный) вариант - разрешить обеим частям записываться независимо и согласовывать конфликты, когда они могут снова соединиться.Вопрос в том, как это сделать, и разные распределенные системы выбирают разные подходы.

Некоторые системы, такие как Cassandra или Amazono DynamoDB, используют «последние выигрыши писателя» - когда мы видим конфликт между двумя конфликтующими записями, последнимодин (согласно некоторым синхронизированным часам) выигрывает.Чтобы этот подход имел смысл, вам нужно быть очень осторожным в том, как вы моделируете свои данные (например, следите за случаями, когда разрешение конфликта приводит к недопустимому сочетанию двух состояний).

В других системах (итакже в Cassandra и DynamoDB - в их «коллекционных» типах) запись может все же происходить независимо на разных узлах, но есть более изощренное разрешение конфликтов.Хорошим примером является «список» Кассандры: можно отправить обновление с надписью «добавить элемент X в список», а другое - «добавить элемент Y в список».Если эти обновления происходят в разных разделах, конфликт позже разрешается добавлением и X и Y в список.Структуры данных, такие как этот список, который позволяет независимо изменять содержимое на определенных узлах определенным образом и затем автоматически согласовывать их разумным способом, известны как Бесконфликтный реплицируемый тип данных (CRDT).

Наконец, в документе Amazon Dynamo был использован другой подход (не путать с их текущей службой DynamoDB!), Известный как «векторные часы»: когда вы хотите записать объект - например, покупкиcart - вы сначала читаете текущее состояние объекта и получаете «векторные часы», которые вы можете рассматривать как «версию» полученных вами данных.Затем вы вносите изменения (например, добавляете товар в корзину) и записываете новую версию, сообщая, с какой старой версии вы начали.Если две из этих модификаций происходят параллельно на разных разделах, мы позже должны согласовать эти два обновления.Векторные часы позволяют системе определить, является ли одна модификация «более новой», чем другая (в этом случае нет конфликта), или они действительно конфликтуют.И когда они это делают, для разрешения конфликта используется логика, специфичная для приложения.В примере с корзиной покупок, если мы видим, что конфликт состоит в том, что в одном разделе раздела элемент A был добавлен в корзину, а в другом разделе элемент B был добавлен в корзину, простое решение состоит в том, чтобы просто добавить оба раза A иB в корзину.

Вам, вероятно, следует выбрать один из этих подходов.Просто сказать, что «теорема CAP не позволяет мне делать это», как правило, не вариант ;-) На самом деле, в некоторых отношениях проблема, с которой вы сталкиваетесь, отличается от некоторых систем, о которых я говорил,В этих системах общим случаем является то, что каждый узел всегда подключен (без разделения) с очень низкой задержкой, и они хотят, чтобы этот общий случай был быстрым.В вашем случае вы, вероятно, можете предположить обратное: две части обычно не связаны, или, если они связаны, существует большая задержка, поэтому разрешение конфликтов скорее норма, чем исключение.Таким образом, вам нужно решить, как сделать это разрешение конфликта - что произойдет, если добавить одно собрание на одном устройстве и другое собрание на другом устройстве (скорее всего, просто сохранить оба как два собрания ...), как вы узнаете, чтоодно устройство изменило ранее существовавшее собрание и не добавило второе собрание (векторные часы? уникальные идентификаторы собраний? и т. д.), поэтому в результате разрешения конфликта фиксируется существующее собрание вместо добавления второго?И так далее.Как только вы это сделаете, вы сохраните данные в обоих разделах (возможно, совершенно разные реализации баз данных на клиенте и на сервере) и какой протокол вы отправляете, когда обновления станут деталями реализации.

Есть еще одна проблема, которая вам понадобитсяучитывать.Когда мы делаем эти согласования?Во многих системах, подобных перечисленным выше, согласование происходит при чтении: если клиент хочет прочитать данные, и мы внезапно видим две конфликтующие версии на двух достижимых узлах, мы сверяем.В вашем приложении календаря вам нужен немного другой подход: возможно, что клиент будет когда-либо только пытаться читать (использовать) календарь, когда он не подключен.Вам нужно использовать редкие возможности, когда он подключен, чтобы примирить все различия.Более того, вам может потребоваться «подтолкнуть» изменения - например, если данные на сервере изменились, клиенту может потребоваться сказать: «Эй, у меня есть некоторые измененные данные, приходите и согласовывайте», поэтому конечный пользователь немедленносм. объявление о новой встрече, например, которое было добавлено удаленно (например, возможно, другим пользователем, использующим тот же календарь).Вам нужно будет выяснить, как вы хотите это сделать.Опять же, нет волшебного решения, такого как «использовать Кассандру».

...