Введение в Riak. : Часть 2. Интеграция Riak как мощного кэш-сервера для Web-приложений

Использование Riak в качестве кэш-сервера для уменьшения нагрузки на серверы приложений и баз данных

Это вторая часть серии из двух статей о Riak, хорошо масштабируемой распределенной системе хранения данных, написанной на языке Erlang и основанной на Dynamo, хранилище пар ключ-значение высокой готовности компании Amazon. Для Web-cайтов с большими нагрузками масштабируемое решение кэширования может снизить нагрузку на серверы приложений и баз данных. Это, в частности, относится к данным, которые читаются часто, но обновляются только изредка. Исследуйте подробный пример сайта интерактивных ставок и способы использования Riak для реализации кэширования. Вы также научитесь интегрировать Riak с существующим Web-сайтом и узнаете о других возможностях Riak, таких как поиск, а также о том, как использовать его для обслуживания пользовательских запросов. Если вы захотите выполнить предложенные примеры, вам понадобится рабочий кластер Riak. Действия по локальной настройке кластера приведены в первой части данной серии статей (EN).

Саймон Бакл, независимый консультант, независимый специалист

Саймон Бакл (Simon Buckle) – фотографияСаймон Бакл (Simon Buckle) - независимый консультант. В сферу его интересов входят распределенные системы, алгоритмы и параллелизм. Получил степень магистра по вычислительной технике в Имперском колледже в Лондоне. Адрес его Web-сайта – simonbuckle.com.



25.09.2012

Введение

Характер доступа к некоторым типам данных делает их идеальным объектом для кэширования. Например, сайты интерактивных ставок имеют интересные характеристики нагрузки: ставки и наборы событий запрашиваются часто, но обновляются относительно редко.

Другие статьи данной серии

Просмотрите другие статьи серии Введение в Riak (EN).

В таких ситуациях для работы с большими нагрузками нужна хорошо масштабируемая система со следующими характеристиками:

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

Система Riak – это хороший выбор для такого решения.

Riak является не единственным кандидатом для реализации такого решения; существует много других кэш-решений. Одним из популярных решений является memcached; однако memcached, в отличие от Riak, не обеспечивает репликацию данных, а это значит, что в случае останова сервера, хранящего конкретный элемент, этот элемент становится недоступным. Redis, еще одно популярное хранилище пар ключ/значение, которое можно использовать в качестве кэш-памяти, поддерживает репликацию посредством конфигурации главный-подчиненный; Riak не имеет концепции главного (master) узла, что делает систему отказоустойчивой.


Интеграция в Web-сайт

Любое решение должно легко интегрироваться в существующий Web-сайт. Это очень важно, поскольку иногда перенести все существующие данные в Riak невозможно (или даже нежелательно). Как упоминалось ранее, некоторые типы данных идеально подходят для кэширования, в частности, данные хранилища ключ-значение с доступом по первичному ключу. Такой тип данных больше всего подходит для переноса в Riak.

Как говорилось в первой части (EN) данной серии статей, есть несколько библиотек на PHP, Ruby и Java™, которые предоставляют программный интерфейс, сильно упрощающий интеграцию с Riak. В данном примере я продемонстрирую использование PHP-библиотеки и покажу, как интегрировать Riak с существующим Web-сайтом.

На рисунке 1 показана конфигурация системы для данного примера. Я опустил некоторые детали, такие как распределение нагрузки, сетевой экран и т.д. В данном случае серверы сами по себе являются простыми интерфейсными системами с установленным на них стеком программ LAMP.

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

Рисунок 1. Простая интеграция в Web-сайт
Рисунок 1. Простая интеграция в Web-сайт

Ниже приведен базовый пример интеграции Riak в существующий Web-сайт. Мы создадим простую форму, которая после отправки будет использовать PHP-клиент для сохранения объекта в Riak, основываясь на введенных в форму значениях.

На рисунке 2 приведен пример простой формы, которую администратор может использовать для создания страницы ввода ставок в системе. Создайте эту форму на HTML и реализуйте в ней запрос POST к PHP-сценарию, приведенному в листинге 1; в качестве отправной точки можно использовать аналогичную форму из исходного кода, сопровождающего данную статью. Поле key, заполненное в форме, будет использоваться в качестве ключа для сохранения объекта в области памяти.

Рисунок 2. Пример формы для создания ставки
Рисунок 2. Пример формы для создания ставки

В листинге 1 приведен пример PHP-кода, демонстрирующего использование библиотеки PHP-клиента для интеграции с Riak. Замените путь к библиотеке PHP-клиента, указанный в require_once, на ваш путь к каталогу установки библиотеки. В данном случае я поместил ее в тот же каталог, в котором находится PHP-сценарий. По умолчанию все клиентские библиотеки для доступа к Riak используют порт 8098.

Листинг 1. Пример PHP-кода для интеграции с Riak
<?php

require_once('./riak.php');

# Здесь можно реализовать проверку того, имеет ли текущий пользователь
# соответствующие полномочия. Делегирована в приложение.

$client = new RiakClient('192.168.1.1', 8098);
$bucket = $client->bucket('odds');

$bet = $bucket->newObject($_POST['key']);        
$data = array(
    'odds' => $_POST['odds'],
    'description' => $_POST['description']
);
$bet->setData($data);

# Сохранить объект в Riak
$bet->store();

echo "Thanks!";
?>

Сохраните код в PHP-файл (дайте ему любое имя) и загрузите его и форму где-нибудь на вашем Web-сайте (например, на http://www.yoursite.com/riak-test.php). Заполните пример формы и отправьте ее. Для проверки работоспособности формы попробуйте извлечь элемент непосредственно из Riak, используя введенный при создании элемента ключ (см. листинг 2).

Листинг 2. Извлечение элемента из Riak
$ curl -i http://localhost:8098/riak/odds/<key>
...
{ "odds":"", "description":"" }

В этом примере интеграции использовался PHP-клиент, но подход аналогичен и для других языков и прикладных сред (например, Java или Ruby on Rails).


Непосредственная обработка запросов

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

Загрузите исходный код к данной статье. Убедитесь, что Riak запущена, и выполните сценарий load.sh. Этот сценарий скопирует все HTML- и JavaScript-файлы в сегмент под именем demo. В данном примере используется JavaScript-клиент.

Для просмотра демонстрации укажите в браузере URL-адрес http://localhost:8098/riak/demo/demo.html.

После ввода в форму значений для создания ставки и отправки формы JSON-объект сохраняется в Riak. Свойства объекта будут соответствовать полям формы. Вы будете направлены на страницу, отображающую значение только что созданного объекта.

В листинг 3 показан исходный код, создающий объект из введенных вами значений. Значения key, odds и description – это значения, введенные в форму.

Листинг 3. Пример использования клиентской JavaScript-библиотеки в Riak
client.bucket("odds", function(bucket) {
    var key = $('#key').val();
    bucket.get_or_new(key, function(status, object) {
        object.contentType = 'application/json';
        object.body = { 'odds': $('#odds').val(), 'description': $('#desc').val() };
        object.store(function(status, object, request) {
            if (status == 'ok') {
                window.location = "http://localhost:8098/riak/odds/"+key;
            } else {
            alert("Failed to create object.");
        }
        }); 
    });
});

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

Несмотря на простоту, этот пример дает представление о том, как Riak напрямую обрабатывает запросы страниц. Для извлечения необходимых данных можно было бы, например, включить хранящиеся в Riak данные непосредственно в существующие Web-страницы либо путем использования методики JSONP или CORS (cross-origin resource sharing – междоменное использование ресурсов), в которой из-за политики same domain (одинаковый домен) AJAX-запросы ограничены тем же сервером, на котором размещена страница, либо направляя запросы в Riak через прокси, т.е. через ваши серверы.


Использование Riak для кэширования

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

Одной из таких возможностей является его подключаемая серверная система хранения (storage back-end); она определяет, как хранятся данные. Есть несколько вариантов, но я не собираюсь рассматривать их все (ссылки на дополнительную информацию приведены в разделе Ресурсы). Системой хранения по умолчанию является Bitcask – Erlang-приложение, предоставляющее программный интерфейс для сохранения и извлечения данных, поддерживаемых хэш-таблицей, обеспечивающей быстрый доступ к ним; данные являются персистентными.

Возможно, для данной статьи больше подходит система Memory. Для хранения всех своих данных Memory использует таблицу в оперативной памяти (по сути, используются Erlang-таблицы ets) и, если разрешено, заставляет Riak вести себя как LRU-кэш с установленным временем истечения срока хранения. Преимуществом хранилища в оперативной памяти является его значительно более быстрая работа по сравнению с использованием данных, извлекаемых с диска. Если данные хранятся в памяти (не персистентны) и узел завершает работу, данные, хранящиеся на нем, теряются. Но поскольку мы используем Riak как кэш, это не проблема – приложение всегда сможет извлечь данные из базы данных, как это было бы при использовании Riak в качестве основного хранилища данных. Riak реплицирует данные на несколько узлов кластера, поэтому они все равно будут доступны.

Система Memory входит в комплект поставки Riak. Для использования Memory откройте файл app.config для каждого узла в кластере, найдите свойство storage_backend и измените его с riak_kv_bitcask_backend на riak_kv_memory_backend. Теперь добавьте в конец файла код, приведенный в листинге 4.

Листинг 4. Использование серверной системы Memory
{memory_backend, [
    {max_memory, 4096},	%% 4GB of memory
    {ttl, 86400}        %% Time in seconds
]}

Измените значения на подходящие для вашей конфигурации. Перезапустите узлы в кластере.

Существует возможность запустить в кластере Riak несколько систем хранения. Это полезно при использовании разных систем хранения для разных сегментов. Например, можно настроить сегмент (назовем его cache) на использование серверной системы Memory, а для остальных сегментов, которые должны сохранять данные, использовать, скажем, Bitcask.

Теперь, когда Riak настроена на работу в качестве кэша, нам необходим какой-то способ обращения к данным в кластере либо для обновления, либо, например, для проверки по какой-либо причине (до истечения срока их действия).


Что-то ищете?

Как вы уже видели, для извлечения хранящихся в Riak данных с использованием HTTP-интерфейса создается URL-адрес, состоящий из названия сегмента и ключа извлекаемого объекта, а затем выполняется запрос HTTP GET по этому URL. Это абсолютно правильно, если известен ключ! Но иногда нам либо не известен ключ объекта, который мы хотим извлечь, либо необходимо извлечь набор объектов, соответствующих определенному критерию. Следовательно, нам нужен метод поиска объектов, хранящихся в кластере.

Вы уже видели, как запрашивать данные путем выполнения задания Map/Reduce для документов, хранящихся в кластере. Время выполнения запроса будет в общем случае прямо пропорционально количеству документов в кластере; чем больше документов, тем дольше выполняется запрос этих документов. Это не проблема для запросов, нечувствительных ко времени. Под ними я подразумеваю запросы, на которые пользователь не ожидает получить немедленный ответ. Для задач поиска нереально каждый раз (динамически) просматривать все документы; получение результатов может продолжаться минуты или часы!

К счастью Riak уже имеет решение этой проблемы – Riak Search. Система Riak Search предоставляет функциональность, необходимую для поиска документов, хранящихся по всему кластеру. Тема поиска слишком обширна для подробного рассмотрения в данной статье, но общий принцип таков: документы морфологически размечаются (Riak Search использует стандартные анализаторы Lucene) и добавляются в инвертированный индекс. Затем к этому индексу выполняется запрос, основанный на поисковых терминах, введенных пользователем. Новые документы тоже индексируются и добавляются в индекс.

По умолчанию функциональность Riak Search отключена. Перед использованием ее необходимо включить. Для каждого узла в кластере откройте файл rel/riakN/etc/app.config, найдите свойство riak_search и установите его в значение true. Перезапустите узлы в кластере.

Riak позволяет указывать имя функции, выполняемой перед или после добавления документа в сегмент, путем использования перехватчиков pre- и post-commit. Например, перед добавлением в кластер документа можно проверить, содержит ли он необходимые поля. Документ для поиска должен быть проиндексирован. Для этого установите перехватчик pre-commit для сегмента, в котором хранятся документы. Выполните команду $ rel/riak/bin/search-cmd install <bucket name>.

Эта команда установит перехватчик pre-commit riak_search_kv_hook для сегмента. Теперь при добавлении в этот сегмент документ будет анализироваться и добавляться в индекс. Анализатором по умолчанию является анализатор пробелов (whitespace); он обрабатывает символы в маркеры на основе пробелов, которые затем индексирует. Существует несколько различных анализаторов, кроме того вы можете определить ваш собственный.

Во многих случаях Riak Search знает, как индексировать ваши данные. Например, если в сегмент добавляется JSON-объект, значение каждого свойства будет индексироваться и к нему можно будет обратиться по имени свойства в строке запроса. Пример поиска приведен в листинге 5. Для более сложных структур можно определить свою собственную схему, указывающую Riak Search, как индексировать данные.

Необходимо уметь обращаться к проиндексированным документам. Одним из способов является выполнение запроса из оболочки Erlang. Например, запрос, приведенный в листинге 5, ищет в сегменте odds все ставки на скачки; для этого выполняется запрос свойства описания сохраненного элемента.

Листинг 5. Поиск в сегменте odds ставок на скачки
$ rel/riak/bin/riak attach

search:search(<<"odds">>, <<"description:horse">>).

Кроме того, Riak Search предоставляет Solr-совместимый HTTP-интерфейс для поиска документов. Apache Solr – это популярный корпоративный поисковый сервер с REST-подобным программным интерфейсом. Совместимость интерфейса с Solr позволяет отключить Solr (если он используется) и использовать возможности Riak Search для выполнения операций поиска. Например, для поиска ставок на конкретное событие с использованием интерфейса Solr можно выполнить команду $ curl "http:localhost:8098/solr/odds/select?start=0&q=description:horse".

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


Заключение

Другие статьи данной серии

Просмотрите другие статьи серии Введение в Riak (EN).

Способность Riak масштабировать и надежно реплицировать данные, а также другие возможности (например, поиск), делают эту систему идеальным выбором для реализации кэширования сайтов с большой нагрузкой. Она легко интегрируется в существующий сайт. Благодаря возможности непосредственно обрабатывать запросы Riak можно использовать для уменьшения нагрузки на серверы приложений и баз данных.


Загрузка

ОписаниеИмяРазмер
Исходный код к статьеriakpt2sourcecode.zip85 КБ

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=837384
ArticleTitle=Введение в Riak. : Часть 2. Интеграция Riak как мощного кэш-сервера для Web-приложений
publish-date=09252012