ただいまHadoop勉強中

 DEVLOVE HangarFlight
     2010.12.18
自己紹介

名前
 能登 諭(のと さとし)

所属
 株式会社トップゲート

Twitter
  @n3104
おしながき

1. Hadoop概要
2. HDFS
3. MapReduce
4. Hive
5. HangarFlight
1.Hadoop概要
Hadoopとは

大規模なデータを複数のコンピューター上で分散して処理するため
のソフトウェアを開発している、オープンソースのプロジェクトです
(※1)。
Hadoopプロジェクトによって開発されているソフトウェアは多数あり
ますが、主となるのはMapReduceとHDFS(Hadoop Distributed
File System)です。この2つはGoogleが公開したMapReduce(※2)と
GFS(Google File System)(※3)の論文を参考に開発されていま
す。

※1 http://hadoop.apache.org/
※2 http://labs.google.com/papers/mapreduce.html
※3 http://labs.google.com/papers/gfs.html
Hadoopのサブプロジェクト群

   サブプロジェクト
     Hadoop Common
     HDFS
     MapReduce
     ZooKeeper
   関連プロジェクト
     Arvo
     Chukwa
     HBase
     Hive
     Mahout
     Pig

プロジェクト間の関連は以下が参考になります。
https://github.com/tomwhite/hadoop-ecosystem
2.HDFS
HDFSとは

Hadoop Distributed File System、つまり分散ファイルシステムで
す。ファイルシステムですので、HDFS上でファイルやディレクトリを
管理することが出来ます。また、そのファイルシステムが分散されて
いるので、複数台のコンピューターを利用したファイルシステムとい
うことになります。
ファイルの一覧表示(1)

【内容】
絶対パス指定でルートディレクトリ直下のファイルの一覧を表示しま
す。

【コマンド】
$ hadoop fs -ls /

【構文】
hadoop fs -ls <path>
ファイルの一覧表示(2)

【コマンド】
$ hadoop fs -ls /

【結果】
Found 4 items
drwxr-xr-x - training supergroup   0 2009-06-17 16:19 /shared
drwxr-xr-x - training supergroup   0 2009-11-12 14:47 /tmp
drwxr-xr-x - training supergroup   0 2009-11-12 14:47 /user
drwxr-xr-x - hadoop supergroup      0 2010-11-22 23:27 /var
ローカルからHDFSへのコピー(1)

【内容】
ローカルのREADMEファイルをHDFSのホームディレクトリに
hdfs_reameという名前でコピーします。

【コマンド】
$ hadoop fs -copyFromLocal README hdfs_readme
ローカルからHDFSへのコピー(2)

【コマンド】
$ hadoop fs -copyFromLocal README hdfs_readme

【結果】
何も出力されません
【構文】
hadoop fs -copyFromLocal <localsrc...> <hdfspath>
ローカルからHDFSへのコピー(3)

【内容】
ローカルからHDFSにREADMEファイルがコピーされたことを確認し
ます。

【コマンド】
$ hadoop fs -ls
【結果】
Found 1 items
-rw-r--r-- 1 training supergroup   538 2010-12-13 09:09 /user/training/hdfs_readme
HDFSの基本操作

hadoop fs -XXX という形でコマンドライン経由で操作します。具体
的には以下のようなものがあります。
   hadoop fs -ls <path>
   hadoop fs -lsr <path>
   hadoop fs -mkdir <path>
   hadoop fs -rm <path>
   hadoop fs -rmr <path>
   hadoop fs -copyFromLocal <localsrc...> <hdfspath>
   hadoop fs -copyToLocal <hdfspath> <localpath>
   hadoop fs -help

※ pathは相対パスと絶対パスが指定可能で、相対パスはホーム
ディレクトリが起点となります。
HDFSのホームディレクトリ

ホームディレクトリはクライアントのユーザー名から自動的に決定さ
れます。/user/${USER}/ がホームディレクトリになります。
HDFSの権限管理

Unixライクな権限管理の仕組みがあります。ただし、認証の仕組み
はありません。現状は認証なしにユーザー名とグループ名を、クライ
アント側でログインしているアカウントから取得しているだけです。た
だしYahoo版のHadoop(※1)(※2)にはKerberosによる認証が追加
されており、Hadoop0.21.0に取り込まれています(※3)。

※1 http://yahoo.github.com/hadoop-common/
※2 Hadoopは本家Apache版以外にもディストリビューションが存
在します。
※3 Hadoop0.21.0は今年の8/23にリリースされていますが、安定
版(stable)は0.20.2です(2010年12月14日時点)。
ディストリビューション

 本家 http://hadoop.apache.org/
 Yahoo http://yahoo.github.com/hadoop-common/
 Cloudera http://www.cloudera.com/downloads/
 IBM http://alphaworks.ibm.com/tech/idah
 Hudson http://wiki.hudson-ci.
 org/display/HUDSON/Hadoop+Plugin
HDFSの構成
HDFSの耐障害性について

HDFSはNameNodeがシングルマスターであるため、障害発生時に
SPoF(単一障害点)となります。そのため、NameNodeに関しては冗
長化するなどの対応を行う必要があります(※1)。DataNodeに関し
ては複数のコンピューターにデータが複製されており、障害発生時
は他のコンピューターにデータが再度複製されるため問題ありませ
ん。
なお、SecondaryNameNodeはCheckPointNodeと言うべきもので、定
期的にNameNodeのデータをバックアップしているだけです。そのた
め、障害時にNameNodeの代わりに動作するものではありません。

※1 http://togetter.com/li/75188
3.MapReduce
MapReduceとは

並列分散処理用のフレームワークです。mapとreduceという処理を
組み合わせて処理を行う点が特徴です。
wordcount(1)

【内容】
ファイル中の単語数をカウントするMapReduceジョブです。Hadoopに
付属しているサンプルプログラムです。以下のようにして実行しま
す。

【コマンド】
$ hadoop jar /usr/src/hadoop-0.20.1+133/hadoop-0.20.1+133-
examples.jar wordcount hdfs_readme wordcount

【構文】
$ hadoop jar <jarファイルのpath> <実行するジョブ>
 <入力ファイル...> <出力ディレクトリ>
wordcount(2)

【内容】
wordcountの処理結果の確認をします。ホームディレクトリに
wordcountというディレクトリが作成されていることが分かります。

【コマンド】
$ hadoop fs -ls
【結果】
Found 2 items
-rw-r--r-- 1 training supergroup   538 2010-12-13 09:09 /user/training/hdfs_readme
drwxr-xr-x - training supergroup     0 2010-12-15 06:16 /user/training/wordcount
wordcount(3)

【内容】
wordcountディレクトリの中に処理結果のファイル(part-r-00000)が
格納されていることを確認します。

【コマンド】
$ hadoop fs -ls wordcount
【結果】
Found 2 items
drwxr-xr-x - training supergroup     0 2010-12-15 06:15 /user/training/wordcount/_logs
-rw-r--r-- 1 training supergroup   582 2010-12-15 06:15 /user/training/wordcount/part-r-
00000
wordcount(4)

【内容】
処理結果のファイル(part-r-00000)の中身を見てみます。

【コマンド】
$ hadoop fs -cat wordcount/p* | less
【結果】
To    2
You 1
a    1
access 1
all 1
and 3
wordcount:map処理

wordcountであるため、keyが単語、valueが「1」となります。
wordcount:reduce処理

reduceの入力時にkey(単語)ごとにvalue「1」がまとめられます。そ
してreduceにおいて「1」を足して出現回数が求められます。
wordcountのソース(1) : map処理

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);
       }
     }
}
wordcountのソース(2) : reduce処理

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);
    }
}
wordcountのソース(3) : main処理

public static void main(String[] args) throws Exception {
  Configuration conf = new Configuration();
  String[] otherArgs = new GenericOptionsParser(conf, args)
        .getRemainingArgs();
  if (otherArgs.length != 2) {
      System.err.println("Usage: wordcount <in> <out>");
      System.exit(2);
  }
  Job job = new Job(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(otherArgs[0]));
  FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
  System.exit(job.waitForCompletion(true) ? 0 : 1);
}
wordcountのソース(4) : Driver

public class ExampleDriver {
  public static void main(String argv[]){
     int exitCode = -1;
     ProgramDriver pgd = new ProgramDriver();
     try {
        pgd.addClass("wordcount", WordCount.class,
           "A map/reduce program that counts the words in the input files.");
        pgd.driver(argv);
        // Success
        exitCode = 0;
     }
     catch(Throwable e){
        e.printStackTrace();
     }
     System.exit(exitCode);
  }
}
MapReduceの構成
MapReduceがやってくれること

 分散処理の制御
   複数台のコンピューターの制御(タスクの割り当て)
   タスクを割り当てたコンピューターに障害が発生した場合に
   別のコンピューターに割り当てて再実行
 入力ファイルの分割
   各mapに処理対象となる入力ファイルを割り当てる
 mapで処理した結果をreduceに渡す
   その際にmapの出力結果についてkey単位でvalueをまとめる
その他の機能

不良レコードのスキップ
カウンター
ジョブスケジューラー
Hadoopストリーミング
  スクリプト言語でmapおよびreduce処理を実装できる。
Hadoop Pipes
  C++でmapおよびreduce処理を実装できる。
4.Hive
Hiveとは

SQLをMapReduceに変換して実行するツールです。Hiveを利用する
ことで、MapReduceプログラムの作成しなくとも、データを抽出した
り、結合したりすることが出来ます。
Hiveのインストール(1)

【前提】
Cloudera's Hadoop Training VM
http://www.vmware.com/appliances/directory/va/78133

【ダウンロードと解凍】
$ wget http://archive.apache.org/dist/hadoop/hive/hive-0.5.0
/hive-0.5.0-bin.tar.gz
$ tar xzf hive-0.5.0-bin.tar.gz
Hiveのインストール(2)

【HDFS上にHiveのディレクトリを作成】
$ cd hive-0.5.0-bin
$ hadoop fs -mkdir /user/hive-0.5.0/warehouse
$ hadoop fs -chmod g+w /user/hive-0.5.0/warehouse
$ sed -i 's;/user/hive/warehouse;/user/hive-0.5.0/warehouse;'
conf/hive-default.xml

【補足】
通常は /user/hive-0.5.0/warehouse だけでなく、 /tmp ディレクトリ
も同様にmkdirしてchmodします。
http://wiki.apache.
org/hadoop/Hive/GettingStarted#Running_Hive
Hive interactive Shellの起動と停止

【起動】
$ bin/hive

【停止】
> quit;

【補足】
Shellの詳細は以下を参照してください。
http://wiki.apache.
org/hadoop/Hive/LanguageManual/Cli#Hive_interactive_Shell_
Command
テーブルの作成

【内容】
テーブルを作成してみます。

【コマンド】
> CREATE TABLE pokes (foo INT, bar STRING);
> SHOW TABLES;

【HDFS】
HDFS上にpokesに対応するディレクトリが作成されています。
> dfs -lsr /user/hive-0.5.0;
データのロード

【内容】
先程作成したpokesテーブルにデータをロードします。

【コマンド】
> LOAD DATA LOCAL INPATH './examples/files/kv1.txt'
OVERWRITE INTO TABLE pokes;
> select * from pokes limit 10;

【HDFS】
HDFS上のHiveディレクトリ内にkv1.txtがコピーされています。
> dfs -lsr /user/hive-0.5.0;
データの抽出

【内容】
count関数を利用してpokesテーブルのレコード件数を集計します。

【コマンド】
> select count(1) from pokes;

MapReduceジョブが起動されることが分かります。このようにSQL
を記述するだけで自動的にMapReduceジョブが生成され処理を行う
ことが出来ます。
explain

【内容】
explainで実行されるMapReduceの実行計画を確認することが出来
ます。

【コマンド】
> explain select count(1) from pokes;

【補足】
構文チェックに利用できます。Hiveはクエリの最小実行時間が長い
上に、途中で処理を止めるのも面倒です。
Hive補足

 SQLがMapReduceに変換されている、つまりファイルを操作して
 いるだけ。
     入力ファイルは全行読み取られる。
     部分更新とかは出来ない。ファイル単位で追加か削除しか
     出来ない。
 開発時はリズムが悪い。explainを使うことで構文チェックできる。
 Ctrl+Cしても止まらない。
     停止するのはHiveのプロセスであって、一度実行した
     MapReduceジョブは別途停止する必要がある。
 デフォルトだと同時に1SQLしか投げられない。
     Metastoreの構築が別途必要になる。
 Cygwinでは動作しない。
5.HangarFlight
とりあえずHadoopを操作してみるには

Cloudera's Hadoop Training VMがお手軽です。入手元としては
ClouderaとVirtual Appliancesがあります。
http://www.cloudera.com/downloads/virtual-machine/
http://www.vmware.com/appliances/directory/va/78133

Virtual Appliancesから落としたファイルはovf形式であるため、
VirtualBoxにインポート可能です。VMWarePlayerで利用する際は
ovftoolを利用してovf形式からvmx形式に変換する必要があります。

ちなみに、HadoopだけならCygwin上にも構築できますが、Hiveは利
用できませんし、激おそなのでおすすめしません。
VirtuslBoxを利用する場合の補足

cloudera-training-0.3.3.ovfの103-111行目を削除しないと
virtualboxにインポート時にエラーになります。以下の部分になりま
す。
 <Item ovf:required="false">
  <rasd:AddressOnParent>3</rasd:AddressOnParent>
  <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
  <rasd:Description>Sound Card</rasd:Description>
  <rasd:ElementName>sound</rasd:ElementName>
  <rasd:InstanceID>10</rasd:InstanceID>
  <rasd:ResourceSubType>vmware.soundcard.ensoniq1371</rasd:ResourceSubType>
  <rasd:ResourceType>1</rasd:ResourceType>
 </Item>
おすすめの書籍・サイト

1. ASCII.technologies 2011年1月号
   http://tech.ascii.jp/elem/000/000/569/569332/
2. Hadoopリンクまとめ(1) - 科学と非科学の迷宮
   http://d.hatena.ne.jp/shiumachi/20100425/1272197037
3. slideshare
   http://www.slideshare.net/search/slideshow?
   searchfrom=header&q=hadoop
4. Hadoop(オライリー)
   http://www.oreilly.co.jp/books/9784873114392/
5. Twitter
   http://twitter.com/#!/n3104/hadoop
6. Resources « Cloudera » Apache Hadoop for the Enterprise
   http://www.cloudera.com/resources/?type=Training
ご静聴ありがとうございました!

ただいまHadoop勉強中