메뉴 건너뛰기

Bigdata, Semantic IoT, Hadoop, NoSQL

Bigdata, Hadoop ecosystem, Semantic IoT등의 프로젝트를 진행중에 습득한 내용을 정리하는 곳입니다.
필요한 분을 위해서 공개하고 있습니다. 문의사항은 gooper@gooper.com로 메일을 보내주세요.


1. data준비

(각 File1, File2는 hdfs상에 존재해야한다,

 즉, hadoop fs -put UserDetails.txt  DeliveryDetails.txt /data1/hadoop/mr/in을 실행한다)

File 1 – UserDetails.txt(mobile#, 사용자이름)
123 456, Jim
456 123, Tom
789 123, Harry
789 456, Richa
 
File 2 – DeliveryDetails.txt(mobile#, 상태코드)
123 456, 001
456 123, 002
789 123, 003
789 456, 004
 
File 3 – DeliveryStatusCodes.txt(상태코드, 상태코드명)
001, Delivered
002, Pending
003, Failed
004, Resend
 
* File3은 os 파일시스템에 존재해야한다.
(예, /home/hadoop/hadoop/working/DeliveryStatusCodes.txt)
2. 예상되는 최종 결과 포맷
Jim, Delivered
Tom, Pending
Harry, Failed
Richa, Resend
 
3. UserFileMapper.java
package com.gooper.join;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
public class UserFileMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {
 private String cellNumber, customerName, fileTag="CD~";
 public void map(LongWritable key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
  String line = value.toString();
  
  String splitarray[] = line.split(",");
  cellNumber = splitarray[0].trim();
  customerName = splitarray[1].trim();
  // reducer에서의 구분을 위해서 value값 앞에 "CD~"를 붙여준다.
  output.collect(new Text(cellNumber),  new Text(fileTag+customerName));
  }
 }
 
4. DeliverFileMapper.java
package com.gooper.join;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
public class DeliverFileMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> {
private String cellNumber, deliveryCode, fileTag="DR~";
public void map(LongWritable key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
 String line = value.toString();

 String splitarray[] = line.split(",");
 cellNumber = splitarray[0].trim();
 deliveryCode = splitarray[1].trim();
 // reducer에서의 구분을 위해서 value값 앞에 "DR~"를 붙여준다.
 output.collect(new Text(cellNumber),  new Text(fileTag+deliveryCode));
 }
}
 
5. SmsDriver.java
package com.gooper.join;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
public class SmsReducer extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
 private String customerName, deliveryReport;
 private static Map<String,String> DeliveryCodesMap = new HashMap<String,String>();
 
 public void configure(JobConf job) {
  loadDeliveryStatusCodes();
 }
 
 public void reduce(Text key, Iterator<Text> values, OutputCollector<Text,Text> output, Reporter reporter) throws IOException {
  while(values.hasNext()) {
   String currValue = values.next().toString();
   String valueSplitted[] = currValue.split("~");
   String keyValue = key.toString();
   
   System.out.println("키값 , 라인값 : "+keyValue+","+currValue);
   //System.out.println("reporter값 : "+reporter.toString());
   
   // CD로 시작되면 고객명을 그대로 사용하고..
   if(valueSplitted[0].equals("CD")) {
    customerName = valueSplitted[1].trim();
   // DR로 시작되면 code값이므로 code에 대한 값을 찾아서 그 명칭을 출력한다.
   } else if(valueSplitted[0].equals("DR")) {
    deliveryReport = DeliveryCodesMap.get(valueSplitted[1].trim());
   }
  }
  if(customerName != null && deliveryReport != null) {
   output.collect(new Text(customerName+"("+key+")"), new Text(deliveryReport));
  } else if(deliveryReport == null) { // codeㅇ mapping되는 값이 없으면 "deliveryReport"라는 문자열 자체를 출력한다.   
   output.collect(new Text(customerName+"("+key+")"),  new Text("deliveryReport"));
  }
 }
 
 private void loadDeliveryStatusCodes() {
  String strRead;
  try {
                       
    //BufferedReader reader = new BufferedReader(new FileReader("/data1/hadoop/mr/in/DeliveryStatusCodes.txt"));
       // 여기는 로컬 os파일 위치를 지정해야 함..
    BufferedReader reader = new BufferedReader(new FileReader("/home/hadoop/hadoop/working/DeliveryStatusCodes.txt"));
    
    while((strRead = reader.readLine() ) != null) {
     String splitarray[] = strRead.split(",");
     DeliveryCodesMap.put(splitarray[0].trim(), splitarray[1].trim()) ;
     
    }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch(IOException e) {
   e.printStackTrace();
  }
 }
}

6. 설명
가. SmsDriver.java에서
MultipleInputs.addInputPath(conf, new Path(args[0]), TextInputFormat.class, UserFileMapper.class);
MultipleInputs.addInputPath(conf, new Path(args[1]), TextInputFormat.class, DeliverFileMapper.class);
을 이용하여 각각의 파일을 읽어 들인다.
이때 읽어들이는 처리는 UserFileMapper와 DeliverFileMapper가 각각 맡는다
이때 join key는 mobile phone no가 된다.
 
나. 두개의 input파일을 reduce에게 보내면 reducer에서는 key를 기준으로 value가 각각의 값을 가지고 있으므로
code값인 경우는 HashMap에 저장된 code정보를 mapping하여 code에 대한 명칭을 output하게 만든다.
최종적으로는 이름과 상태값을 가지는 결과 파일이 만들어진다.
 
다. Reducer에슨 각각의 구분이 필요하므로 Mapper에서 각각의 값에 "CD~" 혹은 "DR~"을 붙여 구분할 수 있도록 선처리를 한다
 
라. 파일을 build하고 jar로 만들고 다음과 같이 실행한다.
hadoop@bigdata-host:~/hadoop/working$ hadoop jar gooper-hadoopexamples.jar com.gooper.join.SmsDriver /data1/hadoop/mr/in/UserDetails.txt /data1/hadoop/mr/in/DeliveryDetails.txt /data1/hadoop/mr/out/join/d
마. 실행 결과 확인
hadoop@bigdata-host:~/hadoop/working$ hadoop fs -cat /data1/hadoop/mr/out/join/d/part-00000
Jim(123 456) Delivered
Tom(456 123) Pending
Harry(789 123) Failed
Richa(789 456) Resend
 
바. reducer에 인입되는 key와 value를 확인하면 아래와 같다.
키값 , 라인값 : 123 456,CD~Jim
키값 , 라인값 : 123 456,DR~001
키값 , 라인값 : 456 123,DR~002
키값 , 라인값 : 456 123,CD~Tom
키값 , 라인값 : 789 123,CD~Harry
키값 , 라인값 : 789 123,DR~003
키값 , 라인값 : 789 456,DR~004
키값 , 라인값 : 789 456,CD~Richa

번호 제목 글쓴이 날짜 조회 수
140 python 2.6.6에서 print 'A=' 형태의 사용이 python 3.5.1에서 오류(SyntaxError: Missing parentheses in call to 'print') 발생함.. 총관리자 2016.05.27 62
139 [TLS/SSL]Kudu Master 설정하기 총관리자 2022.05.13 61
138 [TLS]TLS용 사설 인증서 변경 혹은 신규 지정시 No trusted certificate found 오류 발생시 확인및 조치사항 총관리자 2022.03.15 60
137 lagom-windows용 build.sbt파일 내용 총관리자 2017.10.12 60
136 Mysql DB 생성 및 권한. 특정아이피, 대역에 대한 접근 허용 총관리자 2017.05.04 60
135 Master rejected startup because clock is out of sync 오류 해결방법 총관리자 2016.05.03 60
134 queryTranslator실행시 NullPointerException가 발생전에 java.lang.ArrayIndexOutOfBoundsException발생시 조치사항 총관리자 2016.06.16 58
133 Lagom프레임웍에서 제공하는 HelloWorld 테스트를 수행시 [unknown-version]오류가 발생하면서 빌드가 되지 않는 경우 조치사항 총관리자 2017.12.22 56
132 9대가 hbase cluster로 구성된 서버에서 테스트 data를 halyard에 적재하고 테스트 하는 방법및 절차 총관리자 2017.07.21 56
131 [hive] hive.tbls테이블의 owner컬럼값은 hadoop.security.auth_to_local에 의해서 filtering된다. 총관리자 2022.04.14 55
130 HDFS에서 quota 설정 방법및 확인 방법 총관리자 2022.03.30 55
129 [Impala jdbc]CDP7.1.7환경에서 java프로그램을 이용하여 kerberized impala cluster에 접근하여 SQL을 수행하는 방법 gooper 2023.08.22 54
128 fuseki가 제공하는 web ui를 통해서 dataset를 remove->create할 경우 동일한 동일한 이름으로 지정했을때 fuseki-server.jar가 뜨지 않는 현상 총관리자 2017.02.03 54
127 Windows에서 sbt개발환경 구축 방법(링크) 총관리자 2016.06.02 54
126 서버 5대에 solr 5.5.0 설치하고 index data를 HDFS에 저장/search하도록 설치/설정하는 방법 총관리자 2016.04.08 54
125 DataSetCreator.py 실행시 파일을 찾을 수 없는 오류 총관리자 2016.05.27 53
124 [HDFS]Encryption Zone에 생성된 테이블 조회시 Failed to open HDFS file hdfs://nameservice1/tmp/zone1/sec_test_file.txt Error(255): Unknown error 255 Root cause: AuthorizationException: User:impala not allowd to do 'DECRYPT_EEK' on 'testkey' gooper 2023.06.29 52
123 jar파일의 dependency찾는 프로그램 총관리자 2016.08.11 52
122 RDF4J의 rdf4j-server.war가 제공하는 RESTFul API를 이용하여 repository에 CRUD테스트 총관리자 2017.08.30 51
121 hadoop에서 yarn jar ..를 이용하여 appliction을 실행하여 정상적으로 수행되었으나 yarn UI의 어플리케이션 목록에 나타나지 않는 문제 총관리자 2017.05.02 51

A personal place to organize information learned during the development of such Hadoop, Hive, Hbase, Semantic IoT, etc.
We are open to the required minutes. Please send inquiries to gooper@gooper.com.

위로