2014년 9월 30일 화요일

HDFS 살펴보기 2

  • Java Generic : C++ Template

   WordCount 부분에서  메소드를 지정하는데 Treemap<String, Interger> data 부분
   자세한 내용은 링크를 참조.
   C++ Template Library를 다시 보자.

   ※ 참조 :
1. http://alecture.blogspot.kr/2011/06/generics.html
2. http://arabiannight.tistory.com/entry/%EC%9E%90%EB%B0%94Java-ArrayListT-%EC%A0%9C%EB%84%A4%EB%A6%AD%EC%8A%A4Generics%EB%9E%80

  • Hadoop Map&Reduce


  1. blocking code(Synchronous) :

  코드가 수행되다가 외부 결과 값이 잘못되면 관련된 모든 코드가 실행불가.
  ex) job.waitForCompletion(true);

  2. Non-blocking code :

  결과값이 제대로 출력되었는지 지속적으로 호출한다.
  쓸데없는 호출이 계속되는 문제점이 여전히 존재한다.

  3. 비동기(Asynchronous) :

  결과값이 제대로 출력되면 그때 값을 리턴해준다.
  중간 제어를 다른 것들에게 위임하여 행동한다.
1. Message (Windows)
2. Signal (Unix)
3. Interrupt (H/W)
  but > 우리가 지금까지 짠 코드는 blocking code인데...?

  대용량의 파일들을 빌드해보자.

  • Make(C/C++)
  • ANT(Java)
  • Maven(Java) - dependency

  • WordCount.java 내부 코드 보기

  ===============================================================
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.*;
import org.apache.hadoop.mapreduce.lib.output.*; 
public class WordCount {

public static class MyMapper extends
Mapper<LongWritable, Text, Text, LongWritable> {
private final static LongWritable one = new LongWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line,
"\t\r\n\f |,.()<>");
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken().toLowerCase());
context.write(word, one);
}
}
}
/* Mapper :  파일 내부에 있는 단어들을 카운트한다. */
public static class MyReducer extends
Reducer<Text, LongWritable, Text, LongWritable> {
private LongWritable sumWritable = new LongWritable();
public void reduce(Text key, Iterable<LongWritable> values,
Context context) throws IOException, InterruptedException {
long sum = 0;
for (LongWritable val : values) {
sum += val.get();
}
sumWritable.set(sum);
context.write(key, sumWritable);
}
}
/* Reducer : Mapper에서 카운트한 단어들을 모아서 합산한다. */
/* Reducer는 Text key 값으로 같은 텍스트에 대해서 합산한다. */ 
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf, "WordCount");
job.setJarByClass(WordCount.class);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);

job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
}
}
  ===============================================================

추가해야 될 내용


  • StringTokenizer tokenizer = new StringTokenizer(line,"\t\r\n\f |,.()<>");

  > 'Hello'와 'Hello!'가 다른 단어가 된다.
  > token을 추가


  • 한글 '조사' 처리 문제

  > '부스러기가' 와 '부스러기와'는 서로 다른 단어가 된다.
  > 형태소 분석기가 필요



  • Mapper Class


  ※참조 : p. 112 ~136, p.  143

2014년 9월 29일 월요일

HDFS 살펴보기 1


  • WordCount 실습해보기



1. conf/core-site.xml을 수정한다.
  ===============================================================
   <configuration>
   <property>
   <name>hadoop.tmp.dir</name>
   <value>[경로 설정]</value>
   #경로 설정 부분은 접근 설정이 가능한 권한을 부여해줘야 한다.
   </property>
   <property>
   <name>fs.default.name</name>
   <value>hdfs://localhost:9000</value>
   </property>
   </configuration>
  ===============================================================

2. Hadoop에서 예제로 사용할 파일을 복사한다.
> cd $HADOOP_HOME HADOOP_HOME으로 이동한다
> hadoop fs -mkdir /input input 폴더를 생성한다
> hadoop fs -copyFromLocal README.txt /input HADOOP_HOME 내부에 README.txt파일을 input폴더 내부로 복사한다
> hadoop fs -ls /input input폴더 내부를 확인해본다


3. 복사한 파일의 word를 count한다.
> hadoop jar hadoop-example-1.0.3.jar wordcount /input/README.txt /output hadoop-example-1.0.3.jar에 있는 wordcount를 이용하여 /input/README.txt파일을 카운트한다.
그리고 /output폴더에 결과를 출력해준다.
> hadoop fs -cat /output/part-r-00000|more 출력된 결과를 확인해본다.


  • Error 내용 정리

   : 직접 경험한 에러 내용만 정리

  • NameNode 생성이 되지 않음 : core-site.xml 파일을 확인한다.
  • NullPointException Error
- hadoop 임시 폴더로 지정한 폴더 삭제, namenode 포맷 후 다시 진행한다. 

  • JAVA_HOME is not set
- conf/hadoop-env.sh 파일 내용 수정
> sudo nano hadooop-env.sh
 ================================================================
  (생략)
  #현재 설치된 자바의 홈을 지정해준다.
  export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
  (생략)
 ================================================================


  • Hadoop 명령어 간단 정리

FORM> hadoop fs -[command]

  [정보/출력]
   ls : 현재 디렉토리 정보를 나열한다.
   lsr : 현재 디렉토리 목록과 하위디렉토리 정보를 나열한다.
   du : 디렉토리나 파일의 사용량을 확인하는 명령 바이트 단위로 결과 출력한다.
   dus : 디렉토리 전체의 합계용량을 출력한다.
   cat : 테스트파일의 내용을 표시한다.
   text : 테스트파일뿐 아니라 zip파일 형태의 내용도 표시한다.
   tail : 파일의 마지막 1kb의 내용을 화면에 출력한다.(로그파일의 마지막라인 확인)
   count : 지정경로에 대한 파일갯수 디렉토리갯수 전체파일사이즈를 출력한다.
            -q옵션을 사용할 경우 디렉토리의 파일 용량제한 정보를 조회할 수 있습니다.

  [생성]
   mkdir : 디렉토리를 생성한다.
   touchz : 0바이트 파일을 생성합니다.

  [삭제]
   rm : hdfs 디렉토리나 파일을 삭제한다.
        디렉토리는 반드시 비어있는 경우만 삭제할 수 있다.
   rmr : 비어있지 않은 디렉토리는 rmr로 삭제할 수 있다.

  [이동/복사]
   mv : hdfs의 파일이나 디렉토리를 이동 합니다.
   cp : hdfs간에 소스디렉토리 및 파일을 목적지로 복사한다.

   (목적지 디렉토리가 없을 경우엔 디렉토리를 생성)
   put : 로컬의 파일 및 디렉토리를 목적지 경로로 복사한다.      
   get : hdfs의 파일 및 디렉토리를 로컬의 목적지로 복사한다.

  [변경]
   (-R옵션을 주면 해당 디렉토리에 포함된 파일이나 디렉토리까지 변경)
   chmod : 지정한 파일이나 디렉토리에 대해 권한을 변경합니다.            
   chown : 지정한 파일이나 디렉토리의 소유권을 변경합니다.
           


  • WordCount for Java


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class WordCount {
public static void main(String[] args) {
TreeMap<String, Integer> data = new TreeMap<String, Integer>();
Mread(data);
MprintCNT(data);
}
public static int MCount(String word, TreeMap<String, Integer> data) {
if (data.containsKey(word)) {
return data.get(word);
} else {
return 0;
}
}
public static void MprintCNT(TreeMap<String, Integer> data) {
for (String word : data.keySet()) {
System.out.println("단어(" + word + ") : 카운트 숫자(" + data.get(word)
+ ")");
}
}
public static void Mread(TreeMap<String, Integer> data) {
Scanner sc = null;
String word = null;
int count = 0;
String path = null;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
try {
System.out.print("읽고 싶은 파일의 경로를 입력하세요 : ");
path = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
sc = new Scanner(new FileReader(path));
while (sc.hasNext()) {
word = sc.next();
count = MCount(word, data) + 1;
data.put(word, count);
}
} catch (FileNotFoundException e) {
System.err.println(e);
return;
} finally {
sc.close();
}
}
}

2014년 9월 28일 일요일

Servlet : MySQL과 연동하기


  • 시작하기


  1. OS platform : Windows7 Ultimate K
  2. Develop Tool : Eclipse Luna Java EE IDE, Apache Tomcat 8.0, MySQL Server 5.6
  3. 구상 : 서블릿으로 MySQL과 연동하여 CRUD 기능을 구현한다. 

  • MySQL Table 만들기

   1. DB 생성

   > CREATE DATABASE [DB_name]

   2. Table 생성

   > CREATE TABLE [Table_name] 
   > (ID INT NOT NULL AUTO_INCREMENT,
   > name varchar(40),
   > age varchar(40),
   > tel varchar(40),
   > gender varchar(40),
   > addr varchar(40),
   > PRIMARY KEY (ID));

   3. 확인하기



  • Java Code

  ▶ Research 기능 추가 : Servlet.GenericServlet을 상속받아서 사용한다.
  ▶ Create 기능 추가 : Servlet.http.HttpServlet을 상속받아서 사용한다.
  ▶ Update, Delete 기능 추가
  ▶ 내부 xml 파일 수정
  

 ================================================================

  package mobile.mysql;

  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.annotation.WebServlet;
  @WebServlet("/mobile.mysql/HomeMobile")
  public class HomeMobile extends GenericServlet {

private static final long serialVersionUID = 1911651036498342431L;
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("<html><head><title>MySQL 테이블 관리</title></head>");
out.print("<body>");
out.print("<div data-role=\"page\" id=\"pageone\">");
out.print("<div data-role=\"main\" class=\"ui-content\">");
out.print("<ul data-role=\"listview\" data-inset=\"true\">");
out.print("<li data-role=\"divider\">MySQL Manager</li>");
out.print("<li><a href=\"ResearchMobile\">테이블 보기</a></li>");
out.print("<li><a href=\"CreateMobile\">테이블 생성</a></li>");
out.print("</ul></div></div></body></html>");
}
  }

 ================================================================



 ================================================================
  package mobile.mysql;

  import java.io.*;

  import javax.servlet.*;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.*;

  import java.sql.*;
  @WebServlet("/mobile.mysql/CreateMobile")
  public class CreateMobile extends HttpServlet{
private String name;
private String age;
private String tel;
private String gender;
private String addr;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public String getAddr() {
return addr;
}

public void setAddr(String addr) {
this.addr = addr;
}

protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws
  ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<body><h1>등록하기</h1>");
out.println("<form action='CreateMobile' method='post'>");
out.println("이름: <input type='text' name='Pname'><br>");
out.println("나이: <input type='text' name='Page'><br>");
out.println("전화번호: <input type='text' name='Ptel'><br>");
out.println("성별: <input type='text' name='Pgender'><br>");
out.println("주소: <input type='text' name='Paddr'><br>");
out.println("<input type='submit' value='추가'>");
out.println("<input type='reset' value='초기화'>");
out.println("<input type='reset' value='초기화'>");
out.println("</form>");
out.println("</body></html>");
}

protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws
  ServletException, IOException {
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
Connection con = null;
PreparedStatement ps = null;
try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
con = DriverManager.getConnection(sc.getInitParameter("url"),
  "ID", "PASSWORD");
ps = con.prepareStatement("INSERT INTO introduce(name, age,
  tel, gender, addr) values(?, ?, ?, ?, ?)");

ps.setString(1, request.getParameter("Pname"));
ps.setString(2, request.getParameter("Page"));
ps.setString(3, request.getParameter("Ptel"));
ps.setString(4, request.getParameter("Pgender"));
ps.setString(5, request.getParameter("Paddr"));

con.setAutoCommit(false);
ps.executeUpdate();
con.commit();
out.print("OK");
response.sendRedirect("ResearchMobile");

} catch (Exception exc) {
out.println("WTF");
try {
con.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
exc.printStackTrace();
}finally{
try {
con.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

  }

 ================================================================



 ================================================================

  package mobile.mysql;

  import java.io.*;
  import java.sql.*;

  import javax.servlet.*;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.*;
  @WebServlet("/mobile.mysql/DeleteMobile")
  public class DeleteMobile extends HttpServlet {
private static final long serialVersionUID = 6725810624664408130L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html; charset=UTF-8");
Connection con = null;
PreparedStatement ps = null;
String sql = "DELETE FROM introduce WHERE ID=?";
try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
con = DriverManager.getConnection(sc.getInitParameter("url"),
"ID", "PASSWORD");
ps = con.prepareStatement(sql);
ps.setInt(1, Integer.parseInt(request.getParameter("ID")));
ps.executeUpdate();
response.sendRedirect("ResearchMobile");

} catch (Exception e) {
throw new ServletException(e);

} finally {

}

}
  }
 ================================================================



 ================================================================

  package mobile.mysql;
  import java.io.*;
  import java.sql.*;
  import javax.servlet.*;
  import javax.servlet.annotation.WebServlet;

  @WebServlet("/mobile.mysql/ResearchMobile")
  public class ResearchMobile extends GenericServlet {
/**
*
*/
private static final long serialVersionUID = -5190955829720826944L;

public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
PrintWriter out = response.getWriter();

try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
con = DriverManager.getConnection(sc.getInitParameter("url"),
  "ID", "PASSWORD");
ps = con.prepareStatement("select * from introduce");
rs = ps.executeQuery();
out.print("<html><body>");
out.print("<table>");
out.print("<tr>");
out.print("<td style=\"text-align:center\"> 번호 </td>");
out.print("<td style=\"text-align:center\"> 이름 </td>");
out.print("<td style=\"text-align:center\"> 나이 </td>");
out.print("<td style=\"text-align:center\"> 전화 </td>");
out.print("<td style=\"text-align:center\"> 성별 </td>");
out.print("<td style=\"text-align:center\"> 주소 </td>");
out.print("<td style=\"text-align:center\" colspan=\"2\">
  옵션  </td>");
out.print("</tr>");
while (rs.next()) {
out.print("<tr>");
out.print("<td style=\"text-align:center\">" + rs.getInt("ID") +
  "</td>");
out.print("<td style=\"text-align:center\">" +
  rs.getString("name") + "</td>");
out.print("<td style=\"text-align:center\">" +
  rs.getString("age") + "</td>");
out.print("<td style=\"text-align:center\">" +
  rs.getString("tel") + "</td>");
out.print("<td style=\"text-align:center\">" +
  rs.getString("gender") + "</td>");
out.print("<td style=\"text-align:center\">" +
  rs.getString("addr") + "</td>");
out.print("<td style=\"text-align:center\">
  <a href='UpdateMobile?ID=" + rs.getInt("ID") + "'>수정</a></td>");
out.print("<td style=\"text-align:center\">
  <a href='DeleteMobile?ID=" + rs.getInt("ID") + "'>삭제</a></td>");
out.print("</tr>");
}
out.print("</table>");
out.print("</body></html>");
} catch (Exception exc) {
exc.printStackTrace();

}

}

  }

 ================================================================



 ================================================================

  package mobile.mysql;

  import java.io.*;

  import javax.servlet.*;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.*;

  import java.sql.*;

  @WebServlet("/mobile.mysql/UpdateMobile")
  public class UpdateMobile extends HttpServlet {
private static final long serialVersionUID = 5199742319711990244L;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
conn = DriverManager.getConnection(sc.getInitParameter("url"),
"ID", "PASSWORD");
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM introduce" + " WHERE ID="
+ request.getParameter("ID"));
rs.next();
out.println("<html><head></head>");
out.println("<body><h1>테이블 정보</h1>");
out.println("<form action='UpdateMobile' method='post'>");
out.println("번호 : <input type='text' name='ID' value='"
+ request.getParameter("ID") + "' readonly><br>");
out.println("이름 : <input type='text' name='name' value='"
+ request.getParameter("name") + "'><br />");
out.println("나이 : <input type='text' name='age'" + " value='"
+ rs.getString("age") + "'><br/>");
out.println("전화 : <input type='text' name='tel'" + " value='"
+ rs.getString("tel") + "'><br/>");
out.println("성별 : <input type='text' name='gender'" + " value='"
+ rs.getString("gender") + "'><br/>");
out.println("주소 : <input type='text' name='addr'" + " value='"
+ rs.getString("addr") + "'><br/>");
out.println("<input type='submit' value='저장'>");
out.println("<input type='button' value='취소'"
+ " onclick='location.href=\"ResearchMobile\"'>");
out.println("</form>");
out.println("</body></html>");

} catch (Exception e) {
throw new ServletException(e);

} finally {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
}
try {
if (stmt != null)
stmt.close();
} catch (Exception e) {
}
try {
if (conn != null)
conn.close();
} catch (Exception e) {
}
}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
Connection con = null;
PreparedStatement ps = null;
ServletContext sc = this.getServletContext();
String sql = "UPDATE introduce SET name=?,age=?,tel=?,gender=?,
  addr=? WHERE ID=?";
try {
Class.forName(sc.getInitParameter("driver"));
con = DriverManager.getConnection(sc.getInitParameter("url"),
"ID", "PASSWORD");
ps = con.prepareStatement(sql);
ps.setString(1, request.getParameter("name"));
ps.setString(2, request.getParameter("age"));
ps.setString(3, request.getParameter("tel"));
ps.setString(4, request.getParameter("gender"));
ps.setString(5, request.getParameter("addr"));
ps.setInt(6, Integer.parseInt(request.getParameter("ID")));
ps.executeUpdate();
response.sendRedirect("ResearchMobile");

} catch (Exception exc) {
exc.printStackTrace();
} finally {
try {
if (ps != null)
ps.close();
} catch (Exception e) {
}
try {
if (con != null)
con.close();
} catch (Exception e) {
}

}

}

  }

 ================================================================


2014년 9월 26일 금요일

Hadoop 기초와 구조 그리고 설치

    1. Apache Hadoop



  • What is BigData?

   : 서버 한대로 정의할 수 없는 규모의 데이터
   : 기존 소프트웨어로는 처리할 수 없는 규모의 데이터(PB, EB)
   : 3V(Volume, Velocity, Variety)


  • 어떻게 개발했지?

   : Cite , Citation
   : SCI impact factor
   : The Google File System(2003), MapReduce,
     Simplified Data Processing on Large Cluster(2004) 에서 아이디어를 얻어서 만듬
   >> HaDoopFileSystem MapReduce(저장과 병렬처리)
   : Hadoop Standard : Apache Hadoop

   ※ 참조 : http://hadoop.apache.org/
   ※ Hadoop Company : Cloudera, HortonWorks, MapR


    2. HDFS & MapReduce

   # 전제 : Multi Server System
   : 자동으로 Replication을 수행(HighAvailability)

  • HDFS

   : Name Node, Data Node, JobTracker, Task Tracker
   : file을 여러 개의 block(64MB)으로 나누어 저장한다
   : Write Once Read Many : File Overwrite 구조(Redundancy 개념)

   1) HDFS Architecture

 

   2) Datanode 개념

   
  
   : 접근할 때는 numRepicas를 통해 Datanodes에 접근한다.
   : Page.20
   : Heartbeat, HA swap 개념 이해
   : Namenode - Datanode 간의 Heartbeat으로 통신

    3) MapReduce Framework 개념


   예시) WordCount : 구조를 살펴보자.
   생각 확장하기
   0. 파일을 받아서 처음부터 끝까지 하나씩 세면서 count값을 1씩 증가시킨다.
   > 병렬구조로 짜려면 어떻게 해야할까?

  1. 1/n(프로세스의 숫자)로 잘라서 처리한다.(Splitting)
  2. 각각의 값들을 (object value, int count)형식으로 행동한다.(Mapping)
  3. A~Z순으로 정렬한다.(Shuffling)
  4. 중복되는 값들은 각각의 count값을 더하면서 value값을 표시한다.(Reducing)
  5. 결과값을 (object value, int count)를 출력해준다.(Final result)

   유사성(Parallelism) : 반복작업이 많고 데이터가 커지면 커질수록 활용하기 좋다.
  


    3. Hadoop 시작하기

   OS : Ubuntu 64bit
   Shell : dash(ubuntu default shell)
   Hadoop Version : 1.0.3

  ==============================================================

  •    설치하기


   1) hadoop을 다운받는다(2014.9 최신 버전 : 2.5.1)
   >> sudo wget http://archive.apache.org/dist/hadoop/core/hadoop-1.0.3/hadoop-1.0.3.tar.gz
 
   2) 다운받은 파일 압축을 해제한다.
   >> tar xvfz hadoop-1.0.3.tar.gz

   3) 환경 변수를 설정한다.
   >> export HADOOP_HOME=[hadoop_path]/hadoop-1.0.3
   >> echo $HADOOP_HOME
 
   4) PATH를 설정한다.
   >> export PATH=$PATH:$HADOOP_HOME/bin
   >> echo $PATH

  ==============================================================

   설정하기

   1) [hadoop_path]/conf/mapred-site.xml
 
   <configuration>
    <property>
<name>mapred.job.tracker</name>
<value>localhost:9001</value>
</property>
   </configuration>

   2) [hadoop_path]/conf/hdfs-site.xml

   <configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
   </configuration>

   3) [hadoop_path]/conf/core-site.xml

   <configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
   </configuration>

   4) localhost로 설정되었는지 확인한다.
   > cat masters
   = localhost
   > cat slaves
   = localhost

   5) Namenode를 포맷한다.
    > hadoop namenode -format

   6) demon을 실행해본다.
   > start-all.sh
   = [실행되는 과정 출력]
   > jps
   = [JobTracker, Secondary NameNode, NameNode, DateNode 출력]

2014년 9월 25일 목요일

MVC 모델이란?

  • MVC(Model View Controller)   


   1. How to ?

   - Struts, SpringMVC, Model2 등의 프레임워크를 통해 구현.

   2. 간단하게 구조 설명하기

   - .java(controller).class(model).JSP(view) ▶ browser(client)

   - Controller Action : Business Logic
   - Model : Mapping
   - View : View Page

※ MVC 패턴 이해하기 by ruby : http://rubykr.github.io/rails_guides/getting_started.html

3. How to use in Java?

   - Model2 Architecture : Servlet-API(Controller), JSP(View)
   - 이클립스 연동해서 직접 해보면 됨.

4. ETC

   - Spring : POJO, IoC/DI, AOP

MySQL Patitioning 적용 방법과 장단점

  • MySQL Patitioning

- 웹서비스에 최적화된 Multi-Replication : 읽기 성능을 향상시키기 위해서 사용한다.
- 대용량의 데이터를 쓸 때, 성능을 향상시키기 위해서는 어떻게 해야할까? Patitioning



단점 :


  1. Patitioning : Location Problem


- 데이터를 입력받으면 어디에 넣어야하는가?
- dictionary 방식으로 각각의 Location을 지정한다.
- VLDB(Very Large DBMS)


  1. Patitioning : Join


- Very Large한 테이블을 뒤져서 Join을 하는 것이 가능한가? ▶ 굉장히 힘들다.
- 정규화를 통해 redundancy를 없애는 DB의 기본 규칙(Normalize)에 위배되는데?
- 해결방안 : De-normalization(중복 허용)



장점 :


  1. Patitioning : Write Perfomance Upgrade

- 테이블을 작게 나누어두어 입력에 강점을 보인다.
- 단점을 덮을만큼 강력한 장점

※ 참조 : http://blog.hibrainapps.net/131


  1. MySQL Partition 사용시 제약 사항

- 모든 파티션은 동일한 스토리지 엔진 사용
파티션별 다른 엔진을 지정하여도 에러가 발생하지는 않지만 적용되는것은 아니다.
- 테이블과 인덱스를 별도로 파티션 할수는 없다. 테이블과 인덱스를 같이 Partitioning 하여야 한다.
Partition 된 테이블은 foreign Key를 지원하지 않는다.
- Partition 된 테이블은 FullText Index 를 지원하지 않는다.
- Partition 된 테이블은 Geometry(point, geometry...) 컬럼 타입을 지원하지 않는다.
- 한 테이블당 파티션의 갯수는 최대 1,024개이다.
- Temp Table 은 파티션 사용 불가.
- Partition 값은 정수형이어야 한다.
- 테이블이 Unique 또는 Primary Key를 가지고 있다면, 파티션키는 모든 Unique 또는 Primary Key의 일부 또는 모든 컬럼을 포함해야 한다.

  1. 예제


#####################################################

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (YEAR(hired)) (
    PARTITION p0 VALUES LESS THAN (2010),
    PARTITION p1 VALUES LESS THAN (2011),
    PARTITION p2 VALUES LESS THAN (2012),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

#####################################################

#Partition 추가
ALTER TABLE employees ADD PARTITION(PARTITION p4 VALUES LESS THAN (2009));
#Partition 삭제
ALTER TABLE employees DROP PARTITION p4;
#기존 파티션의 분리
ALTER TABLE employees 
REORGANIZE PARTITION p3 INTO (
PARTITION p3 VALUES LESS THAN (2013),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
#기존 파티션의 병합
ALTER TABLE employees 
REORGANIZE PARTITION p2,p3 INTO (
PARTITION p23 VALUES LESS THAN (2012)
);

#####################################################

  1. 기존 테이블을 파티션 적용하기



#####################################################

alter table [테이블이름] partition by range ([컬럼값])
(partition c0 values less than (100000),
 partition c1 values less than (500000),
 partition c2 values less than (1000000),
 partition c3 values less than MAXVALUE);

#MAXVALUE를 설정하지 않으면 범위에 대한 에러메시지가 처리된다.

#####################################################

  1. MySQL Partition 종류

  • Partition by Range
  • Partition by List
  • Partition by Hash
  • Partition by Key

CSS3, HTML5, jQuery 참고하기


  • CSS3


- 파편화가 심각하며, 기능이 지원되는 브라우저가 각각 다르다.
- 그러나 UserInterface에서 편리한 기능을 지원한다.
※ CSS3 링크 : http://www.w3schools.com/css/

  • HTML5
※ 링크 : http://www.w3schools.com/html/html5_intro.asp


  • JQuery Mobile

※ 링크 : http://www.w3schools.com/jquerymobile/

  • What is Web Kit?

- html/JavaScript Engine
- IE를 제외한 모든 브라우저에 내장되었'었'다.
- Chrome 역시 Blink 엔진을 만들어 사용


  • ETC

- CSS3 스타일로 UI 꾸미기

- JQuery Mobile을 이용한 주소록 만들기
- Font
- html, css, javascript, jquery 개념 정리

JavaScript와 jQuery, HTML5


  • Why used Java Script or JQuery?

- 성능이 좋아서?
- 표준화가 되어있기 때문에
- 다양한 plug-in이 상용화되면서 UI관리 용이(Bootstrap, YUI, extJS)

※ Twitter Bootstrap : http://getbootstrap.com/
YUI : http://yuilibrary.com/
Sencha : http://www.sencha.com/products/extjs/ (유료)

Full Frame : 필름 사이즈가 full-frame이다...


  • JQuery Mobile

- 모바일 폼에서 UserInterface를 만들기 쉽게 

  • HTML5, CSS3

- JavaScript와 HTML5는 대비되는 코드인가?
   : 그렇지는 않지만 실질적으로 HTML5로 구현되는 코드를 JS로 구현하는 것도 가능하다.

  1. Add element in HTML5

semantic elements : <header>, <footer>, <article>, <section>.
form controls : number, date, time, calendar, range.
graphic elements : <svg> ,<canvas>.
multimedia elements : <audio>, <video>.

  1. Add Storage in HTML5
쿠키말고도 저장이 가능하다니!

- 캔버스(Canvas)의 이해
- SVG(Scalabale Vector Graphic) : ※참조
- Geolocation : 위치정보서비스
- Drag and Drop

- Local Storage : 쿠키 이외의 정보를 브라우저에 저장

=================================================================
(생략)
...
// Check browser support
if (typeof(Storage) != "undefined") {
    // Store
    localStorage.setItem("lastname", "Smith");
    // Retrieve
    document.getElementById("result").innerHTML = localStorage.getItem("lastname");
} else {
    document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Storage...";
}
...
=================================================================

- WEB Socket :

※ Bitmap vs Vector = (image make dot, low quality/low resource) vs  (image make line(x, y), high quality/high resource)

Oracle : 오라클 원격 접속 허용


  • Client Configuration


1. ora파일을 확인하기



  • \network\admin\tnsnames.ora
======================================================

LISTENER_ORCL =
  (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))


ORACLR_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
    (CONNECT_DATA =
      (SID = CLRExtProc)
      (PRESENTATION = RO)
    )
  )

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

#굵은 글씨로 표시된 부분을 복사해서 붙여넣는다.

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = [Client_IP_Addr])(PORT = 1521))
    (CONNECT_DATA =
      # (SERVER = DEDICATED)
      # 윗 부분은 삭제한다.
      (SERVICE_NAME = orcl)
      # 접속할 Service name을 입력한다.
    )
  )

=================================================================

2. 클라이언트에서 접속되는지 확인

Client OS : Windows 7 Ultimate

=================================================================
>sqlplus [user_id]/[user_password]@[service_name]
=================================================================

예 >> sqlplus scott/tiger@orcl

DB Replication를 사용하는 이유


Database Replication이란? 

  • DBMS [master 'A'] 생성 -> DBMS [slave 'B'] 생성
  • A에서 Query 문이 실행되면 B에서도 같은 Query문이 실행된다.
사용하는 이유?

  • Redundancy(중복)
  • Read(CRUD) 성능 향상을 위해 사용
  • master(Create, Update, Delete)에서 입력받은 값이 여러 개의 slave(only-Read)에서 실행되어 값이 입력된다. 
※ MYSQL에서 DB replication 세팅해서 사용하기 :http://yupmin.net/tag/replication

2014년 9월 4일 목요일

Ubuntu : Java, MySQL, JDBC 설치 및 환경 변수 설정 / 언어 설정


  • 다운로드


   1. MySQL Server 설치 : apt-get install mysql-server
   2. JDK 설치 : apt-get install openjdk-7-jdk
   3. JDBC설치 : apt-get install libmysql-java

   4. tomcat7 설치 : apt-get install tomcat7
   5. apache2 설치 : apt-get install apache2

※설치하는데는 ROOT권한으로 설치해야 되므로 앞에 sudo를 기입 


  • 환경 변수 설정


  1. 환경 변수를 설정하기 위해 .bash파일이나 .profile 파일을 편집한다.

   > sudo nano .bashrc (또는 .profile)

   2. .bashrc(또는 .profile) 맨 끝에 아래와 같은 구문을 추가한다.

  ===================================================================
   # Java 경로 설정
   export JAVA_HOME=/usr/lib/jvm/java-[version]-openjdk-amd64
   # Tomcat7 경로 설정
   export CATALINA_HOME=/usr/share/tomcat7
   # ClassPath 경로 설정
   export CLASSPATH=home/[사용자이름]:
   $JAVA_HOME/lib:
   $CATALINA_HOME/lib:
   /usr/share/java/mysql-connector-java-5.1.28.jar:
  ===================================================================
   

   3. 현재 넣은 소스를 적용한다

   > source .bashrc

   4. echo로 각각의 변수들을 확인해본다.

   > echo $CLASSPATH
   > echo $JAVA_HOME
   > echo $CATALINA_HOME



  • Ubuntu 한글 사용 설정


   1. /etc/default/locale을 편집기로 실행한다.

   > sudo nano /etc/default/locale


   2. 다음과 같이 내용을 변경한 후 저장한다.

  ===================================================================
   LANG="ko_KR.UTF-8"
   LANGUAGE="ko_KR:ko:en_US:en"
  ===================================================================

   3. 언어를 변경하고 시스템에 적용시킨다.

   > sudo locale-gen ko_KR.UTF-8