Hadoop 애플리케이션 테스트하기 클라우다인대표김병곤 fharenheit@gmail.com
2 주제 Hadoop 의기본 MapReduce 의특징과테스트의어려운점 MRUnit 을이용한단위테스트기법 통합테스트를위한 Mini Cluster 성능테스트
3 V Model Requirement Acceptance Test Analysis System Test Design Integration Test Code Unit Test
테스트의중요성 4
5 파일시스템 : HDFS Yahoo Hadoop Tutorial
6 프로그래밍모델 : MapReduce HDFS 의파일을처리하기위한프로그래밍모델 Oreilly Hadoop Definitive Guide
7 WordCount Hadoop 의 MapReduce Framework 동작을이해하는핵심예제 각각의 ROW 에하나의 Word 가있을때 Word 의개수를알아내는예제 입력파일 (Mapper 의 Input) hadoop apache page hive hbase cluster hadoop page cloud copywrite 출력파일 (Reduce Output) apache 1 cloud 1 cluster 1 copywrite 1 hadoop 2 hbase 1 hive 1 page 2
WordCount 8
MapReduce 가가지는특징 Map 과 Reduce 가네트워크를경계로동작한다. Map 의 Output Key 를중심으로 Reduce 에서데이터를취합한다. Map, Reduce, Combiner, Partitioner, Input Format, Output Format, Multiple Output, Comparator 등등다양한구성요소가동작에영향을준다. 파일을직접다룬다. 분산환경에서동작한다. 대용량파일을다루므로처리하는데시간이오래걸린다. 9
MapReduce 의개발시주의할점 로그파일이크므로처리하는데오랜시간이소요되므로시간을단축시키는것은매우큰비용이절감됨 현장에서발생하는로그는훨씬더다양한케이스가존재하므로사전에충분한검증이이루어지지않으면추후급격한비용이발생 ( 일반개발은저리가라!!) 개발기간보다테스트기간이더길수있다. 데이터를이해하는눈썰미가꽤장점으로작용한다. 10
단위테스트 개발자가개발시진행해야하는단위로직에대한테스트 White Box 테스트 단위테스트의주요특징 단순 격리 자동화 커버리지 11
단위테스트 :: MRUnit Hadoop 의내장 Object 를 Mock Object 로구현한단위테스트프레임워크 Cloudera 가개발해서 Apache 에기증 최근 Top Level Project 로승격 문서없음. 기대하지마시길 직접빌드해서사용하세요. 매우친절하지않습니다. 12
MRUnit 이없다면 Hadoop Cluster 에 MR Job 실행하면서고생하게됩니다. Pseudo Mode 에서뭐좀해보려고하겠죠 생산성이도저히나오지않을거고, 메모리도부족할겁니다. 결과파일과입력파일을검증하는데고생좀할겁니다. 13
MRUnit 은어디서구하나요? 14
MRUnit 은어디서구하나요? 지금까지봤던 Apache Top Level Project 에서가장소스코드가없습니다. Map, Reduce, MapReduce 를별도로테스트할수있는 Driver 가제공됩니다. MRUnit 은 Map, Reduce 테스트그자체만집중합니다. 15
MRUnit 초기화 // Map, Reduce, MapReduce 테스트범위에따라서 Driver 를다르게생성합니다. public class GroupByMapReduceTest { private Mapper mapper; private Reducer reducer; private MapReduceDriver driver; } @Before public void setup() { mapper = new GroupByMapper(); reducer = new GroupByReducer(); driver = new MapReduceDriver(mapper, reducer); // Map & Reduce }... 16
MRUnit 테스트케이스작성 public class GroupByMapReduceTest {... @Test public void groupby() { Configuration conf = new Configuration(); conf.set("inputdelimiter", ","); conf.set("keyvaluedelimiter", ","); conf.set("valuedelimiter", ","); conf.set("allowduplicate", "false"); conf.set("allowsort", "false"); conf.set("groupbykey", "0"); driver.setconfiguration(conf); } } driver.withinput(new LongWritable(1), new Text(" 홍길동,a,b")); driver.withinput(new LongWritable(2), new Text(" 홍길동,b")); driver.withoutput(nullwritable.get(), new Text(" 홍길동,a,b")); driver.runtest(); 17
MRUnit 테스트케이스작성 public class GroupByMapReduceTest {... @Test public void groupby() { Configuration conf = new Configuration(); conf.set("inputdelimiter", ","); conf.set("keyvaluedelimiter", ","); conf.set("valuedelimiter", ","); conf.set("allowduplicate", "false"); conf.set("allowsort", "false"); conf.set("groupbykey", "0"); driver.setconfiguration(conf); } } driver.withinput(new LongWritable(1), new Text(" 홍길동,a,b")); driver.withinput(new LongWritable(2), new Text(" 홍길동,b")); driver.withoutput(nullwritable.get(), new Text(" 홍길동,a,b")); driver.runtest(); 18
MRUnit 의테스트케이스위치 19
MRUnit 의테스트케이스실행 20
Emma Code Coverage 설치 21
Code Coverage (1) 22
Code Coverage (2) 23
시간의흐름에따른단위테스트문제 처리해야할대상날짜 MapReduce Job 이실행하는날짜 D+0 D+1 D+2 D+3 D+4 날짜 : 20121103 단위데이터 OUTPUT /vdi/logical/2012/11/02 OUTPUT INPUT /incomplete/2012/11/02 /log/2012/11/02 24
시간의흐름에따른단위테스트문제 처리해야할대상날짜 MapReduce Job 이실행하는날짜 D+0 D+1 D+2 D+3 D+4 날짜 : 20121104 단위데이터 OUTPUT /logical/2012/11/03 OUTPUT /physical/2012/11/03 INPUT /incomplete/2012/11/02 INPUT /log/2012/11/03 25
시간의흐름에따른단위테스트문제 날짜를입력받을수있도록조정하고현재날짜의기준을입력받은파라미터로처리 Configuration conf = new Configuration(); conf.set("currentdate", "20121102"); driver.setconfiguration(conf); // 입력파일을로딩한다. load(driver, "/20121102_complete.csv"); // MapReduce 를실행한다. List<Pair<NullWritable, UserPreference>> ran = driver.run(); DrivingInformation first = ran.get(0).getsecond(); DrivingInformation last = ran.get(ran.size() - 1).getSecond(); Assert.assertEquals("2012110211204500", first.curtime); Assert.assertEquals("2012110211210000", last.curtime); Assert.assertEquals(16, ran.size()); 26
통합테스트 MRUnit 이 Mapper 와 Reducer 를함께테스트는할수있지만 MapReduce Job 자체를테스트하지는않음 그렇다고 Hadoop Cluster 에직접테스트하는것은너무앞서가는것 Mini Cluster 를사용하자 MapReduce를시뮬레이션하는 MiniMRCluster HDFS를시뮬레이션하는 MiniDFSCluster 27
성능테스트 MapReduce 의성능시험은 MapReduce Job 의수행시간을대략적으로예상해볼수있다. 주요모니터링항목 Disk I/O 성능 CPU 점유율 Network Bandwidth MapReduce Job의수행시간 MapReduce Job의에러건수 MapReduce Job의 Task 개수에따른수행시간 벤치마킹도구 : MR Bench, TeraSort, TeraGen, DFSIO 28
Ganglia 모니터링 29
Task 개수와 JVM Heap Size 파일명구분키값 core-site.xml fs.default.name fs.checkpoint.dir hadoop.tmp.dir io.compression.codecs hdfs://192.168.0.100:9000 /data/secondary /tmp/hadoop-${user.name} org.apache.hadoop.io.compress.gzipcodec, org.apache.hadoop.io.compress.defaultcodec, org.apache.hadoop.io.compress.bzip2codec, org.apache.hadoop.io.compress.snappycodec hdfs-site.xml mapred-site.xml dfs.name.dir /data/name dfs.name.dir /data1/data,/data2/data, dfs.http.address 192.168.0.100:50070 dfs.secondary.http.address 192.168.0.101:50090 dfs.block.size 134217728 mapred.local.dir /data/mred/local mapred.system.dir /hadoop/mapred/system mapred.tasktracker.map.tasks.maximum 8 mapred.tasktracker.reduce.tasks.maximum 4 mapred.child.java.opts -Xmx1024M mapred.job.tracker 192.168.0.100:9001 mapred.map.tasks 24 mapred.reduce.tasks 12 30
워크로드패턴식별 실제데이터가없다면벤치마킹할 MapReduce Job 과유사한벤치마킹테스트로시뮬레이션해본다. 31
CPU 리소스모니터링 32
DFSIO # hadoop jar hadoop-mapreduce-*tests.jar TestDFSIO \ -write \ -nrfiles 1000 \ -filesize 500... Total MBytes processed: 50000.0 Throughput mb/sec: 4.280953865016388 Average IO rate mb/sec: 6.916503429412842 IO rate std deviation: 6.55725357815042 Test exec time sec: 1050.286 33
JBoss Community (http://www.jboss.org) Korea JBoss User Group (http://cafe.naver.com/jbossug) 34