一、WordCount原理
初學MapReduce編程,WordCount作為入門經典,類似於初學編程時的Hello World。WordCount的邏輯就是給定一個/多個文本,統計出文本中每次單詞/詞出現的次數。網上找的一張MapReduce實現WordCount的圖例,基本描述清楚了WordCount的內部處理邏輯。本文主要是從Hive使用的角度處理WordCount,就不贅述,之前的一篇博文有MapReduce實現WordCount的代碼,可參考 https://www.cnblogs.com/walker-/p/9669631.html。
圖1 MapRecude實現Word Count圖例
二、Hive實現WordCount
2.1 SQL實現
先直接上SQL語句,可以看出SQL實現確實比MapReduce實現要清爽得多。大概實現流程分為三步:
- 分割本文。根據分割符對文本進行分割,切分出每個單詞;
- 行轉列。對分割出來的詞進行處理,每個單詞作為一行;
- 統計計數。統計每個單詞出現的次數。
SELECT word, count(1) AS count FROM (SELECT explode(split(line, '\r')) AS word FROM docs) w GROUP BY word ORDER BY word;
2.2 實現細節
1. 准備文本內容
新建一個 /home/kwang/docs.txt 文本,文本內容如下:
hello world
hello kwang rzheng
2. 新建hive表
這里由於hive環境建表默認格式是ORC,直接load數據hive表無法直接讀取,故建表時指定了表格式。
CREATE TABLE `docs`( `line` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
3. 加載數據到hive表中
加載數據到hive表中有兩種方式,一種是從Linux本地文件系統加載,一種是從HDFS文件系統加載。
(1)從Linux本地文件系統加載
LOAD DATA LOCAL INPATH '/home/kwang/docs.txt' OVERWRITE INTO TABLE docs;
(2)從HDFS文件系統加載
首先需要將文件上傳到HDFS文件系統
$ hadoop fs -put /home/kwang/docs.txt /user/kwang/
其次從HDFS文件系統加載數據
LOAD DATA INPATH 'docs.txt' OVERWRITE INTO TABLE docs;
加載數據到hive表后,查看hive表的內容,和原始文本格式並沒有區別,將文本按行存儲到hive表中,可以通過 'select * from docs;' 看下hive表內容:
hello world
hello kwang rzheng
4. 分割文本
分割單詞SQL實現:
SELECT split(line, '\s') AS word FROM docs;
分割后結果:
["hello","world"] ["hello","kwang","rzheng"]
可以看出,分割后的單詞仍是都在一行,無法實現想要的功能,因此需要進行行轉列操作。
5. 行轉列
行轉列SQL實現:
SELECT explode(split(line, ' ')) AS word FROM docs;
轉換后的結果:
hello
world
hello
kwang
rzheng
6. 統計計數
SELECT word, count(1) AS count FROM (SELECT explode(split(line, ' ')) AS word FROM docs) w GROUP BY word ORDER BY word;
統計后結果:
hello 2 kwang 1 rzheng 1 world 1
至此,Hive已實現WordCount計數功能。
【參考資料】
[1]. https://www.oreilly.com/library/view/programming-hive/9781449326944/ch01.html