Для синхронизации данных в приложениях не подходят обычные «файловые» облачные хранилища. Слишком много проблем с консистентностью данных приходится решать самим авторам приложений. Поэтому сегодня мы открываем всем желающим технологию DataSync API, которую команда Яндекс.Диска разрабатывала для собственных сервисов Яндекса. Она позволяет синхронизировать структурированные данные между облачным хранилищем и устройствами. API использует логин Яндекса, который есть почти у каждого пользователя интернета в России и у многих в других странах. DataSync мультиплатформенный и не завязан только на Android или iOS.
Мы правда очень рады, ведь еще три года назад, когда запускался Яндекс.Диск, хотели синхронизировать не только файлы между компьютерами, а вообще любые данные между всеми устройствами человека. Наша цифровая жизнь – это не только файлы, но еще и точки на картах, маршруты, закладки в браузере, список рекордов в компьютерной игре и много другое.
Уже более двух лет Яндекс.Браузер работает на технологиях синхронизации Я.Диска. В ближайшем будущем другие крупные сервисы Яндекса начнут объединять свои платформы на DataSync. Под катом — больше подробностей о том, как он устроен, зачем нужен, и примеры, на которых можно посмотреть и попробовать, как всё работает.
Когда-то базовым инфраструктурным элементом интернета стал веб-сервер, без которого теперь невозможно представить существование всемирной сети. Теперь времена изменились, и мы уверены, что облачная самосинхронизирующаяся база данных будет не менее важным элементом современного мультиплатформенного интернета.
Раньше у пользователя было только одно устройство и только один способ взаимодействовать с интернет-сервисом – пойти на сайт. И для разработчика все было просто. База-Код-Веб-интерфейс. Где-то в недрах сайта работала база данных, где разработчик сохранял нужные ему данные, и откуда их забирал, отображая на одном единственном устройстве пользователя, а точнее — в браузере его компьютера.
Однако времена сильно изменились, и теперь у человека может быть множество устройств, а один сервис может быть представлен целым набором приложений. Это сильно усложнило жизнь разработчика. У него всего стало больше: интерфейсов, баз, логики и даже языков программирования. Но самое ужасное — это данные. На каких-то устройствах есть локальные копии данных, которые живут на сервере и других устройствах, и их все необходимо синхронизировать между собой. Это вовсе не простая задача: возможны конфликты, потеря данных, потеря связи, требуется нормальная скорость работы на всех устройствах – и много другое.
Очевидно, что если разработчик каждый раз будет сам решать с нуля задачи синхронизации приложений и облачного хранения данных, он, скорее всего, забудет, что он собственно собирался сделать изначально или доберется до этого совсем не скоро.
Конечно же, задача решить описываемую проблему появилась и в Яндексе. Мы начали работать над созданием «облачной базы данных», которая освободит разработку от рутинной задачи синхронизации и позволит сфокусироваться на создании приложений.
Обычная база данных скучно живет на одном компьютере, а мы делали базу, которая живет одновременно в облаке и на всех устройствах пользователя. Это, разумеется, как готовое решение, принципиально упрощает задачу разработки мультиплатформенных приложений. Где бы ни были сохранены данные в такую базу – на телефоне, в браузере, на сервере, – ничего не потеряется и везде появятся актуальные данные.
Во внутренней документации на проект написано так: «DataSync API — это хранилище произвольных структурированных данных, привязанных к пользователю или паре пользователь + приложение. Оно заточено под возможность синхронизации между пользовательскими устройствами и нормальную работу в условиях плохой мобильной сети».
Для внешнего разработчика наша база данных очень похожа на популярную noSQL базу MongoDB — суть та же. Она состоит из коллекций, коллекции — из объектов. Объект — это набор key-value полей. Но мы поставили перед собой задачу сделать так, чтобы разработчик не думал о том, как ему связывать данные на разных устройствах и в облаке, а просто работал с нашим API, в то время как вся синхронизация данных происходила магическим образом. Конечно же, такая «магия» возможна, когда вы используете и облако, и клиентскую часть нашего «синхронизирующего» SDK.
И тут хочется чуть подробнее рассказать, какие проблемы и как мы решали, чтобы она случилась.
Конфликты
В предложенном устройстве мира у нас много экземпляров базы, и все они меняются локально. В такой ситуации неизбежно появление конфликтов, когда данные меняются одновременно в разных местах. А терять данные совсем не хочется. Алгоритм решения этой проблемы достаточно традиционный:
- у всех экземпляров данных появляется версия, о которой знает каждое устройство и сервер;
- при отправке изменений она отсылается и проверяется на сервере;
- в случае несовпадений версий клиент получает список изменений, о которых он не знал, и может правильно разрешить конфликт.
Прозрачная работа без сети
Мобильное приложение (да и многие другие) не может рассчитывать на стабильную связь, а данные сервиса могут измениться в любой момент. Это не должно быть проблемой для того, кто использует нашу облачную базу. Очевидно это так же очень важно учитывать в нашем SDK. Мы решили эту проблему такой схемой действий:
- все общение с сервером на себя берет наш SDK;
- общение с сервером полностью асинхронно и происходит в фоне;
- методы, которые SDK представляет разработчикам, никогда не ждут окончания чтения/записи из сети.
В документации DataSync API описаны все методы, которые используют наши собственные SDK. Вам ничего не стоит сделать собственную защищенную от конфликтов и обрывов связи библиотеку для любой платформы.
Мы сначала сделали так, что каждое «приложение» синхронизируется с таким же на других платформах и на сервере. Но потом нашлись примеры, когда важно синхронизировать данные между разными приложениями на одном устройстве – грубо говоря, иметь общую базу данных. И тогда мы реализовали и такое. Теперь, например, если у вас есть lite-приложение и полноценное, то вы без труда сможете пробросить данные пользователя, который решился на апгрейд, из одного в другое. Или отправить или получить данные из приложения партнера.
Как устроен API
В процессе работы с API клиент в основном оперирует такими понятиями, как:
- база данных (БД),
- дельта обновления,
- снэпшот,
- конфликт.
БД является единицей синхронизации для API. Она содержит в себе объекты (записи), объединенные в коллекции. Но все операции по сути дела производятся с отдельными объектами. При этом чтобы однозначно идентифицировать объект, необходимо указать идентификатор его и коллекции.
Идентификатором состояния БД является номер ревизии. В API реализована схема контроля ревизий, что позволяет отслеживать и фиксировать конфликтные ситуации. При создании БД ревизия равна нулю, при дальнейшем получении каких-либо изменений для данной базы номер ревизии будет увеличиваться на единицу. Любые изменения осуществляются за счет отправки дельты обновлений. С её помощью можно создавать, удалять и редактировать записи.
Конфликтом считается такая ситуация, при которой клиент отправляет на сервер ревизию младше существующей на нём. В таком случае сервер смотрит на номер пришедший ревизии и отправляет набор изменений до существующей версии.
В случае, когда ревизия на клиенте настолько устарела, что сервер не может предоставить список необходимых изменений, клиенту необходимо получить снэпшот базы и обновиться до текущей ревизии самостоятельно. Схема решения конфликтов остается на усмотрение разработчиков.
Снэпшот базы отражает состояние актуальной ревизии базы на сервере. Его необходимо запрашивать при создании локальной БД на устройстве или при решении конфликтных ситуаций.
Для того чтобы расшаривать данные только в рамках собственного приложения, необходимо запрашивать права на доступ хранения данных приложения, для расшаривания данных – доступ к общим данным пользователя.
Заключение
Начать использовать HTTP API и JS SDK вы можете уже сейчас. В ближайшем будущем мы выпустим SDK для Android и iOS.
Посмотреть, как всё работает, можно на примере адресной книги в тестовом браузерном приложении. Оно демонстрирует, как может происходить синхронизация телефонных номеров пользователя с шагом в 20 секунд. Данные синхронизируются с облаком и любым экземпляром веб-приложения. Самый простой способ увидеть это — открыть две вкладки в браузере.
Автор: vladimirrusinov