SlideShare a Scribd company logo
1 of 40
Download to read offline
7가지 동시성 모델
Lambda Architecture
아꿈사 송성곤
Lambda Architecture
Lambda Architecture는 Nathan Marz 에 의해 대중화된용어로 scalable and fault-tolerant data processing
architecture.
Backtype과 Twitter에서 분산 데이터 처리 시스템에서일한 경험이 바탕이 됨.
Lambda Architecture 1. All data entering the system is dispatched to both the
batch layer and the speed layer for processing.
2. The batch layer has two functions: (i) managing the
master dataset (an immutable, append-only set of
raw data), and (ii) to pre-compute the batch views.
3. The serving layer indexes the batch views so that
they can be queried in low-latency, ad-hoc way.
4. The speed layer compensates for the high latency of
updates to the serving layer and deals with recent
data only.
5. Any incoming query can be answered by merging
results from batch views and real-time views.
출처 : http://lambda-architecture.net/
Batch layer and Speed layer
ALL Data
New data
stream
(Kafka)
Storm
Hadoop MR
Cassandra
Hbase
Riak
ElephantDB
Voldemort
Query
Hadoop MapReduce
● Mapper :
○ Processes input key/value pair,
○ Produces set of intermediate
pairs.
● Reducer :
○ Combines all intermediate
values for a particular key,
○ Produces a set of merged
output values
Count word occurrences
Mapper
public static class Map extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString(); // <label id="code.map.tostring"/>
Iterable<String> words = new Words(line); // <label id="code.map.words"/>
for (String word: words)
context.write(new Text(word), one); // <label id="code.map.write"/>
}
}
Reducer
public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val: values)
sum += val.get();
context.write(key, new IntWritable(sum));
}
}
Driver
public class WordCount extends Configured implements Tool {
public int run(String[] args) throws Exception {
Configuration conf = getConf();
Job job = Job.getInstance(conf, "wordcount");
job.setJarByClass(WordCount.class);
job.setMapperClass(Map.class); // <label id="code.mapperclass"/>
job.setReducerClass(Reduce.class); // <label id="code.reducerclass"/>
job.setOutputKeyClass(Text.class); // <label id="code.keyclass"/>
job.setOutputValueClass(IntWritable.class); // <label id="code.valueclass"/>
FileInputFormat.addInputPath(job, new Path(args[0])); // <label id="code.inputpath"/>
FileOutputFormat.setOutputPath(job, new Path(args[1])); // <label id="code.outputpath"/>
boolean success = job.waitForCompletion(true); // <label id="code.waitforcompletion"/>
return success ? 0 : 1;
}
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new WordCount(), args);
System.exit(res);
지역적으로 실행하기
$ hadoop jar target/wordcount-1.0-jar-with-dependencies. jar input output
Amazon EMR에서 실행하기
● EMR : Elastic MapReduce
● Input/Ouput : Amazon S3
● 커다란 파일 올리기 : Amazon EC2 활용 → Amazon S3와 EC2 대역폭이
높음
클러스터 만들기 - Amazon EMR
● $ elastic-mapreduce --create --name wordcount -num-instances 11 
--master-instance-type m1.large --slave-instance-type m1.large V
--ami-version 3.0.2 --jar s3://pb7con-lambda/wordcount. jar V --arg
s3://pb7con-wikipedia/text --arg S3://pb7con-wikipedia/Counts Created
job flow j-2LSRGPBSR79ZV
진행상황 모니터 - Amazon EMR
● $ elastic-mapreduce --jobflow j -2LSRGPBSR79ZW -ssh
● $ tail -f /mnt/var/log/hadoop/steps/1/syslog
결과 검사하기 - Amazon EMR
● 작업이 완료되면 S3 버켓에 여러 개의 파일을 발견할 수 있을 것이다.
part-r-00000
part-r-00001
part-r-00002
….
part-r-00028
XML 처리하기-Driver
public int run(String[] args) throws Exception {
Configuration conf = getConf();
conf.set("xmlinput.start", "<text"); // <label id="code.xmlinputstart"/>
conf.set("xmlinput.end", "</text>"); // <label id="code.xmlinputend"/>
Job job = Job.getInstance(conf, "wordcount");
job.setJarByClass(WordCount.class);
job.setInputFormatClass(XmlInputFormat.class); // <label id="code.setinputformat"/>
job.setMapperClass(Map.class);
job.setCombinerClass(Reduce.class); // <label id="code.setcombiner"/>
job.setReducerClass(Reduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
boolean success = job.waitForCompletion(true);
return success ? 0 : 1;
XML 처리하기-Mapper
public static class Map extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private final static Pattern textPattern =
Pattern.compile("^<text.*>(.*)</text>$", Pattern.DOTALL);
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String text = value.toString();
Matcher matcher = textPattern.matcher(text);
if (matcher.find()) {
Iterable<String> words = new Words(matcher.group(1));
for (String word: words)
context.write(new Text(word), one);
}
}
}
하둡을 사용하는 것이 전적으로 속도
때문인가?
대용량 분산 처리
장애를 처리하고 회복할수 있음
● 노드 장애 : 장애가 발생한 노드에서재시도(map, reduce 재 실행)
● 디스크 장애 : 데이터를여러 노드에 중복하여저장하는장애 허용 분산 파일 시스템
● 유한한 메모리 : 메모리에전체 데이터를모두 올리는 대신, 처리하는동안 HDFS에 키/값쌍 들을 저장
1일차 마무리
● Hadoop streaming API : https://hadoop.apache.org/docs/r1.2.1/streaming.html
● Hadoop pipe API : https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/mapred/pipes/package-summary.html
● Hadoop java/scala api
○ Scalding : http://www.cascading.org/projects/scalding/
○ Cascading : http://www.cascading.org/projects/cascading/
○ Cascalog : http://cascalog.org/
전통적인 데이터 시스템의 문제
● 규모 - 복제, 샤딩으로 확장... 장비가 늘어날수록 질의가 많이 질수록 쉽지 않다!
● 유지보수 오버 헤드 - 여러대의 컴퓨터에 퍼져있는 데이터 베이스관리 쉽지 않다!
● 복잡성 - 복제와 샤딩은 어플리케이션의 지원이 필요
● 사람의 실수 - 사람이 저지르는 잘못을 처리하는 것
● 과거의 정보에 대한 접근이 필요한 분석과 보고서
Batch layer
● 불멸의 진리 데이터 : 원천 데이터 + 도출된 데이터
● 원천데이터가 불변이 될려면 ?
○ 타임스탬프 만 추가하면 된다.
● 원천데이터가 불변이면 ...
○ 대량의 데이터를 처리할 수 있는 고도의 병렬성
○ 만기도 쉽고 장애도 잘 일어나지 않는 단순함
○ 기술적 고장이나 사람의 실수를 허용하는 능력
○ 매일의 업무는 물론 과거의 데이터를 대상으로 하는 보고서나 분석도 가능하게 만드는
능력
● "지연"이라는 단점이 있음
WikiContributorsBatch
● 타임스탬프
● 기여 자체를 나타내는 식별자
● 기여를 한 사용자를 나타내는 식별자
● 사용자의 이름
Mapper - WikiContributorsBatch
public static class Map extends Mapper<Object, Text, IntWritable, LongWritable> {
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
Contribution contribution = new Contribution(value.toString());
context.write(new IntWritable(contribution.contributorId),
new LongWritable(contribution.timestamp));
}
}
Mapper - WikiContributorsBatch
class Contribution {
static final Pattern pattern = Pattern.compile("^([^s]*) (d*) (d*) (.*)$"); // <label id="code.contributorpattern"/>
static final DateTimeFormatter isoFormat = ISODateTimeFormat.dateTimeNoMillis(); // <label id="code.isoformat"/>
public long timestamp;
public int id;
public int contributorId;
public String username;
public Contribution(String line) {
Matcher matcher = pattern.matcher(line);
if(matcher.find()) {
timestamp = isoFormat.parseDateTime(matcher.group(1)).getMillis(); // <label id="code.getmillis"/>
id = Integer.parseInt(matcher.group(2));
contributorId = Integer.parseInt(matcher.group(3));
username = matcher.group(4);
}
}
Reducer - WikiContributorsBatch
public static class Reduce
extends Reducer<IntWritable, LongWritable, IntWritable, Text> {
static DateTimeFormatter dayFormat = ISODateTimeFormat.yearMonthDay();
static DateTimeFormatter monthFormat = ISODateTimeFormat.yearMonth();
public void reduce(IntWritable key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
HashMap<DateTime, Integer> days = new HashMap<DateTime, Integer>(); // <label id="code.days"/>
HashMap<DateTime, Integer> months = new HashMap<DateTime, Integer>(); // <label id="code.months"/>
for (LongWritable value: values) {
DateTime timestamp = new DateTime(value.get());
DateTime day = timestamp.withTimeAtStartOfDay(); // <label id="code.day"/>
DateTime month = day.withDayOfMonth(1); // <label id="code.month"/>
incrementCount(days, day);
incrementCount(months, month);
}
for (Entry<DateTime, Integer> entry: days.entrySet()) // <label id="code.outputcountsstart"/>
context.write(key, formatEntry(entry, dayFormat));
for (Entry<DateTime, Integer> entry: months.entrySet())
Reducer - WikiContributorsBatch
private void incrementCount(HashMap<DateTime, Integer> counts, DateTime key) {
Integer currentCount = counts.get(key);
if (currentCount == null)
counts.put(key, 1);
else
counts.put(key, currentCount + 1);
}
private Text formatEntry(Entry<DateTime, Integer> entry,
DateTimeFormatter formatter) {
return new Text(formatter.print(entry.getKey()) + "t" + entry.getValue())
}
}
Service Layer 배치뷰 업데이트에적합한 서비스 계층 DB ?
ElephantDB (Clojure)► This is system created exactly for
this case. It is very simple.
참조: http://www.slideshare.net/nathanmarz/elephantdb
Voldemort(java) ► NoSQL, Pluggable Storage engines,
Consistent hashing, Eventual consistency, Support for
batch-computed read-only stores
An open source clone of Amazon's Dynamo.
출처 :
http://www.slideshare.net/DavidGroozman/challenge-26788828
Speed Layer ● Batch Layer 속도 지연의 극복
● 점진적인 접근 방식을 사용
● 무작위 쓰기를 허용하는
전통적인 데이터베이스를
사용
Speed Layer
동기적 접근 방법
비동기적 접근 방법
데이터의 만료
STORM
● 스톰 시스템은 튜플의 스트림을 처리한다.
● 튜플은 스파우트에 의해서 생성되고 볼트에 의해서 처리된다.
STORM 작업자들
● 스파우트/볼트를 여러 노드에 분산시키는 이유는 장애 허용 때문
● 클러스터에 있는 노드 중 하나에 장애 : 스톰 토폴로지는 튜플을 정상적으로
동작하는 노드에 보냄 → 튜플 “최소한 한 번" 처리 보장
STORM을 이용해 기여 세기
● 로그 읽기 스파우트
● 로그 항목 해석 볼트
● 데이터베이스 업데이트 볼트
Spout
public class RandomContributorSpout extends BaseRichSpout { // <label id="code.spout"/>
private static final Random rand = new Random();
private static final DateTimeFormatter isoFormat =
ISODateTimeFormat.dateTimeNoMillis();
private SpoutOutputCollector collector;
private int contributionId = 10000;
public void open(Map conf, TopologyContext context, // <label id="code.spoutopen"/>
SpoutOutputCollector collector) {
this.collector = collector;
}
public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.spoutdeclare"/>
declarer.declare(new Fields("line"));
}
public void nextTuple() { // <label id="code.spoutnexttuple"/>
Utils.sleep(rand.nextInt(100));
++contributionId;
String line = isoFormat.print(DateTime.now()) + " " + contributionId + " " +
rand.nextInt(10000) + " " + "dummyusername";
Parser Bolt
class ContributionParser extends BaseBasicBolt { // <label id="code.bolt"/>
public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.parserdeclare"/>
declarer.declare(new Fields("timestamp", "id", "contributorId", "username"));
}
public void execute(Tuple tuple, BasicOutputCollector collector) { // <label id="code.parserexecute"/>
Contribution contribution = new Contribution(tuple.getString(0));
collector.emit(new Values(contribution.timestamp, contribution.id,
contribution.contributorId, contribution.username));
}
}
Record Bolt
class ContributionRecord extends BaseBasicBolt {
private static final HashMap<Integer, HashSet<Long>> timestamps = // <label id="code.recordertimestamps"/>
new HashMap<Integer, HashSet<Long>>();
public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.recorderdeclare"/>
}
public void execute(Tuple tuple, BasicOutputCollector collector) { // <label id="code.recorderexecute"/>
addTimestamp(tuple.getInteger(2), tuple.getLong(0));
}
private void addTimestamp(int contributorId, long timestamp) { // <label id="code.addtimestamp"/>
HashSet<Long> contributorTimestamps = timestamps.get(contributorId);
if (contributorTimestamps == null) {
contributorTimestamps = new HashSet<Long>();
timestamps.put(contributorId, contributorTimestamps);
}
contributorTimestamps.add(timestamp);
}
}
Topology
public class WikiContributorsTopology {
public static void main(String[] args) throws Exception {
TopologyBuilder builder = new TopologyBuilder(); // <label id="code.topologybuilder"/>
builder.setSpout("contribution_spout", new RandomContributorSpout(), 4); // <label id="code.setspout"/>
builder.setBolt("contribution_parser", new ContributionParser(), 4). // <label id="code.shufflegrouping"/>
shuffleGrouping("contribution_spout");
builder.setBolt("contribution_recorder", new ContributionRecord(), 4). // <label id="code.fieldsgrouping"/>
fieldsGrouping("contribution_parser", new Fields("contributorId"));
LocalCluster cluster = new LocalCluster();
Config conf = new Config();
cluster.submitTopology("wiki-contributors", conf, builder.createTopology()); // <label id="code.submittopology"/>
Thread.sleep(10000);
cluster.shutdown(); // <label id="code.clustershutdown"/>
}
}
Stream Group
스톰의 스트림 그룹은 어느 작업자(Task)가 어느 튜플을 받는가라는 질문에 대한 대답을 제공한다.
(http://storm.apache.org/releases/current/Concepts.html)
Shuffle grouping
튜플이 볼트의 작업자(Task)에 랜덤하게 분산됨.
Fields grouping
튜플이 가지는 특정 데이터 필드에 따라 작업자(Task)가 선택됨. 예를들어 만약 튜플이
contributorId로 그룹되어 진다면, 동일한 contributorId를 가지는 튜플들은 항상 동일한 작업자(Task)에
가게 됨.
Global grouping
전체 튜플은 볼트의 작업자(Task)중 하나로만 가게됨. (가장 낮은 아이디의 작업자로 가게됨)
Stream Group
All grouping
하나의 튜플이 모든 볼트 작업자 들에 전달됨. (모든 볼트 작업자 들에 브로드캐스트 됨)
Direct grouping
튜플의 생산자는 어떤 작업자가 이 튜플을 받을 것인지를 결정함.(1:1)
Local or shuffle grouping
Target 볼트가 동일한 작업자(Task) 프로세스에 하나 이상의 작업을 수행할 경우, 튜플 작업을
in-process 작업으로 처리함. 그렇지 않으면 일반적인 Shuffle grouping과 같이 동작
Partial Key grouping
Fields grouping과 같이 튜플이 가지는 특정 데이터 필드에 따라 작업자가 선택되지만, 두개의
downstream 볼트 사이에 부하가 배분됨.
3일차 마무리
속도 계층은 최근 데이터에 대한 실시간 뷰를 제공
속도 계층의 스톰은 비동기적인 속도 계층을 만들 때 사용
마치며
● 람다 아키텍처 - 여러 개념을 하나로 통합
○ 원천 데이터 불변 : 클로저가 아이덴티티와 상태를 분리하는것을 연상
○ Mapper/Reducer 병렬처리 : 병렬적 함수 프로그래밍과 유사
○ 작업과정을 클러스터에 분산 : 액터
○ 스톰 튜플의 스트림 : 액터와 CSP 메시지 전달
● 장점/단점
○ 람다 아키텍처는 거대한 양의 데이터를 다루기 위한 것/거대한 양의 데이터 - > 오버헤드
● 대안
○ 스파크는 DAG 실행 엔진을 구현하는 수많은 알고리즘(특히 그래프 알고리즘)이
맵리듀스와 비교해서 더 자연스럽게 표현되도록 만들어주는 클러스터 컴퓨팅 프레임워크
■ 내부에 스트리밍 API : 배치 계층과 속도 계층이 모두 구현 가능

More Related Content

What's hot

2.apache spark 실습
2.apache spark 실습2.apache spark 실습
2.apache spark 실습동현 강
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912Yooseok Choi
 
발표자료 11장
발표자료 11장발표자료 11장
발표자료 11장Juhui Park
 
Node.js를 사용한 Big Data 사례연구
Node.js를 사용한 Big Data 사례연구Node.js를 사용한 Big Data 사례연구
Node.js를 사용한 Big Data 사례연구ByungJoon Lee
 
처음 접하는 Oozie Workflow, Coordinator
처음 접하는 Oozie Workflow, Coordinator처음 접하는 Oozie Workflow, Coordinator
처음 접하는 Oozie Workflow, CoordinatorKim Log
 
Chapter3 - learning spark
Chapter3 - learning sparkChapter3 - learning spark
Chapter3 - learning sparkMungyu Choi
 
Java 초보자를 위한 hadoop 설정
Java 초보자를 위한 hadoop 설정Java 초보자를 위한 hadoop 설정
Java 초보자를 위한 hadoop 설정HyeonSeok Choi
 
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...Jemin Huh
 
Ots2014 arcus-collection-open source
Ots2014 arcus-collection-open sourceOts2014 arcus-collection-open source
Ots2014 arcus-collection-open sourceNAVER D2
 
[252] 증분 처리 플랫폼 cana 개발기
[252] 증분 처리 플랫폼 cana 개발기[252] 증분 처리 플랫폼 cana 개발기
[252] 증분 처리 플랫폼 cana 개발기NAVER D2
 
learning spark - Chatper8. Tuning and Debugging
learning spark - Chatper8. Tuning and Debugginglearning spark - Chatper8. Tuning and Debugging
learning spark - Chatper8. Tuning and DebuggingMungyu Choi
 
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)SANG WON PARK
 
20141029 하둡2.5와 hive설치 및 예제
20141029 하둡2.5와 hive설치 및 예제20141029 하둡2.5와 hive설치 및 예제
20141029 하둡2.5와 hive설치 및 예제Tae Young Lee
 
[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)NAVER D2
 
[243]kaleido 노현걸
[243]kaleido 노현걸[243]kaleido 노현걸
[243]kaleido 노현걸NAVER D2
 
[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_databaseNAVER D2
 
Spark 소개 2부
Spark 소개 2부Spark 소개 2부
Spark 소개 2부Jinho Yoo
 

What's hot (20)

Cluster - spark
Cluster - sparkCluster - spark
Cluster - spark
 
2.apache spark 실습
2.apache spark 실습2.apache spark 실습
2.apache spark 실습
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
 
발표자료 11장
발표자료 11장발표자료 11장
발표자료 11장
 
Node.js를 사용한 Big Data 사례연구
Node.js를 사용한 Big Data 사례연구Node.js를 사용한 Big Data 사례연구
Node.js를 사용한 Big Data 사례연구
 
Spark sql
Spark sqlSpark sql
Spark sql
 
처음 접하는 Oozie Workflow, Coordinator
처음 접하는 Oozie Workflow, Coordinator처음 접하는 Oozie Workflow, Coordinator
처음 접하는 Oozie Workflow, Coordinator
 
Chapter3 - learning spark
Chapter3 - learning sparkChapter3 - learning spark
Chapter3 - learning spark
 
Java 초보자를 위한 hadoop 설정
Java 초보자를 위한 hadoop 설정Java 초보자를 위한 hadoop 설정
Java 초보자를 위한 hadoop 설정
 
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...
서비스 모니터링 구현 사례 공유 - Realtime log monitoring platform-PMon을 ...
 
Ots2014 arcus-collection-open source
Ots2014 arcus-collection-open sourceOts2014 arcus-collection-open source
Ots2014 arcus-collection-open source
 
[252] 증분 처리 플랫폼 cana 개발기
[252] 증분 처리 플랫폼 cana 개발기[252] 증분 처리 플랫폼 cana 개발기
[252] 증분 처리 플랫폼 cana 개발기
 
learning spark - Chatper8. Tuning and Debugging
learning spark - Chatper8. Tuning and Debugginglearning spark - Chatper8. Tuning and Debugging
learning spark - Chatper8. Tuning and Debugging
 
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)
OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens)
 
20141029 하둡2.5와 hive설치 및 예제
20141029 하둡2.5와 hive설치 및 예제20141029 하둡2.5와 hive설치 및 예제
20141029 하둡2.5와 hive설치 및 예제
 
[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)
 
[243]kaleido 노현걸
[243]kaleido 노현걸[243]kaleido 노현걸
[243]kaleido 노현걸
 
[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database
 
Spark 소개 2부
Spark 소개 2부Spark 소개 2부
Spark 소개 2부
 
Druid+superset
Druid+supersetDruid+superset
Druid+superset
 

Similar to 7가지 동시성 모델 람다아키텍처

Hadoop 제주대
Hadoop 제주대Hadoop 제주대
Hadoop 제주대DaeHeon Oh
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
웹개발자가 알아야할 기술
웹개발자가 알아야할 기술웹개발자가 알아야할 기술
웹개발자가 알아야할 기술jaypi Ko
 
Distributed Programming Framework, hadoop
Distributed Programming Framework, hadoopDistributed Programming Framework, hadoop
Distributed Programming Framework, hadoopLGU+
 
Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Jay Park
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)LanarkSeung
 
Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Gruter
 
Programming Cascading
Programming CascadingProgramming Cascading
Programming CascadingTaewook Eom
 
Spark_Overview_qna
Spark_Overview_qnaSpark_Overview_qna
Spark_Overview_qna현철 박
 
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제NAVER D2
 
Webrtc 허영남 20150528
Webrtc 허영남 20150528Webrtc 허영남 20150528
Webrtc 허영남 20150528영남 허
 
PostGIS - National Education Center for GIS: Open Source GIS
PostGIS - National Education Center for GIS: Open Source GIS PostGIS - National Education Center for GIS: Open Source GIS
PostGIS - National Education Center for GIS: Open Source GIS MinPa Lee
 
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용중선 곽
 
20131217 html5
20131217 html520131217 html5
20131217 html5DK Lee
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
 
KCSE 2015 Tutorial 빅데이터 분석 기술의 소프트웨어 공학 분야 활용 (...
KCSE 2015 Tutorial 빅데이터 분석 기술의  소프트웨어 공학 분야 활용 (...KCSE 2015 Tutorial 빅데이터 분석 기술의  소프트웨어 공학 분야 활용 (...
KCSE 2015 Tutorial 빅데이터 분석 기술의 소프트웨어 공학 분야 활용 (...Chanjin Park
 

Similar to 7가지 동시성 모델 람다아키텍처 (20)

Redis
RedisRedis
Redis
 
Hadoop 제주대
Hadoop 제주대Hadoop 제주대
Hadoop 제주대
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
웹개발자가 알아야할 기술
웹개발자가 알아야할 기술웹개발자가 알아야할 기술
웹개발자가 알아야할 기술
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
Distributed Programming Framework, hadoop
Distributed Programming Framework, hadoopDistributed Programming Framework, hadoop
Distributed Programming Framework, hadoop
 
Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발Mean 스택을 사용한 IoT 개발
Mean 스택을 사용한 IoT 개발
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
 
Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)
 
Programming Cascading
Programming CascadingProgramming Cascading
Programming Cascading
 
Spark_Overview_qna
Spark_Overview_qnaSpark_Overview_qna
Spark_Overview_qna
 
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제
[D2 COMMUNITY] Spark User Group - 스파크를 통한 딥러닝 이론과 실제
 
Webrtc 허영남 20150528
Webrtc 허영남 20150528Webrtc 허영남 20150528
Webrtc 허영남 20150528
 
PostGIS - National Education Center for GIS: Open Source GIS
PostGIS - National Education Center for GIS: Open Source GIS PostGIS - National Education Center for GIS: Open Source GIS
PostGIS - National Education Center for GIS: Open Source GIS
 
Html5
Html5 Html5
Html5
 
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
 
20131217 html5
20131217 html520131217 html5
20131217 html5
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
 
KCSE 2015 Tutorial 빅데이터 분석 기술의 소프트웨어 공학 분야 활용 (...
KCSE 2015 Tutorial 빅데이터 분석 기술의  소프트웨어 공학 분야 활용 (...KCSE 2015 Tutorial 빅데이터 분석 기술의  소프트웨어 공학 분야 활용 (...
KCSE 2015 Tutorial 빅데이터 분석 기술의 소프트웨어 공학 분야 활용 (...
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 

More from Sunggon Song

K8s in action chap15
K8s in action chap15K8s in action chap15
K8s in action chap15Sunggon Song
 
랜덤Walks, 몬테카를로 시뮬레이션
랜덤Walks, 몬테카를로 시뮬레이션랜덤Walks, 몬테카를로 시뮬레이션
랜덤Walks, 몬테카를로 시뮬레이션Sunggon Song
 
Function approximation as supervised learning
Function approximation as supervised learningFunction approximation as supervised learning
Function approximation as supervised learningSunggon Song
 
서포트 벡터머신
서포트 벡터머신서포트 벡터머신
서포트 벡터머신Sunggon Song
 
대칭가중치와 심층신뢰네트워크
대칭가중치와 심층신뢰네트워크대칭가중치와 심층신뢰네트워크
대칭가중치와 심층신뢰네트워크Sunggon Song
 
데이터처리와 통계 기본 머신러닝
데이터처리와 통계 기본 머신러닝데이터처리와 통계 기본 머신러닝
데이터처리와 통계 기본 머신러닝Sunggon Song
 
합성곱 신경망
합성곱 신경망합성곱 신경망
합성곱 신경망Sunggon Song
 
밑바닥부터 시작하는딥러닝 8장
밑바닥부터 시작하는딥러닝 8장밑바닥부터 시작하는딥러닝 8장
밑바닥부터 시작하는딥러닝 8장Sunggon Song
 
함수형사고 3장 양도하라
함수형사고 3장 양도하라함수형사고 3장 양도하라
함수형사고 3장 양도하라Sunggon Song
 
7가지 동시성 모델-2장
7가지 동시성 모델-2장7가지 동시성 모델-2장
7가지 동시성 모델-2장Sunggon Song
 
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장Sunggon Song
 

More from Sunggon Song (13)

K8s in action chap15
K8s in action chap15K8s in action chap15
K8s in action chap15
 
랜덤Walks, 몬테카를로 시뮬레이션
랜덤Walks, 몬테카를로 시뮬레이션랜덤Walks, 몬테카를로 시뮬레이션
랜덤Walks, 몬테카를로 시뮬레이션
 
Function approximation as supervised learning
Function approximation as supervised learningFunction approximation as supervised learning
Function approximation as supervised learning
 
서포트 벡터머신
서포트 벡터머신서포트 벡터머신
서포트 벡터머신
 
대칭가중치와 심층신뢰네트워크
대칭가중치와 심층신뢰네트워크대칭가중치와 심층신뢰네트워크
대칭가중치와 심층신뢰네트워크
 
데이터처리와 통계 기본 머신러닝
데이터처리와 통계 기본 머신러닝데이터처리와 통계 기본 머신러닝
데이터처리와 통계 기본 머신러닝
 
합성곱 신경망
합성곱 신경망합성곱 신경망
합성곱 신경망
 
밑바닥부터 시작하는딥러닝 8장
밑바닥부터 시작하는딥러닝 8장밑바닥부터 시작하는딥러닝 8장
밑바닥부터 시작하는딥러닝 8장
 
함수형사고 3장 양도하라
함수형사고 3장 양도하라함수형사고 3장 양도하라
함수형사고 3장 양도하라
 
7가지 동시성 모델-2장
7가지 동시성 모델-2장7가지 동시성 모델-2장
7가지 동시성 모델-2장
 
Ddd start 10장
Ddd start 10장Ddd start 10장
Ddd start 10장
 
DDD start 1장
DDD start 1장DDD start 1장
DDD start 1장
 
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
 

7가지 동시성 모델 람다아키텍처

  • 1. 7가지 동시성 모델 Lambda Architecture 아꿈사 송성곤
  • 2. Lambda Architecture Lambda Architecture는 Nathan Marz 에 의해 대중화된용어로 scalable and fault-tolerant data processing architecture. Backtype과 Twitter에서 분산 데이터 처리 시스템에서일한 경험이 바탕이 됨.
  • 3. Lambda Architecture 1. All data entering the system is dispatched to both the batch layer and the speed layer for processing. 2. The batch layer has two functions: (i) managing the master dataset (an immutable, append-only set of raw data), and (ii) to pre-compute the batch views. 3. The serving layer indexes the batch views so that they can be queried in low-latency, ad-hoc way. 4. The speed layer compensates for the high latency of updates to the serving layer and deals with recent data only. 5. Any incoming query can be answered by merging results from batch views and real-time views. 출처 : http://lambda-architecture.net/
  • 4. Batch layer and Speed layer ALL Data New data stream (Kafka) Storm Hadoop MR Cassandra Hbase Riak ElephantDB Voldemort Query
  • 5. Hadoop MapReduce ● Mapper : ○ Processes input key/value pair, ○ Produces set of intermediate pairs. ● Reducer : ○ Combines all intermediate values for a particular key, ○ Produces a set of merged output values
  • 7. Mapper public static class Map extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); // <label id="code.map.tostring"/> Iterable<String> words = new Words(line); // <label id="code.map.words"/> for (String word: words) context.write(new Text(word), one); // <label id="code.map.write"/> } }
  • 8. Reducer public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val: values) sum += val.get(); context.write(key, new IntWritable(sum)); } }
  • 9. Driver public class WordCount extends Configured implements Tool { public int run(String[] args) throws Exception { Configuration conf = getConf(); Job job = Job.getInstance(conf, "wordcount"); job.setJarByClass(WordCount.class); job.setMapperClass(Map.class); // <label id="code.mapperclass"/> job.setReducerClass(Reduce.class); // <label id="code.reducerclass"/> job.setOutputKeyClass(Text.class); // <label id="code.keyclass"/> job.setOutputValueClass(IntWritable.class); // <label id="code.valueclass"/> FileInputFormat.addInputPath(job, new Path(args[0])); // <label id="code.inputpath"/> FileOutputFormat.setOutputPath(job, new Path(args[1])); // <label id="code.outputpath"/> boolean success = job.waitForCompletion(true); // <label id="code.waitforcompletion"/> return success ? 0 : 1; } public static void main(String[] args) throws Exception { int res = ToolRunner.run(new Configuration(), new WordCount(), args); System.exit(res);
  • 10. 지역적으로 실행하기 $ hadoop jar target/wordcount-1.0-jar-with-dependencies. jar input output
  • 11. Amazon EMR에서 실행하기 ● EMR : Elastic MapReduce ● Input/Ouput : Amazon S3 ● 커다란 파일 올리기 : Amazon EC2 활용 → Amazon S3와 EC2 대역폭이 높음
  • 12. 클러스터 만들기 - Amazon EMR ● $ elastic-mapreduce --create --name wordcount -num-instances 11 --master-instance-type m1.large --slave-instance-type m1.large V --ami-version 3.0.2 --jar s3://pb7con-lambda/wordcount. jar V --arg s3://pb7con-wikipedia/text --arg S3://pb7con-wikipedia/Counts Created job flow j-2LSRGPBSR79ZV
  • 13. 진행상황 모니터 - Amazon EMR ● $ elastic-mapreduce --jobflow j -2LSRGPBSR79ZW -ssh ● $ tail -f /mnt/var/log/hadoop/steps/1/syslog
  • 14. 결과 검사하기 - Amazon EMR ● 작업이 완료되면 S3 버켓에 여러 개의 파일을 발견할 수 있을 것이다. part-r-00000 part-r-00001 part-r-00002 …. part-r-00028
  • 15. XML 처리하기-Driver public int run(String[] args) throws Exception { Configuration conf = getConf(); conf.set("xmlinput.start", "<text"); // <label id="code.xmlinputstart"/> conf.set("xmlinput.end", "</text>"); // <label id="code.xmlinputend"/> Job job = Job.getInstance(conf, "wordcount"); job.setJarByClass(WordCount.class); job.setInputFormatClass(XmlInputFormat.class); // <label id="code.setinputformat"/> job.setMapperClass(Map.class); job.setCombinerClass(Reduce.class); // <label id="code.setcombiner"/> job.setReducerClass(Reduce.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); boolean success = job.waitForCompletion(true); return success ? 0 : 1;
  • 16. XML 처리하기-Mapper public static class Map extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private final static Pattern textPattern = Pattern.compile("^<text.*>(.*)</text>$", Pattern.DOTALL); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String text = value.toString(); Matcher matcher = textPattern.matcher(text); if (matcher.find()) { Iterable<String> words = new Words(matcher.group(1)); for (String word: words) context.write(new Text(word), one); } } }
  • 17. 하둡을 사용하는 것이 전적으로 속도 때문인가? 대용량 분산 처리 장애를 처리하고 회복할수 있음 ● 노드 장애 : 장애가 발생한 노드에서재시도(map, reduce 재 실행) ● 디스크 장애 : 데이터를여러 노드에 중복하여저장하는장애 허용 분산 파일 시스템 ● 유한한 메모리 : 메모리에전체 데이터를모두 올리는 대신, 처리하는동안 HDFS에 키/값쌍 들을 저장
  • 18. 1일차 마무리 ● Hadoop streaming API : https://hadoop.apache.org/docs/r1.2.1/streaming.html ● Hadoop pipe API : https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/mapred/pipes/package-summary.html ● Hadoop java/scala api ○ Scalding : http://www.cascading.org/projects/scalding/ ○ Cascading : http://www.cascading.org/projects/cascading/ ○ Cascalog : http://cascalog.org/
  • 19. 전통적인 데이터 시스템의 문제 ● 규모 - 복제, 샤딩으로 확장... 장비가 늘어날수록 질의가 많이 질수록 쉽지 않다! ● 유지보수 오버 헤드 - 여러대의 컴퓨터에 퍼져있는 데이터 베이스관리 쉽지 않다! ● 복잡성 - 복제와 샤딩은 어플리케이션의 지원이 필요 ● 사람의 실수 - 사람이 저지르는 잘못을 처리하는 것 ● 과거의 정보에 대한 접근이 필요한 분석과 보고서
  • 20. Batch layer ● 불멸의 진리 데이터 : 원천 데이터 + 도출된 데이터 ● 원천데이터가 불변이 될려면 ? ○ 타임스탬프 만 추가하면 된다. ● 원천데이터가 불변이면 ... ○ 대량의 데이터를 처리할 수 있는 고도의 병렬성 ○ 만기도 쉽고 장애도 잘 일어나지 않는 단순함 ○ 기술적 고장이나 사람의 실수를 허용하는 능력 ○ 매일의 업무는 물론 과거의 데이터를 대상으로 하는 보고서나 분석도 가능하게 만드는 능력 ● "지연"이라는 단점이 있음
  • 21. WikiContributorsBatch ● 타임스탬프 ● 기여 자체를 나타내는 식별자 ● 기여를 한 사용자를 나타내는 식별자 ● 사용자의 이름
  • 22. Mapper - WikiContributorsBatch public static class Map extends Mapper<Object, Text, IntWritable, LongWritable> { public void map(Object key, Text value, Context context) throws IOException, InterruptedException { Contribution contribution = new Contribution(value.toString()); context.write(new IntWritable(contribution.contributorId), new LongWritable(contribution.timestamp)); } }
  • 23. Mapper - WikiContributorsBatch class Contribution { static final Pattern pattern = Pattern.compile("^([^s]*) (d*) (d*) (.*)$"); // <label id="code.contributorpattern"/> static final DateTimeFormatter isoFormat = ISODateTimeFormat.dateTimeNoMillis(); // <label id="code.isoformat"/> public long timestamp; public int id; public int contributorId; public String username; public Contribution(String line) { Matcher matcher = pattern.matcher(line); if(matcher.find()) { timestamp = isoFormat.parseDateTime(matcher.group(1)).getMillis(); // <label id="code.getmillis"/> id = Integer.parseInt(matcher.group(2)); contributorId = Integer.parseInt(matcher.group(3)); username = matcher.group(4); } }
  • 24. Reducer - WikiContributorsBatch public static class Reduce extends Reducer<IntWritable, LongWritable, IntWritable, Text> { static DateTimeFormatter dayFormat = ISODateTimeFormat.yearMonthDay(); static DateTimeFormatter monthFormat = ISODateTimeFormat.yearMonth(); public void reduce(IntWritable key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException { HashMap<DateTime, Integer> days = new HashMap<DateTime, Integer>(); // <label id="code.days"/> HashMap<DateTime, Integer> months = new HashMap<DateTime, Integer>(); // <label id="code.months"/> for (LongWritable value: values) { DateTime timestamp = new DateTime(value.get()); DateTime day = timestamp.withTimeAtStartOfDay(); // <label id="code.day"/> DateTime month = day.withDayOfMonth(1); // <label id="code.month"/> incrementCount(days, day); incrementCount(months, month); } for (Entry<DateTime, Integer> entry: days.entrySet()) // <label id="code.outputcountsstart"/> context.write(key, formatEntry(entry, dayFormat)); for (Entry<DateTime, Integer> entry: months.entrySet())
  • 25. Reducer - WikiContributorsBatch private void incrementCount(HashMap<DateTime, Integer> counts, DateTime key) { Integer currentCount = counts.get(key); if (currentCount == null) counts.put(key, 1); else counts.put(key, currentCount + 1); } private Text formatEntry(Entry<DateTime, Integer> entry, DateTimeFormatter formatter) { return new Text(formatter.print(entry.getKey()) + "t" + entry.getValue()) } }
  • 26. Service Layer 배치뷰 업데이트에적합한 서비스 계층 DB ? ElephantDB (Clojure)► This is system created exactly for this case. It is very simple. 참조: http://www.slideshare.net/nathanmarz/elephantdb Voldemort(java) ► NoSQL, Pluggable Storage engines, Consistent hashing, Eventual consistency, Support for batch-computed read-only stores An open source clone of Amazon's Dynamo. 출처 : http://www.slideshare.net/DavidGroozman/challenge-26788828
  • 27. Speed Layer ● Batch Layer 속도 지연의 극복 ● 점진적인 접근 방식을 사용 ● 무작위 쓰기를 허용하는 전통적인 데이터베이스를 사용
  • 28. Speed Layer 동기적 접근 방법 비동기적 접근 방법
  • 30. STORM ● 스톰 시스템은 튜플의 스트림을 처리한다. ● 튜플은 스파우트에 의해서 생성되고 볼트에 의해서 처리된다.
  • 31. STORM 작업자들 ● 스파우트/볼트를 여러 노드에 분산시키는 이유는 장애 허용 때문 ● 클러스터에 있는 노드 중 하나에 장애 : 스톰 토폴로지는 튜플을 정상적으로 동작하는 노드에 보냄 → 튜플 “최소한 한 번" 처리 보장
  • 32. STORM을 이용해 기여 세기 ● 로그 읽기 스파우트 ● 로그 항목 해석 볼트 ● 데이터베이스 업데이트 볼트
  • 33. Spout public class RandomContributorSpout extends BaseRichSpout { // <label id="code.spout"/> private static final Random rand = new Random(); private static final DateTimeFormatter isoFormat = ISODateTimeFormat.dateTimeNoMillis(); private SpoutOutputCollector collector; private int contributionId = 10000; public void open(Map conf, TopologyContext context, // <label id="code.spoutopen"/> SpoutOutputCollector collector) { this.collector = collector; } public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.spoutdeclare"/> declarer.declare(new Fields("line")); } public void nextTuple() { // <label id="code.spoutnexttuple"/> Utils.sleep(rand.nextInt(100)); ++contributionId; String line = isoFormat.print(DateTime.now()) + " " + contributionId + " " + rand.nextInt(10000) + " " + "dummyusername";
  • 34. Parser Bolt class ContributionParser extends BaseBasicBolt { // <label id="code.bolt"/> public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.parserdeclare"/> declarer.declare(new Fields("timestamp", "id", "contributorId", "username")); } public void execute(Tuple tuple, BasicOutputCollector collector) { // <label id="code.parserexecute"/> Contribution contribution = new Contribution(tuple.getString(0)); collector.emit(new Values(contribution.timestamp, contribution.id, contribution.contributorId, contribution.username)); } }
  • 35. Record Bolt class ContributionRecord extends BaseBasicBolt { private static final HashMap<Integer, HashSet<Long>> timestamps = // <label id="code.recordertimestamps"/> new HashMap<Integer, HashSet<Long>>(); public void declareOutputFields(OutputFieldsDeclarer declarer) { // <label id="code.recorderdeclare"/> } public void execute(Tuple tuple, BasicOutputCollector collector) { // <label id="code.recorderexecute"/> addTimestamp(tuple.getInteger(2), tuple.getLong(0)); } private void addTimestamp(int contributorId, long timestamp) { // <label id="code.addtimestamp"/> HashSet<Long> contributorTimestamps = timestamps.get(contributorId); if (contributorTimestamps == null) { contributorTimestamps = new HashSet<Long>(); timestamps.put(contributorId, contributorTimestamps); } contributorTimestamps.add(timestamp); } }
  • 36. Topology public class WikiContributorsTopology { public static void main(String[] args) throws Exception { TopologyBuilder builder = new TopologyBuilder(); // <label id="code.topologybuilder"/> builder.setSpout("contribution_spout", new RandomContributorSpout(), 4); // <label id="code.setspout"/> builder.setBolt("contribution_parser", new ContributionParser(), 4). // <label id="code.shufflegrouping"/> shuffleGrouping("contribution_spout"); builder.setBolt("contribution_recorder", new ContributionRecord(), 4). // <label id="code.fieldsgrouping"/> fieldsGrouping("contribution_parser", new Fields("contributorId")); LocalCluster cluster = new LocalCluster(); Config conf = new Config(); cluster.submitTopology("wiki-contributors", conf, builder.createTopology()); // <label id="code.submittopology"/> Thread.sleep(10000); cluster.shutdown(); // <label id="code.clustershutdown"/> } }
  • 37. Stream Group 스톰의 스트림 그룹은 어느 작업자(Task)가 어느 튜플을 받는가라는 질문에 대한 대답을 제공한다. (http://storm.apache.org/releases/current/Concepts.html) Shuffle grouping 튜플이 볼트의 작업자(Task)에 랜덤하게 분산됨. Fields grouping 튜플이 가지는 특정 데이터 필드에 따라 작업자(Task)가 선택됨. 예를들어 만약 튜플이 contributorId로 그룹되어 진다면, 동일한 contributorId를 가지는 튜플들은 항상 동일한 작업자(Task)에 가게 됨. Global grouping 전체 튜플은 볼트의 작업자(Task)중 하나로만 가게됨. (가장 낮은 아이디의 작업자로 가게됨)
  • 38. Stream Group All grouping 하나의 튜플이 모든 볼트 작업자 들에 전달됨. (모든 볼트 작업자 들에 브로드캐스트 됨) Direct grouping 튜플의 생산자는 어떤 작업자가 이 튜플을 받을 것인지를 결정함.(1:1) Local or shuffle grouping Target 볼트가 동일한 작업자(Task) 프로세스에 하나 이상의 작업을 수행할 경우, 튜플 작업을 in-process 작업으로 처리함. 그렇지 않으면 일반적인 Shuffle grouping과 같이 동작 Partial Key grouping Fields grouping과 같이 튜플이 가지는 특정 데이터 필드에 따라 작업자가 선택되지만, 두개의 downstream 볼트 사이에 부하가 배분됨.
  • 39. 3일차 마무리 속도 계층은 최근 데이터에 대한 실시간 뷰를 제공 속도 계층의 스톰은 비동기적인 속도 계층을 만들 때 사용
  • 40. 마치며 ● 람다 아키텍처 - 여러 개념을 하나로 통합 ○ 원천 데이터 불변 : 클로저가 아이덴티티와 상태를 분리하는것을 연상 ○ Mapper/Reducer 병렬처리 : 병렬적 함수 프로그래밍과 유사 ○ 작업과정을 클러스터에 분산 : 액터 ○ 스톰 튜플의 스트림 : 액터와 CSP 메시지 전달 ● 장점/단점 ○ 람다 아키텍처는 거대한 양의 데이터를 다루기 위한 것/거대한 양의 데이터 - > 오버헤드 ● 대안 ○ 스파크는 DAG 실행 엔진을 구현하는 수많은 알고리즘(특히 그래프 알고리즘)이 맵리듀스와 비교해서 더 자연스럽게 표현되도록 만들어주는 클러스터 컴퓨팅 프레임워크 ■ 내부에 스트리밍 API : 배치 계층과 속도 계층이 모두 구현 가능