Для синхронизации данных в приложениях не подходят обычные «файловые» облачные хранилища. Слишком много проблем с консистентностью данных приходится решать самим авторам приложений. Поэтому сегодня мы открываем всем желающим технологию 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 секунд. Данные синхронизируются с облаком и любым экземпляром веб-приложения. Самый простой способ увидеть это — открыть две вкладки в браузере.

Комментарии (20)


  1. AndrewNikolaevich
    09.04.2015 15:04

    Если устройства находятся в одной локальной сети и у них нет доступа к интернету, как осуществлять синхронизацию между ними?


    1. vladimirrusinov Автор
      09.04.2015 15:06
      +2

      Это, конечно, совсем другая задача. Не та, которую мы решали. Но согласитесь — современный смартфон/планшет без интернета – это редкость. :)


      1. AndrewNikolaevich
        09.04.2015 15:24

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


        1. vladimirrusinov Автор
          09.04.2015 15:31
          +1

          Как написано в статье – DataSync обеспечивает синхронизацию данных и при нестабильной сети. То есть ничего не ломается, но синхронизация откладывается. Но если вам хочется иметь свое домашнее облако и все устройства синхронизировать через него, то это будет конечно совсем другое решение, которое мы не делали. И у него конечно будет множество собственных недостатков, как минимум вы же не сидите всегда дома :) А надежность нашего облака и его доступность откуда угодно, всегда будет выше обычного «домашнего» :)


          1. AndrewNikolaevich
            09.04.2015 15:40

            Почему бы не добавить функционал, позволяющий передавать каждому устройству данные о размещении других устройств в сети. Условно говоря вместе с файлами приходит список адресов устройств подключённых к облаку, и получившее устройство их запоминает и при необходимости уже само пытается «достучаться» до них напрямую. Хотя видно я всё сильно усложняю.


            1. vladimirrusinov Автор
              09.04.2015 15:42
              +1

              Примерно такие мысли у нас есть, но для другой задачи и пока про это рано говорить :)


              1. AndrewNikolaevich
                09.04.2015 15:44
                +1

                Тогда желаю вам удачи :)


        1. evnuh
          09.04.2015 16:29

          del


  1. Bris
    09.04.2015 15:47
    +1

    А когда уже мобильные Яндекс.Карты научатся закладки в облаке хранить? Каждый раз после смены устройства/обновления прошивки все закладки теряются — жутко раздражает и делает фичу фактически неюзабельной.


    1. vladimirrusinov Автор
      09.04.2015 15:48
      +2

      Следите за новостями. Технология была сделана и для этого :)


      1. Mur466
        14.04.2015 12:59
        +2

        Я себе это так и вижу.
        Команда Я.Карт: давайте мы сами запилим синхронизацию, люди еще со времен WM и Symbian требуют ее.
        Команда SyncAPI, нет-нет, мы придумали проект синхронизации и все в яндексе будут его юзать…
        Команда Я.Карт: давайте мы хотя бы кнопку импорта/экспорта сделаем, временно?
        Команда SyncAPI, нет-нет, у нас почти все готово. Еще буквально месяц…
        … прошло 5 лет
        Я уже поменял 5 телефонов и 5 раз вручную перебивал все избранные места…
        И вот, свершилось! Первая публичная бета.
        Теперь начнется самое интересное — попытки команды Я.карт прикрутить этот API, проблемы синхронизации, стоны пользователей, потерявших свои закладки…
        Думаю через годик все наладится…
        А всего-то надо было сделать кнопку «выгрузить в файл», «загрузить из файла». И пилите свой API хоть до конца эры интернета.


  1. yurash
    09.04.2015 21:56

    Я в документации не смог найти сведений о предельных/допустимых объёмах для сохранения (и тому подобное). Не то чтоб это мне было прям сильно нужно сейчас, просто обычно хочется сразу знать границы.


    1. vladimirrusinov Автор
      10.04.2015 00:11

      Пока это 10 баз по 10мб каждая. В документацию обязательно добавим ASAP


  1. JC_Piligrim
    09.04.2015 22:27

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

    Свежий пример — телефон на Android стал сильно глючить, пришлось обновлять прошивку и делать вайпы. В итоге, из Яндекс.Навигатора пропало всё избранное (которого, к слову, было не мало, благо важные точки в Google Maps перенёс до того). Вам рассказать, как это нелепо, или сами догадаетесь? Сколько там навигатор лет уже в продакшене? Так сложно все эти годы было отправлять на сервер парукилобайтный текстовый файлик с координатами точек и сделать привязку к яндекс-аккаунту?

    Это как со скайпом — можно пользоваться, вроде. Но если важная переписка, которую важно хранить — нужно использовать что-то другое, потому что история мало того, что не сохраняется толком и её легко потерять, так ещё и синхронизация этой истории работает через раз. Почему из всех популярных мессенджеров только в Hangouts это сделано по-уму?


    1. vladimirrusinov Автор
      10.04.2015 00:12
      +1

      Да, сейчас не везде где можно есть синхронизация, даже среди наших приложений. Сама технология сделана для того чтобы исправить и это в том числе. Следите за новостями.


    1. bormotov
      12.04.2015 17:42

      потому, что компания пытается сохранять «дух стартапа»

      За последний месяц что ни анонс Я.Денег, Я.Карт, идешь смотреть — и видишь, что то, что в соседнем приложении Яндекса уже давно есть, в новой анонсируемой фиче не использовали.

      Отвечают, конечно дипломатично «не всё сразу», «следите за новостями» итд.


  1. JC_Piligrim
    09.04.2015 22:41

    Кстати, насчёт разруливания конфликтов. Что думаете по поводу Swarm?
    www.youtube.com/watch?v=uyZKWyciSXY


    1. vladimirrusinov Автор
      10.04.2015 00:18

      Подробно мы ее не изучали, но еще посмотрим обязательно.


      1. gritzko
        10.04.2015 08:52

        Зовите в гости, я в Москве бываю.


        1. vladimirrusinov Автор
          10.04.2015 12:44

          Да лекго :) Напишите мне, когда будете следующий раз в Москве.