在這篇論文之前 — 它所降落的世界
到了 2009 年,業界為了商業智慧所蒐集的資料規模成長飛快,傳統資料倉儲方案的價格已高到難以負擔,Facebook 於是把日誌處理搬到 Hadoop,也就是跑在一般商用硬體上的開源 map-reduce 實作。問題出在介面:map-reduce 是非常底層的程式模型,每冒出一個新的商業問題,就得有工程師從頭撰寫、除錯,之後還要長期維護一支專用程式。這些程式難以重用,把檔案的實體配置寫死在程式碼裡,也讓只懂 SQL、不懂 Java 的分析師完全碰不到資料。當時已有其他 map-reduce 前端,最有名的是 Pig 與微軟的 Scope,但它們是資料流語言、沒有系統目錄,schema 與儲存格式散落在各個腳本中,而不是集中在一個共享、可查詢的地方。Hive 就是為了讓 Hadoop 叢集表現得像 Facebook 已經買不起的那座資料倉儲而寫的。
術語 — 依本篇論文的用法
- Table(表)
- 具名的關聯,其資料存放在單一 HDFS 目錄中,依系統目錄記錄的格式序列化成檔案。Hive 也支援 external table,直接查詢已存在於 HDFS、NFS 或本機目錄的資料。
- Partition(分割)
- 表的一種切分方式,分割欄位的值編碼在目錄路徑上而非存進資料列,例如 /wh/T/ds=20090101/ctry=US。分割決定資料在表目錄內的分布,也讓最佳化器能整個目錄地裁掉。
- Bucket
- 分割之下再依某欄位雜湊做的切分,每個 bucket 存成分割目錄中的一個檔案。Bucket 讓抽樣查詢能整個檔案跳過,也給 join 一份預先雜湊好的配置。
- SerDe
- 以 Java 撰寫的自訂 serialize 與 de-serialize 方法組,讓 Hive 能讀寫某種資料格式。SerDe 的實作類別存放在系統目錄中,於查詢編譯與執行時自動套用。
- Metastore
- Hive 的系統目錄,收錄 database、table 與 partition,內含欄位與型別、擁有者、儲存位置、bucket 與 SerDe 資訊。因為需要隨機存取更新,它跑在關聯式資料庫或一般檔案系統上,而不是 HDFS。
- HiveQL
- Hive 的類 SQL 宣告式語言,涵蓋 select、project、join、彙總、union all、from 子句中的子查詢,以及可指定序列化與分割選項的建表 DDL 和 load/insert DML。它會被編譯成執行計畫,而非逐列直譯。
- Multi-table insert
- 單一 HiveQL 敘述對同一份輸入跑多道查詢,並把各自結果寫入不同的表或分割。Hive 的最佳化方式是讓所有輸出共用同一次輸入掃描。
- Repartition 運算子(ReduceSinkOperator)
- 最佳化器在 join、group by 與自訂 map-reduce 運算子前插入的標記運算子,代表一次 shuffle。它標示 map 階段與 reduce 階段的邊界,實體計畫產生器會在每個這種標記處開啟新的 map-reduce 工作。
- External table(外部表)
- 資料留在原處(HDFS、NFS 或本機目錄)就地查詢的表,而不是載入倉儲目錄中的資料。它是讓既有檔案免複製即可被查詢的機制。