Spark と大規模データ処理...Apache Spark とは...
Transcript of Spark と大規模データ処理...Apache Spark とは...
Sparkと大規模データ処理NAISTビッグデータアナリティクス第 3回
鈴木優
2016年 10月 21日
本日の内容
ビッグデータとはHadoopから SparkまでApache Sparkの使い方
2 / 39
ビッグデータとは
大きなデータとは(ガードナーによる定義 (three V))量が多い (Volume)
地球上に存在するデータ量は 2011年には 1.8ZB,2020年には 35ZBに達する見込み1ZB(1ゼッタバイト)= 1021 B(バイト)= 1, 000 EB(エクサバイト) = 1, 000, 000 PB = 1, 000, 000, 000 TB =
1, 000, 000, 000, 000 GB
種類が多い (Variety)
Word, Excelなどの文書,電子メール,ソーシャルメディアのデータ,センサーデータ
頻度が多い (Velocity)
商品の購買履歴データ -クレジットカード,銀行の預貯金センサーデータ -気象データ,河川の水位観測,気温
3 / 39
ビッグデータとは今までと何が違うのか
何も違わない(バズワード)という批判基盤となる技術は既存のものと同じデータ工学,情報検索,データマイニング,機械学習など
色々なデータを混ぜ合わせ一つの知見を得たい大量の埋もれているデータから今まで知られていなかった情報を得たい
4 / 39
データベース
Relational Database Management System(RDBMS)
関係データベースOracle, MySQL, PostgreSQL, MicrosoftSQL, ...
SQLという標準形式で問合せできる異なるデータベースを使っても問合せを変更する必要が無い
データを表形式で格納,抽出複雑な問合せが可能一つのシステムで動く =負荷分散できない処理は必ず成功 or失敗する=中途半端に処理が終わらない
5 / 39
データベースの ACID特性
データベースは,以下の四つの性質を満たしている必要がある.
Atomicity(原子性): トランザクション処理はすべて実行されるか,全く実行されない状態かのいずれかで終わるConsistency(一貫性): トランザクション処理の前後でデータに矛盾を生じないIsolation(独立性): 他のトランザクション処理から影響されないDurability(耐久性): 障害が発生しても更新結果は保持されるこれらを全部合わせて「整合性 (Consistency)」と呼ぶ
6 / 39
CAP定理
以下の三つを同時に保証することは不可能データの整合性 (Consistency)
データの可用性 (Availability)
データの分散化 (Partition-tolerance)
RDBでは,整合性を保証した結果,分散化できない→ KVS (Key Value Store)の出現 分散化できるが整合性を保証しない
7 / 39
KVSの出現
整合性は犠牲,可用性や分散性を向上という発想データは表形式ではなく, “Key”と “Value”の組検索方法はシステム依存
SQLは使えない =独自の問合せ言語NoSQLと呼ばれることも
Not Only SQLの略NO SQL(SQLは不要)という印象をもつ人も
ドキュメント指向のものが多いValueの部分に,大量のデータを入れることも
8 / 39
KVSの歴史
Googleが BigTableを開発 (2004-2005)
数百台から数千台のサーバでペタバイト級のデータを扱うGoogle内のサービスで活用 (Google Reader, Google Map,
Blogger, ...)
ソースや実行環境は公開されていないGoogle以外のサーバでは使えない
クローンの出現BigTableの論文を基に様々な実装を
Apache HBase - Hadoop上の KVS実装Apache Cassandra
MongoDB
Neo4j -グラフを対象にした KVS
... などなど9 / 39
最近の傾向
Standaloneで SQLを使いたい: 商用なら Oracle,特に何もなければ MySQL
地理データを使いたい: PostgreSQL
プロトタイプで簡単に: SQLite
NoSQLなら: MongoDB,CassandraなどHadoop, Sparkと同時に使いたい: HBase
何も考えずに: ファイル
10 / 39
Key Value Store
JSON形式を用いられることが多いJSON形式
{"Key" : "Value"}
{"Key" :
{"Key2": "Value2"}
}
[{"Key":"Value"}, {"Key2": "Value2"}, ...]
{"ノートパソコン":
{"重量":"10kg", "大きさ":"A4", "バッテリー":"10 時間"}
}
Javaの Mapや Perlの Hashなど,実装方法は様々 11 / 39
最近のシステム構築に関する動向
一つの大きなシステムよりも複数の小さなシステム倍の値段のサーバは性能が倍とはならない性能/価格比が最も良いサーバ =コモディティサーバ
サーバの数が多い =壊れやすい少しは壊れても問題無いようにシステムを設計する必要あり一つのポイントが壊れてしまうとシステムが動作しない点SPOF (Single Point Of Failure)を無くす
12 / 39
文字のカウント
「台風」は何回出現するか (Java like language)
File file = fopen("file.txt"); //ファイルを開くint count = 0; //変数 count を設定for(String s: file){
if(s.contains("台風")){ //「台風」が入っていたら・・・?count += 1; // count に 1 を足す
}
}
System.out.println("台風は"+count+"回出現しました");
変数 countはこのプログラム内でしか利用できない.もし他のマシンで変数の値が変わってもこの値は変化せず
13 / 39
このプログラムは何が問題なのか
メモリが足りない大量のデータに比例するメモリが無ければ,メモリ不足になり処理続行できない
CPUを有効に活用できていない結局 1個の CPUだけしか活かせていない
データの読み出し速度が遅いハードディスクからデータを読み出す速度はシーケンシャルで 200MiB/s,ランダムで 380 IOPS (SAS 15000rpm)
いくらお金をかけてもこれ以上にはならない
お金をかけてサーバを増やすと速度が上がるようにしたい14 / 39
並列化
複数のマシン間で協調させて動かすのは難しいファイル番号が偶数ならシステム A,奇数なら Bが動作するようにすると,偶数と奇数が同じ処理数でなければ,有効に動かすことができない分け方によっては同じファイルを 2回処理してしまうことも最後に集計は 1個のマシンしか動作させられない
メモリはマシンの間で共有できないあるマシンへ変数の値を変えても別のマシンに知らせることは難しい
マシン間で影響が無いように問題を分割15 / 39
複数マシンの並列化手法の登場
MapReduceの出現 (Google)
一つのタスクを細かな単位 (map)に細分化し処理mapで処理された部分をまとめる (reduce)MapReduceは Google以外では利用できない
誰でも使える実装として Hadoopが作られる分散ファイルシステム Google File Systemの出現多くのサーバにデータを分散して配置いくつかディスクやサーバが壊れてもデータは無事GFSは Google以外では利用できない
誰でも使える実装として hdfsが作られるHadoop Distributed File System
16 / 39
サーバの変化
一つの大きなサーバ 小さなサーバの集合体(ブレードサーバ)
*1
*1by Robert Kloosterhuis (Wikimedia Commons)17 / 39
京
京のラック
2
一つひとつは小さなコンピュータ上の方 12個のサーバ中央は電源下の方 12個のサーバ
複数のサーバを効率良く組み合わせられるかが勝負
2by CES1596 (Wikimedia Commons)18 / 39
Hadoopや Sparkに対する誤解
(誤解 1) Hadoopや Sparkで書くと処理スピードが速くなる少量のデータを扱う時は逆に遅くなるデータが非常に多いときに処理可能になる
(誤解 2)並列処理のプログラミングが面倒並列処理を意識したプログラムはほとんどありません
19 / 39
Hadoopのプログラム (単語の数え上げ)
import java.io.IOException;import java.util.StringTokenizer;
import org.apache.hadoop.*
public class WordCount {
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);}}}
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);
}}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(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(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}}
20 / 39
Hadoopの問題点
主にバッチ処理時々刻々と更新されるデータを処理するのは苦手
出力は常にファイルMap→ Reduceの先はディスクに保存しなければならないMap→ Reduce→ Map→ Reduce→などの処理を行うときに,ディスクアクセスが発生し速度が低下
特に機械学習において速度の問題は深刻同じデータを何度も繰り返し読む場面が多い
21 / 39
Apache Sparkとは
大規模なデータを活用するための高速で総合的なデータプラットフォーム利用しやすい
Scala, Java, Python, R shellが使えるSQLやストリームデータなどを扱うことができる機械学習フレームワークが既に幾つか実装されている
どこででも動くJava JVMが動くこと,相互にネットワーク接続されて入ればどこでも動くただし,動作させるまでに設定が結構大変NAISTでは ITCで既に設定済み.誰でも動作可能
22 / 39
Apache Sparkを使ってみよう
1 bda1node??へログイン?? は 05~16のうちのどれかを使ってください
2 データの準備Sparkのプログラムから見えるファイルシステム hdfsへファイルを移動します
3 プログラムの作成この授業では pythonを使いますが,Java/Scalaでも作成可能です
4 プログラムの実行実際にプログラムを実行し,実行結果を出力します
23 / 39
ログイン・PySparkを起動・終了
以下,リモート側のプロンプトは %,ローカル側は $で示します.pyspark起動・終了
$ ssh bda1node05.naist.jp
(05の部分を 05から 18までの数に変える)% pyspark ← Spark を立ち上げるPython 2.6.6 (r266:84292, Jan 22 2014, 01:49:05)
(中略)Using Python version 2.6.6
SparkContext available as sc.
>>> exit() ← Spark を終わる.Ctl-Dでも良い% logout
24 / 39
データを取ってくる
データ取得
% ls | grep txt
iphone6.ja.txt.xz iphone6s.ja.txt.xz Apple.txt.xz
オリンピック.ja.txt.xz 台風.ja.txt.xz
// 最後に xz が付いているものは圧縮されている// なので解凍する(ちょっと時間かかります)% xz -d Apple.txt.xz
// ファイル確認% ls |grep txt
Apple.txt
25 / 39
対象データの準備
hdfsへデータを移動
% ls | grep ja.txt
iphone6.ja.txt iphone6s.ja.txt
オリンピック.ja.txt 台風.ja.txt
// 台風.ja.txt を spark で読み書きできるように% hadoop fs -put 台風.ja.txt
// ファイル名一覧% hadoop fs -ls
Found 2 items
drwx------ - ysuzuki is-staff 0 2015-10-06
10:14 .Trash
-rw-r--r-- 3 ysuzuki is-staff 543921683 2015-10-06
00:04 台風.ja.txt
26 / 39
プログラミング
文字のカウント
% pyspark
// ファイルの読み込み>>> tweets = sc.textFile(u’台風.ja.txt’)
// ‘‘奈良’’が入っている行だけを抽出>>> nara = tweets.filter(lambda s: u’奈良’ in s)
// 行をカウント>>> nara.count()
(省略)15/10/06 15:25:03 INFO DAGScheduler: Job 3 finished: count at <stdin>:1, took 8.239254 s
2640
// 2640 行あった
27 / 39
RDD (Resilient Distributed Dataset)
不変 (イミュータブル)で並列実行可能な (分割された)コレクション情報が出てくる蛇口メモリ上で保持される分割され,サーバ上に分散して配置される今回はファイル.DB上のデータやインターネット上のデータを扱うことも可能遅延実行実際に処理が必要となるまで処理が開始されない
三種類の RDDRDD (一行に一つの値だけが入る RDD)
PairRDD (一行に Keyと Valueの二つが入っている RDD)
SchemaRDD (SparkSQLで扱う RDD)28 / 39
プログラミング
”奈良”が含まれる
% pyspark
// ファイルの読み込み>>> tweets = sc.textFile(u’台風.ja.txt’)
// ‘‘奈良’’が入っている行だけを抽出>>> nara = tweets.filter(lambda s: u’奈良’ in s)
// 行をカウント>>> nara.count()
(省略)15/10/06 15:25:03 INFO DAGScheduler: Job 3 finished:
count at <stdin>:1, took 8.239254 s
2640
// 2640 行あった29 / 39
プログラミング
複数台のサーバを使う
// マシンを二つ利用する (--master local[2])
% pyspark --master local\[2\]
// 同じ処理を行う15/10/06 15:25:03 INFO DAGScheduler: Job 3 finished:
count at <stdin>:1, took 8.166796 s
2640
// 8.23秒かかっていたのが 8.16秒になった// もっと複雑な処理ならば高速化が実現できるはず
30 / 39
ファイルに保存されているプログラムを実行
wordcount.py(ホームページに掲載しています)
from pyspark import SparkContext
sc = SparkContext(appName="WordCount")
// RDD 作成text = sc.textFile("Apple.txt")
// tab で区切り 左から 3 個目だけをとってくるcounts = text.flatMap(lambda line: line.split(’\t’)[2].
// スペースで区切るsplit(’ ’) if len(line.split(’\t’)) == 4 else ’’)\
// (単語,1) というペアを作成.map(lambda word: (word,1))\
// 同じ単語を集約,(単語,a) と (単語,b) が来たら (単語, a+b)を返す.reduceByKey(lambda a,b: a+b) 31 / 39
ファイルに保存されているプログラムを実行
wordcount.py(続き)
// ペア (単語, x ) を (x, 単語) へ変換output = counts.map(lambda x:(x[1],x[0])).\
// Key で順序付け,10個取り出すsortByKey(ascending=False).take(10)
// 出力for (count, word) in output:
print("%s: %i" % (word.encode(’utf_8’),count))
// Spark を停止sc.stop()
1分から 2分ほどかかります.32 / 39
結果を出力
実行
// データを投入 (英語の Twitter データ)% hadoop fs -put Apple.txt
// タスクを投入% spark-submit wordcount.py
// 結果が出てくるRT: 1057117
Apple: 788480
the: 640973
to: 416088
: 396710
-: 382765
// RT という単語が一番多い.次は Apple
33 / 39
Sparkでの基本的な処理
二つの処理方法を組み合わせるTransformations
ある RDDを別の RDDへ変換するTransformationsに属する処理が呼び出されても処理は行われないActions
データの処理・保存・出力Actionに属する処理が呼び出され他時処理は行われる
34 / 39
Transformations
filter: 条件を満たす要素だけを抽出map: 要素を別の要素へ変換(元の要素数と変換後の要素数は同じ) flatMap: 要素を別の要素へ変換(元の要素数と変換ごの要素数が違う)reduceByKey: キーごとに要素を演算sample: ランダムに要素を抽出など,多数
35 / 39
Action
collect: 全要素を配列に入れて返すcount: 要素の数を返すtake: 先頭 k個の要素を返すなど,多数
36 / 39
RDDを二つ組み合わせ
join: 同じキーのものを合わせるsubtract: 差集合を作るなど
37 / 39
練習問題
Twitterデータから次のような集計を行いましょう台風データから “NAIST”という文字列は何回出てくるか台風データから “生駒”という文字列は何回出てくるかiPhone6sで最もツイートされている色は何色?
PS4, XBox. “Good”と言われる確率が高いのはどっち?
PS4のデータで “XBox”と共に良く使われている単語は何?
38 / 39
練習用データ
授業のページからダウンロードしてください.Apple (E)
GalaxyS6 (E)
iPad (E)
iPhone6/6s (E/J)
iPhone (E)
オリンピック (J)
PS4 (E)
SONY (E)
Surface (E)
XboxOne (E)
Xbox (E)
Xperia (E)
台風 (J)←一番大きい39 / 39