Aggregation - Mongo
Oldmethod
● Take LVM snapshot
● Upload snapshot to HDFS
○ Tar the data files, upload to HDFS.
● MongoDump to sequence files
○ downloads untar, start a mongod process
○ Scan all records, write out to bson sequence files in HDFS
○ One time conversion of bson → thrift sequence files
Luigi is aPython package that helps building complex
pipelines and handling all the plumbing typically
associated with long-running batch jobs.
It handles:
● dependency resolution
● workflow management
● visualization
● failures handling
● command line integration
● and much more...
Luigi
• MapReduce
• Map/ Reduce 모델이 모든 데이터 처리에 좋지는 않음
• Join 구현이 매우 복잡함
• Cascading
• MapReduce 대신 data flow를 구현하게 해주는 Java wrapper
• Data flow를 구현하면 계산 엔진이 작업을 MapReduce로 변환
• Java 특유의 verbosity 문제
• Scalding
• Scala로 구현한 Cascading
• 함수형 프로그래밍으로 데이터 처리를 구현
• 코드가 간결하고 유지보수가 쉬움
Scalding
• Data flowframeworks allow data
processing jobs to be expressed as a
series of operations on streams of data.
• Pros
• Composable - Share series of
operations between jobs.
• Simplifies - Complex joins are
much easier to write.
• Brevity - Faster iteration
• Functional programming style
is great for writing data flows.
• Cons
○ Adds complexity.
○ Debugging may require looking
behind the framework's
"magic."
○ Impacts performance
■ Time
■ Memory pressure
Scalding
46.
Example: Word Count
importjava.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCount {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
Scalding
public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
47.
Example: Word Count
SchemesourceScheme = new TextLine( new Fields( "line" ) );
Tap source = new Hfs( sourceScheme, inputPath );
Scheme sinkScheme = new TextLine( new Fields( "word", "count" ) );
Tap sink = new Hfs( sinkScheme, outputPath, SinkMode.REPLACE );
Pipe assembly = new Pipe( "wordcount" );
String regex = "(?<!pL)(?=pL)[^ ]*(?<=pL)(?!pL)";
Function function = new RegexGenerator( new Fields( "word" ), regex );
assembly = new Each( assembly, new Fields( "line" ), function );
assembly = new GroupBy( assembly, new Fields( "word" ) );
Aggregator count = new Count( new Fields( "count" ) );
assembly = new Every( assembly, count );
Properties properties = new Properties();
FlowConnector.setApplicationJarClass( properties, Main.class );
FlowConnector flowConnector = new FlowConnector( properties );
Flow flow = flowConnector.connect( "word-count", source, sink, assembly );
flow.complete();
Scalding
HFile
● 불변 K/V저장 방식
● Thrift를 이용해 typing
● 파일 작성시 정렬이 되어있기 때문에 빠른 Seek
● Sharding으로 한 dataset에서 높은 QPS 지원
● Foursquare에서 자체제작한 파일서버로 손쉽게
관리
● MapReduce나 Scalding Job의 output으로 생성
Redshift
● Relational DBfrom AWS
● Hadoop을 거치지 않고 질의 가능
● Columnar DB라는 구조로 최적화에 신경쓰면 꽤
좋은 성능을 얻을 수 있음
● 주로 실험 결과 분석과 대시보드 계산에 사용
● HDFS <-> Redshift 데이터 이동 필요
70.
Presto
● Open sourceSQL engine from Facebook
● Hadoop을 거치지 않고 질의 가능
● In-memory computation
● Really, Really, Really fast
● Hive connector를 사용해 Foursquare HDFS에 있는
thrift를 그대로 사용 가능
72.
Presto
● Dedicated prestoboxes
○ $$$, 질의가 없을 시 장비의 낭비
● Co-location on Hadoop boxes
○ 배포가 까다롭고 올바른 배포 과정을 찾을 때
까지의 iteration이 지나치게 힘듦
○ Netflix, Facebook에서 사용하는 방식
● Yarn
○ Hadoop이 해야 하는 작업과 리소스 경쟁
73.
Presto
● Presto-Yarn
○ ApacheSlider를 통해 Yarn이 presto를 배포하고
관리하게 하는 OSS
○ 올바른 설정을 찾기 까지 힘들지만 (직접
배포하는것보다는 훨씬 쉬움) 설정 이후
배포/관리가 굉장히 쉬움
Presto
From our experience:
●“Larger”, fewer boxes > “smaller” many boxes
● Each worker needs more than 1 vcores
● Container memory <-> JVM memory <-> Presto
memory
● Yarn labels can help debug
Backup
● HDFS spaceisn’t free
○ 매일 HDFS <-> S3 백업
○ 일정 기간이 지나면 HDFS에서 삭제
● S3 also isn’t free
○ 일정 기간이 지나면 Glacier로 변환
○ Glacier Pricing: $0.007 per GB / month
79.
Retention
● HFile, Hivetables have retention policy
○ Collection 자체가 늘어나지 않으면 HDFS 용량
역시 일정 한도 내에서 머물 수 있음
● Retention때문에 필요한 데이터가 지워졌다?
○ Job을 다시 돌리면 다시 얻을 수 있음
80.
Compression
● 기본 압축방식: Snappy
○ Fast read, low compression
● HDFS에는 있어야 하지만 시간이 지나 많이
사용되지 않는 데이터: Gzip
○ Slow read, high compression
● 로그 백업
○ Snappy -> Gzip, Gzip to S3, replace Snappy
with Gzip after n days
Hardware Stats
Useful stats(Hadoop):
● Hadoop
○ CPU usage / role, rack
○ Network stats (HDFS <-> AWS)
● Kafka
○ Bytes In/Bytes Out
○ Producer requests/s, Consumer fetch/s
○ GC time
○ SSD read/write time
87.
Hadoop Stats
Cloudera Manager
●HDFS alerts
○ HDFS Bytes/Blocks read/written
○ RPC Connections
● YARN alerts
○ RM health
○ Jobs that run too long
○ Failing tasks
Inviso
● 기본적으로 Inviso는ES 1.0+을 지원
● ES 2+로 포팅할 경우 Kibana 사용가능
○ . 를 모두 _로 변환
○ Timestamp handling
○ Inviso-imported stats != all available stats
○ 원하는 stat은 추가, 필요 없는 stat은 제거
■ CPU time
■ Pool-based resource usage
Wrapping Up
● Engineeringbased on philosophy
● Solve problems
○ It would be better if we solved problems before
they became problems
● Always be monitoring
○ Monitoring isn’t really fun
○ So make it easier/more fun to monitor!