Riak

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 21:34, 2 марта 2019.
Riak
Riak.png
Создатели: Andy Gross[1]
Разработчики: Basho Technologies, Inc.
Выпущена: 30 September 2011 года; 11 years ago (2011-09-30)[2]
Постоянный выпуск: 2.2.3[3]
Состояние разработки: Active
Написана на: Erlang
Операционная система: Linux, BSD, Mac OS X, Solaris
Платформа: IA-32, x86-64
Тип ПО: NoSQL-база данных, облачное хранилище данных
Лицензия: Apache 2.0
Веб-сайт basho.com/products

Riak – это распределённая децентрализованная система хранения данных, созданная компанией Basho Technologies. Riak является масштабируемым и отказоустойчивым NoSQL-решением для хранения информации.

Riak представлен тремя продуктами: Riak KV, Riak TS и Riak CS. Riak KV – это распределенная NoSQL-база данных, которая проста в использовании и обладает высокой доступностью[Источник 1]. В основе Riak TS лежит Riak KV, оптимизированный для IoT и временных рядов. Riak CS – это распределенное отказоустойчивое хранилище данных, совместимое c Amazon S3.

Riak интегрируется с Riak S2 для оптимизации хранения больших объектов (видео, картинок и др.), а также с такими продуктами, как Apache Spark, Redis, Apache Solr и Apache Mesos.

Особенности Riak

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

Рисунок 1 – Архитектура Riak

Riak имеет бесступенчатую многоузловую архитектуру (см. рисунок 1), которая обеспечивает быстрое чтение и запись даже в случае сбоев сети или оборудования (благодаря репликации узлов).

Riak безопасно распределяет данные по кластеру серверов, называемых узлами. Группа узлов формирует кластер Riak. Каждый узел в кластере может обслуживать запросы чтения и записи.

Чтобы обеспечить доступность данных, Riak по умолчанию копирует данные на три узла кластера. Это гарантирует, что по крайней мере одна копия данных будет доступна. Нет выделенного мастера, а значит, и единой точки отказа. Каждый узел может обслуживать любой входящий запрос.

Riak распределяет данные поровну по узлам кластера и позволяет добавлять узлы с минимальным перераспределением данных и без простоя. Если один узел выходит из строя, то другой узел в кластере может реагировать на запросы чтения и записи.

Высокая масштабируемость

Благодаря автоматическому распределению данных по узлам кластера Riak дает почти линейное увеличение производительности по мере добавления новых узлов[Источник 2].

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

Простота в эксплуатации

Riak использует архитектуру Ring с автоматической репликацией и возможностью направленной отправки (hinted handoff), чтобы обеспечить отказоустойчивость приложений и эффективность работы.

Каждый узел в Riak Ring управляет одним или несколькими виртуальными узлами, называемыми vnodes.

Данные распределяются равномерно по узлам. При добавлении/удалении узлов данные автоматически асинхронно балансируются.

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

Мультикластерная репликация

Рисунок 2 – Мультикластерная репликация

Обобщенная схема мультикластерной репликации показана на рисунке 2. Один кластер действует как основной. Он реплицирует данные в один или несколько резервных кластеров, которые часто расположены в других регионах или странах. Если основной кластер выходит из строя, то резервный кластер может автоматически переключиться в режим основного.

В мультикластерной репликации существуют два основных режима работы:

  • полная синхронизация – синхронизация между основным и резервным кластерами осуществляется периодически;
  • режим реального времени – синхронизация происходит постоянно при изменении данных на основном кластере.

Настраиваемый срок хранения объектов

Riak позволяет указать TTL (время жизни) для всех объектов в кластере. На основе этой настройки Riak автоматически удаляет старые данные на уровне кластера, что позволяет не делать этого вручную. Данные, у которых истек срок хранения, не будут возвращаться в запросах. Riak поддерживает возможность указания режима TTL для LevelDB и Bitcask.

Чтобы установить TTL в LevelDB, необходимо использовать настройку retention_time. В следующем примере срок действия объектов истекает через 8 дней и 9 часов:

leveldb.expiration = on
leveldb.expiration.retention_time = 8d9h

Чтобы установить TTL в Bitcask, необходимо использовать настройку expiry. В следующем примере срок действия объектов истекает через 1 день:

bitcask.expiry = 1d

Интеграция с Apache Spark

Riak Spark Connector предоставляет возможность передать данные из Riak в Apache Spark для расширенного анализа, а затем сохранить результаты в Riak для дальнейшей обработки. Он поддерживает пакетный и потоковый анализ, что позволяет оперативно анализировать данные в режиме реального времени.

Spark Connector позволяет считывать данные из Spark, а также передавать их в виде распределенных наборов данных (RDD) или DataFrames.

В приведенном ниже примере показано чтение всех данных с использованием одной команды на Scala:

val data = sc.riakBucket[String](new Namespace("bucket-full-of-data"))
.queryAll()

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

val rdd = sc.riakBucket(new Namespace("FOO"))
.queryBucketKeys("mister X", "miss Y", "dog Z")

В приведенном ниже примере показан диапазон значений (1 - 5000), определяемый числовым вторичным индексом, где пространство ключей называется «Bar», а индекс – «myIndex»:

val rdd = sc.riakBucket(new Namespace("BAR"))
.query2iRange("myIndex", 1L, 5000L)

Интеграция с Apache Mesos

Riak Mesos Framework предназначен для эффективного развертывания и управления кластерами Riak с помощью Apache Mesos. Он предназначен для оптимизации использования ресурсов и масштабирования кластеров Riak.

Riak Mesos Framework позволяет создавать кластер, добавлять в него узлы с помощью CLI и просматривать состояние и конфигурацию узлов через веб-интерфейс Riak Explorer.

Riak Mesos Framework обычно развертывается как приложение Marathon с помощью инструмента CLI (riak-mesos или dcos riak). После развертывания он может принимать команды для создания узлов Riak в качестве дополнительных задач для других агентов Mesos (см. рисунок 3). Если запрошенных узлов больше, чем доступных агентов, то планировщик начнет добавлять новые узлы Riak к существующим агентам. Для автоматизации операций доступно HTTP API.

Клиентские приложения, использующие кластер на базе Mesos, должны регулярно обновлять текущее состояние кластера. Чтобы не реализовывать это самостоятельно, можно использовать прокси-приложение Riak Mesos Director, которое автоматически поддерживает состояние кластера актуальным (см. рисунок 4).

Рисунок 3 – Архитектура Riak Mesos Framework

Рисунок 4 – Использование Riak Mesos Director

Особенности Riak KV

Интеллектуальная репликация

Рисунок 5 – Интеллектуальная репликация Riak KV

Riak KV является кластерной системой, содержащей несколько узлов (серверы или облачные экземпляры). Интеллектуальная репликация является основной особенностью архитектуры Riak KV и позволяет сохранять данные на нескольких узлах одновременно с одним запросом на запись. Это гарантирует, что в случае отказа одного из узлов операции чтения и записи все равно будут доступны. Riak KV позволяет установить параметр N, известный также как n_val, который определяет количество узлов для репликации данных.

Например, значение n_val = 3 означает, что каждый объект реплицируется 3 раза (см. рисунок 5). Когда производится запись на один узел, Riak KV автоматически реплицирует данные на два дополнительных узла.

Поддержка распределенного поиска

Riak KV обладает мощными возможностями для поиска данных, что особенно полезно при использовании Big Data. Поиск осуществляется при помощи Riak Search и вторичных индексов.

Riak Search интегрируется с Apache Solr, который позволяет осуществлять распределенный полнотекстовый поиск. Riak Search контролирует изменения данных в Riak KV и распространяет эти изменения на индексы, управляемые Apache Solr. Автоматическая синхронизация индексов обеспечивает высокую скорость запросов и полный набор результатов при подключении к одному из узлов. Riak KV обеспечивает равномерное распределение входящих данных по всем узлам кластера. Каждый узел кластера Riak KV также контролирует экземпляр Solr. На каждом узле Riak KV экземпляр Solr управляет индексами для этого узла.

Riak Search принимает стандартные запросы Solr и расширяет их до распределенных поисковых запросов. Распределенные поисковые запросы используют несколько экземпляров Solr, чтобы обеспечить полный набор результатов в репликах.

Riak Search поддерживает контроль процессов Solr для их автоматического запуска или перезапуска при обнаружении сбоев. Кроме того, Riak KV включает в себя API запросов клиента Solr для интеграции с другими приложениями.

Примеры запросов к Apache Solr:

  • Шаг 1: Указание типа атрибута.

Например, если необходимо индексировать атрибут name внутри объекта JSON как строку, то надо переименовать его в name_s. Если необходимо индексировать атрибут age как целое число для запросов диапазона, то надо переименовать его в age_i.

  • Шаг 2: Запрос к индексу.

Получить всех бегунов с пробегами 10 или более миль:

search/runners?wt=ison&a=miles_run_i: [10 TP *]

Получить всех бегунов с именем, которое начинается с Jake:

search/runners?wt=ison&a=name_s: Jake*

Получить всех бегунов с биографией, которая содержит ссылки на «Roger Bannister»:

search/runners?wt=ison&a=bio_t: "Roger Bannister"

Dotted Version Vectors (DVVs)

Для обеспечения доступности записи Riak KV позволяет нескольким клиентам писать одновременно и потенциально по одному и тому же ключу. Для автоматического разрешения конфликтов и обеспечения точности данных Riak KV использует логическое, а не хронологическое время для отслеживания истории обновлений значений и обнаружения конфликтных записей. DVV – это метаданные, привязанные к каждой реплике данных при ее создании. Они обновляются каждый раз, когда обновляется реплика данных, чтобы отслеживать версии данных.

При запросе на чтение Riak KV просматривает все реплики для этого объекта. По умолчанию возвращается самая последняя обновленная версия, определяемая путем просмотра объекта DVV. Riak KV использует DVV для сопоставления каждого значения с обновлением, которое его создало. Если несколько клиентов одновременно обновляют объект, то каждое из этих обновлений будет помечено точкой (минимальным векторным часом), которая указывает на конкретное событие, которое ее добавило. Это означает, что повторяющиеся значения всегда можно идентифицировать и удалить.

Интеграция с Redis Database

В Riak KV Cache Proxy обеспечивает предварительную настройку и агрегацию соединений, что уменьшает задержку и увеличивает адресное пространство кэш-памяти, позволяя использовать более дешевое оборудование[Источник 3]. Cache Proxy повышает производительность путем конвейерной обработки запросов Redis. Конвейерная обработка уменьшает количество обращений по сети до Redis и снижает использование ЦП на Redis.

Поскольку любой клиент Redis может запрашивать кэш, для существующих клиентов Redis не требуется никаких изменений для доступа к данным в Riak KV. Если у Redis нет данных в кэше, к нему обращаются из Riak KV. Данные автоматически синхронизируются между Redis и Riak KV (см. рисунок 6).

Рисунок 6 – Интеграция Riak KV с Redis Database

Встроенные типы данных

Встроенные типы данных Riak KV основаны на CRDT (Conflict-free Replicated Data Types) и уменьшают сложность построения распределенных приложений. Riak KV автоматически применяет правила разрешения конфликтов для этих типов данных, упрощая разработку приложений.

Все приведенные ниже примеры выполнены на языке Python.

Map

Является наиболее универсальным из типов данных Riak KV, потому что в него могут быть встроены все другие типы данных, включая сам map. Это позволяет создавать сложные пользовательские типы данных.

Пример создания map:

customers = client.bucket_type('map_bucket').bucket('customers')
map = customers.net('ahmed_info')

Flag

Представляет собой логическое значение, но вместо true\false имеет значение enable\disable. Флаги могут использоваться только в map.

Пример установки флага:

map.flags['enterprise_customer'].disable()
map.store()

Пример получения флага:

map.reload().flags['enterprise_customer'].value

Register

Представляет собой двоичный тип данных. Любое двоичное значение может являться значением регистра. Регистры могут использоваться только в map.

Пример записи значений регистра:

map.registers['first_name'].assign('Ahmed')
map.registers['phone_number'].assign('5551234567')
map.store()

Counter

Значение счетчика может быть только неотрицательным целым числом.

Пример создания счетчика:

bucket = client.bucket_type('counters').bucket('traffic_tickets')
counter = bucket.new('traffic_tickets')

Увеличение/уменьшение счетчика:

counter.increment(5)
counter.decrement(3)
counter.store()

Получение значения счетчика:

counter.dirty_value # локальное значение
counter.value       # значение на сервере
counter.reload()    # отправка изменений на сервер

Set

Хранит двоичные данные. Все значения в set уникальны.

Пример создания set:

travel = client.bucket_type('sets').bucket('travel')
cities_set = travel.new('cities')

Получение размера set :

len(cities_set)

Добавление/удаление элементов:

cities_set.add('Toronto')
cities_set.add('Montreal')
cities_set.discard('Montreal')
cities_set.store()

Получение значения:

cities_set.dirty_value # локальное значение
cities_set.value       # значение на сервере
cities_set.reload()    # отправка изменений на сервер

Особенности Riak TS

Совместное хранение данных

С помощью Riak TS данные временных рядов записываются так, что данные из определенного периода времени записываются в один и тот же раздел и поэтому совместно расположены с другими данными за этот период времени. Этот период времени называется квантом.

Благодаря совместному размещению и упорядочению данных на основе квантов, Riak TS может обслуживать запросы из настраиваемого количества разделов. Это позволяет быстрее выполнять запросы, так как сгруппированные данные могут быть прочитаны одновременно и обработаны вместе.

SQL-команды

Riak TS позволяет получать, преобразовывать, хранить и анализировать данные временных рядов с использованием команд SQL.

Запросы диапазона в Riak TS состоят из стандартных операторов SELECT, которые позволяют указывать временной диапазон (используя временную метку или диапазон дат) и подмножество столбцов, которые необходимо получить. Для фильтрации результатов необходимо использовать оператор WHERE.

Пример SELECT с использованием временных меток:

SELECT * from WEATHER
WHERE city = 'Seattle' AND
      time >= 1451606400000 AND
      time <= 1454284800000;

Также поддерживаются форматы даты и времени ISO 8601. Для группировки результатов запроса по одному или нескольким столбцам необходимо использовать оператор GROUP BY.

Пример GROUP BY с использованием формата даты и времени:

SELECT * from WEATHER
WHERE city = 'Seattle' AND
      time >= ‘2016-01-01’ AND
      time <= ‘2016-02-01 00:00:00’ 
GROUP BY city;

Пример создания таблицы и выполнения запроса с использованием Python:

table = 'WEATHER'
fmt = """CREATE TABLE {table} (
city varchar not null,
location varchar not null,
time timestamp not null,
weather varchar not null,
temperature double,
PRIMARY KEY ((myfamily, myseries, quantum(time, 2, 'h')),
myfamily, myseries,, time))
"""
query = fmt.format(table=table)
ts_obj - client.ts_query(table,query)

Агрегация данных

Функции агрегации, поддерживаемые в Riak TS:

  • COUNT() – возвращает количество записей, соответствующих указанным критериям.
  • SUM() – возвращает сумму записей, соответствующих указанным критериям.
  • AVG() & MEAN() – возвращает среднее значение записей, соответствующих указанным критериям.
  • MIN() – возвращает наименьшее значение записей, соответствующих указанным критериям.
  • MAX() – возвращает наибольшее значение записей, соответствующих указанным критериям.
  • STDDEV() – возвращает статистическое стандартное отклонение всех записей, соответствующих указанным критериям.

Пример использования функции AVG:

SELECT AVG(temperature) from WEATHER
WHERE city = 'Seattle' AND 
      time >= 1451606400000 AND
      time <= 1454284800000;

Поддерживаемые языки программирования и платформы

Riak поддерживает широкий набор API и клиентских библиотек.

Riak имеет встроенную поддержку языков программирования Java, Ruby, Python, C#, Erlang, PHP, Go.

Riak KV

Сообщество Riak KV поддерживает языки программирования C++, Clojure, Perl, Scala, R.

Riak KV поддерживается на следующих платформах:

Riak TS

Riak TS поддерживается на следующих платформах:

Установка Riak KV

curl -s https://packagecloud.io/install/repositories/basho/riak/script.deb.sh | sudo bash
sudo apt-get install riak

Для установки на Debian необходимо предварительно установить curl и sudo, если устанавливать от имени пользователя.

Пример использования Riak KV

В качестве примера настроим кластер из 3 узлов. Узлы будем разворачивать в Docker-контейнерах.

Скачаем образ Riak KV:

docker pull basho/riak-kv

Создадим файл docker-compose.yml:

tee docker-compose.yml <<-EOF
version: "2"
services:
  coordinator:
    image: basho/riak-kv
    ports:
      - "8087:8087"
      - "8098:8098"
    environment:
      - CLUSTER_NAME=riakkv
    labels:
      - "com.basho.riak.cluster.name=riakkv"
    volumes:
      - schemas:/etc/riak/schemas
  member:
    image: basho/riak-kv
    ports:
      - "8087"
      - "8098"
    labels:
      - "com.basho.riak.cluster.name=riakkv"
    links:
      - coordinator
    depends_on:
      - coordinator
    environment:
      - CLUSTER_NAME=riakkv
      - COORDINATOR_NODE=coordinator

volumes:
  schemas:
    external: false
EOF

Запустим один узел:

docker-compose up -d coordinator

После этого будет доступна панель администратора по адресу localhost:8098/admin/. Теперь запустим ещё 2 узла.

docker-compose scale member=2

В панели администратора после обновления можно увидеть, что теперь в кластере 3 узла.

Источники

  1. Riak Documentation // riak. URL: http://docs.basho.com/ (дата обращения: 13.11.2018)
  2. Massive Scalability // riak. URL: http://basho.com/products/riak-kv/massive-scalability/ (дата обращения: 22.11.2018).
  3. Redis Database Integration // riak. URL: http://basho.com/products/riak-kv/redis-integration/ (дата обращения: 23.12.2018).

Примечания

  1. Sheehy, Justin. Riak 1.0 Release Party.
  2. По данным официального блога Basho.
  3. Последняя версия Riak KV на момент написания данной статьи в соответствии с документацией Riak.