Riak
![]() | |
Создатели: | Andy Gross[1] |
---|---|
Разработчики: | Basho Technologies, Inc. |
Выпущена: | 30 September 2011 года[2] |
Постоянный выпуск: | 2.2.3[3] |
Состояние разработки: | Active |
Написана на: | Erlang |
Операционная система: | Linux, BSD, Mac OS X, Solaris |
Платформа: | IA-32, x86-64 |
Тип ПО: | NoSQL-база данных, облачное хранилище данных |
Лицензия: | Apache 2.0 |
Веб-сайт |
basho |
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
Отказоустойчивость
Riak имеет бесступенчатую многоузловую архитектуру (см. рисунок 1), которая обеспечивает быстрое чтение и запись даже в случае сбоев сети или оборудования (благодаря репликации узлов).
Riak безопасно распределяет данные по кластеру серверов, называемых узлами. Группа узлов формирует кластер Riak. Каждый узел в кластере может обслуживать запросы чтения и записи.
Чтобы обеспечить доступность данных, Riak по умолчанию копирует данные на три узла кластера. Это гарантирует, что по крайней мере одна копия данных будет доступна. Нет выделенного мастера, а значит, и единой точки отказа. Каждый узел может обслуживать любой входящий запрос.
Riak распределяет данные поровну по узлам кластера и позволяет добавлять узлы с минимальным перераспределением данных и без простоя. Если один узел выходит из строя, то другой узел в кластере может реагировать на запросы чтения и записи.
Высокая масштабируемость
Благодаря автоматическому распределению данных по узлам кластера Riak дает почти линейное увеличение производительности по мере добавления новых узлов[Источник 2].
Riak значительно упрощает масштабирование приложений, устраняя ручную настройку, и уменьшает количество узких мест в системе, реплицируя данные.
Простота в эксплуатации
Riak использует архитектуру Ring с автоматической репликацией и возможностью направленной отправки (hinted handoff), чтобы обеспечить отказоустойчивость приложений и эффективность работы.
Каждый узел в Riak Ring управляет одним или несколькими виртуальными узлами, называемыми vnodes.
Данные распределяются равномерно по узлам. При добавлении/удалении узлов данные автоматически асинхронно балансируются.
В случае сбоя одного узла соседний узел будет выполнять необходимые операции. Когда вышедший из строя узел включается в работу, то соседний узел отсылает ему все изменения данных, которые произошли во время сбоя. Это обеспечивает доступность записей и их автоматическое обновление.
Мультикластерная репликация
Обобщенная схема мультикластерной репликации показана на рисунке 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).
Особенности 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).
Встроенные типы данных
Встроенные типы данных 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 поддерживается на следующих платформах:
- Amazon Web Services;
- Microsoft Azure;
- Debian & Ubuntu;
- Mac OS X;
- Red Hat Enterprise Linux & CentOS;
- SUSE.
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 узла.
Источники
- ↑ Riak Documentation // riak. URL: http://docs.basho.com/ (дата обращения: 13.11.2018)
- ↑ Massive Scalability // riak. URL: http://basho.com/products/riak-kv/massive-scalability/ (дата обращения: 22.11.2018).
- ↑ Redis Database Integration // riak. URL: http://basho.com/products/riak-kv/redis-integration/ (дата обращения: 23.12.2018).
Примечания
- ↑ Sheehy, Justin. Riak 1.0 Release Party.
- ↑ По данным официального блога Basho.
- ↑ Последняя версия Riak KV на момент написания данной статьи в соответствии с документацией Riak.