Статьи

Интеграция MapR с Ruby: Начало работы с потоками MapR-DB и MapR на JRuby

MapR Streams и MapR-DB являются очень интересными разработками в Платформе конвергентных данных MapR. В этой записи блога я собираюсь показать вам, как получить код Ruby для естественного взаимодействия с потоками MapR-DB и MapR. Я разработчик Ruby, и существующие клиенты / библиотеки Ruby для HBase и Kafka просто не работали должным образом с эквивалентами MapR. Поэтому я решил найти способ заставить код на Ruby общаться с обеими этими технологиями MapR. Я решил изучить портирование примеров Java на JRuby, и это работало довольно хорошо. В этот пост включено несколько примеров Java, поэтому я также расскажу, как перенести код Java на JRuby (полностью поточная реализация Ruby на Java). Давайте начнем!

Исходный код этого поста можно найти по адресу https://github.com/rvictory/MapR-JRuby-Demos. На него оказывают сильное влияние https://github.com/mapr-demos/maprdb-ojai-101 и https: //github.com/mapr-demos/mapr-streams-sample-programs

Основы — загрузка клиентских библиотек MapR

JRuby старается придерживаться правил Ruby, позволяя вам взаимодействовать с Java-кодом и библиотеками. Однако для того, чтобы он «нашел» Java-классы, вам нужно загрузить их JAR-файлы так же, как вы бы сделали Gem или другой исходный файл Ruby. Для того, чтобы загрузить все, я использовал очень жесткий подход (насколько я могу судить, это не влияет на производительность). По сути, я подготовил свои сценарии, чтобы иметь возможность ссылаться на любой MapR JAR со следующими строками вверху каждого сценария Ruby:

включить Java

Dir["/opt/mapr/lib/\*.jar"].each { |jar| require jar }

Очевидно, это будет работать, только если MapR установлен в / opt / mapr; однако, это достаточно легко изменить, если вы не используете эту конфигурацию по умолчанию.

Использование MapR-DB с JRuby

Теперь, когда мы сослались на соответствующие JAR-файлы, нужно перенести код с Java на Ruby. По большей части это простая задача — просто возьмите конструкции, используемые в Java, и сделайте их «Ruby». Например, вот следующий код из демонстрации MapR-DB:

1
2
3
4
5
Table table;
if (!MapRDB.tableExists(tableName)) {
    table = MapRDB.createTable(tableName); // Create the table if not already present } else {
    table = MapRDB.getTable(tableName); // get the table
}

становится:

1
2
3
4
5
6
table = nil
if !MapRDB.tableExists(tableName)
    table = MapRDB.createTable(tableName)
else
    table = MapRDB.getTable(tableName)
end

Следует отметить, что случаи, когда вам нужно вызывать конструктор, обрабатываются так, как вы, вероятно, ожидаете, то есть этот код Java:

Test test = new Test("arguments");

Получается следующий код Ruby:

test = Test.new("arguments")

Кроме того, Java Generics не является «вещью» в JRuby (поскольку типы в любом случае выводятся), поэтому в большинстве случаев (по крайней мере, в тех случаях, которые я обнаружил) их можно просто игнорировать. Могут быть сценарии, когда компилятор / интерпретатор JRuby не может определить тип — я еще не сталкивался с этим, но я уверен, что есть способ решить эту проблему.

Что касается работы с MapR-DB, мы можем просто использовать тот же API, который вы использовали бы в Java:

( http://maprdocs.mapr.com/apidocs/maprdb_json/51/com/mapr/db/MapRDB.html ). Чтобы создать новый документ, мы можем сделать это одним из двух способов:

1
2
3
4
5
6
document = MapRDB.newDocument()
      .set("_id", "jdoe")
      .set("first_name", "John")
      .set("last_name", "Doe")
      .set("dob", ODate.parse("1970-06-23"))
table.insertOrReplace(document)

Или мы можем использовать формат JSON вместо API:

1
2
document = MapRDB.newDocument('{"_id" : "test", "first_name" : "John", "last_name" : "Doe", "dob" : "1970-06-23"}')
table.insertOrReplace(document)

Это в значительной степени так для основ MapR-DB с использованием JRuby. Посмотрите файл с исходным кодом «maprdb.rb» для полного примера. Стоит упомянуть, что по умолчанию созданные таблицы хранятся в каталоге пользователя в MapR-FS для текущего пользователя. Если вы работаете как пользователь, отличный от mapr, убедитесь, что вы создали каталог /users/<username/ в MapR-FS для своего пользователя и что у него есть права на чтение и запись в этот каталог.

Использование потоков MapR с JRuby

Теперь, когда мы заложили основу для переноса кода Java на Ruby, код Streams так же прост, как и код MapR-DB. Единственное отличие состоит в том, что исходный пример Java Streams использует файлы «Свойства» для хранения конфигурации, поэтому мы просто помещаем эти файлы в тот же каталог, что и скрипт Ruby, и они будут получены кодом.

Помимо небольшого изменения (с использованием файлов props), код является довольно простым портом из примера Java. Проверьте фактический код на моей странице Github, чтобы увидеть производителя и потребителя. Убедитесь, что вы создали поток (и имеете соответствующие разрешения для пользователя, выполняющего код) с помощью следующей команды MapR:

maprcli stream create -path /sample-stream

И создайте тему, используя следующую команду:

maprcli stream topic create -path /sample-stream -topic fast-messages

Чтобы разрешить всем пользователям взаимодействовать с потоком, используйте следующую команду:

maprcli stream edit -path /sample-stream -produceperm p -consumeperm p -topicperm p

И это все — пример кода должен работать просто отлично. Производитель создает 100 сообщений и записывает их в поток, а потребитель выбирает любые сообщения, которые он видит. Остальные операции Stream совпадают с документацией по API Java. Я рекомендую перемещать сообщения JSON в Stream, это позволяет любому потребителю / языку работать с данными.

Что дальше

Теперь вы знаете, как заставить Ruby взаимодействовать с MapR-DB и MapR Streams. Я очень взволнован перспективами использования Платформы конвергентных данных в будущих проектах; возможности действительно бесконечны. В дальнейшем я намереваюсь обернуть API-интерфейсы Streams и MapR-DB в более «рубиновый» пакет и предоставить его в качестве драгоценного камня для общего потребления. Я также намереваюсь написать API запросов MapR-DB, который имитирует синтаксис запросов, используемый MongoDB (запросы на основе JSON, а не на основе API). Источник Gem будет опубликован на моем GitHub, когда он будет завершен. Не стесняйтесь обращаться ко мне, если у вас есть какие-либо вопросы, вопросы или жалобы.

Спасибо за чтение!