2014년 11월 10일 월요일

Ubuntu : Solr 4.6.0 Eclipse 프로젝트 연동하기


  • 다운로드 

Solr 4.6.0 다운로드http://archive.apache.org/dist/lucene/solr/4.6.0/solr-4.6.0.tgzEclipse 다운로드http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/luna/SR1/eclipse-jee-luna-SR1-win32-x86_64.zip&mirror_id=466
※ 톰캣과 이클립스를 연동하는 과정이 필요하지만, 연동하는 부분에 대한 설명은 생략한다.

  • Solr 4.6.0 import 시키기


  01. Solr 4.6.0 파일 압축을 해제한다.

  02. \temp 디렉토리를 만들어 solr-4.6.0\dist\solr-4.6.0.war 파일을 복사한뒤 압축을 해제한다.
    > cp solr-4.6.0.war temp/
    > jar xf solr-4.6.0.war

  03. solr-4.6.0\example\lib\ext 내부에 있는 라이브러리 파일을 war파일 압축을 해제한 WEB-INF/lib에 복사한다.

  04. \temp 디렉토리 내부에 있는 모든 파일을 solr.war파일로 다시 압축한다.
    > jar cf solr.war *

  05. 임의의 공간에 solr_home 디렉토리를 생성한다.(예시 : E:\solr_home)

  06. solr-4.6.0\dist 와 solr-4.6.0\contrib를 solr_home디렉토리로 복사한다.

  07. solr-4.6.0\solr-4.6.0\example\solr 내부에 있는 모든 파일을 solr_home 디렉토리로 복사한다.

  08. 중간 결과


  09. 이클립스를 실행한다.(이클립스 버전 : Eclipse Luna x64)

  10. File > import 실행하여 04 단계에서 만든 solr.war파일을 import 시킨다.

  11. Server를 생성하여 server.xml을 수정한다. (굵은 글씨를 추가해준다.)
 ================================================================
   ...(생략)

      <Context docBase="solr" path="/solr" reloadable="true"  source="org.eclipse.jst.jee.server:solr">
      <Environment name="solr/home" type="java.lang.String" value="E:\solr_home" override="true" />
      </Context>

  ...(생략)
 ================================================================

  12. 실행하면 다음과 같이 실행된다.



2014년 10월 20일 월요일

Ubuntu : solr 4.6 살펴보기 2

  • Nutch


  다운로드 : archive.apache.org/dist/nutch/


  • Nutch 설치 및 solr과 연동


  : 1.5.1 버전을 가지고 진행하였다.

  1. 다운로드 

  # 1.5.1 버전을 다운받는 과정이다.
  # 상위 폴더에는 다양한 버전들이 존재하므로 선택하여 다운로드 받아도 무방하다.
  > wget http://archive.apache.org/dist/nutch/1.5.1/apache-nutch-1.5.1-bin.tar.gz

  2. 압축 해제

  > gzip -d apache-nutch-1.5.1-bin.tar.gz
  > tar -xvf apache-nutch-1.5.1-bin.tar

  3. 폴더 이동

  # 편의를 위해 폴더를 옮기는 것 뿐이다.
  # 이 과정을 패스해도 상관없다.
  > sudo mv apache-nutch-1.5.1 /usr/share/nutch

  4. Path 설정

  # 편의를 위해 패스를 선언하여 진행하는 것이다.
  # 이 과정을 패스해도 상관없다.
  > sudo nano .bashrc

 ================================================================
  export NUTCH_HOME=/usr/share/nutch
  export PATH=$PATH:$NUTCH_HOME/bin:
 ================================================================

  > source .bashrc

  5. NUTCH_HOME으로 이동

  # urls 폴더 에서 seed.txt 파일을 생성하여 주소를 날린다.
  # crawl 폴더에 crawling한 데이터들을 저장한다.
  > sudo mkdir urls
  > sudo mkdir crawl

  6. NUTCH_HOME/conf/nutch-default.xml 파일 수정

  # 중간에 http.agent.name의 내용을 수정한다.
  > sudo nano nutch-default.xml

 ================================================================
  ...
  (생략)

  <!-- HTTP properties -->
  <property>
  <name>http.agent.name</name>
  <!-- value를 지정해준다. -->
  <value>nutch spider</value>
  <description>HTTP 'User-Agent' request header.</description>
  </property>

  (생략)
  ...
 ================================================================

  7. NUTCH_HOME/conf/regex-urlfilter.txt 파일 수정

  # 마지막 라인을 수정해 준다.
  > sudo nano regex-urlfilter.txt
 ================================================================
  ...
  (생략)

  +^http://([a-z0-9]*\.)*naver.com/
 ================================================================

  8. NUTCH_HOME/conf/schema-solr4.xml 파일 수정

  > sudo nano schema-solr4.xml

 ================================================================
  ...
  (생략)

  <!-- version="1.5.1" 을  version="1.5"로 수정한다. --> 
  <schema name="nutch" version="1.5">

  ...
  (생략)

  <!-- <fields> 안에 선언되어 있는 <field name ="boost"...>를 찾는다.
  type="string"을 type="long"으로 수정한다.
  또한 _version_을 추가한다.  -->   
  <field name="_version_" type="long" stored="true" indexed="true"/>
  <field name="boost" type="float" stored="true" indexed="true"/>  

  (생략)
  ...
 ================================================================

  9. NUTCH_HOME/conf/schema-solr4.xml 파일 복사

  #기존에 있던 schema 파일의 이름을 변경한다.
  #nutch에서 수정한 schema-solr4.xml을 schema.xml로 사용한다.
  > sudo mv SOLR_HOME/collection1/conf/schema.xml SOLR_HOME/collection1/conf/schema.xml.org
  > sudo cp NUTCH_HOME/conf/schema-solr4.xml SOLR_HOME/collection1/conf/schema.xml

  10. SOLR_HOME/collection1/conf/stopwords_en.txt 생성

  > sudo nano stopwords_en.txt

 ================================================================
 #빈 공간으로 남기고 저장한다.
 ================================================================

  11. NUTCH_HOME/urls/seed.txt 생성

  #앞서 regex-urlfilter.txt에서 지정한 주소를 기록한다.
  > sudo nano seed.txt

 ================================================================
  http://www.naver.com
 ================================================================

  12. jetty 재실행

  > sudo service jetty restart

  13. crawling 실행

  # NUTCH_HOME에서 명령어를 타이핑한다.
  # 깊이는 3으로, 앞에 존재하는 길이 50을 긁어온다.
  > bin/nutch crawl urls -solr http://localhost:8983/solr/collection1 -depth 3 -topN 50

2014년 10월 15일 수요일

Ubuntu : solr 4.6 살펴보기 1



  • 한글 형태소 분석기(Arirang)

  다운로드 : http://cafe.naver.com/korlucene
  한글 연동 참고 : http://dev.meye.net/entry/Solr-%EC%84%A4%EC%A0%95




  • etc...

  설치와 연동은 저기 블로그에서 너무 설명을 잘해주셔서 링크를 달아두었다.  

  이후는 open web crawler인 nutch를 이용하여 crawling 하는 방법에 대해 진행한다.

2014년 10월 14일 화요일

Ubuntu Server : File/Redmine Server 만들기

  • Ubuntu Server USB 만들기


  1. 준비 과정

  Ubuntu Server : http://www.ubuntu.com/server
  UUI : http://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/

  2. 설치과정 참조

  참조 링크 : http://webdir.tistory.com/187
  ※주의사항 : 중간 설치 과정에서 Samba Package를 포함하여 설치하도록 한다.




  • Samba File Server 만들기


  1. etc/samba/smb.conf 수정

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

  [ubuntu_user_name]
  comment = comment
  path = samba_conf_path
  valid users = samba_user
  public = yes/no
  writable = yes/no

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

  2. Samba에 접속할 user 생성

  #valid users에서 설정한 유저 값과 동일한 유저 이름을 생성한다.
  > sudo smbpasswd -a samba_user
  > 삼바 패스워드 입력

  3. Samba Server 재시작

  > sudo service smbd restart




  • Redmine Server 만들기



  1. 준비 과정

  bitnami : https://bitnami.com/stack/redmine/installer

  2. 주어진 링크에서 설치파일 다운로드 받기

  > wget https://bitnami.com/redirect/to/43933/bitnami-redmine-2.5.2-3-linux-x64-installer.run

  3. run 파일 설치하기

  > chmod +x bitnami-redmine-2.5.2-3-linux-x64-installer.run
  > ~/bitnami-redmine-2.5.2-3-linux-x64-installer.run

  4. 과정에 따라 설치하기

  5. etc/rc.local

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

  (상략)
  ...
  #아래 코드만 추가한다.
  redmine 설치 경로/ctlscript.sh start &
  exit 0

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

  ※ 위 코드를 추가하면 서버가 시작될 때 자동으로 Redmine이 실행된다.



  • Subversion 설정하기


  1. SVN 저장 폴더를 생성


  2. 저장소 설정

  > svnadmin create --fs-type fsfs [SVN 저장 폴더 경로]/[저장소 이름]

  3. conf/svnserve.conf

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

  (상략)
  ... 
  [general]
  # 임의의 유저의 접근은 허용하지 않는다.
  anon-access = none
  # 아이디로 접근한 유저는 쓰기를 허용한다.
  auth-access = write
  # db테이블에 접속할 수 있는 비밀번호를 설정한다.
  password-db = password
  ...
  (하략)

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

  4. conf/passwd

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

  [users]
  # id = password 형식을 사용
  sally = 1111

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

  5. SVN 재시작


  ※ 참조 : http://jhroom.co.kr/23908

2014년 10월 7일 화요일

Cassandra & NoSQL

  • NoSQL


  1. NoSQL 특징

  데이터 관계를 정의하지 않음.
  Table Schema 구성이 유동적.(Schemaless)
  분산형 구조가 기본.


  CAP 이론 중 2개만 만족.(3개를 모두 만족할 순 없다.)
    - Availability : 고가용성.
    - Consistency : 일관성. 어떤 노드를 통해 접근해도 같은 결과값이 출력.
    - Patition tolerance : 네트워크에 장애가 있어도 어떻게든 수행.

  참조 : http://www.oss.kr/oss_repository14/81878
  Fault tolerance : 데이터 손실을 우려하여 Recovery Data를 같이 전송한다.


2014년 10월 1일 수요일

Eclipse와 톰캣 연동하기

1. Eclipse Java EE 설치 

1) 이클립스 다운로드 : http://eclipse.org/downloads/
2) 위 링크로 이동하여 'Java EE Developer'를 다운받는다.
3) 다운받은 파일을 압축을 풀고 eclipse를 실행한다.

2. 아파치 톰캣 설치

1) 아파치 톰캣 8.0 버전 다운로드 : http://tomcat.apache.org/download-80.cgi
2) Core > Window Service Installer 32/64bit 를 다운받는다.
3) 실행 과정은 http://dkatlf900.tistory.com/35 아래 주소를 참고한다.

3. 환경 변수 설정

1) 시작 > 컴퓨터(마우스 우클릭) > 속성을 클릭한다.

2) 고급 시스템 설정을 클릭한다.
 

3) 환경 변수를 설정한다.

4.1) 시스템 변수 > 새로 만들기 선택
4.2) 새 시스템 변수 > 변수 이름 > CATALINA_HOME
4.3) 새 시스템 변수 > 변수 값 > C:\Program Files\Apache Software Foundation\Tomcat 8.0

5.1) 시스템 변수 > Path를 더블 클릭
5.2) 시스템 변수 편집 > 변수 값에서 마지막에 %CATALINA_HOME%\bin을 추가한다.(각 변수들은 세미콜론(;)으로 구분한다.)

6) 명령어 콘솔 창(cmd)에서 "catalina start"를 입력한다.

7) 아래와 같은 화면이 뜨면 성공!

4. Eclipse 내부 설정

1) Tomcat 서버 연동하기

① 이클립스 실행 후 Window > Preferences 를 선택한다.

② Server > Runtime Environment 를 선택한 뒤, Add를 클릭한다. 

③ Apache Tomcat v8.0(자신이 설치한 톰캣 버전)을 선택한다.

2) 프로젝트와 톰캣 서버 연동하여 사용하기 

① File > New > Other 를 클릭한뒤 Web > Dynamic Web Project를 선택한다.

② 프로젝트 이름을 생성한 뒤 Targer Runtime은 방금 만든 서버로 선택한다.

③ Next 버튼을 누르고 클래스패스는 보면서 Next 버튼을 눌러준다.

④ Context root를 확인하고 Finish를 누른다. 
(localhost:8080/(Context root)/(파일 이름) 으로 접속된다.)
(Context root는 따로 설정하지 않으면 프로젝트 이름과 동일하다.)

⑤ JSP파일을 생성하여 파일을 실행하여 본다.

HDFS 살펴보기 3


  • 생각해보기

TopN 예제 분석하기
1. Scheduling
비선점 알고리즘
선점 알고리즘 : RR, WRR, DWRR, WFQ, GFQ(FQ로 검색)
CountTrigram 예제 분석하기

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 출력]