hadoop14--hive函數, 壓縮, 調優, 日誌分析

函數

在hive中存在系統自帶的函數, 如果說自帶的函數不能滿足開發需求的時候, 就必須編寫自定義函數

查看系統自帶的函數

ow functions
================
tab_name
!
!=
%
...
...
xpath_short
xpath_string
year
=================

自定義函數

主要是爲了對hive中函數進行擴展, 因爲hive中雖然自定義了一些函數, 但是在實際開發中基本上是滿足不了需求的, 就需要自定義函數

創建自定義函數的步驟

需要hive jar包的環境, 可以使用maven, 也可以直接導入hive中jar包

  1. 解壓hive安裝包, 在lib路徑下的所有jar包拷貝到項目中, build path
  2. 如果要想自定義函數的開發, 則自定義創建的類, 必須繼承自UDF
import org.apache.hadoop.hive.ql.exec.UDF;
  1. 創建自定義函數
import org.apache.hadoop.hive.ql.exec.UDF;

public class Myudf extends UDF {
	// 需要實現evaluate函數
	public String evaluate(String s) {
		if (s == null) {
			return null;
		}

		return s.toString().toUpperCase();

	}
}

對於以上的自定義函數, 完成之後需要打成jar包上傳到服務器中

  1. 打成jar包, 通過eclipse導出
  2. 把導出的jar包與hive進行關聯, 添加到hive的classpath中
add jar /home/hadoop/data/myUdf.jar;
  1. 創建臨時函數, 與開發好的Javaclass進行關聯
create temporary function myUdf as 'com.hive.udf.Myudf';
  1. 在hive中使用自定義函數
select name ,myudf(name) from student;

壓縮和存儲格式

在hive中壓縮的目的是爲了節省數據傳輸的帶寬, hive中底層運行的是MapReduce, 在設置壓縮的時候有以下幾種格式:

bin/hadoop checknative
------------------------------------
hadoop:  true /opt/app/hadoop-2.7.2/lib/native/libhadoop.so.1.0.0
zlib:    true /lib64/libz.so.1
snappy:  false
lz4:     true revision:99
bzip2:   false

對於hadoop支持的壓縮格式, 在hive中設置壓縮格式之後就可以使用, 但是對於不支持的壓縮格式, 需要安裝編譯

壓縮

map階段的輸出, 減少map到reduce之間的數據傳輸量

開啓map端輸出壓縮配置
  1. 開啓傳輸壓縮的功能
<property>
    <name>hive.exec.compress.intermediate</name>
    <value>true</value>
  -----------  <description>
		這個是開啓壓縮
    </description>
  </property>
  1. 開啓MapReduce中map的輸出壓縮功能
set mapreduce.map.output.compress=true;
  1. 設置MapReduce中map輸出壓縮的方式
set mapreduce.map.output.compress.codec;
-----------------------------------------
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec

由於沒有安裝snappy 首先使用默認壓縮方式進行壓縮

  1. 執行查詢語句
select count(*) from emp;
開啓reduce端的輸出壓縮
  1. 開啓最終的輸出壓縮功能
hive (default)> set hive.exec.compress.output=true;
  1. 開啓最終輸出壓縮的設置
hive (default)> set mapreduce.output.fileoutputformat.compress=true;
  1. 設置最終輸出壓縮的方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec;
mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
  1. 最終輸出數據格式
hive (default)> set mapreduce.output.fileoutputformat.compress.type;
mapreduce.output.fileoutputformat.compress.type=RECORD
//這裏默認是RECORD,也可以設置成BLOCK
  1. 查看輸出的數據是否是壓縮文件
insert overwrite local  directory '/home/hadoop/data' select * from emp distribute by deptno sort by empno desc;
---------------------------------------------
cat /home/hadoop/data/000000_0.deflate
---------------------------------------------
ly▒!▒3 ▒7\▒36▒뒹▒t▒v▒▒▒[▒E▒▒▒;▒F▒▒g▒mb▒q▒▒8;▒▒▒p▒"▒y▒o▒▒kaV▒▒s▒a▒▒R▒|▒[

文件的存儲格式

file_format:
  : SEQUENCEFILE
  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
  | ORC         -- (Note: Available in Hive 0.11.0 and later)
  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
  | JSONFILE    -- (Note: Available in Hive 4.0.0 and later)
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
  1. TEXTFILE : hive中默認的存儲格式, 該文件格式是按照行進行存儲的.
  2. ORC: 在hive 0 .11版本之後引用的存儲格式, 可以存放索引 index , row data 存放具體的數據, findex 下標數據
  3. JSONFILE: 可以通過web前端, 編寫js 埋點, 進行事件處理, 生成json數據, 傳輸到後臺, 以json的格式進行存儲
  4. PARQUET : 同樣也是面向列式的存儲格式, 以二進制的方式保存.

列式存儲和行式存儲

行式存儲的特點:

​ 存儲數據的時候, 以一行數據爲準進行存儲, 在檢索的時候方便檢索相鄰字段. 檢索相鄰字段的時候效率快, 但是對於如果存在大量數據的時候, 檢索單個字段的時候會把所有行的數據全部檢索出來.

列式存儲的特點:

​ 每個字段都在數據列上進行存儲, 和相鄰的字段關聯不大, 這樣的話在檢索的時候, 尤其是檢索少數列的時候, 增加了檢索的效率, 節省了緩存數據的空間.

安裝snappy壓縮支持

  1. 解壓snappy
[hadoop@hadoop apache-hive-1.2.1-bin]$ tar -zxvf ~/data/native-2.7.3-snappy.tar.gz
  1. 替換解壓之後本地庫的native
[hadoop@hadoop apache-hive-1.2.1-bin]$ mv native native.bak
  1. 關閉集羣, 分發到各個節點, 重啓集羣
scp -r /opt/app/hadoop-2.7.2/lib/native hadoop02:/opt/app/hadoop-2.7.2/lib/native
sbin/stop-all.sh
sbin/start-dfs.sh
sbin/start-yarn.sh

調優

fetch 抓取

hive在運行查詢任務的時候, 很多時候都會運行MapReduce任務, 在某些情況下, 不需要運行MapReduce任務, 這個時候就可以進行一些設置, 設置什麼情況下運行MapReduce任務, 什麼時候不運行MapReduce任務

<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
    <description>
      Expects one of [none, minimal, more].
      Some select queries can be converted to single FETCH task minimizing latency.
      Currently the query should be single sourced not having any subquery and should not have
      any aggregations or distincts (which incurs RS), lateral views and joins.
      0. none : disable hive.fetch.task.conversion
      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
      2. more    : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
    </description>
  </property>
  1. none : disable hive.fetch.task.conversion, 在運行任何查詢語句的時候, 都會運行MapReduce任務
set hive.fetch.task.conversion=none;
  1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only

  2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns) , 默認的方式, 以下查詢方式不運行MapReduce任務

//使用 * 的時候不運行MapReduce任務
select * from emp;

//使用單個字段的方式不運行MapReduce任務
select ename from emp;

//使用limit的時候不運行MapReduce任務
select ename from emp limit 1;

本地模式

hive中的本地模式, 在hive所在的本地節點上, 運行小量的數據, 這樣就不會涉及到集羣分配資源, 在小數據量的情況下, 效率會高很多

<property>
    <name>hive.exec.mode.local.auto</name>
    <value>false</value>
    <description>Let Hive determine whether to run in local mode automatically</description>
</property>
set hive.exec.mode.local.auto=true;

可以通過以上兩種方式開啓本地模式, hive會自動判斷數據量, 如果數據量較大會在集羣上運行, 如果數據量較小, 則會在本地節點上運行.

可以通過以下屬性進行文件大小的設置

set hive.exec.mode.local.auto.inputbytes.max==134217728

設置MapReduce最大文件輸入量, 如果超過該數量則再集羣中運行任務, 沒有超過該數據則再本地節點上運行

set hive.exec.mode.local.auto.input.files.max=4

測試本地模式:

select * from emp cluster by deptno;

開啓本地模式之前:

Time taken: 11.851 seconds, Fetched: 14 row(s)

開啓本地模式之後

Time taken: 1.378 seconds, Fetched: 14 row(s)

日誌分析

"27.38.5.159" "-" "31/Aug/2015:00:04:37 +0800" "GET /course/view.php?id=27 HTTP/1.1" "303" "440" - "http://www.qianfeng.com/user.php?act=mycourse" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "-" "learn.qianfeng.com"
  1. 建庫
create database if not exists qianfeng_test;
  1. 建表(字段)
create table IF NOT EXISTS qianfeng_source (
remote_addr string,
remote_user string,
time_local string,
request string,
status string,
body_bytes_sent string,
request_body string,
http_referer string,
http_user_agent string,
http_x_forwarded_for string,
host string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
stored as textfile ;
  1. 將數據加載到HDFS上, 通過hive對其映射成一張表
load data local inpath '/data/moodle.qianfeng.access.log' into table qianfeng_source;
  1. 對於以上數據加載之後, 發現實際上導入的數據與源數據不一致, 出現丟失的數據, 經過分析之後發現, 一個字段存在多個空格, 一個字段被切分成多個

  2. 經過分析, 可以使用正則表達式進行匹配. 以下爲hive觀望中提供的正則表達式建表實例

CREATE TABLE apachelog (
  host STRING,
  identity STRING,
  user STRING,
  time STRING,
  request STRING,
  status STRING,
  size STRING,
  referer STRING,
  agent STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  "input.regex" = "([^]*) ([^]*) ([^]*) (-|\\[^\\]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\".*\") ([^ \"]*|\".*\"))?"
)
STORED AS TEXTFILE;
  1. 建立正則表達式
"(\"[^ ]*\") (\"[-|^ ]*\") (\"[^}]*\") (\"[^}]*\") (\"[0-9]*\") (\"[0-9]*\") ([-|^ ]*) (\"[^ ]*\") (\"[^}]*\") (\"[-|^ ]*\") (\"[^ ]*\")"
  1. 重新建表
create table IF NOT EXISTS qianfeng_source (
remote_addr string,
remote_user string,
time_local string,
request string,
status string,
body_bytes_sent string,
request_body string,
http_referer string,
http_user_agent string,
http_x_forwarded_for string,
host string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  "input.regex" = "(\"[^ ]*\") (\"[-|^ ]*\") (\"[^}]*\") (\"[^}]*\") (\"[0-9]*\") (\"[0-9]*\") ([-|^ ]*) (\"[^ ]*\") (\"[^}]*\") (\"[-|^ ]*\") (\"[^ ]*\")"
)
STORED AS TEXTFILE;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章