新版新特色,內容更權威,更適合收藏和找Hadoop之父簽名兒!2014年12月13日中國大數據大會,http://bdtc2014.hadooper.cn/歡迎光臨新云南皇冠假日酒店,與Hadoop之父Doug Cutting不見不散!
TOC \o "1-3" \h \z \u 第1章 初識Hadoop.. 1
1.1 數據!數據!... 1
1.2 數據的存儲與分析... 3
1.3 相較于其他系統的優勢... 4
1.3.1 關系型數據庫管理系統... 5
1.3.2 網格計算... 7
1.3.3 志愿計算... 9
1.4 Hadoop發展簡史... 10
1.5 Apache Hadoop和Hadoop生態系統.... 14
1.6 Hadoop的發行版本............................................................................................................. 15
1.6.1 本書包含的內容... 16
1.6.2 兼容性... 17
第2章 關于MapReduce.. 19
2.1 氣象數據集... 19
2.2 使用Unix工具來分析數據... 21
TOC \o "1-3" \h \z \u 第1章 初識Hadoop.. 1
1.1 數據!數據!... 1
1.2 數據的存儲與分析... 3
1.3 相較于其他系統的優勢... 4
1.3.1 關系型數據庫管理系統... 5
1.3.2 網格計算... 7
1.3.3 志愿計算... 9
1.4 Hadoop發展簡史... 10
1.5 Apache Hadoop和Hadoop生態系統.... 14
1.6 Hadoop的發行版本............................................................................................................. 15
1.6.1 本書包含的內容... 16
1.6.2 兼容性... 17
第2章 關于MapReduce.. 19
2.1 氣象數據集... 19
2.2 使用Unix工具來分析數據... 21
2.3 使用Hadoop來分析數據... 23
2.3.1 map和reduce. 23
2.3.2 Java MapReduce. 24
2.4 橫向擴展... 33
2.4.1 數據流... 34
2.4.2 combiner函數... 37
2.4.3 運行分布式的MapReduce作業... 39
2.5 Hadoop Streaming. 40
2.5.1 Ruby版本... 40
2.5.2 Python版本... 43
2.6 Hadoop Pipes. 44
第3章 Hadoop分布式文件系統.... 49
3.1 HDFS的設計... 49
3.2 HDFS的概念... 51
3.2.1 數據塊... 51
3.2.2 namenode和datanode. 52
3.2.3 聯邦HDFS. 53
3.2.4 HDFS的高可用性... 54
3.3 命令行接口... 56
3.4 Hadoop文件系統... 58
3.5 Java接口... 62
3.5.1 從Hadoop URL讀取數據... 63
3.5.2 通過FileSystem API讀取數據... 64
3.5.3 寫入數據... 68
3.5.4 目錄... 70
3.5.5 查詢文件系統... 70
3.5.6 刪除數據... 75
3.6 數據流... 75
3.6.1 剖析文件讀取... 75
3.6.2 剖析文件寫入... 78
3.6.3 一致模型... 81
3.7 通過Flume和Sqoop導入數據... 83
3.8 通過distcp并行復制... 84
3.9 Hadoop存檔... 86
3.9.1 使用Hadoop存檔工具... 86
3.9.2 不足... 88
第4章 Hadoop的I/O操作.... 89
4.1 數據完整性... 89
4.1.1 HDFS的數據完整性... 89
4.1.2 LocalFileSystem.. 91
4.1.3 ChecksumFileSystem.. 91
4.2 壓縮... 92
4.2.1 codec. 93
4.2.2 壓縮和輸入分片... 98
4.2.3 在MapReduce中使用壓縮... 99
4.3 序列化... 102
4.3.1 Writable接口... 103
4.3.2 Writable類... 105
4.3.3 實現定制的Writable集合... 114
4.3 序列化框架... 118
4.4 Avro. 121
4.4.1 Avro數據類型和模式... 122
4.4.2 內存中的序列化和反序列化... 126
4.4.3 Avro數據文件... 129
4.4.4 互操作性... 130
4.4.5 模式的解析... 133
4.4.6 排列順序... 135
4.4.7 關于AvroMapReduce. 137
4.4.8 使用AvroMapReduce進行排序... 141
4.4.9 其他語言的Avro MapReduce. 143
4.5 基于文件的數據結構... 143
4.5.1 關于SequenceFile. 143
4.5.2 關于MapFile. 151
第5章 MapReduce應用開發... 157
5.1 用于配置的API 157
5.1.1 資源合并... 159
5.1.2 可變的擴展... 160
5.2 配置開發環境... 160
5.2.1 管理配置... 162
5.2.2 輔助類GenericOptionsParser,Tool和ToolRunner 165
5.3 用MRUnit來寫單元測試... 168
5.3.1 關于Mapper 168
5.3.2 關于Reducer 170
5.4 本地運行測試數據... 171
5.4.1 在本地作業運行器上運行作業... 171
5.4.2 測試驅動程序... 175
5.5 在集群上運行... 176
5.5.1 打包作業... 177
5.5.2 啟動作業... 179
5.5.3 MapReduce的Web界面... 181
5.5.4 獲取結果... 184
5.5.5 作業調試... 185
5.5.6 Hadoop日志... 190
5.5.7 遠程調試... 192
5.6 作業調優... 193
5.7 MapReduce的工作流... 196
5.7.1 將問題分解成MapReduce作業... 197
5.7.2 關于JobControl 198
5.7.3 關于Apache Oozie. 199
第6章 MapReduce的工作機制... 205
6.1 剖析MapReduce作業運行機制... 205
6.1.1 經典的MapReduce (MapReduce 1) 206
6.1.2 YARN (MapReduce 2) 213
6.2 失敗... 219
6.2.1 經典MapReduce中的失敗... 219
6.2.2 YARN中的失敗... 222
6.3 作業的調度... 224
6.3.1 公平調度器... 225
6.3.2 容量調度器... 225
6.4 shuffle和排序... 226
6.4.1 map端... 226
6.4.2 reduce端... 228
6.4.3 配置調優... 230
6.5 任務的執行... 232
6.5.1 任務執行環境... 232
6.5.2 推測執行... 233
6.5.3 關于OutputCommitters. 235
6.5.4 任務JVM重用... 237
6.5.5 跳過壞記錄... 238
第7章 MapReduce的類型與格式.... 241
7.1 MapReduce的類型... 241
7.1.1 默認的MapReduce作業... 245
7.1.2 默認的Streaming作業... 249
7.2 輸入格式... 252
7.2.1 輸入分片與記錄... 252
7.2.2 文本輸入... 264
7.2.3 二進制輸入... 268
7.2.4 多個輸入... 269
7.2.5 數據庫輸入(和輸出) 270
7.3 輸出格式... 271
7.3.1 文本輸出... 271
7.3.2 二進制輸出... 272
7.3.3 多個輸出... 272
7.3.4 延遲輸出... 277
7.3.5 數據庫輸出... 277
第8章 MapReduce的特性.... 279
8.1 計數器... 279
8.1.1 內置計數器... 279
8.1.2 用戶定義的Java計數器... 284
8.1.3 用戶定義的Streaming計數器... 289
8.2 排序... 289
8.2.1 準備... 290
8.2.2 部分排序... 291
8.2.3 全排序... 295
8.2.4 輔助排序... 299
8.3 連接... 305
8.3.1 map端連接... 307
8.3.2 reduce端連接... 307
8.4 邊數據分布... 311
8.4.1 利用JobConf來配置作業... 311
8.4.2 分布式緩存... 311
8.5 MapReduce庫類... 318
第9章 構建Hadoop集群.... 321
9.1 集群規范... 321
9.2 集群的構建和安裝... 325
9.2.1 安裝Java. 326
9.2.2 創建Hadoop用戶... 326
9.2.3 安裝Hadoop. 326
9.2.4 測試安裝... 327
9.3 SSH配置... 327
9.4 Hadoop配置... 328
9.4.1 配置管理... 329
9.4.2 環境設置... 332
9.4.3 Hadoop守護進程的關鍵屬性... 336
9.4.4 Hadoop守護進程的地址和端口... 341
9.4.5 Hadoop的其他屬性... 343
9.4.6 創建用戶帳號... 346
9.5 YARN配置... 346
9.5.1 YARN守護進程的重要屬性... 347
9.5.2 YARN守護進程的地址和端口... 350
9.6 安全性... 352
9.6.1 Kerberos和Hadoop. 353
9.6.2 委托令牌... 355
9.6.3 其他安全性改進... 356
9.7 利用基準評測程序測試Hadoop集群... 358
9.7.1 Hadoop基準評測程序... 358
9.7.2 用戶作業... 361
9.8 云端的Hadoop. 361
第10章 管理Hadoop.. 367
10.1 HDFS. 367
10.1.1 永久性數據結構... 367
10.1.2 安全模式... 373
10.1.3 日志審計... 375
10.1.4 工具... 375
10.2 監控... 380
10.2.1 日志... 381
10.2.2 度量... 382
10.2.3 Java管理擴展(JMX) 385
10.3 維護... 387
10.3.1 日常管理過程... 387
10.3.2 委任和解除節點... 389
10.3.3 升級... 392
第11章 關于Pig.. 397
11.1 安裝與運行Pig. 398
11.1.1 執行類型... 399
11.1.2 運行Pig程序... 400
11.1.3 Grunt 401
11.1.4 Pig Latin編輯器... 401
11.2 示例... 402
11.3 與數據庫進行比較... 405
11.4 Pig Latin. 406
11.4.1 結構... 407
11.4.2 語句... 408
11.4.3 表達式... 413
11.4.4 類型... 414
11.4.5 模式... 415
11.4.6 函數... 420
11.4.7 宏... 422
11.5 用戶自定義函數... 423
11.5.1 過濾UDF. 423
11.5.2 計算UDF. 427
11.5.3 加載UDF. 429
11.6 數據處理操作... 432
11.6.1 數據的加載和存儲... 432
11.6.2 數據的過濾... 433
11.6.3 數據的分組與連接... 436
11.6.4 數據的排序... 441
11.6.5 數據的組合和切分... 442
11.7 Pig實戰... 443
11.7.1 并行處理... 443
11.7.2 參數代換... 444
第12章 關于Hive.. 447
12.1 安裝Hive. 448
12.2 示例... 450
12.3 運行Hive. 451
12.3.1 配置Hive. 452
12.3.2 Hive服務... 454
12.3.3 Metastore. 456
12.4 Hive與傳統數據庫相比... 458
12.4.1 讀時模式vs.寫時模式... 458
12.4.2 更新、事務和索引... 459
12.5 HiveQL. 460
12.5.1 數據類型... 461
12.5.2 操作與函數... 463
12.6 表... 464
12.6.1 托管表和外部表.. 465
12.6.2 分區和桶... 466
12.6.3 存儲格式... 471
12.6.4 導入數據... 477
12.6.5 表的修改... 479
12.6.6 表的丟棄... 480
12.7 查詢數據... 480
12.7.1 排序和聚集... 480
12.7.2 MapReduce腳本... 481
12.7.3 連接... 482
12.7.4 子查詢... 486
12.7.5 視圖... 486
12.8 用戶定義函數... 488
12.8.1 寫UDF. 489
12.8.2 寫UDAF. 491
第13章 關于HBase.. 497
13.1 HBase基礎... 497
13.2 概念... 498
13.3.1 數據模型的“旋風之旅” 498
13.3.2 實現... 500
13.3 安裝... 503
13.4 客戶端... 506
13.4.1 Java. 506
13.4.2 Avro、REST和Thrift 510
13.5 示例... 511
13.5.1 模式... 511
13.5.2 加載數據... 512
13.5.3 Web查詢... 516
13.6 HBase和RDBMS的比較... 519
13.6.1 成功的服務... 520
13.6.2 HBase. 521
13.6.3 實例:HBase在Streamy.com的使用... 522
13.7 Praxis. 524
13.7.1 版本... 524
13.7.2 HDFS. 525
13.7.3 用戶界面... 526
13.7.4 度量... 526
13.7.5 模式的設計... 526
13.7.6 計數器... 527
13.7.7 批量加載... 528
第14章 關于ZooKeeper. 529
14.1 安裝和運行ZooKeeper 530
14.2 示例... 532
14.2.1 ZooKeeper中的組成員關系... 533
14.2.2 創建組... 534
14.2.3 加入組... 536
14.2.4 列出組成員... 537
14.2.5 刪除組... 539
14.3 ZooKeeper服務... 540
14.3.1 數據模型... 540
14.3.2 操作... 543
14.3.3 實現... 548
14.3.4 一致性... 549
14.3.5 會話... 552
14.3.6 狀態... 554
14.4 使用ZooKeeper來構建應用... 555
14.4.1 配置服務... 555
14.4.2 可復原的ZooKeeper應用... 559
14.4.3 鎖服務... 563
14.4.4 更多分布式數據結構和協議... 565
14.5 生產環境中的ZooKeeper 567
14.5.1 可恢復性和性能... 567
14.5.2 配置... 568
第15章 關于Sqoop.. 571
15.1 獲取Sqoop. 571
15.2 Sqoop連接器... 573
15.3 一個導入的例子... 573
15.4 生成代碼... 577
15.5 深入了解數據庫導入... 578
15.5.1 導入控制... 580
15.5.2 導入和一致性... 581
15.5.3 直接模式導入... 581
15.6 使用導入的數據... 581
15.7 導入大對象... 585
15.8 執行導出... 587
15.9 深入了解導出功能... 589
15.9.1 導出與事務... 590
15.9.2 導出和SequenceFile. 591
第16章 實例學習.... 593
16.1 Hadoop 在Last.fm的應用... 593
16.1.1 Last.fm:社會音樂史上的革命... 593
16.1.2 Hadoop在Last.fm中的應用... 593
16.1.3 用Hadoop制作圖表... 594
16.1.4 Track Statistics程序... 595
16.1.5 總結... 602
16.2 Hadoop和Hive在Facebook的應用... 603
16.2.1 Hadoop在Facebook的使用... 603
16.2.2 虛構的使用樣例... 606
16.2.3 Hive. 609
16.2.4 存在的問題與未來工作計劃... 613
16.3 Nutch搜索引擎... 615
16.3.1 背景介紹... 615
16.3.2 數據結構... 616
16.3.3 Nutch系統利用Hadoop進行數據處理的精選實例... 619
16.3.4 總結... 630
16.4 Rackspace的日志處理... 631
16.4.1 要求/問題... 631
16.4.2 簡史... 632
16.4.3 選擇Hadoop. 632
16.4.4 收集和存儲... 632
16.4.5 對日志的MapReduce處理... 634
16.5 關于Cascading. 640
16.5.1 字段、元組和管道... 641
16.5.2 操作... 644
16.5.3 Tap、Scheme和Flow.. 645
16.5.4 Cascading實戰... 646
16.5.5 靈活性... 650
16.5.6 Hadoop和Cascading在ShareThis的應用... 650
16.5.7 總結... 655
16.6 Apache Hadoop上萬億數量級排序... 655
16.7 用Pig和Wukong探索10億數量級邊的網絡圖... 659
16.7.1 社區判斷... 661
16.7.2 每個人都在和我說話:Twitter回復關系圖... 661
16.7.3 對稱鏈接... 664
16.7.4 社區提取... 666
附錄A 安裝Apache Hadoop.. 669
附錄B 關于CDH... 675
附錄C 準備NCDC氣象數據.... 677
rd hd01.doc
初識Hadoop
在古時候,人們用牛來拉重物。當一頭牛拉不動一根圓木時,人們從來沒有考慮過要培育更強壯的牛。同理,我們也不該想方設法打造超級計算機,而應該千方百計綜合利用更多計算機來解決問題。^
——格蕾斯·霍珀(Grace Hopper)
1.1 數據!數據!^
我們生活在這個數據大爆炸的時代,很難估算全球電子設備中存儲的數據總共有多少。國際數據公司(IDC)曾經發布報告稱,2006年數字世界(digital universe)項目統計得出全球數據總量為0.18 ZB并預測在2011年將達到1.8 ZB。[1]1 ZB等于1021字節,等于1000 EB(exabytes),1 000 000 PB (petabytes),等于大家更熟悉的10億TB(terrabytes)!這相當于全世界每人一個硬盤中保存的數據總量!^
數據“洪流”有很多來源。以下面列出的為例:[2]^
l 紐約證交所每天產生的交易數據多達1 TB^
l 臉譜網(Facebook)存儲的照片約100 億張,存儲容量約為 1 PB^
l 家譜網站Ancestry.com存儲的數據約為2.5 PB^
l 互聯網檔案館(The Internet Archive)存儲的數據約為2 PB,并以每月至少20 TB的速度持續增長^
l 瑞士日內瓦附近的大型強子對撞機每年產生的數據約為15 PB^
還有其他大量的數據。但是你可能會想它對自己又有哪些影響呢?地球人都知道,大部分數據都嚴密鎖存在一些大型互聯網公司(如搜索引擎公司)或科學機構與金融機構中。難道所謂的“大數據”只影響小機構和個人?^
我個人是這樣認為的。以照片為例,我妻子的爺爺是一個骨灰級的攝影愛好者。在成年之后,他一直都在拍照。他的整個相冊,包括普通膠片、幻燈片、35mm膠片,在掃描成高分辨率的圖片之后,大約有10 GB。相比之下,在2008年,我家用數碼相機拍攝的照片總共有5 GB。對照爺爺的照片生成速度,我家是他老人家的35倍!并且,而且這個速度還在不斷增長中,因為現在拍照片真的是越來越容易了。^
有一種情況更普遍,個人產生的數據正在快速增長。微軟研究院的MyLifeBits 項目[3](http://research.microsoft.com/enus/projects/mylifebits/default.aspx)顯示,在不久的將來,個人信息檔案將日益普及。MyLifeBits的一個實驗是獲取和保存個人的對外聯系情況(包括電話、郵件和文件),供日后存取。收集的數據中包括每分鐘拍攝的照片等,數據量每月約為1 GB。當存儲成本急劇下降以至于可以存儲音頻和視頻時,MyLifeBits項目在未來的存儲的數據量將是現在的很多倍。^
保存個人成長過程中產生的所有數據似乎逐漸成為主流,但更重要的是,計算機產生的數據可能遠遠超過我們個人所產生的。機器日志、RFID檢測儀、傳感器網絡、車載GPS 和零售交易數據等——所有這些都將產生巨量的數據。^
在網上公開發布的數據也在逐年增加。組織或企業,要想在未來取得成功,不僅需要管理好自己的數據,更需要從其他組織或企業的數據中獲取有價值的信息。^
這方面的先鋒有Amazon Web Services(http://aws.amazon.com/publicdatasets)、Infochimps.org(http://infochimps.org/)和theinfo.org(http://theinfo.org),它們所發布的共享數據集,正在促進信息共享(informationcommons),供所有人自由下載和分析 (或者只需要支付合理的價格通過AWS 平臺來共享)。不同來源的信息在經過混搭和處理之后,會帶來意外的效果和我們今天難以想象的應用。^
以Astrometry.net(http://astrometry.net)為例,主要查看和分析Flickr網站上星空機器人小組所拍攝的星空照片。它對每一張照片進行分析并能辨別出它來自星空或其他天體(例如恒星和銀河系等)的哪一部分。雖然這項研究尚處于試驗階段,但也表明如果可用的數據足夠多(在本例中,為加有標簽的圖片數據),通過它們而產生的后續應用也許會超乎這些拍照片的人最初的想象 (圖片分析)。^
有句話說得好:“大數據勝于好算法。” 意思是說對于某些應用 (譬如根據以往的偏好來推薦電影和音樂),不論算法有多牛,基于小數據的推薦效果往往都不如基于大量可用數據的一般算法的推薦效果。[4]^
現在,我們已經有了大量數據,這是個好消息。但不幸的是,我們必須想方設法好好地存儲和分析這些數據。^
1.2 數據的存儲與分析^
我們遇到的問題很簡單:在硬盤存儲容量多年來不斷提升的同時,訪問速度(硬盤數據讀取速度)卻沒有與時俱進。1990年,一個普通硬盤可以存儲1370MB數據,傳輸速度為4.4MB/s[5],因此只需要5分鐘就可以讀完整個硬盤中的數據。20年過去了,1 TB的硬盤已然成為主流,但其數據傳輸速度約為100 MB/s,讀完整個硬盤中的數據至少得花2.5個小時。^
讀完整個硬盤中的數據需要更長時間,寫入數據就別提了。一個很簡單的減少讀取時間的辦法是同時從多個硬盤上讀數據。試想,如果我們有100個硬盤,每個硬盤存儲1%的數據,并行讀取,那么不到兩分鐘就可以讀完所有數據。^
僅使用硬盤容量的1%似乎很浪費。但是我們可以存儲100個數據集,每個數據集1 TB,并實現共享硬盤的讀取。可以想象,用戶肯定很樂于通過硬盤共享來縮短數據分析時間;并且,從統計角度來看,用戶的分析工作都是在不同時間點進行的,所以彼此之間的干擾并不太大。^
雖然如此,但要對多個硬盤中的數據并行進行讀寫數據,還有更多問題要解決。第一個需要解決的是硬件故障問題。一旦開始使用多個硬件,其中個別硬件就很有可能發生故障。為了避免數據丟失,最常見的做法是復制(replication):系統保存數據的復本(replica),一旦有系統發生故障,就可以使用另外保存的復本。例如,冗余硬盤陣列(RAID)就是按這個原理實現的,另外,Hadoop的文件系統(HDFS,Hadoop Distributed FileSystem)也是一類,不過它采取的方法稍有不同,詳見后文的描述。^
第二個問題是大多數分析任務需要以某種方式結合大部分數據來共同完成分析,即從一個硬盤讀取的數據可能需要與從另外99個硬盤中讀取的數據結合使用。各種分布式系統允許結合不同來源的數據進行分析,但保證其正確性是一個非常大的挑戰。MapReduce提出一個編程模型,該模型抽象出這些硬盤讀寫問題并將其轉換為對一個數據集(由鍵值對組成)的計算。后文將詳細討論這個模型,這樣的計算由map和reduce兩部分組成,而且只有這兩部分提供對外的接口。與HDFS類似,MapReduce自身也有很高的可靠性。^
簡而言之,Hadoop為我們提供了一個可靠的共享存儲和分析系統。HDFS實現數據的存儲,MapReduce實現數據的分析和處理。雖然Hadoop還有其他功能,但HDFS和MapReduce是它的核心價值。^
1.3 相較于其他系統的優勢^
MapReduce看似采用了一種蠻力方法。每個查詢需要處理整個數據集或至少一個數據集的絕大部分。但反過來想,這也正是它的能力。MapReduce是一個批量查詢處理器,能夠在合理的時間范圍內處理針對整個數據集的動態查詢。它改變了我們對數據的傳統看法,解放了以前只是保存在磁帶和硬盤上的數據。它讓我們有機會對數據進行創新。以前需要很長時間處理才能獲得結果的問題,到現在變得頃刻之間就迎刃而解,同時還可以引發新的問題和新的見解。^
例如,Rackspace公司的郵件部門Mailtrust就用Hadoop來處理郵件日志。他們寫動態查詢,想借此找出用戶的地理分布。他們是這么描述的:“這些數據非常有用,我們每月運行一次MapReduce任務來幫助我們決定哪些Rackspace數據中心需要添加新的郵件服務器。” ^
通過整合好幾百GB的數據,用MapReduce來分析這些數據,Rackspace的工程師從中發現了以前從來沒有注意到的數據,甚至還運用這些信息來改善了現有的服務。第16章將詳細介紹Rackspace公司內部是如何使用Hadoop的。^
1.3.1 關系型數據庫管理系統^
為什么不能用數據庫來對大量硬盤上的大規模數據進行批量分析呢?我們為什么需要MapReduce?^
這兩個問題的答案來自于計算機硬盤的另一個發展趨勢:尋址時間的提升遠遠不敵于傳輸速率的提升。尋址是將磁頭移動到特定硬盤位置進行讀寫操作的過程。它是導致硬盤操作延遲的主要原因,而傳輸速率取決于硬盤的帶寬。
如果數據訪問模式中包含大量的硬盤尋址,那么讀取大量數據集就必然會花更長的時間(相較于流數據讀取模式,流讀取主要取決于傳輸速率)。另一方面,如果數據庫系統只更新一小部分記錄,那么傳統的B樹就更有優勢(關系型數據庫中使用的一種數據結構,受限于尋址的比例)。但數據庫系統如果有大量數據更新時,B樹的效率就明顯落后于MapReduce,因為需要使用“排序/合并“(sort/merge)來重建數據庫。^
在許多情況下,可以將MapReduce視為關系型數據庫管理系統的補充。兩個系統之間的差異如表1-1所示。^
MapReduce比較適合以批處理方式處理需要分析整個數據集的問題,尤其是動態分析。RDBMS適用于點查詢 (point query)和更新,數據集被索引之后,數據庫系統能夠提供低延遲的數據檢索和快速的少量數據更新。MapReduce適合一次寫入、多次讀取數據的應用,關系型數據庫則更適合持續更新的數據集。^
表1-1. 關系型數據庫和MapReduce的比較^
| 傳統的關系型數據庫 | MapReduce |
數據大小 | GB | PB |
數據存取 | 交互式和批處理 | 批處理 |
更新 | 多次讀/寫 | 一次寫入,多次讀取 |
結構 | 靜態模式 | 動態模式 |
完整性 | 高 | 低 |
橫向擴展 | 非線性的 | 線性的 |
MapReduce和關系型數據庫之間的另一個區別在于它們所操作的數據集的結構化程度。結構化數據(structureddata)是具有既定格式的實體化數據,如XML文檔或滿足特定預定義格式的數據庫表。這是RDBMS包括的內容。另一方面,半結構化數據(semi-structured data)比較松散,雖然可能有格式,但經常被忽略,所以它只能作為對數據結構的一般性指導。例如電子表格,它在結構上是由單元格組成的網格,但是每個單元格內可以保存任何形式的數據。非結構化數據(unstructureddata)沒有什么特別的內部結構,例如純文本或圖像數據。MapReduce對非結構化或半結構化數據非常有效,因為它是在處理數據時才對數據進行解釋。換句話說,MapReduce輸入的鍵和值并不是數據固有的屬性,而是由分析數據的人來選的。^
關系型數據往往是規范的(normalized),以保持其數據的完整性且不含冗余。規范給MapReduce帶來了問題,因為它使記錄讀取成為非本地操作,而MapReduce的核心假設之一偏偏就是可以進行(高速的)流讀寫操作。^
Web服務器日志是典型的非規范化數據記錄(例如,每次都需要記錄客戶端主機全名,這會導致同一客戶端的全名可能多次出現),這也是MapReduce非常適用于分析各種日志文件的原因之一。^
MapReduce是一種線性的可伸縮編程模型。程序員要寫兩個函數,分別為map函數和reduce函數,每個函數定義從一個鍵值對集合到另一個鍵值對集合的映射。這些函數不必關注數據集及其所用集群的大小,可以原封不動地應用于小規模數據集或大規模的數據集。更重要的是,如果輸入的數據量是原來的兩倍,那么運行時間也需要兩倍。但如果集群是原來的兩倍,作業的運行速度卻仍然與原來一樣快。SQL查詢一般不具備該特性。^
但是,在不久的將來,關系型數據庫系統和MapReduce系統之間的差異很可能變得模糊。關系型數據庫都開始吸收MapReduce的一些思路(如Aster Data的數據庫和GreenPlum的數據庫),另一方面,基于MapReduce的高級查詢語言(如Pig和Hive)使傳統數據庫的程序員更容易接受MapReduce系統。[6]^
1.3.2 網格計算^
高性能計算(High Performance Computing,HPC)和網格計算(Grid Computing)組織多年以來一直在研究大規模數據處理,主要使用類似于消息傳遞接口(MessagePassing Interface,MPI)的API。從廣義上講,高性能計算采用的方法是將作業分散到集群的各臺機器上,這些機器訪問存儲區域網絡(SAN)所組成的共享文件系統。這比較適用于計算密集型的作業,但如果節點需要訪問的數據量更龐大 (高達幾百GB,MapReduce開始施展它的魔法),很多計算節點就會因為網絡帶寬的瓶頸問題不得不閑下來等數據。^
MapReduc盡量在計算節點上存儲數據,以實現數據的本地快速訪問。[7]數據本地化(datalocality)特性是MapReduce的核心特征,并因此而獲得良好的性能。意識到網絡帶寬是數據中心環境最珍貴的資源(到處復制數據很容易耗盡網絡帶寬)之后,MapReduce通過顯式網絡拓撲結構來保留網絡帶寬。注意,這種排列方式并沒有降低MapReduce對計算密集型數據進行分析的能力。^
雖然MPI賦予程序員很大的控制權,但需要程序員顯式控制數據流機制,包括用C語言構造底層的功能模塊(例如套接字)和高層的數據分析算法。而MapReduce則在更高層次上執行任務,即程序員僅從鍵值對函數的角度考慮任務的執行,而且數據流是隱含的。^
在大規模分布式計算環境下,協調各個進程的執行是一個很大的挑戰。最困難的是合理處理系統的部分失效問題——在不知道一個遠程進程是否掛了的情況下——同時還需要繼續完成整個計算。有了MapReduce,程序員不必操心系統部分失效的問題,因為它自己的系統實現能夠檢測到并重新執行那些失敗的map或reduce任務。正因為采用的是無共享(shared-nothing)框架,MapReduce才能夠實現失敗檢測,這意味著各個任務之間是彼此獨立的。[8]因此,從程序員的角度來看,任務的執行順序無關緊要。相比之下,MPI程序必須顯式管理自己的檢查點和恢復機制,雖然賦予程序員的控制權加大了,但編程的難度也增加了。^
MapReduce聽起來似乎是一個相當嚴格的編程模型,而且在某種意義上看的確如此:限定用戶使用有特定關聯的鍵值對,mapper和reducer彼此間的協調非常有限(每個mapper將鍵值對傳給reducer)。由此,我們自然聯想到一個問題:能用這個編程模型做一些有用或實際的事情嗎?^
答案是肯定的。MapReduce由谷歌的工程師開發,用于構建搜索引擎的索引,而且,事實已經證明它能夠一次又一次地解決這個問題(MapReduce 的靈感來自于傳統的函數式編程、分布式計算和數據庫社區),但此后,該模型在其他行業還有著很多其他的應用。我們欣喜地發現,有很多算法都可以用MapReduce來表達,從圖像圖形分析到各種各樣基于圖像分析的問題,再到機器學習算法。[9]當然,它也不是包治百病的靈丹妙藥,不能解決所有問題,但它真的是一個很通用的數據處理工具。^
我們將在第16章介紹Hadoop的一些典型應用。^
1.3.3 志愿計算^
人們第一次聽說Hadoop和MapReduce的時候,經常會問這個問題:“它們和SETI@home有什么不同?”SETI全稱為Searchfor Extra-Terrestrial Intelligence(搜索外星智能),項目名稱為SETI@home(http://setiathome.berkeley.edu)。在該項目中,志愿者把自己計算機CPU的空閑時間貢獻出來分析無線天文望遠鏡的數據,借此尋找外星智慧生命信號。SETI@home因為擁有龐大的志愿者隊伍而非常出名,其他還有“搜索大素數”(Great Internet MersennePrime Search)項目與Folding@home項目(了解蛋白質構成及其與疾病之間的關系)。^
志愿計算項目將問題分成很多塊,每一塊稱為一個工作單元(work unit),發到世界各地的計算機上進行分析。例如,SETI@home的工作單元是0.35 MB無線電望遠鏡數據,要對這等大小的數據量進行分析,一臺普通計算機需要幾個小時或幾天時間才能完成。完成分析后,結果發送回服務器,客戶端隨后再獲得另一個工作單元。為防止欺騙,每個工作單元要發送到3臺不同的機器上執行,而且收到的結果中至少有兩個相同才會被接受。^
從表面上看,SETI@home與MapReduce好像差不多(將問題分解為獨立的小塊,然后并行進行計算),但事實上還是有很多明顯的差異。SETI@home問題是CPU高度密集的,比較適合在全球成千上萬臺計算機上運行,[10]因為計算所花的時間遠遠超過工作單元數據的傳輸時間。也就是說,志愿者貢獻的是CPU周期,而不是網絡帶寬。^
MapReduce有三大設計目標:(1)為只需要短短幾分鐘或幾個小時就可以完成的作業提供服務;(2)運行于同一個內部有高速網絡連接的數據中心內;(3)數據中心內的計算機都是可靠的、定制的硬件。相比之下,SETI@home則是在接入互聯網的不可信的計算機上長時間運行,這些計算機的網絡帶寬不同,對數據本地化也沒有要求。^
1.4 Hadoop發展簡史^
Hadoop是Apache Lucene創始人Doug Cutting創建的,Lucene是一個應用廣泛的文本搜索系統庫。Hadoop起源于開源的網絡搜索引擎Apache Nutch,它本身也是Lucene項目的一部分。^
Hadoop的得名 Hadoop不是縮寫,它是一個生造出來的詞。Hadoop之父Doug Cutting這樣解釋Hadoop的來歷: “這個名字是我的小孩給他的毛絨象玩具取的。我的命名標準是好拼讀,含義寬泛,不會被用于其他地方。小孩子是這方面的高手。Googol就是小孩子起的名字。” Hadoop的子項目及后續模塊所使用的名稱也往往與其功能不相關,通常也以大象或其他動物為主題取名(例如Pig)。較小一些的組件,名稱通常都有較好的描述性(因此也更流俗)。這個原則很好,意味著我們可以望文知義,例如jobtracker[11],一看就知道它是用來跟蹤MapReduce作業的。 |
從頭打造一個網絡搜索引擎是一個雄心勃勃的計劃,不只是因為寫爬蟲程序很復雜,更因為必須有一個專職團隊來實現——項目中包含許許多多需要隨時修改的活動部件。同時,構建這樣的系統代價非常高——據Mike Cafarella和Doug Cutting估計,一個支持10億網頁的索引系統,單是硬件上的投入就高達50萬美元,另外還有每月高達3萬美元的運維費用。[12]不過,他們認為這個工作仍然值得投入,因為它開創的是一個優化搜索引擎算法的平臺。^
Nutch項目開始于2002年,一個可以運行的網頁爬取工具和搜索引擎系統很快面試。但后來,開發者認為這一架構的靈活性不夠,不足以解決數十億網頁的搜索問題。一篇發表于2003年的論文為此提供了幫助,文中描述的是谷歌產品架構,該架構稱為“谷歌分布式文件系統”,簡稱GFS。[13]GFS或類似的架構,可以解決他們在網頁爬取和索引過程中產生的超大文件的存儲需求。特別關鍵的是,GFS能夠節省系統管理(如管理存儲節點)所花的大量時間。在2004年,他們開始著手做開源版本的實現,即Nutch分布式文件系統(NDFS)。^
2004年,谷歌發表論文向全世界介紹他們的MapReduce系統。[14]2005年初,Nutch的開發人員在Nutch上實現了一個MapReduce系統,到年中,Nutch的所有主要算法均完成移植,用MapReduce和NDFS來運行。^
Nutch的NDFS和MapReduce實現不只適用于搜索領域。在2006年2月,開發人員將NDFS和MapReduce移出Nutch形成Lucene的一個子項目,命名為Hadoop。大約在同一時間,Doug Cutting加入雅虎,雅虎為此組織了專門的團隊和資源,將Hadoop發展成能夠處理Web數據的系統(參見后面的補充材料“Hadoop在雅虎“)。在2008年2月,雅虎宣布,雅虎搜索引擎使用的索引是在一個擁有1萬個內核的Hadoop集群上構建的。[15]^
2008年1月,Hadoop已成為Apache的頂級項目,證明了它的成功、多樣化和生命力。到目前為止,除雅虎之外,還有很多公司在用Hadoop,例如Last.fm、Facebook和《紐約時報》等。第16章和Hadoop 維基頁面(英文)介紹了一些案例(http://wiki.apache.org/hadoop/PoweredBy)。^
《紐約時報》的案例廣為流傳,他們把1851 年到 1980 年的存檔掃描之后得到4 TB的文件并用亞馬遜的EC2云服務將文件存為PDF格式放到網上共享。[16]整個過程一共使用了100臺計算機,所花的時間不到24小時。如果沒有亞馬遜的按小時付費模式(即允許《紐約時報》短期內訪問大量機器)和Hadoop好用的并發編程模型珠聯璧合,這個項目不太可能這么快就啟動和完成。^
2008年4月,Hadoop打破世界紀錄,成為最快的TB級數據排序系統。在一個910節點的群集,Hadoop在209 秒內(不到3.5分鐘)完成了對1TB數據的排序,擊敗了前一年的297秒冠軍(詳情參見15.5節的補充材料“ApacheHadoop的TB級數據處理”)。同年11月,谷歌在報告中聲稱,它的MapReduce對1 TB數據排序只用了68秒。[17]2009年5月本書第1版出版的時候,有報道稱雅虎有一個的團隊使用 Hadoop對1 TB數據進行排序只花了62秒。^
從那以后,Hadoop躍升為企業主流的部署系統。在工業界,Hadoop已經是公認的大數據通用存儲和分析平臺,這一事實主要體現在大量直接使用或者間接輔助Hadoop系統的產品如雨后春筍般大量涌現。一些大公司也發布Hadoop發行版本,包括EMC,IBM,Microsft和Oracle以及一些專注于Hadoop的公司,如Cloudera,Hortonworks[18]和MapR。^
Hadoop在雅虎^ 作者:Owen O’Melly ^ 構建互聯網規模的搜索引擎離不開大量的數據,因此也離不開大量的機器來處理巨量的數據。雅虎搜索引擎(Yahoo!Search)有4個主要組成部分:Crawler,從網頁服務器爬取網頁;WebMap,構建一個已知網頁的鏈接圖;Indexer,為最佳頁面構建一個反向索引;Runtime,處理用戶的查詢。WebMap生成的鏈接圖非常大,大約包括一萬億(1012)條邊(每條邊代表一個網頁鏈接)和一千億(1011)個節點(每個節點代表不同的網址)。創建并分析如此大的圖需要大批計算機很多天長時間運行。到2005年初,WebMap用的底層架構Dreadnaught需要重新設計以便日后擴展到更多的節點。^ |
Dreadnaught從20個節點成功擴展到600個,但需要完全重新設計才能進一步擴大。Dreadnaught與MapReduce在很多方面都很相似,但靈活性更強,結構也更松散。說具體點,一個Dreadnaught作業的每一個片斷(fragment,也稱“分塊”)都可以輸送到下一階段的各個片段繼續執行,排序則是通過庫函數來完成的。但實際情形是,大多數WebMap階段是兩兩一對,對應于MapReduce。因此,WebMap應用不需要做大量重構操作就可以適應MapReduce。 Eric Baldeschwieler(Eric14)組建了一個小團隊,于是我們開始設計并在GFS和MapReduce上用C++來建立一個新框架的原型,并打算用它來取代Dreadnaught。盡管我們的當務之急是需要一個新的WebMap框架,但更清楚的是,建立雅虎搜索引擎批處理平臺的標準對我們更重要。使平臺更通用以便支持其他用戶,才能夠更好地實現新平臺的均衡性投資。 與此同時,我們也關注在Hadoop(當時也是Nutch的一部分)及其進展情況。2006年1月,雅虎聘請了Doug Cutting。一個月后,我們決定放棄原型,轉而采用 Hadoop。與我們的原型和設計相比,Hadoop的優勢在于它已經在20 個節點上實際應用過(Nutch)。這樣一來,我們便能在兩個月內搭建一個研究集群并能夠以很快的速度幫助我們的客戶使用這個新的框架。另一個顯著的優點是Hadoop已經開源,比較容易(盡管也不是想象的那么容易!)從雅虎法務部門獲得許可對該開源系統進行進一步研究。因此,我們在2006年初建立了一個200節點的研究集群并暫時擱置WebMap計劃,轉而為研究用戶提供Hadoop支持和優化服務。 Hadoop大事記 2004年 | Doug Cutting和Mike Cafarella實現了HDFS和MapReduce的初版 | 2005年12月 | Nutch移植到新框架,Hadoop在20個節點上穩定運行 | 2006年1月 | Doug Cutting加入雅虎 | 2006年2月 | Apache Hadoop項目正式啟動,支持MapReduce和HDFS獨立發展 | 2006年2月 | 雅虎的網格計算團隊采用Hadoop | 2006年4月 | 在188個節點上(每節點10 GB)運行排序測試集需要47.9個小時) | 2006年5月 | 雅虎建立了一個300個節點的Hadoop研究集群 | 2006年5月 | 在500個節點上運行排序測試集需要42個小時(硬件配置比4月份的更好) | 2006年11月 | 研究集群增加到600個節點 | | |
|
2006年12月 | 排序測試集在20個節點上運行1.8個小時,100個節點上運行3.3小時,500個節點上運行5.2小時,900個節點上運行7.8個小時 | 2007年1月 | 研究集群增加到900個節點 | 2007年4月 | 研究集群增加到兩個集群1000個節點 | 2008年4月 | 在900個節點上運行1 TB排序測試集僅需209秒,成為全球最快 | 2008年10月 | 研究集群每天裝載10 TB的數據 | 2009年3月 | 17個集群共24 000個節點 | 2009年4月 | 在每分鐘排序中勝出,59秒內排序500 GB(在1400個節點上)和173分鐘內排序100 TB數據(在3400個節點上) |
|
[1] Gantz等人2008年3月發表的文章“The Diverse and Exploding Digital Universe”(紛繁多樣并不斷膨脹的數字世界),網址為http://china.emc.com/collateral/analyst-reports/expanding-digital-idc-white-paper.pdf。^
[2] http://www.intelligententerprise.com/showArticle.jhtml?articleID=207800705;http://mashable.com/ 2008/10/15/facebook-10-billion-photos/;http://blog.familytreemagazine.com/insider/ Inside+Ancestrycoms+TopSecret+Data+Center.aspx;http://www.archive.org/about/faqs.php;
http://www.interactions.org/cms/?pid=1027032。^
[3] 編注:更多詳細介紹可以參見阮一峰的博客文章“微軟的MyLifeBits項目”,網址為http://www.ruanyifeng.com/blog/2007/12/mylifebits.html。^
[4] 引自Anand Rajaraman發表的文章“Netflix Challenge”(Negfix挑戰大賽),網址為 http://anand.typepad.com/datawocky/2008/03more-data-usual.html。在這個挑戰大賽中,Netflix公司公開自己的用戶評分數據,讓研究者根據這些數據對用戶沒有看過的電影預測評分,誰最先比現有系統好10%,誰就能贏得100萬美元的獎金。Alon Halevy,Peter Norvig(谷歌研究主管)和Fernando Pereira在他們的一篇文章中也提出了類似的觀點,題為“TheUnreasonable Effectiveness of Data”(數據的非理性效果),發表于IEEE Intelligent Systems 2009年3/4月合刊。
[5] 這些規格對應的是希捷的ST-41600n硬盤。
[6] 2007年1月,數據庫理論專家David J. DeWitt和Michael Stonebraker發表的論文引發一場激烈的口水大戰,論文標題為“MapReduce: A major step backwards”(MapReduce:一個巨大的倒退),原文可參見http://databasecolumn.vertica.com/ database-innovation/mapreduce a-major-step-backwards,中文版可參考http://wap.oschina.net/question/17793_31108)。在文中,他們認為MapReduce不宜取代關系型數據庫。許多評論認為這是一種錯誤的比較,詳情可參見Mark C. Chu-Carroll的文章“Databasesare hammers; MapReduce is a screwdriver”(如果說數據庫是錘子,MapReduce則是螺絲刀),英文版網址為http://scienceblogs.com/goodmath/2008/01 databases_are_hammers_mapreduc.php,中文版可以參考http://blog.csdn.net/ wanghai__/article/details/5954108。DeWitt與Stonebraker以“再說MapReduce”一文對其他人的觀點進行了闡述,原文可參見http://databasecolumn.vertica.com/database-innovation/mapreduce-ii,他們對其他人的主要觀點進行了闡述。
[7] 1998年圖靈獎得主Jim Gray在2003年3月發表的“DistributedComputing Economics”(分布式計算經濟學)一文中,率先提出這個結論:數據處理應該在離數據本身比較近的地方進行,因為這樣有利于降低成本,尤其是網絡帶寬消費所造成的成本。原文網址為http://research.microsoft.com/apps/pubs/default.aspx?id=70001。
[8] 這里講得太簡單了一點,因為MapReduce 系統本身控制著mapper輸出結果傳給reducer的過程,所以在這種情況下,重新運行reducer比重新運行mapper更要小心,因為reducer需要獲取必要的mapper輸出結果,如果沒有,必須再次運行對應的mapper,重新生成輸出結果。
[9] Apache Mahout(http://mahout.apache.org/)是一個在Hadoop上運行的機器學習類庫(例如分類和聚類算法)。
[10] 2008年1月,SETI@home發表評論說每天使用320 000臺計算機處理300 GB數據,同時他們也在做其他的一些數據計算,原文參見http://www.planetary.org/programs/ projects/setiathome/setiathome_20080115。
[11] 在本書中我們使用小寫的jobtracker來代表實體(泛稱),用駝峰體JobTracker來表示對Java類的實現。
[12] Mike Cafarella和Doug Cutting在2004年4月發表在ACM Queue上的文章“Building Nutch: Open Source Search”,網址為http://queue.acm.org/detail.cfm?id=988408。
[13] Sanjay Ghemawat,Howard Gobioff和Shun-Tak Leung在2003年10月發表的文章“The Google File System”,網址為http://labs.google.com/papers/gfs.html。
[14] 參見Jeffrey Dean和Sanjay Ghemawat 2004年12月發表的文章“MapReduce: Simplified Data Processing on Large Clusters”(MapReduce: 大型集群的數據簡化處理),網址為http://labs.google.com/papersmapreduce.html。
[15] 參見2008年2月19日發表的文章“雅虎發布全球最大的Hadoop產品應用”(Yahoo!Lauches World’s Largest Hadoop ProductionApplications),網址為http://developer. yahoo.com/blogs/hadoop/posts/2008/ 02/yahoo-worlds-largest-production-hadoop/。
[16] 參見Derek Gottfrid在 2007年11月1日發表的文章“Self-service, Prorated Super Computing Fun!”(自助式比例分配超級計算的樂趣!),網址為http://open.blogs.nytimes.com/2007/11/01/self-service-prorated-super-computing-fun/。
[17] 全文參見2008年11月21日的文章“Sorting 1PB with MapReduce”(MapReduce處理1 PB數據),網址為http://googleblog.blogspot.com/2008/11/sorting-1pb-with-mapreduce.html。
[18] 編者注:該公司是雅虎的幾個核心開發人員創辦的,主要提供Hadoop支持和咨詢服務,他們已經與微軟在2011年建立戰略合作關系,幫助微軟將Hadoop移植到Wiondows Server和Azure。