Storm 훑어보기

6,922 views

Published on

팀 내 발표자료 Storm 훑어보기

Published in: Technology
0 Comments
26 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,922
On SlideShare
0
From Embeds
0
Number of Embeds
2,868
Actions
Shares
0
Downloads
171
Comments
0
Likes
26
Embeds 0
No embeds

No notes for slide

Storm 훑어보기

  1. 1. 스톰Storm 훑어보기 최범균 2014-01-17
  2. 2. 스톰Storm ● 데이터의 스트림을 처리하는 시스템 ○ 실시간 데이터 처리 목적 ○ 예 - 주식 실시간 트레이딩, 기계 데이터 분석 ● 주요 특징 ○ 프로세싱 병렬 실행 ■ 클러스터에서 연산 수행 ○ 안정성 ■ 데이터의 처리를 보장 ○ 내고장성(fault-tolerant) ■ 프로세스 재시작으로 작업 재할당
  3. 3. 토폴로지/클러스터 ● 토폴로지(topology) ○ ○ ○ ○ 데이터 처리 프로그램 단위 데이터의 흐름을 정의 데이터 변환을 구현 물리적으로 jar 파일 형태로 클러스터에 전송 ● 스톰 클러스터(cluster) ○ 토폴로지를 실행 ○ 다수의 JVM에서 토폴로지의 각 작업을 병렬 실행
  4. 4. 스톰 토폴로지 토폴로지(topology): 데이터 스트림 처리를 위한 작업 단위 스파우트(Spout): 스트림 데이터를 볼트에 전달. 외부 메시징 시스 템 등에서 데이터 가져옴 이미지 출처: http://storm-project.net/ 볼트(Bolt): 데이터를 처리해서 다른 볼트에 전달 하거나 외부에 저 장
  5. 5. 스트림의 데이터: 튜플 튜플은 [이름:값, 이름:값, 이름:값, …] 형식의 데이터 튜플 튜플 튜플 볼트는 튜플을 입력으로 받아 연산 수행 후, 새로운 튜플을 생성해서 다른 볼트에 전달 또는 연산 결과를 별도 처리(DB 저장 등)
  6. 6. 스톰 클러스트 ● 토폴로지를 실행 님버스(Nimbus): 토폴로지의 각 태스크를 Worker에 할당하고, 모니터링 수퍼바이저(Supervisor): 토폴로지의 태스크를 실행하기 위 해 worker 프로세스 생성 토폴로지: jar 파일 Nimbus (master) 주키퍼(Zookeeper): 토폴로지의 실행 상태 보관 Zookeeper 클러스터 Supervisor Supervisor Supervisor
  7. 7. 개발자가 해야 할 일 ● 스톰 클러스터 구축 ● 코드 구현 ○ 스파우트 구현 ○ 볼트 구현 ○ 토폴로지 구성 -- 토폴로지 구성 예 TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("word-reader", new WordReader()); builder.setBolt("word-normalizer", new WordNormalizer()).shuffleGrouping("word-reader"); builder.setBolt("word-counter", new WordCounter()).shuffleGrouping("word-reader"); word-reader word-normalizer word-counter
  8. 8. 병렬 실행 ● 워커worker 프로세스 ○ 클러스터에서 생성되는 JVM 프로세스, 토폴로지 단위로 설정 가능 ● executor ○ ○ 스파우트/볼트를 실행하는 쓰레드, worker가 생성 스파우트/볼트 단위로 개수 지정, 지정하지 않으면 1개 사용 ● 태스크task ○ ○ 스파우트/볼트 당 생성할 작업(인스턴스) 개수 지정하지 않으면 executor 당 1개 builder.setBolt("word-normalizer", new WordNormalizer(), 4) // 4개의 쓰레드 .setNumTasks(8) // 8개의 작업 생성 .shuffleGrouping("word-reader"); conf.setNumWorkers(2); // worker 프로세스 2개 * 1개 worker에서 2개 쓰레드 실행 / 1개 쓰레드가 2개의 태스크를 실행 * 즉, 각 worker에서 4개의 태스크 실행
  9. 9. 스트림 그룹핑 ● 태스크가 2개 이상일 때 각 태스크에 튜플을 분배하는 기준 필요 1번 태스크로 전 달? word-reader 스파우트 word-normalizer 볼트 튜플 튜플 1번 태스크 2번 태스크
  10. 10. 스트림 그룹핑 종류 그룹핑 설명 Shuffle (None도 동일) 각 튜플을 랜덤하게 볼트 태스크로 보낸다. 각 태스크에 보내지 는 튜플은 균등한다. Field 튜플의 지정한 필드 값을 이용해서 볼트 태스크를 선택한다. 동 일 필드 값을 가진 튜플은 같은 볼트 태스크로 전달된다. All 동일 튜플이 모든 볼트 태스크에 전달된다. Direct 튜플을 생성하는 쪽에서 직접 볼트 태스크를 지정한다. Global n개의 태스크 중, 작은 ID를 가진 태스크로 튜플을 전달한다. * Global Grouping 사용 이유에 대한 힌트: https://groups.google.com/forum/#!msg/storm-user/JalFsPvksxw/l4RnjM7qI0wJ -- 코드 샘플 builder.setBolt("word-normalizer", new WordNormalizer(), 4).shuffleGrouping("word-reader"); builder.setBolt("word-counter", new WordCounter(), 2).fieldGrouping("word-reader", new Field(“word”));
  11. 11. 스파우트와 볼트 구현 방식 public class WordReader extends BaseRichSpout { // 튜플을 스트림으로 보낼 때 사용 private SpoutOutputCollector collector; public class WordNormalizer extends BaseRichBolt { private OutputCollector collector; @Override public void prepare(Map conf, TopologyContext context, OutputCollector collector) { this.collector = collector; …. // 데이터 처리 위한 준비 } @Override public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) { this.collector = collector; // 메시지 큐 연결 등의 처리 } @Override public void execute(Tuple input) { String sentence = input.getString(0); String[] words = sentence.split(" "); for (String word : words) { word = word.trim().toLowerCase(); // 다른 볼트에 전달할 튜플 생성 collector.emit(new Values(word)); } collector.ack(input); } @Override public void nextTuple() { … // 데이터를 읽어와 알맞은 튜플 생성 collector.emit(new Values(line), line); } @Override public void declareOutputFields( OutputFieldsDeclarer declarer) { // 생성할 튜플의 필드 정의 declarer.declare(new Fields("line")); } @Override public void declareOutputFields( OutputFieldsDeclarer declarer) { // 볼트가 튜플 생성할 경우, 필드 정의 declarer.declare(new Fields("word")); } @Override public void close() { …연결 종료 등 처리 } } }
  12. 12. 메시지(튜플) 처리 여부 확인 public class WordReader extends BaseRichSpout { @Override public void nextTuple() { … collector.emit(new Values(line), msgId); } @Override public void ack(Object msgId) { // 처리가 된 튜플의 아이디 수신 } @Override public void fail(Object msgId) { // 처리에 실패한 튜플의 아이디 수신 // 실패 메시지에 대한 알맞은 재처리 필요 } public class WordNormalizer extends BaseRichBolt { @Override public void execute(Tuple input) { try { String sentence = input.getString(0); String[] words = sentence.split(" "); for (String word : words) { word = word.trim(); if (!word.isEmpty()) { word = word.toLowerCase(); collector.emit(new Values(word)); } } collector.ack(input); // 메시지 처리 됨을 알림 } catch(Exception e) { collector.fail(input); // 메시지 처리 실패 알림 } } } * 스파우트는 ack()와 fail()을 통해 발생시킨 메시지가 처리되었는지 알 수 있음 * 스파우트가 fail 메시지를 받는 경우: - 수신 볼트에서 fail() 호출하거나 메시지를 제한된 시간 안에 처리하지 못한 경우 * 튜플의 처리 여부 상태를 메모리로 관리하므로, 반드시 수신 볼트에서 ack와 fail을 해야 함
  13. 13. 최초의 메시지가 여러 튜플을 거치면? word-reader ack로 인식 word-normalizer ack collector.emit(new Values(word)); collector.ack(input); fail 응답이 원본 스파우트에 전 달되지 않음 word-counter collector.fail(input);
  14. 14. Anchoring ● 메시지를 연결해서 전체에서 처리되었는지 확인하기 위한 방법 연결된 모든 튜플에 대해 ack를 받을 때 비로서 ack 처리 word-reader word-normalizer ack -- 스트림에서 받은 input을 연결 collector.emit(input, new Values(word)); collector.ack(input); ack word-counter collector.ack(input);
  15. 15. Fault tolerance ● 워커 프로세스 죽을 때 ○ 수퍼바이저가 워커 프로세스 재 구동 ● 님버스/수퍼바이저가 죽을 때 ○ 얼른 재시작하면, 태스크 재시작 ● 님버스가 실행 중인 노드가 죽을 때 ○ 얼른 다른 장비 구해서 님버스 실행 ■ 수퍼바이저는 기능 제공 ● 수퍼바이저가 실행 중인 노드가 죽을 때 ○ 님버스가 노드에서 실행 중인 태스크를 다른 노드에 할당
  16. 16. 기타 ● ● ● ● ● ● 스톰 클러스터 설치 Trient 다중 언어 지원 주키퍼 스톰 + Esper Kestrel (메시지 큐)

×