big data и ruby
TRANSCRIPT
Big Data и Ruby
Равиль Байрамгалин@brainopia
Обработка данных поверх множества серверов:
● удобная модель автоматического распределения данных и вычислений по серверам
● отказоустойчивость● минимизация перемещения данных по сети
Big Data
● Hadoop Distributed File System (HDFS) — распределяет данные
● Hadoop MapReduce — распределяет вычисления
Hadoop
● распределенная файловая система● хранит файлы блоками по 128МБ● распределяет отдельные блоки по разным серверам
● реплицирует каждый блок 3 раза
HDFS
MapReduce
Hadoop Streaming
Word Count: mapper.rb
STDIN.each do |line| line.split.each do |word| puts [word, 1].join("\t") endend
Word Count: counter.rb
STDIN .chunk {|line| line.split.first } .each do |key, lines| puts [key, lines.size].join "\t" end
Word Count
● Local: cat test | ruby mapper.rb | sort | ruby counter.rb● Hadoop:
hadoop jar hadoop-streaming-2.5.1.jar \
-input myInputDirs \
-output myOutputDir \
-mapper mapper.rb \
-reducer counter.rb \
-file mapper.rb \
-file counter.rb
Отчет
● Таблицы
Users: id, age
Messages: sender_id● Задача:
Распределение сообщений по возрасту
Отчет: job 1
sqoop import --table messages --columns sender_id ...
mapper: identity
reducer: counter.rb
Отчет: job 2
$ sqoop import --table users --columns id,age ...
mapper: STDIN.each do |line| if line.includes? ',' id, age = line.split(',') puts [id, :age, age].join "\t" else id, count = line.split puts [id, :count, count].join "\t" endend
Отчет: job 2
reducer: STDIN .lazy .map {|line| key, type, value = line.split { sender: key, type.to_sym => value } } .chunk {|hash| hash[:sender] } .each do |sender, hashes| data = hashes.inject({}, :merge) puts [data[:age], data[:count]].join "\t" end
Отчет: job 3
mapper: identity
reducer: counter.rb
Плюсы● Простая масштабируемая модель вычислений
● Эффективность за счет больших батчей и локальности данных
● Отказоустойчивый
Минусы● Все пишется на диск● Слишком низкоуровневый● Невозможность итеративных алгоритмов● Невозможность потоковой обработки
Storm
Распределенный реалтаймпроцессинг
потоков данных
Топология
Потоковый Word Count
class RandomSentence < RedStorm::DSL::Spout on_init { @sentences = [...] } on_send { @sentences.sample }end
Потоковый Word Count
class RandomSentence < RedStorm::DSL::Spout on_init { @sentences = [...] } on_send { @sentences.sample }end
class SplitSentence < RedStorm::DSL::Bolt on_receive do |sentence,| sentence.split.map {|word| [word] } endend
Потоковый Word Count
class RandomSentence < RedStorm::DSL::Spout on_init { @sentences = [...] } on_send { @sentences.sample }end
class SplitSentenceBolt < RedStorm::DSL::Bolt on_receive do |sentence,| sentence.split.map {|word| [word] } endend
class WordCountBolt < RedStorm::DSL::Bolt on_init { @counts = Hash.new 0 } on_receive {|word,| [word, @counts[word] += 1] }end
class WordCountTopology < RedStorm::DSL::Topology
spout RandomSentence do
output_fields :sentence
end
bolt SplitSentenceBolt do
output_fields :word
source RandomSentence
end
bolt WordCountBolt, parallelism: 2 do
output_fields :word, :count
source SplitSentenceBolt, fields: ['word']
end
configure :word_count do
num_workers 4
end
end
Особенности
● Подходит для реалтайм потоков данных, мониторинга, алертинга, DRPC, анализа по временным интервалам
● Не подходит для полноценного анализа по всем данным
Lambda Architecture
● Храним все входные данные в необработанном виде
● Для анализа данных создаем подходящие материализованные представления
● Как получить реалтайм представления?
Lambda архитектура по-нашему
● Не хотим писать одинаковые вычисления для разных платформ
● Не хотим поддерживать две полностью разных платформы
● Не хотим пересчитывать все данные, если код остался неизменным или незначительно изменился.
Стриминг на стероидах
● Реактивные связи для автоматического инкрементализма вычислений — возможность стримить не только новые значения, но и откатывать предыдущие
● Интеграция с хранилищем — exactly-once семантика, эффективность через колокацию данных (отсутствие распределенных локов и сетевого оверхеда ), отказоустойчивость через репликацию
● Floq — система очередей с простой коллокацией данных, батчингом, отказоустойчивостью (сайдкик не является ни одним из этих пунктов)
● Flow — реактивный стриминг для реалтайм представлений
request_flow(event_map)
.if_match(:cookie)
.if_match(:user_id)
.tap do |flow|
flow.target timeline(:user)
flow.target timeline(:logins)
end
request_flow('session_create' => :prepare_session)
.match_time timeline(:logins), after: true do |session, user|
session.merge user_id: user[:user_id]
end
Другие интересные системы
● Spark● SummingBird● Samza
@brainopia
Буду рад общению с вами!