Share
Embed
Transcript
33 slides
-
Обработка данных поверх множества серверов: • удобная модель автоматического распределения
данных и вычислений по серверам • отказоустойчивость • минимизация перемещения данных по сети Big Data -
• Hadoop Distributed File System (HDFS) — распределяет данные •
Hadoop MapReduce — распределяет вычисления Hadoop -
• распределенная файловая система • хранит файлы блоками по 128МБ
• распределяет отдельные блоки по разным серверам • реплицирует каждый блок 3 раза HDFS -
Word Count: mapper.rb STDIN.each do |line| line.split.each do |word| puts
[word, 1].join("\t") end end -
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" end end -
Отчет: 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 -
Плюсы • Простая масштабируемая модель вычислений • Эффективность за счет
больших батчей и локальности данных • Отказоустойчивый Минусы • Все пишется на диск • Слишком низкоуровневый • Невозможность итеративных алгоритмов • Невозможность потоковой обработки -
Потоковый 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] } end end -
Потоковый 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] } end end 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