什么是HADOOP?
Hadoop 是海量數據的分布式存儲和計算平台。
Hadoop 的核心組成部分如圖所示,其中 Common 部分是基礎,有各個框架編寫時
不可缺少的代碼。HDFS 是底層負責存儲數據的技術,存放着以后需要被處理的海量數據,
類似於 MySQL 數據庫。YARN 是負責分配程序運行時需要的資源的,類似於 Apache 或者
Tomcat。MapReduce 是程序員編寫的處理存儲在 HDFS 中數據的代碼程序,類似於 php 程
序或者 java 程序。
Common 部分包含 Hadoop 框架的底層組件,包括數據 IO、數據類型、序列化、安全等
等,是各個組件通用的部
HDFS 是 Hadoop Distributed File System 的縮寫,即 Hadoop 分布式文件系統。在各種操
作系統中都有文件的管理,HDFS 是分布式的,本質上是一個分布式存儲數據的文件管理系
統。HDFS 是在 Linux 的文件系統之上套了一層管理文件的軟件技術。
YRAN 是 Yet Another Resource Negotiator 的縮寫,字面意思是另一個資源協調者,理解
為作業調度和資源管理平台,更方便一些。這里的“作業”指的是跑在 YRAN 上面的一組
程序,“資源”指的是集群中的 CPU、內存、硬盤、網絡帶寬等。
MapReduce 是 Hadoop 中的分布式計算模型,適合批處理的計算任務,分為 map 和 reduce
前后兩個階段。
HDFS命令行
(1)查看幫助
hdfs dfs -help
(2)查看當前目錄信息
hdfs dfs -ls /
(3)上傳文件
hdfs dfs -put /本地路徑 /hdfs路徑
(4)剪切文件
hdfs dfs -moveFromLocal a.txt /aa.txt
(5)下載文件到本地
hdfs dfs -get /hdfs路徑 /本地路徑
(6)合並下載
hdfs dfs -getmerge /hdfs路徑文件夾 /合並后的文件
(7)創建文件夾
hdfs dfs -mkdir /hello
(8)創建多級文件夾
hdfs dfs -mkdir -p /hello/world
(9)移動hdfs文件
hdfs dfs -mv /hdfs路徑 /hdfs路徑
(10)復制hdfs文件
hdfs dfs -cp /hdfs路徑 /hdfs路徑
(11)刪除hdfs文件
hdfs dfs -rm /aa.txt
(12)刪除hdfs文件夾
hdfs dfs -rm -r /hello
(13)查看hdfs中的文件
hdfs dfs -cat /文件
hdfs dfs -tail -f /文件
(14)查看文件夾中有多少個文件
hdfs dfs -count /文件夾
(15)查看hdfs的總空間
hdfs dfs -df /
hdfs dfs -df -h /
(16)修改副本數
hdfs dfs -setrep 1 /a.txt
什么是HIVE?
Hive 是建立在 Hadoop 上的數據倉庫基礎構架。它提供了一系列的工具,可以用來進行數據提取轉化加載(ETL ),這是一種可以存儲、查詢和分析存儲在 Hadoop 中的大規模數據的機制。Hive 定義了簡單的類 SQL 查詢語言,稱為 HQL ,它允許熟悉 SQL 的用戶查詢數據。同時,這個語言也允許熟悉 MapReduce 開發者的開發自定義的 mapper 和 reducer 來處理內建的 mapper 和 reducer 無法完成的復雜的分析工作。
簡單來說,Hive是SQL解析引擎,它將SQL語句轉譯成M/R Job然后在Hadoop執行。
Hive的表其實就是HDFS的目錄,按表名把文件夾分開。如果是分區表,則分區值是子文件夾,可以直接在M/R Job里使用這些數據。
Hive相當於hadoop的客戶端工具,部署時不一定放在集群管理節點中,可以放在某個節點上。
Hive 是建立在Hadoop上的數據倉庫基礎構架。
數據倉庫
倉庫中存放的數據:
為公司各個級別的決策提供數據支撐的數據數據。
數據庫
數據庫和數據倉庫的區別
數據庫注重OLTP(Online transcation process聯機事務處理)的操作
數據倉庫注重OLAP(Online analysis process 聯機分析處理/過程),追加導入的操作
數據提取轉化加載(ETL )----BI
E:Extract(提取,采集)
T:Transform(轉化)
L:Load(加載)
hive的特點
能夠存儲海量數據--->依托於hdfs
能夠分析,查詢海量數據
Hive是SQL解析引擎,它將SQL語句轉譯成M/R Job然后在Hadoop執行,在升級到3.0以后M/R 隨之被TEZ所替換。
HIVE的數據存儲
Hive的數據存儲基於Hadoop HDFS
Hive沒有專門的數據存儲格式
存儲結構主要包括:數據庫、文件、表、視圖、索引
Hive默認可以直接加載文本文件(TextFile),還支持SequenceFile、RCFile、OrcFile、TextFile
創建表時,指定Hive數據的列分隔符與行分隔符,Hive即可解析數據
HIVE的數據模型
內部表 受控表
所有的 Table 數據(不包括 External Table)都保存在warehouse這個目錄中。
刪除表時,元數據與數據都會被刪除
創建過程和數據加載過程(這兩個過程可以在同一個語句中完成),在加載數據的過程中,實際數據會被移動到數據倉庫目錄中;之后對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除
Eg:
創建表
create table inner_table (key string);
外部表
刪除外部表只刪除metastore的元數據,不刪除hdfs中的表數據
外部表 只有一個過程,加載數據和創建表同時完成,並不會移動到數據倉庫目錄中,只是與外部數據建立一個鏈接。當刪除一個 外部表 時,僅刪除該鏈接
指向已經在 HDFS 中存在的數據,可以創建 Partition
它和 內部表 在元數據的組織上是相同的,而實際數據的存儲則有較大的差異
Eg:
創建表
create external table external_table1 (key string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' location '/home/external';
在HDFS創建目錄/home/external
#hadoop fs -put /home/external_table.dat /home/external
加載數據
LOAD DATA INPATH '/home/external_table1.dat' INTO TABLE external_table1;
分區表
分區可以理解為分類,通過分類把不同類型的數據放到不同的目錄下。
分類的標准就是分區字段,可以一個,也可以多個。
分區表的意義在於優化查詢。查詢時盡量利用分區字段。如果不使用分區字段,就會全部掃描。
創建表
CREATE TABLE t3(...) PARTITIONED BY (province string);
查看分區
SHOW PARTITIONS t3 [partition (province='beijing')];
添加分區
ALTER TABLE t3 ADD [IF NOT EXISTS] PARTITION(...) LOCATION '...';
刪除分區
ALTER TABLE t3 DROP PARTITION(...);
桶表是對數據進行哈希取值,然后放到不同文件中存儲。
創建表
create table bucket_table(id string) clustered by(id) into 4 buckets;
加載數據
set hive.enforce.bucketing = true;
insert into table bucket_table select name from stu;
insert overwrite table bucket_table select name from stu;
內外部表之間的轉換
內-->外:
alter table t1 set tblproperties("EXTERNAL"="TRUE");
外部表-->內:
alter table t1 set tblproperties("EXTERNAL"="FALSE");
當一個外部表轉化成為內部表,如果刪除這個內部表,則其原先引用的數據也一並被刪除。
HIVE視圖
優點:
1、 視圖能夠簡化用戶的操作
2、 視圖使用戶能以多鍾角度看待同一數據
3、 視圖對重構數據庫提供了一定程度的邏輯獨立性
4、 視圖能夠對機密數據提供安全保護
5、 適當的利用視圖可以更清晰的表達查詢
eg:create view t9 as select id from t1 where dt="2020-07-22";
Hive數據加載和導出
加載
[]表示可選,<>表示必須
load data [local] inpath 'path' [overwrite] into table tblName [partition partition_sepc];
local:
有:數據從linux本地path去加載數據
無:數據到hdfs的相關目錄path下去加載數據,相當於hadoop fs -mv /cp
overwrite:
有:刪除原來的數據,新增一份
沒有:在原來的基礎上追加一份
導出
導出到本地文件系統
insert overwrite local directory '/home/hadoop/output' row format delimited fields terminated by ',' select * from testa;--目前權限不夠不能導出
導出到HDFS
INSERT OVERWRITE DIRECTORY '/home/hadoop/output' select * from testA;(導入到HDFS和導入本地文件類似,去掉HQL語句的LOCAL就可以了)
采用hive的-e和-f參數來導出數據。
hive -e "select * from testA" >> /home/hadoop/output/testA.txt
Hive中文件的類型
使用壓縮可以提高hdfs的存儲能力,還有加快我們查詢效率。
四種壓縮格式
textfile:TextFile文件不支持塊壓縮,默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大
Rcfile:RCFile是一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取
Orc:ORCFile數據按行分塊,每塊按照列存儲,壓縮快,快速列存取,效率比rcfile高,是rcfile的改良版本,相比RC能夠更好的壓縮,能夠更快的查詢,但還是不支持模式演進。
Sequencefile:
使用方式:
ROW FORMAT DELIMITED
NULL DEFINED AS ''
STORED AS ORC;
修改已存在的表
alter table hive_tb set serdeproperties('serialization.null.format' = '');
存儲過程的寫法:
我們大數據平台中共經常用到的庫名為:
ODS_TMP_TD/ EDW_TMP_TD / EDW_TD / ODS_TD
一.在寫存儲過程時 臨時表均寫在TMP庫中,並且為了核查數據方便在創建臨時表前添加刪除臨時表即可,(如不需核查臨時表數據 可以在過程最后刪除)例如:
drop table if exists t1;
Create table if not exists t1 (id int );
二.創建表的字段類型:
Varchar/char -> string
Decimal(1-9,0) -> int
Decimal(10以上,0) -> bigint
Decimal(1-20,1-20) -> double (如又精度必須改為double)
Date/timestamp -> timestamp
三.UPDATE
在需要修改的時候可以創建臨時表 將需要修改的數據可以通過case when 進行處理
如:update t1 set name=’張三’ where month_id=202101 and id=1;
Insert overwrite table t1
Select
Id,
Month_id,
Case when month_id=202101 and id=1 then ‘張三’ else name end name
From t1;
四:DELETE
在需要刪除數據時可以通過臨時表的方式來刪除,分區表除外(overwrite)。如刪除個別數據那也必須通過臨時表。
Eg1: delete from t1 where moth_id=202010;
Create table tmp.t1 as select * from t1 where month_id <>202010;
Insert overwrite table t1 select * from tmp.t1;
Eg2: delete from t1 where month_id=202010 and id=1;
Create table tmp.t1 as select * from t1 where month_id <>202010;
Insert into tmp.t1 select * from t1 where month_id=202010 and id <>1;
Insert overwrite table t1 select * from tmp.t1;
四.INSERT
在插入的時候 如果要插入的表的數據為空,第一句可以寫成overwrite 后續再往相同的表插入的話使用 into。
overwrite : 表覆蓋 into:增量插入
Eg:
insert into table t1 select * from t2; (t1表中原有的數據不會刪除)
Insert overwrite table t1 select * from t2;(t1表中原有的數據會刪除)
在往分區表插入的時候:
動態分區 需要把分區字段放在字段中的最后一行
Insert overwrite table t1 partition(month_id)
Select
...
Month_id
from t2 where month_id=202010;
靜態分區:month_id 在字段中不需要寫
Insert overwrite table t1 partition(month_id=202010)
Select
...
from t2 where month_id=202010;
存儲過程結構
set hive.exec.compress.output=false;
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.auto.convert.join = false;
set hive.mapred.mode=nonstrict;
HIVE建表語句后綴常用
ROW FORMAT DELIMITED FIELDS TERMINATED BY '^'
STORED AS TEXTFILE
HIVE常用語句
Use edw_td; 使用庫
Show tables; 查看所有表,前提時先使用庫
Show tables ‘*t1*’; 模糊查詢表,前提使用庫
Desc t1;查看表結構
Show create table t1;查看建表語句
Show functions; 查看函數
ALTER TABLE t1 RENAME TO t2;修改表名
desc function upper; 顯示自帶的函數的用法
desc function extended upper;詳細顯示自帶的函數的用法
HIVE常用函數
數學函數
round(double d, int n):返回保留n位小數的近似d值
floor(double d): 返回小於d的最大整值
ceil(double d): 返回大於d的最小整值
rand(int seed): 返回隨機數,seed是隨機因子
bin(int d): 計算二進制值d的string值
日期函數
to_date(string timestamp):返回時間字符串中的日期部分,如to_date('1970-01-01 00:00:00')='1970-01-01'
current_date:返回當前日期
year(date):返回日期date的年,類型為int如year('2019-01-01')=2019
month(date):返回日期date的月,類型為int,如month('2019-01-01')=1
day(date): 返回日期date的天,類型為int,如day('2019-01-01')=1
weekofyear(date1):返回日期date1位於該年第幾周。如weekofyear('2019-03-06')=10
datediff(date1,date2):返回日期date1與date2相差的天數,如datediff('2019-03-06','2019-03-05')=1
date_add(date1,int1):返回日期date1加上int1的日期,如date_add('2019-03-06',1)='2019-03-07'
date_sub(date1,int1):返回日期date1減去int1的日期,如date_sub('2019-03-06',1)='2019-03-05'
months_between(date1,date2):返回date1與date2相差月份,如months_between('2019-03-06','2019-01-01')=2
add_months(date1,int1):返回date1加上int1個月的日期,int1可為負數。如add_months('2019-02-11',-1)='2019-01-11'
last_day(date1):返回date1所在月份最后一天。如last_day('2019-02-01')='2019-02-28'
next_day(date1,day1):返回日期date1的下個星期day1的日期。day1為星期X的英文前兩字母如next_day('2019-03-06','MO') 返回'2019-03-11'
trunc(date1,string1):返回日期最開始年份或月份。string1可為年(YYYY/YY/YEAR)或月(MONTH/MON/MM)。如trunc('2019-03-06','MM')='2019-03-01',trunc('2019-03-06','YYYY')='2019-01-01'
unix_timestamp():返回當前時間的unix時間戳,可指定日期格式。如unix_timestamp('2019-03-06','yyyy-mm-dd')=1546704180
from_unixtime():返回unix時間戳的日期,可指定格式。如select from_unixtime(unix_timestamp('2019-03-06','yyyy-mm-dd'),'yyyymmdd')='20190306'
條件函數
if(boolean,t1,t2):若布爾值成立,則返回t1,反正返回t2。如if(1>2,100,200)返回200
case when boolean then t1 else t2 end:若布爾值成立,則t1,否則t2,可加多重判斷
coalesce(v0,v1,v2):返回參數中的第一個非空值,若所有值均為null,則返回null。如coalesce(null,1,2)返回1
isnull(a):若a為null則返回true,否則返回false
字符串函數
length(string1):返回字符串長度
concat(string1,string2):返回拼接string1及string2后的字符串
concat_ws(sep,string1,string2):返回按指定分隔符拼接的字符串
lower(string1):返回小寫字符串,同lcase(string1)。upper()/ucase():返回大寫字符串
trim(string1):去字符串左右空格,ltrim(string1):去字符串左空格。rtrim(string1):去字符串右空格
repeat(string1,int1):返回重復string1字符串int1次后的字符串
reverse(string1):返回string1反轉后的字符串。如reverse('abc')返回'cba'
rpad(string1,len1,pad1):以pad1字符右填充string1字符串,至len1長度。如rpad('abc',5,'1')返回'abc11'。lpad():左填充
split(string1,pat1):以pat1正則分隔字符串string1,返回數組。如split('a,b,c',',')返回["a","b","c"]
substr(string1,index1,int1):以index位置起截取int1個字符。如substr('abcde',1,2)返回'ab'
聚合函數
count():統計行數
sum(col1):統計指定列和
avg(col1):統計指定列平均值
min(col1):返回指定列最小值
max(col1):返回指定列最大值
窗口函數
row_number() over(partitiion by .. order by .. ):根據partition排序,相同值取不同序號,不存在序號跳躍
rank() over(partition by .. order by .):根據partition排序,相同值取相同序號,存在序號跳躍
dense_rank() over(partition by .. order by ..):根據partition排序,相同值取相同序號,不存在序號跳躍
sum() over(partition by .. order by ..)
count() over(partition by .. order by ..)
lag(col,n) over(partition by .. order by ..) :查看當前行的上第n行
lead(col,n) over(partition by .. order by ..):查看當前行的下第n行
first_value() over(partition by .. order by ..):滿足partition及排序的第一個值
last_value() over(partition by .. order by ..):滿足partition及排序的最后值
ntile(n) over(partition by .. order by ..):滿足partition及排序的數據分成n份
行列轉換
concat_ws(sep, collect_set(col1)) 同組不同行合並成一列,以sep分隔符分隔。collect_set在無重復的情況下也可以collect_list()代替。collect_set()去重,collect_list()不去重
lateral view explode(split(col1,',')) :同組同列的數據拆分成多行,以sep分隔符區分