Elliptics

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 22:32, 23 ноября 2017.
Elliptics
Elliptics2.png
Разработчики: Евгений Полаков с поддержкой Яндекса
Выпущена: 2008 (2008)
Написана на: C++, Python, Go
Тип ПО: NoSQL
Веб-сайт www.reverbrain.com

Elliptics — это распределенное хранилище данных с ключом с открытым кодом. По умолчанию это классическая распределенная хеш-таблица (DHT) с несколькими репликами, помещенными в разные группы (распределенные хэши). Elliptics[Источник 1] был создан для удовлетворения требований многоцентрового центра и физически распределенных мест хранения,при хранении огромного количества средних и больших файлов (от 1 до 256 гигабайт, от тысяч до миллиардов объектов).

История

История его создания берет свое начало в далеком 2007 году как части POHMELFS[1]. В следующем году Elliptics был вынесен в отдельный проект, и в нем было перепробовано множество различных подходов к распределенному хранению данных, многие из них не подошли из-за сложности, из-за слишком малой практичности в реальной жизни. В конце концов его автор, Евгений Поляков, пришёл к созданию Elliptics в современном виде.

В 2012 году Поляков объявил о новой версии POHMELFS на основе Elliptics[Источник 2].

С 2014 года Elliptics используется в Яндекс- Картах , Диске, Музыке и Фотографиях.

Общее

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

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

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

Для связи между узлами в Elliptics используется свой расширяемый асинхронный бинарный протокол с поддержкой мультиплексирования. В каждом пакете есть заголовок и, возможно, тело запроса или ответа.

В заголовке указаны:

  • ключ, по которому совершен запрос
  • статус команды
  • номер транзакции
  • номер (идентификатор) команды
  • набор общих для всех команд флагов
  • размер тела запроса/ответа

Всего заголовок занимает 96 байт, тело же запроса и ответа специфично для команды и, с точки зрения сетевого движка, представляет собой просто набор байт. Данный протокол позволяет абстрагировать собственно сетевое взаимодействие между узлами от логики работы сервера — хранения данных. За счет этого можно сказать, что Elliptics — это уже давно не просто система хранения данных, а распределенная система выполнения команд.

Архитектура[Источник 3]

По умолчанию Elliptics формирует распределенную хеш-таблицу в одной группе (реплика). Группа может содержать один или несколько серверов, а также физический сервер может содержать несколько эллиптических групп (реплик), хранящихся на разных серверах. Группы могут жить в разных физических местах, что позволяет запросам клиентов серверов, когда другие местоположения недоступны. Одноранговый (P2P)[2] протокол может использоваться для доступа к данным непосредственно с серверов хранения без "проксирования". Elliptics поддерживает сценарии на стороне сервера на C++ , JavaScript , Python , на основе технологии Cocaine[3] , кэша SLRU и множества подключаемых бэкендов. Рассмотрим основные особенности Elliptics:

  • Отказоустойчивость
  • Расширяемость
  • Сохранность данных
  • Скорость
  • Простота архитектуры

Отказоустойчивость

Это одно из пяти свойств, на сохранение которых направлен Elliptics.Машины постоянно ломаются, жесткие диски выходят из строя.Наиболее очевидные из них – это обрыв кабеля и потеря электричества. Все уже давно знают, что делать в случае, если отключился диск или сервер. Но никто не задумывается, что будет с их системой, если откажет дата-центр, регион Amazon'а или произойдет иное крупное событие. Elliptics же изначально планировался для решения такого класса проблем.

В Elliptics все документы хранятся по 512-битовым ключам, которые получаются как результат sha512-функции от названия документа. Все ключи можно представить в виде Distributed Hash Table (DHT), кольца с диапазоном значений от 0 до 2^512 . Кольцо случайным образом делится между всеми машинами одной группы, причем каждый ключ может одновременно храниться в нескольких различных группах. Можно приближенно считать, что одна группа – один дата-центр. Как правило, компания Яндекс хранит 3 копии всех документов, и в случае выхода из строя какой-то машины мы теряем лишь одну копию части кольца. Даже при выходе из строя всего дата-центра информация не теряется, у нас все документы остаются еще как минимум в двух копиях.

Расширяемость

В Elliptics есть возможность добавлять дополнительные машины.При подключении нового компьютера к группе, он забирает себе случайные интервалы из тех 2^512 ключей, и все последующие запросы по этим ключам будут приходить на данную машину.

Если у нас есть три группы, состоящие из сотни машин каждая, то добавление новых повлечет за собой ребалансировку и, как следствие, придется большие объемы данных переливать по сети для их восстановления. Для тех, кому это не подходит, мы разработали систему балансировки нагрузки – Mastermind, которая работает на облачной платформе Cocaine.Mastermind – это набор равноправных супер-узлов, которые определяют в каких группах будет храниться тот или иной файл исходя из нагрузки на каждый из серверов.В случае выхода из строя любого из узлов Mastermind все продолжает работать, как и прежде. Если размер групп поддерживается небольшим, тогда при добавлении новых машин достаточно им выдать новую группу и дать знать об этом Mastermind’у. В этом случае к идентификатору файла добавляется информация о том, в каких группах его следует искать. Этот механизм позволяет обеспечивать поистине бесконечное и очень простое расширение хранилища.

Сохранность данных

Рассмотрим ситуацию,когда "старые" данные оказались не на тих машинах или потерялись.

На этот случай в Elliptics предусмотрена система восстановления. Схема ее работы выглядит следующим образом: она проходится по всем машинам и, в случае если данные лежат на не своей машине, перемещает их на нужную. Если окажется, что какой-то документ лежит не в трех копиях, то во время этой процедуры документ будет размножен на нужные машины. При этом если система работает с Mastermind’ом, то номер группы расположения файла берется из мета-информации. Скорость восстановления зависит от многих факторов и нельзя назвать точную скорость восстановления ключей, но, как показывает нагрузочное тестирование, наиболее узким местом является сетевой канал между машинами, который используется для передачи данных.

Скорость

Elliptics обладает небольшими накладными расходами и способен на одной машине при работе к кэшем выполнять до 240 тысяч операций чтения в секунду. При работе с диском скорость, естественно, падает и упирается в скорость чтения данных с диска.

На основе Elliptics реализован проект HistoryDB. С его помощью мы храним логи, поступающие от различных внешних событий. Во время тестирования, группа из трех машин спокойно и ровно справлялась с нагрузкой в 10 тысяч запросов в секунду, когда писались логи от 30 млн пользователей. При этом 10% из них генерировала 80% всех данных. В сумме на 30 млн пользователей пришлось около 500 млн обновлений каждый день. Однако просто хранить эти данные было бы слишком просто. Поэтому система была протестирована таким образом, что работая под нагрузкой, она позволила получить список всех пользователей, которые были активны в определенный период (день/месяц), посмотреть логи любого пользователя за любой день и имелась возможность добавить любые другие вторичные индексы к пользовательским данным.

Также на основе Elliptics в компании Яндекс построена работа таких сервисов как Яндекс.Музыка, Фотки, Карты, Маркет, вертикальные поиски, поиск по людям, бэкап почты.

Простота архитектуры

В Elliptics клиенты подключаются напрямую к серверам, и это позволяет:

  • иметь простую архитектуру
  • гарантировать, что транзакции выполняются корректно
  • всегда знать, какая машина в группе отвечает за тот или иной ключ

Для пользователей сервиса хранения данных существуют следующие API, с помощью которых можно легко записывать, удалять, читать и обрабатывать данные:

  • асинхронная библиотека на C++
  • биндинг на Python
  • HTTP-фронтенды на основе FastCGI и TheVoid

Минусы и ограничения

  • Eventual consistency. Так как Elliptics полностью распределен, то при различных неполадках сервер может отдать версию файла старее, чем актуальная. В некоторых случаях это может быть неприменимо, тогда за счет проседания времени ответа можно использовать более надежные способы запроса данных.
  • Из-за того, что данные клиентом пишутся параллельно на несколько серверов, сеть между клиентом и серверами может стать узким местом.
  • API может быть недостаточно удобен для высокоуровневых запросов. На данный момент мы не предоставляем удобных SQL-like запросов к данным.
  • Так же в Elliptics нет высокоуровневой поддержки транзакций, поэтому невозможно гарантировать, что группа команд либо выполнится вся, либо не выполнится вообще.

Использование Elliptics

Рассмотрим пример использования Elliptics на собственной отказоустойчивой YourMusic. YourMusic — это ваше личное хранилище музыки с поддержкой региональности, реплицирования данных, минимальной нагрузкой на диск и сеть, а также простым HTTP API , который можно использовать в любом вашем приложении или на личном сайте.

Разворачиваем Elliptics на Ubuntu[Источник 4]

Сначала вы должны установить Reverbrain Repository. Добавьте файл /etc/apt/sources.list.d/reverbrain.list с описанием репозитория:

deb http://repo.reverbrain.com/precise/ current/amd64/
deb http://repo.reverbrain.com/precise/ current/all/

Также вы должны добавить ключ значение репозитория:

curl http://repo.reverbrain.com/REVERBRAIN.GPG | apt-key add -

Далее мы собираем пакеты в репозитории под Ubuntu 12.04:

apt-get update
sudo apt-get install elliptics elliptics-client rift

Отлично, пакеты поставлены. Теперь пришла пора запускать свой кластер. В рамках данного туториала мы будем запускать все сервера на одной машине. Для начала ознакомимся с примером конфигурационного файла node-1.json:

        "loggers": {
                "type": "/srv/elliptics/1/log.txt",
                "level": 4
        },
        "options": {
                "join": true,
                "flags": 4,
                "remote": [
                        "autodiscovery:224.0.0.5:1025:2"
                ],
                "address": [
                        "localhost:1025:2"
                ],
                "wait_timeout": 60,
                "check_timeout": 60,
                "io_thread_num": 16,
                "nonblocking_io_thread_num": 16,
                "net_thread_num": 4,
                "daemon": true,
                "auth_cookie": "<-Don't forget to change it->",
                "cache": {
                        "size": 1073741824
                },
                "indexes_shard_count": 16,
                "monitor_port": 20000
        },
        "backends": 
               { {
                "type": "blob",
                "group": 1,
                "history": "/srv/elliptics/1/history/",
                "data": "/srv/elliptics/1/blob/data",
                "sync": "-1",
                "blob_flags": "129",
                "blob_size": "10G",
                "records_in_blob": "1000000"
                }}

Чтобы запустить Elliptics с этим конфигурационным файлом, надо создать следующие каталоги:

mkdir /srv/elliptics/1/ 
Здесь в файл log.txt будут писаться логи с уровнем Debug
mkdir /srv/elliptics/1/blob/ 
Здесь будут лежать "блобы" с данными
mkdir /srv/elliptics/1/history/ 
Здесь будет лежать файл с началами интервалов из DHT-кольца

Далее для запуска необходимо прописать:

dnet_ioserv -c node-1.json

Но мы ведь хотим построить отказоустойчивый кластер. Для этого надо поднять еще хотя бы одну машину во второй группе. В её конфиге нужно будет указать другой адрес, а также другие remote-адреса. В итоге, пока используются конфигурационные файлы node-1.json, node-2.json для хранения данных в 2 копиях. Создадим каталоги, нужные для первых двух нод, и запустим каждую из них:

for id in `seq 1 2`; do mkdir /srv/elliptics/$id/{history,blob} -p; done
for id in `seq 1 2`; do dnet_ioserv -c node-$id.json; done

Python API

А теперь, когда сервера у нас запущены,приступим к Python API.

Подключение к серверам

Сперва нужно создать клиентскую ноду для подключения к серверам Elliptics.

import elliptics
log = elliptics.Logger(“/dev/stderr”, elliptics.log_level.debug)
node = elliptics.Node(log)

node.add_remote(“localhost”, 1025)
node.add_remote(“localhost”, 1026)

sess = elliptics.Session(node)
sess.group = [ 1, 2, 3 ]

Записываем данные в Elliptics

Запишем в Elliptics немного данных:

async_result = sess.write_data(“test_key”, “some_data”, offset)

Обработка ответа от сервера

Асинхронный запрос:

def handler(results, error):
    if error.code != 0:
       return
    for entry in results:
       pass
async_result.connect(handler)

Чтение данных

async_result = sess.read_data(“test_key”, offset, size)

Удаление данных

async_result = sess.remove_data(“test_key”)

Примечания

Источники

  1. Elliptics // Википедия. [2017—2017]. Дата обновления: 23.09.2017. URL: https://en.wikipedia.org/wiki/Elliptics (дата обращения: 10.11.2017).
  2. Elliptics // Yandex. [2017—2017]. Дата обновления: 18.09.2017. URL: https://tech.yandex.com/elliptics/ (дата обращения: 10.11.2017).
  3. Как устроены облака Яндекса: Elliptics // ХабрХабр. [2017—2017]. Дата обновления: 30.09.2013. URL: https://habrahabr.ru/company/yandex/blog/200080/ (дата обращения: 10.11.2017).
  4. Elliptics tutorial// Reverbrain_wiki. [2012—2017]. Дата обновления: 10.09.2014. URL: http://doc.reverbrain.com/elliptics:server-tutorial (дата обращения: 10.11.2017).