1. 程式人生 > >Hive(統計分析)

Hive(統計分析)

報錯1:Error: Error while compiling statement: FAILED: ParseException line 2:0 missing EOF at ‘select’ near ‘)’ (state=42000,code=40000)

解決辦法:把單引號換成雙引號

報錯2:0: jdbc:hive2://localhost:10000 (closed)>

解決辦法:start-all.sh (hdfs沒起來),或者mysql連線不上伺服器(連線本地(修改hive-site.xml檔案localhost換成本地IP地址)或者使用docker),netstat -ntlp | grep 3306,檢視3306端口占用情況。

1.內部連線:

select 
a.name as aname,
a.num as anum,
b.name as bname,
b.nick as bnick
from t_a a
inner join t_b b
on a.name=b.name

2.注意:多個欄位必須用逗號隔開,一般語句不用逗號。

一、為什麼使用Hive

  • 直接使用hadoop所面臨的問題 人員學習成本太高 專案週期要求太短 MapReduce實現複雜查詢邏輯開發難度太大

  • 為什麼要使用Hive 操作介面採用類SQL語法,提供快速開發的能力。 避免了去寫MapReduce,減少開發人員的學習成本。 功能擴充套件很方便。、

二、Hive的特點

1.可擴充套件 Hive可以自由的擴充套件叢集的規模,一般情況下不需要重啟服務。

2.延展性 Hive支援使用者自定義函式,使用者可以根據自己的需求來實現自己的函式。

3.容錯 良好的容錯性,節點出現問題SQL仍可完成執行

三、hive安裝

1.最簡安裝:用內嵌derby作為元資料庫

準備工作:安裝hive的機器上應該有HADOOP環境(安裝目錄,HADOOP_HOME環境變數)

安裝:直接解壓一個hive安裝包即可

此時,安裝的這個hive例項使用其內嵌的derby資料庫作為記錄元資料的資料庫,此模式不便於讓團隊成員之間共享協作

2.標準安裝:將mysql作為元資料庫。

3.mysql安裝
1.上傳mysql安裝包
2.解壓:
[
[email protected]
~]# tar -xvf MySQL-5.6.26-1.linux_glibc2.5.x86_64.rpm-bundle.tar 3.安裝mysql的server包 [[email protected] ~]# rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm 依賴報錯: 缺perl yum install perl 安裝完perl後 ,繼續重新安裝mysql-server (可以配置一個本地yum源進行安裝: 1、先在vmware中給這臺虛擬機器連線一個光碟映象 2、掛在光碟機到一個指定目錄:mount -t iso9660 -o loop /dev/cdrom /mnt/cdrom 3、將yum的配置檔案中baseURL指向/mnt/cdrom [[email protected] ~]# rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm 又出錯:包衝突conflict with 移除老版本的衝突包:mysql-libs-5.1.73-3.el6_5.x86_64 [[email protected] ~]# rpm -e mysql-libs-5.1.73-3.el6_5.x86_64 --nodeps 繼續重新安裝mysql-server [[email protected] ~]# rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm 成功後,注意提示:裡面有初始密碼及如何改密碼的資訊 初始密碼:/root/.mysql_secret 改密碼指令碼:/usr/bin/mysql_secure_installation 4.安裝mysql的客戶端包: [[email protected] ~]# rpm -ivh MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm 5.啟動mysql的服務端: [[email protected] ~]# service mysql start Starting MySQL. SUCCESS! 6.修改root的初始密碼: [[email protected] ~]# /usr/bin/mysql_secure_installation 按提示 7.測試: 用mysql命令列客戶端登陸mysql伺服器看能否成功 [[email protected] ~]# mysql -uroot -proot mysql> show databases; 8.給root使用者授予從任何機器上登陸mysql伺服器的許可權: mysql> grant all privileges on *.* to 'root'@'%' identified by '你的密碼' with grant option; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) 注意點:要讓mysql可以遠端登入訪問 最直接測試方法:從windows上用Navicat去連線,能連,則可以,不能連,則要去mysql的機器上用命令列客戶端進行授權: 在mysql的機器上,啟動命令列客戶端: mysql -uroot -proot mysql>grant all privileges on *.* to 'root'@'%' identified by 'root的密碼' with grant option; mysql>flush privileges; 3.2.2.hive的元資料庫配置 vi conf/hive-site.xml <configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>root</value> <description>password to use against metastore database</description> </property> </configuration> 2、上傳一個mysql的驅動jar包到hive的安裝目錄的lib中 3、配置HADOOP_HOME 和HIVE_HOME到系統環境變數中:/etc/profile 4、source /etc/profile 5、hive啟動測試 然後用命令啟動hive互動介面: [[email protected] ~]# hive
4.hive使用方式
4.1.最基本使用方式
啟動一個hive互動shell
bin/hive
hive>

設定一些基本引數,讓hive使用起來更便捷,比如:
1、讓提示符顯示當前庫:
hive>set hive.cli.print.current.db=true;
2、顯示查詢結果時顯示欄位名稱:
hive>set hive.cli.print.header=true; 

但是這樣設定只對當前會話有效,重啟hive會話後就失效,解決辦法:
在linux的當前使用者目錄中,編輯一個.hiverc檔案,將引數寫入其中:
vi .hiverc
set hive.cli.print.header=true;
set hive.cli.print.current.db=true;


4.2.啟動hive服務使用
啟動hive的服務:
[[email protected] hive-1.2.1]# bin/hiveserver2 -hiveconf hive.root.logger=DEBUG,console

上述啟動,會將這個服務啟動在前臺,如果要啟動在後臺,則命令如下:
nohup bin/hiveserver2 1>/dev/null 2>&1 &


啟動成功後,可以在別的節點上用beeline去連線
方式(1)
[[email protected] hive-1.2.1]# bin/beeline  回車,進入beeline的命令介面
輸入命令連線hiveserver2
beeline> !connect jdbc:hive2//mini1:10000
(hadoop01是hiveserver2所啟動的那臺主機名,埠預設是10000)
方式(2)
啟動時直接連線:
bin/beeline -u jdbc:hive2://mini1:10000 -n root

接下來就可以做正常sql查詢了


4.3.指令碼化執行
大量的hive查詢任務,如果用互動式shell來進行輸入的話,顯然效率及其低下,因此,生產中更多的是使用指令碼化執行機制:
該機制的核心點是:hive可以用一次性命令的方式來執行給定的hql語句

[[email protected] ~]#  hive -e "insert into table t_dest select * from t_src;"

然後,進一步,可以將上述命令寫入shell指令碼中,以便於指令碼化執行	hive任務,並控制、排程眾多hive任務,示例如下:
vi t_order_etl.sh
#!/bin/bash
hive -e "select * from db_order.t_order"
hive -e "select * from default.t_user"
hql="create table  default.t_bash as select * from db_order.t_order"
hive -e "$hql"

如果要執行的hql語句特別複雜,那麼,可以把hql語句寫入一個檔案:
vi x.hql
select * from db_order.t_order;
select count(1) from db_order.t_user;

然後,用hive -f /root/x.hql 來執行


5.hive建庫建表與資料匯入
5.1.建庫
hive中有一個預設的庫:
庫名: default
庫目錄:hdfs://hdp20-01:9000/user/hive/warehouse

新建庫:
create database db_order;
庫建好後,在hdfs中會生成一個庫目錄:
hdfs://hdp20-01:9000/user/hive/warehouse/db_order.db

5.2.建表
5.2.1.基本建表語句
use db_order;
create table t_order(id string,create_time string,amount float,uid string);
表建好後,會在所屬的庫目錄中生成一個表目錄
/user/hive/warehouse/db_order.db/t_order
只是,這樣建表的話,hive會認為表資料檔案中的欄位分隔符為 ^A

正確的建表語句為:
create table t_order(id string,create_time string,amount float,uid string)
row format delimited
fields terminated by ',';

這樣就指定了,我們的表資料檔案中的欄位分隔符為 ","
5.2.2.刪除表
drop table t_order;
刪除表的效果是:
hive會從元資料庫中清除關於這個表的資訊;
hive還會從hdfs中刪除這個表的表目錄;

5.2.3.內部表與外部表
內部表(MANAGED_TABLE):表目錄按照hive的規範來部署,位於hive的倉庫目錄/user/hive/warehouse中

外部表(EXTERNAL_TABLE):表目錄由建表使用者自己指定
create external table t_access(ip string,url string,access_time string)
row format delimited
fields terminated by ','location '/access/log';
匯入資料:在Linux下opt目錄建立一個數據檔案,然後用load data local inpath'路徑'into table 表名;

建立外部表:
create external table t_logdata(cid_sn string,os_ver string,resolution string,commit_time string,sdk_ver string,device_id_type string,device_model string,promotion_channel string,app_ver_name string,app_ver_code string,pid string,net_type string,device_id string,app_device_id string,release_channel string,country string,time_zone string,os_name string,manufacture string,commit_id string,app_token string,app_id string,language string,User_id string)
partitioned by(day string)
row format delimited
fields terminated by ','
location '/log-data-clean-data/';(HDFS的目錄)

向外部表分割槽匯入資料:
 load data local(本地) inpath '/opt/log/data/*' into table t_logdata partition(day='2017-08-15');
  load data inpath'/log-data-clean/android/*' into table t_logdata partition(day='2017-08-15');
 select * from t_logdata where day='’2017-08-15';

外部表和內部表的特性差別:
1、內部表的目錄在hive的倉庫目錄中 VS 外部表的目錄由使用者指定
2、drop一個內部表時:hive會清除相關元資料,並刪除表資料目錄
3、drop一個外部表時:hive只會清除相關元資料;

一個hive的資料倉庫,最底層的表,一定是來自於外部系統,為了不影響外部系統的工作邏輯,在hive中可建external表來對映這些外部系統產生的資料目錄;
然後,後續的etl操作,產生的各種表建議用managed_table


5.2.4.分割槽表
分割槽表的實質是:在表目錄中為資料檔案建立分割槽子目錄,以便於在查詢時,MR程式可以針對分割槽子目錄中的資料進行處理,縮減讀取資料的範圍。

比如,網站每天產生的瀏覽記錄,瀏覽記錄應該建一個表來存放,但是,有時候,我們可能只需要對某一天的瀏覽記錄進行分析
這時,就可以將這個表建為分割槽表,每天的資料匯入其中的一個分割槽;
當然,每日的分割槽目錄,應該有一個目錄名(分割槽欄位)

一個分割槽欄位的例項:
示例如下:
1、建立帶分割槽的表
create table t_access(ip string,url string,access_time string)
partitioned by(dt string)
row format delimited
fields terminated by ',';
注意:分割槽欄位不能是表定義中的已存在欄位

show partitions t_logdata;
新增分割槽:
alter table t_logdata add partition (day='2017-08-16');
刪除分割槽:
alter table t_logdata drop partition (day='2017-08-15');

2、向分割槽中匯入資料
load data local inpath '/root/access.log.2017-08-04.log' into table t_access partition(dt='20170804');
load data local inpath '/root/access.log.2017-08-05.log' into table t_access partition(dt='20170805');

3、針對分割槽資料進行查詢
 select count(*) as number  from fengze where dt="20170806";(as後面加別名)
a、統計8月4號的總PV:
select count(*) from t_access where dt='20170804';
實質:就是將分割槽欄位當成表字段來用,就可以使用where子句指定分割槽了

b、統計表中所有資料總的PV:
select count(*) from t_access;
實質:不指定分割槽條件即可

多個分割槽欄位示例
建表:
create table t_partition(id int,name string,age int)
partitioned by(department string,sex string,howold int)
row format delimited fields terminated by ',';

導資料:
load data local inpath '/root/p1.dat' into table t_partition partition(department='xiangsheng',sex='male',howold=20);

5.2.5.CTAS建表語法
可以通過已存在表來建表:
1、create table t_user_2 like t_user;
新建的t_user_2表結構定義與源表t_user一致,但是沒有資料

2、在建表的同時插入資料
create table t_access_user 
as
select ip,url from t_access;
t_access_user會根據select查詢的欄位來建表,同時將查詢的結果插入新表中
!!!此語句是倒著分析!!!1

5.2.4.桶(bucket)
把表組織成桶有兩個理由:
1.第一個理由是獲得更高的查詢處理效率。桶為表加上了額外的結構。Hive在處理有些查詢時能夠利用這個結構。連線兩個在(包含連線列的)相同列上劃分了桶的表,可以使用map端連線(map-side join)高效地實現。
2.把表劃分成桶的 第二個理由是使“取樣”或者說“取樣”更高效。
使用clustered by 子句來指定劃分桶所用的列 和要劃分的桶的個數:
eg:create table bucketed_users(id int,name string)
    clustered by(id) into 4 buckets;
有個沒有劃分桶的使用者表,要向分桶後的表中填充成員,需要將hive.enforce.bucketing屬性設定為true。然後使用insert:
eg:insert overwrite table bucketed_users
    select * from users;
用tablesample子句對錶進行取樣:
eg:> select * from bucketed_users
    > tablesample(bucket 1 out of 4 on id);


5.3.資料匯入匯出
5.3.1.將資料檔案匯入hive的表
方式1:匯入資料的一種方式:
手動用hdfs命令,將檔案放入表目錄;
Hadoop fs -put w.text /input
方式2:在hive的互動式shell中用hive命令來匯入本地資料到表目錄
hive>load data local inpath '/root/order.data.2' into table t_order;

方式3:用hive命令匯入hdfs中的資料檔案到表目錄
hive>load data inpath '/access.log.2017-08-06.log' into table t_access partition(dt='20170806');

注意:導本地檔案和導HDFS檔案的區別:
本地檔案匯入表:複製
hdfs檔案匯入表:移動

5.3.2.將hive表中的資料匯出到指定路徑的檔案
1、將hive表中的資料匯入HDFS的檔案
insert overwrite directory '/root/access-data'
row format delimited fields terminated by ','
select * from t_access;


2、將hive表中的資料匯入本地磁碟檔案
insert overwrite local directory '/root/access-data'
row format delimited fields terminated by ','
select * from t_access limit 100000;


5.3.3.hive檔案格式

HIVE支援很多種檔案格式: SEQUENCE FILE | TEXT FILE | PARQUET FILE | RC FILE

create table t_pq(movie string,rate int)  stored as textfile;
create table t_pq(movie string,rate int)  stored as sequencefile;
create table t_pq(movie string,rate int)  stored as parquetfile;


演示:
1、先建一個儲存文字檔案的表
create table t_access_text(ip string,url string,access_time string)
row format delimited fields terminated by ','
stored as textfile;

匯入文字資料到表中:
load data local inpath '/root/access-data/000000_0' into table t_access_text;

2、建一個儲存sequence file檔案的表:
create table t_access_seq(ip string,url string,access_time string)
stored as sequencefile;

從文字表中查詢資料插入sequencefile表中,生成資料檔案就是sequencefile格式的了:

insert into t_access_seq
select * from t_access_text;

3、建一個儲存parquet file檔案的表:

create table t_access_parq(ip string,url string,access_time string)
stored as parquetfile;

select * from t_students distribute by sex sort by age;(以男女年齡排序查詢)

方法:
1、執行機制和原理
2、動手:安裝配置
3、寫程式

Hive: 基於HDFS之上的資料倉庫
=======================================
一、什麼是資料倉庫?
	1、其實就是一個數據庫(Oracle、MySQL等等)
	2、比較大,資料多
	3、一般select

二、什麼是Hive?(蜂巢)
	1、是基於HDFS之上的資料倉庫
		Hive        HDFS
		表  ---->   目錄
		資料 --->   檔案
		分割槽 --->   目錄
		
	2、是一個翻譯器:  SQL ---> Hive ---> MapReduce
	    舉例:  select ---> hive  ---> MapReduce程式

三、Hive的體系結構和安裝配置
	1、Hive的體系結構
	2、Hive的元資訊:表名、列名、列的型別 *****
	3、安裝配置(簡單一點)
	(*)安裝模式:嵌入模式、本地模式、遠端模式
	(*)嵌入模式:
		(1)不需要MySQL
		(2)自帶Derby資料儲存元資訊
		(3)特點:只支援一個連線
		
	(*)本地模式、遠端模式
		(1)MySQL資料庫
		(2)生產:遠端模式
		
	核心的配置檔案:/root/training/apache-hive-2.3.0-bin/conf/hive-site.xml
	<?xml version="1.0" encoding="UTF-8" standalone="no"?>
	<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
	<configuration>
	<property>
	  <name>javax.jdo.option.ConnectionURL</name>
	  <value>jdbc:mysql://localhost:3306/hive?useSSL=false</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>com.mysql.jdbc.Driver</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionUserName</name>
	  <value>hiveowner</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionPassword</name>
	  <value>Welcome_1</value>
	</property>
	</configuration>

	注意:
	Hive-on-MR: 過期了
	Hive-on-Spark: 不成熟,還在開發階段
	Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.	
	
四、Hive的資料模型:表(重要)
	注意:Hive中,資料預設的分隔符是 tab鍵

	1、內部表:類似MySQL中表
	hive> create table newemp
		> (empno int,
		>  ename string,
		>  job string,
		>  mgr int,
		>  hiredate string,
		>  sal int,
		>  comm int,
		>  deptno int
		> )row format delimited fields terminated by ',';
	
	匯入資料: load 
	本地資料:load data local inpath '/root/temp/emp.csv' into table newemp;
	HDFS:    load data inpath '/HDFS的目錄/emp.csv' into table newemp;
	
	2、分割槽表:
	hive> create table emp_part
		> (empno int,
		>  ename string,
		>  job string,
		>  mgr int,
		>  hiredate string,
		>  sal int,
		>  comm int
		> )partitioned by (deptno int)
		> row format delimited fields terminated by ',';	
	
	3、桶表
	4、外部表
	
	5、檢視:
	(*)檢視是一個虛表
	(*)簡化複雜的查詢
		hive> create view newview10
			> as
			> select * from newemp where deptno=10;
		hive> select * from newview10;
		7782    CLARK   MANAGER 7839    1981/6/9        2450    NULL    10
		7839    KING    PRESIDENT       NULL    1981/11/17      5000    NULL    10
		7934    MILLER  CLERK   7782    1982/1/23       1300    NULL    10

五、使用JDBC操作Hive
	1、JDBC:操作RDBMS的標準介面

1.從本地檔案系統中匯入資料到hive表

(1)資料準備(/home/sopdm/test.dat):

1,wyp,25,13188888888

2,test,30,13899999999

3,zs,34,89931412

(2)首先建立表

use sopdm;

drop table if exists sopdm.wyp;

create table if not exists sopdm.wyp(id int,name string,age int,tel string)

row format delimited

fields terminated by ‘,’

stored as textfile;

(3)從本地檔案系統中匯入資料到Hive表

load data local inpath ‘/home/sopdm/test.dat’ into table sopdm.wyp;

(4)可以到wyp表的資料目錄下檢視,如下命令

dfs -ls /user/sopdm/hive/warehouse/sopdm.db/wyp;

2.從HDFS上匯入資料到Hive表

(1)現在hdfs中建立一個input目錄存放HDFS檔案

hadoop fs -mkdir input; 或 hadoop fs -mkdir /user/sopdm/input;

(2)把本地檔案上傳到HDFS中,並重命名為test_hdfs.dat

hadoop fs -put /home/sopdm/test.dat /user/sopdm/input/test_hdfs.dat;

(3)檢視檔案

dfs -cat /user/sopdm/input/test_hdfs.dat;

(4)將內容匯入hive表中

–拷貝“本地資料”到“hive”使用:load data local…

–轉移“HDFS”到“hive”(必須同一個叢集)使用:load data…

load data inpath ‘/user/sopdm/input/test_hdfs.dat’ into table sopdm.wyp;

3.從別的Hive表中匯入資料到Hive表中

create table if not exists sopdm.wyp2(id int,name string,tel string)

row format delimited

fields terminated by ‘,’

stored as textfile;

–overwrite是覆蓋,into是追加

insert into table sopdm.wyp2

select id,name,tel from sopdm.wyp;

–多表插入

–高效方式-查詢語句插入多個分割槽

from sopdm.wyp w

insert overwrite table sopdm.wyp2

select w.id,w.name,w.tel where w.age=25

insert overwrite table sopdm.wyp2

select w.id,w.name,w.tel where w.age=27;

4.建立Hive表的同時匯入查詢資料

create table sopdm.wyp3

   as select id,name,tel,age from sopdm.wyp where age=25;