Hive&HDFS&Hbase基本操作

Hive基本操作

Hive產(chǎn)生背景:

mapreduce編程的不便性
HDFS上文件缺少Schema (Schema:關(guān)系型數(shù)據(jù)庫里面創(chuàng)建一張表宜猜,需要?jiǎng)?chuàng)建表名末荐、列的名稱今豆、列的類型蛛芥,每個(gè)字段的分隔符),如果沒有Schema藻丢,就無法對(duì)分布式文件上的數(shù)據(jù)進(jìn)行相應(yīng)的查詢病蛉。
hive不支持更改數(shù)據(jù)的操作扛施,Hive基于數(shù)據(jù)倉庫汽烦,提供靜態(tài)數(shù)據(jù)的動(dòng)態(tài)查詢涛菠。其使用類SQL語言,底層經(jīng)過編譯轉(zhuǎn)為MapReduce程序撇吞,在Hadoop上運(yùn)行俗冻,數(shù)據(jù)存儲(chǔ)在HDFS上。

Hive:

(1)facebook開源牍颈,用于解決海量結(jié)構(gòu)化的日志數(shù)據(jù)統(tǒng)計(jì)問題
(2)構(gòu)建在Hadoop之上的數(shù)據(jù)倉庫
(3)Hive定義了一種類SQL查詢語言:HQL(類似SQL但不完全相同)
(4)通常用于進(jìn)行離線數(shù)據(jù)處理(剛剛開始時(shí)是采用MapReduce)
(5)目前底層支持多種不同的執(zhí)行引擎
Hive底層的執(zhí)行引擎有:MapReduce迄薄、Tez、Spark
Hive on MapReduce
Hive on Tez
Hive on Spark
(6)支持多種不同的壓縮格式颂砸、存儲(chǔ)格式以及自定義函數(shù)
壓縮:GZIP噪奄、LZ0死姚、Snappy人乓、BZIP2……
存儲(chǔ):TextFile、SequenceFile都毒、RCFile色罚、ORC、Parquet账劲。默認(rèn)是TextFile戳护,一般可選用RCFile金抡,也可以選擇ORC。
UDF:自定義函數(shù)
java寫一個(gè)自定義udf函數(shù)

//刪除原有的函數(shù)
drop function default.w2v_vector;
//創(chuàng)建新函數(shù)腌且,讀取jar包中的類梗肝,jar包需要上傳到hdfs或s3。
create function w2v_vector as 'xxx.udf.W2VVector' using jar 's3://mildom/hive/jar/xxx-udf-1.0.0-jar-with-dependencies.jar';

然后這個(gè)函數(shù)可以在寫hive sql時(shí)直接使用铺董。

Hive體系架構(gòu)及部署架構(gòu)


通過hive腳本和JDBC來訪問hive

Hive環(huán)境搭建

Hive環(huán)境搭建
1)Hive下載:http://archive.cloudera.com/cdh5/cdh/5/
wget http://archive.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.7.0.tar.gz

2)解壓
tar -zxvf hive-1.1.0-cdh5.7.0.tar.gz -C ~/app/

3)配置
系統(tǒng)環(huán)境變量(~/.bash_profile)

        export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.7.0
        export PATH=$HIVE_HOME/bin:$PATH
實(shí)現(xiàn)安裝一個(gè)mysql巫击, yum install xxx
    hive-site.xml
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://localhost:3306/sparksql?createDatabaseIfNotExist=true</value>
    </property>
    
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
    </property>

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

    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>root</value>
    </property>

4)拷貝mysql驅(qū)動(dòng)到$HIVE_HOME/lib/

5)啟動(dòng)hive: $HIVE_HOME/bin/hive

Hive基本使用

啟動(dòng)hive前要先啟動(dòng)HDFS和mysql,否則無法啟動(dòng)精续。
./start-dfs.sh hadoop啟動(dòng)HDFS
啟動(dòng)hive:在sbin目錄下執(zhí)行: ./start-dfs.sh

任務(wù)分析常用語句

(1)想知道分區(qū)修剪是否起作用么坝锰?

答案:用explain語句吧,看看要讀取哪些目錄就知道了重付。另外顷级,通過這個(gè)語句的執(zhí)行結(jié)果,還可以檢查你的查詢計(jì)劃是否合理确垫。

例句:

Explain select t.col1,t.col3 from dbname::tablename t where t.ftime=‘20130104’

(2)show rowcount的作用

Show rowcount dbname::tablename //顯示整個(gè)表有多少行

通過這個(gè)命令可以知道一個(gè)表有多少行記錄弓颈,有了它的幫助就可以在連接時(shí)基本保證小表連接大表,也可以知道是否適合使用map join删掀。

Show rowcount extended dbname::tablename //按分區(qū)顯示每個(gè)分區(qū)有多少行

這個(gè)命令更有用的形式是show rowcount extended tablename恨豁,這個(gè)命令可以按分區(qū)來顯示每個(gè)分區(qū)有多少行記錄。

注意:本命令和下一條命令只對(duì)結(jié)構(gòu)化存儲(chǔ)文件生效爬迟。如對(duì)文本文件執(zhí)行該命令將報(bào)錯(cuò)橘蜜。

(3)show tablesize的作用

Show tablesize dbname::tablename

通過這個(gè)命令可以知道一個(gè)表有多大,單位是字節(jié)付呕。

擴(kuò)展形式:

Show tablesize extended dbname::tablename

說明:

通過該命令的結(jié)果计福,可以估算出大約需要多少個(gè)map任務(wù),現(xiàn)在一般256MB/512MB一個(gè)map任務(wù)徽职。如果你想知道join的時(shí)候需要多少個(gè)map任務(wù)象颖,只需要把每個(gè)表需要的map任務(wù)數(shù)求和就可以了。

需要的map數(shù)太多可不是好事姆钉,通常map數(shù)超過1萬就是較大的任務(wù)了说订。

構(gòu)建基礎(chǔ)測(cè)試數(shù)據(jù)

create table test_user_login_3days(
    user_id int,
    login_date date
);
insert into test_user_login_3days values (123,'2018-08-02');
insert into test_user_login_3days values (123,'2018-08-03');
insert into test_user_login_3days values (123,'2018-08-04');
insert into test_user_login_3days values (456,'2018-11-02');
insert into test_user_login_3days values (456,'2018-12-09');
insert into test_user_login_3days values (789,'2018-01-01');
insert into test_user_login_3days values (789,'2018-04-23');
insert into test_user_login_3days values (789,'2018-09-10');
insert into test_user_login_3days values (789,'2018-09-11');
insert into test_user_login_3days values (789,'2018-09-12');
insert into test_user_login_3days values (10001,'2018-04-23');
insert into test_user_login_3days values (10001,'2018-04-24');
insert into test_user_login_3days values (10001,'2018-09-11');
insert into test_user_login_3days values (10001,'2018-09-12');

基礎(chǔ)語法

創(chuàng)建表
CREATE  TABLE table_name 
  [(col_name data_type [COMMENT col_comment])]

CREATE TABLE IF NOT EXISTS TableName
  
CREATE EXTERNAL TABLE IF NOT EXISTS TableName
PARTITIONED BY (day bigint)
STORED AS ORC
LOCATION 's3://mildom/hive/${DATA_BASE}.db/${DATA_TABLE}

COMMENT關(guān)鍵字為字段注釋(comment = 表注釋內(nèi)容)

CREATE EXTERNAL TABLE table_name 
未被external修飾的是內(nèi)部表(managed table),被external修飾的為外部表(external table)
刪除內(nèi)部表會(huì)直接刪除元數(shù)據(jù)(metadata)及存儲(chǔ)數(shù)據(jù)潮瓶;刪除外部表僅僅會(huì)刪除元數(shù)據(jù)陶冷,HDFS上的文件并不會(huì)被刪除;
對(duì)內(nèi)部表的修改會(huì)將修改直接同步給元數(shù)據(jù)毯辅,而對(duì)外部表的表結(jié)構(gòu)和分區(qū)進(jìn)行修改埂伦,則需要修復(fù)(MSCK REPAIR TABLE table_name;)

雖然說,建立外部表會(huì)使用LOCATION指定位置思恐,而建立內(nèi)部表不使用LOCATION沾谜,會(huì)默認(rèn)保存在/hive/warehouse/下膊毁,自動(dòng)生成一個(gè)目錄,目錄名為表名基跑。
但是通過一系列對(duì)比婚温,我們可以發(fā)現(xiàn),這兩個(gè)參數(shù)之間是沒有關(guān)系的媳否。
我們可以建立外部表缭召,不使用LOCATION;也可以建立內(nèi)部表逆日,使用LOCATION嵌巷。
所以我們是否會(huì)在HDFS上看到生成新的目錄,取決于是否使用LOCATION室抽,而不是外部表搪哪、內(nèi)部表的關(guān)系。


刪除表
DROP TABLE IF EXISTS TableName

加載數(shù)據(jù)到hive表
LOAD DATA LOCAL INPATH 'filepath' INTO TABLE tablename 

load data local inpath '/home/hadoop/data/hello.txt' into table hive_wordcount;

為單詞計(jì)數(shù)
select word, count(1) from hive_wordcount lateral view explode(split(context,'\t')) wc as word group by word;
拆分列為行:
lateral view explode(): 是把每行記錄按照指定分隔符進(jìn)行拆解

where是在表中查詢坪圾,作用于表中的列晓折,所以where不能放在group by的后面,而having是作用于查詢結(jié)果中的列兽泄,group by 之后可以用having來過濾漓概。
例如:
select s_id,avg(s_score) as avgScore from score
group by s_id
having avgScore > 60;

拆分列為多列
select split("116:151:1", '\\:')[0] as gid
     , split("116:151:1", '\\:')[1] as sid
     , split("116:151:1", '\\:')[2] as rid
from table


hiveql提交執(zhí)行以后會(huì)生成mr作業(yè),并在yarn上運(yùn)行

create table emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

create table dept(
deptno int,
dname string,
location string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

load data local inpath '/home/hadoop/data/emp.txt' into table emp;
load data local inpath '/home/hadoop/data/dept.txt' into table dept;

求每個(gè)部門的人數(shù)
select deptno, count(1) from emp group by deptno;

Hive下查看數(shù)據(jù)表信息的方法
方法1:查看表的字段信息病梢,describe該表
desc table_name;
方法2:查看表的字段信息及元數(shù)據(jù)存儲(chǔ)路徑
desc extended table_name;
方法3:查看表的字段信息及元數(shù)據(jù)存儲(chǔ)路徑
desc formatted table_name;

當(dāng)日期精確到小時(shí)的時(shí)候例如2019121206胃珍,用substring切取前面八位。字段內(nèi)容過濾用in和括號(hào)蜓陌。
SELECT app
from table_name
where substring(stat_date,0,8) = 20180913 and app in ('com.taobao.taobao', 'com.xunmeng.pinduoduo', 'com.jingdong.app.mall', 'com.achievo.vipshop', 'com.xingin.xhs', 'com.tmall.wireless')

查看分區(qū)
SHOW PARTITIONS table_name觅彰;
查看某個(gè)表是否存在某個(gè)特定分區(qū)鍵
SHOW PARTITIONS table_name PARTITION(stat_date='20180625')
DESCRIBE EXTENDED table_name PARTITION(stat_date='20180625')


刪除分區(qū)(例如分區(qū)為日期)
ALTER TABLE table_name DROP IF EXISTS PARTITION (stat_date = "20180625")
alter table table_name drop if exists partition (stat_date>='20181102',stat_date<='20181104')

刪除date&hour兩個(gè)分區(qū)(刪除昨天的分區(qū)數(shù)據(jù),hour_1ago為‘date_1ago’+‘23’钮热,設(shè)置了兩個(gè)分區(qū))
ALTER TABLE table_name DROP IF EXISTS PARTITION(day=${date_1ago},hour=${hour_1ago});



添加分區(qū)
ALTER TABLE table_name IF NOT EXISTS ADD PARTITION (p_hour='2017113003', p_city='573', p_loctype='MHA');

轉(zhuǎn)換數(shù)據(jù)格式(類型)
select umid,cast(cnt_active_day_7 as double) from tablename

查看制表信息(可以查看在hdfs/s3中的location)
show create table tablename

表重命名
alter table old_table_name rename to new_table_name

添加字段(添加列)
添加hour字段
alter table table_name add columns(hour bigint)
alter table table_name add columns(col_name string COMMENT '字段信息')
調(diào)整位置
alter table table_name change hour hour string after user_name
需要調(diào)整位置填抬、名稱和注釋可以如下:
ALTER TABLE table_name CHANGE col_old_name col_new_name column_type AFTER column_name

改變列名/類型/位置/注釋
ALTER TABLE table_name CHANGE
[CLOUMN] col_old_name col_new_name column_type
[CONMMENT col_conmment]
[FIRST|AFTER column_name];
這個(gè)命令可以修改表的列名,數(shù)據(jù)類型隧期,列注釋和列所在的位置順序飒责,F(xiàn)IRST將列放在第一列,AFTER col_name將列放在col_name后面一列仆潮,
只改列名:
ALTER TABLE table_name CHANGE column_name new_name new_type

刪除字段
建表語句宏蛉,如果已經(jīng)建過表了則可以忽略該語句
create table table_name (
column_1 string,
column_2 int);

刪除column_2
alter table table_name replace columns(
column_1 string);    --column_2不寫,即刪除column_2鸵闪,保留column_1



類型轉(zhuǎn)換 cast(value AS TYPE)
SELECT name, salary FROM employees WHERE cast(salary AS FLOAT) < 100000.0;
這里把整數(shù)轉(zhuǎn)化為浮點(diǎn)數(shù)再比較
如果需要把浮點(diǎn)數(shù)轉(zhuǎn)化為整數(shù)檐晕,推薦round()或floor()函數(shù),不推薦使用cast


If函數(shù):if和case類似蚌讼,都是處理單個(gè)列的查詢結(jié)果
語法: if(boolean testCondition, T valueTrue, T valueFalseOrNull)
返回值: T
說明:  當(dāng)條件testCondition為TRUE時(shí)辟灰,返回valueTrue;否則返回valueFalseOrNull
舉例:if(條件表達(dá)式篡石,結(jié)果1芥喇,結(jié)果2)相當(dāng)于java中的三目運(yùn)算符,只是if后面的表達(dá)式類型可以不一樣。
if中的等于條件用“=”或“==”均可
hive> select if(a=a,’bbbb’,111) from dual;
           bbbb
hive> select if(1<2,100,200) from dual;
          200
可以和其他函數(shù)和字段組合使用凰萨,例如計(jì)算30天內(nèi)的觀看時(shí)長:
hive>select sum(if(CreateTime>"2020-10-10 00:00:00"),WatchTime,0) as recent_watch_time from dual;

CASE WHEN THEN語句和if條件語句類似继控,用于處理單個(gè)列的查詢結(jié)果:
SELECT name,salary,
CASE
    WHEN salary < 50000.0 THEN 'low'
    WHEN salary >= 50000.0 AND salary < 70000.0 THEN 'middle'
    WHEN salary > 70000.0 AND salary<100000.0 THEN 'high'
    ELSE 'very high'
END AS bracket FROM employees;

|name|salary|bracket|
|KEVIN|100000|high|

NVL函數(shù)
NVL(expr1, expr2):空值轉(zhuǎn)換函數(shù)
備注:
1、如果expr1為NULL胖眷,返回值為 expr2武通,否則返回expr1。
2珊搀、適用于數(shù)字型冶忱、字符型和日期型,但是 expr1和expr2的數(shù)據(jù)類型必須為同類型境析。


decode(binary bin, string charset)返回string
使用默認(rèn)編碼類型且只能指定一個(gè)編碼類型囚枪,將第一個(gè)參數(shù)解碼為字符串,如果任何一個(gè)參數(shù)為null劳淆,返回null链沼。可選編碼類型為: 'US_ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16BE', 'UTF-16LE', 'UTF-16'

unbase64(string str)返回binary 
將base64字符串轉(zhuǎn)換為二進(jìn)制
對(duì)某一個(gè)需要提取特征的文本列沛鸵,可以如此轉(zhuǎn)碼括勺。
select  decode(unbase64(col_name), 'utf-8') from table_name

distinct 取唯一
select distinct name, id from table


獲取最新分區(qū),按照日期stat_date字段分區(qū)的數(shù)據(jù)曲掰,有時(shí)候會(huì)出現(xiàn)數(shù)據(jù)阻塞朝刊,
規(guī)定時(shí)間內(nèi)數(shù)據(jù)沒有跑出來,那么為了不影響業(yè)務(wù)使用蜈缤,到規(guī)定時(shí)間內(nèi)當(dāng)天數(shù)據(jù)沒有出來則取最近的日期數(shù)據(jù)上報(bào)
select t2.* 
from (select max(stat_date) as latest_op_day from algo.wallpaper_user_recommend where stat_date>date_add(current_date,-3)) t1 
join algo.wallpaper_user_recommend t2 
on t1.latest_op_day = t2.stat_date

常用join的用法拾氓,查看兩次表里面性別不一致的人:
select a.flymeid,a.sex,b.flyme_id,b.sex from (select flymeid,case when q1 = 'A' THEN '1' when q1 = 'B' THEN '2'  ELSE 'unknown'  END as sex from algo.wy_questionnaire_data_new) a join (select flyme_id,sex from user_profile.ods_question_answer_by_flyme) b on a.flymeid=b.flyme_id where a.sex != b.sex

全連階FULL OUTER,合并key
SELECT
    COALESCE(a.ID, b.ID, c.ID) AS ID
   ,COALESCE(a.Attr, b.Attr, c.Attr) AS Attr
FROM TA a
FULL OUTER JOIN TB b ON (a.ID = b.ID)
FULL OUTER JOIN TC c ON (a.ID = c.ID OR b.ID = c.ID)

hive交集
left semi join: 并不拼接兩張表底哥,兩個(gè)表對(duì) on 的條件字段做交集咙鞍,返回前面表的記錄,相較于其他的方法趾徽,這樣子 hive 處理速度比較快续滋。

排序

SELECT cast(substring(value_str,14,13) AS bigint) AS key FROM src SORT BY key ASC
SELECT cast(substring(value_str,14,13) AS bigint) AS key FROM src SORT BY key DESC

hive中在不需要全局排序的情況下,寫排序語句時(shí)孵奶,最好用distribute by 表中字段名 sort by 表中字段名 asc | desc 的形式疲酌,盡量不用order by形式。
distribute by通常用來緩解數(shù)據(jù)傾斜的問題,在sql結(jié)尾加上distribute by rand()朗恳,
可以控制map數(shù)據(jù)的結(jié)果湿颅,保證每個(gè)分區(qū)的數(shù)據(jù)量基本一致。
distribute by關(guān)鍵字控制map輸出結(jié)果的分發(fā),相同字段的map輸出會(huì)發(fā)到一個(gè)reduce節(jié)點(diǎn)去處理粥诫。sort by的數(shù)據(jù)只能保證在同一個(gè)reduce中的數(shù)據(jù)可以按指定字段排序油航,每一個(gè)reducer產(chǎn)生一個(gè)排序文件,所以不是全局排序怀浆。使用sort by可以指定執(zhí)行的reduce個(gè)數(shù)(通過set mapred.reduce.tasks=n來指定)谊囚,對(duì)輸出的數(shù)據(jù)再執(zhí)行歸并排序,即可得到全部結(jié)果执赡。

#相同的col_name會(huì)倒序排在一起
select * from table_name distribute by col_name sort by col_name desc;
#更常見的用法镰踏,全局排序,distribute by用在ID列上控制map沙合,然后奠伪、后sort by把想要排序的字段放到一個(gè)reducer中全局排序。
select * from table_name distribute by ID_col_name sort by col_name desc;
#另一種用法灌诅,distribute by用在ID列上控制map芳来,然后sort by把想要排序的多個(gè)字段放到一個(gè)reducer中全局排序。
select * from table_name distribute by ID_col_name sort by ID_col_name asc,col_name desc;
#結(jié)果是所有相同的ID_col_name組合在一起并升序排排列猜拾,col_name列為降序即舌。
ID_name     col_name
1              3
1              1
2              8
3              5
3              4
3              1

Distribute by和sort by的使用場(chǎng)景
1.Map輸出的文件大小不均。
2.Reduce輸出文件大小不均挎袜。
3.小文件過多顽聂。
4.文件超大。
cluster by相當(dāng)于distribute by組合sort by用法盯仪,但是只能升序

采樣

數(shù)據(jù)塊抽樣(tablesample()函數(shù))
1) tablesample(n percent) 根據(jù)hive表數(shù)據(jù)的大小按比例抽取數(shù)據(jù)紊搪,并保存到新的hive表中。如:抽取原h(huán)ive表中10%的數(shù)據(jù)
(注意:測(cè)試過程中發(fā)現(xiàn)全景,select語句不能帶where條件且不支持子查詢耀石,可通過新建中間表或使用隨機(jī)抽樣解決)
create table xxx_new as select * from xxx tablesample(10 percent)
2)tablesample(n M) 指定抽樣數(shù)據(jù)的大小,單位為M爸黄。
3)tablesample(n rows) 指定抽樣數(shù)據(jù)的行數(shù)滞伟,其中n代表每個(gè)map任務(wù)均取n行數(shù)據(jù),map數(shù)量可通過hive表的簡單查詢語句確認(rèn)(關(guān)鍵詞:number of mappers: x)

分桶抽樣
hive中分桶其實(shí)就是根據(jù)某一個(gè)字段Hash取模炕贵,放入指定數(shù)據(jù)的桶中梆奈,比如將表table_1按照ID分成100個(gè)桶,其算法是hash(id) % 100称开,這樣亩钟,hash(id) % 100 = 0的數(shù)據(jù)被放到第一個(gè)桶中乓梨,hash(id) % 100 = 1的記錄被放到第二個(gè)桶中。創(chuàng)建分桶表的關(guān)鍵語句為:CLUSTER BY語句清酥。
分桶抽樣語法:
TABLESAMPLE (BUCKET x OUT OF y [ON colname])
其中x是要抽樣的桶編號(hào)扶镀,桶編號(hào)從1開始,colname表示抽樣的列总处,y表示桶的數(shù)量狈惫。
例如:將表隨機(jī)分成10組睛蛛,抽取其中的第一個(gè)桶的數(shù)據(jù)
select * from table_01 tablesample(bucket 1 out of 10 on rand())

隨機(jī)抽樣(rand()函數(shù))
1)使用rand()函數(shù)進(jìn)行隨機(jī)抽樣鹦马,limit關(guān)鍵字限制抽樣返回的數(shù)據(jù),其中rand函數(shù)前的distribute和sort關(guān)鍵字可以保證數(shù)據(jù)在mapper和reducer階段是隨機(jī)分布的忆肾,案例如下:
select * from table_name where col=xxx distribute by rand() sort by rand() limit num;
2)使用order 關(guān)鍵詞
案例如下:
select * from table_name where col=xxx order by rand() limit num;
經(jīng)測(cè)試對(duì)比荸频,千萬級(jí)數(shù)據(jù)中進(jìn)行隨機(jī)抽樣 order by方式耗時(shí)更長,大約多30秒左右客冈。

均值旭从、方差、標(biāo)準(zhǔn)差场仲、皮爾遜相關(guān)系數(shù)和悦、偏度、峰度統(tǒng)計(jì)字段

--均值有時(shí)候是avg()
SELECT mean(age) AS '均值', variance(age) AS '方差', stddev(age) AS '標(biāo)準(zhǔn)差', corr(age,yearsmarried) AS '兩個(gè)指標(biāo)的相關(guān)系數(shù)', skewness(age) AS 'skewness偏度', kurtosis(age) AS 'kurtosis峰度'
FROM table
collect_list和collect_set函數(shù)

這兩個(gè)函數(shù)是用來做聚合渠缕,區(qū)別是collect_set會(huì)去重鸽素。
網(wǎng)上的例子:


按用戶分組,取出每個(gè)用戶每天看過的所有視頻的名字:
select username, collect_list(video_name) from t_visit_video group by username ;

去重的結(jié)果
select username, collect_set(video_name) from t_visit_video group by username;

collect_set很多時(shí)候和concat_ws搭配使用亦鳞。

select user_id,concat_ws(',',collect_set(follow_user_id)) as follow_user_ids
group by user_id
COALESCE函數(shù):

COALESCE是一個(gè)函數(shù)馍忽, (expression_1, expression_2, ...,expression_n)依次參考各參數(shù)表達(dá)式,遇到非null值即停止并返回該值燕差。如果所有的表達(dá)式都是空值遭笋,最終將返回一個(gè)空值。

比如我們要登記用戶的電話徒探,數(shù)據(jù)庫中包含他的person_tel,home_tel,office_tel,我們只要取一個(gè)非空的就可以瓦呼,則我們可以寫查詢語句

select COALESCE(person_tel,home_tel,office_tel) as contact_number from Contact;

使用實(shí)例:
這個(gè)參數(shù)使用的場(chǎng)合為:假如某個(gè)字段默認(rèn)是null测暗,你想其返回的不是null央串,而是比如0或其他值,可以使用這個(gè)函數(shù) 

SELECT COALESCE(field_name,0) as value from table;

select coalesce(a,b,c);
參數(shù)說明:如果a==null,則選擇b偷溺;
如果b==null,則選擇c蹋辅;
如果a!=null,則選擇a;
如果a b c 都為null 挫掏,則返回為null侦另。
切分字符串
//當(dāng)日期精確到小時(shí)的時(shí)候例如2019121206,用substring切取第二個(gè)元素后面的前面八位。
SELECT imei,search,app,match_kw as keyword 
from mzreader.ods_stream_search_action_overall 
where substring(stat_date,2,8) = 20180913 and app in ('com.taobao.taobao', 'com.xunmeng.pinduoduo', 'com.jingdong.app.mall')
時(shí)間戳和json格式處理

時(shí)間戳轉(zhuǎn)化成普通日期格式使用hive自帶的udf:from_unixtime褒傅,后面可以轉(zhuǎn)換得出的格式弃锐,比如只要年月日可以寫成:'yyyyMMdd'。
get_json_object用來解析json
這里是取了一個(gè)json格式的字段里的timestamp

select from_unixtime(cast(get_json_object(字段名字,'$.timestamp') as bigint),'yyyyMMdd HH:mm:ss') from hive表名

日期偏移

--返回當(dāng)前日期:current_date() 使用這個(gè)方法的時(shí)候要注意殿托,服務(wù)區(qū)的區(qū)時(shí)不一定是北京時(shí)間霹菊,比如使用的是世界區(qū)時(shí)GMT,就要用這個(gè)代替要在GMT加上8小時(shí):substring(from_utc_timestamp(current_timestamp(),'GMT+8'),1,10)
--自定義日期操作函數(shù)(返回帶橫線的日期):get_date
 select get_date();--返回當(dāng)前日期,返回  2020-02-09
 select get_date(-2);--返回當(dāng)前日期往前偏移2天的日期 ,返回  2020-02-07
 --自定義日期操作函數(shù)(返回不帶橫線的日期):get_dt_date
 select get_dt_date();--獲取當(dāng)前日期支竹,返回 20200209
 select get_dt_date(get_date(-2));--獲取當(dāng)前日期偏移旋廷,轉(zhuǎn)為不帶橫桿的格式
 select get_dt_date('2020-02-02',-2);--20200131
#####日期函數(shù)(比較,往后推礼搁,往前推)饶碘,通常需要用from_unixtime轉(zhuǎn)化成對(duì)應(yīng)格式再比較
datediff(string enddate,string startdate)
select datediff('2000-01-30','2000-01-29')  //比較相差幾天,這里是一天

date_add(string startdate, intdays) 
select date_add('2000-01-01',10)//開始日期往后推10天

date_sub (string startdate,int days) 
select date_sub('2000-01-01',10)//開始日期往前推10天

所以去當(dāng)前前10天的數(shù)據(jù)就可以寫成
select * from table where datediff(current_timestamp,stat_date)<=10
其中stat_date是表里的當(dāng)前的時(shí)間馒吴,current_timestamp直接返回當(dāng)前時(shí)間
或者
date是當(dāng)前取到的日期
select * from table where stat_date<='date' and stat_date>date_sub('date',10)
這種更好理解一些扎运。
有的時(shí)候時(shí)間不是這個(gè)格式,那就需要用from_unixtime處理一下饮戳,再用replace把"-"刪除
select replace(date_sub(from_unixtime(unix_timestamp('20181224','yyyyMMdd'),'yyyy-MM-dd'),60),'-','')

有時(shí)候把不同格式的數(shù)據(jù)進(jìn)行比較會(huì)報(bào)錯(cuò)豪治,比如比較日期,一個(gè)是bigint(20191111)扯罐,一個(gè)是string('20191212')负拟,日志會(huì)報(bào)錯(cuò)會(huì)有sethive.strict.checks.type.safety to false的字樣
在代碼前加上set hive.strict.checks.type.safety = false;
關(guān)閉嚴(yán)格類型安全模式,就可以比較了篮赢。

以下有幾種齿椅,節(jié)選自網(wǎng)絡(luò):
啟用嚴(yán)格模式:hive.mapred.mode = strict // Deprecated
hive.strict.checks.large.query = true
該設(shè)置會(huì)禁用:

  1. 不指定分頁的order by
  2. 對(duì)分區(qū)表不指定分區(qū)進(jìn)行查詢
  3. 和數(shù)據(jù)量無關(guān),只是一個(gè)查詢模式

hive.strict.checks.type.safety = true
嚴(yán)格類型安全启泣,該屬性不允許以下操作:

  1. bigint和string之間的比較
  2. bigint和double之間的比較

hive.strict.checks.cartesian.product = true
該屬性不允許笛卡爾積操作
具體例子:

select gid,
        uid,
        DAY,
        watch_time,
        first_watch_date
from(
    SELECT gid,
           user_id AS uid, 
           host_id,                                                   
           DAY,                                                       
           sum(watch_time) AS watch_time,                             
           min(hour(tm)) as first_watch_hour,
           min(to_date(tm)) as first_watch_date
    FROM dwd.dwd_room_watch_time
    WHERE gid IS NOT NULL
      AND host_id IS NOT NULL
      AND watch_time is not null
      AND DAY <= 20201012
      AND DAY >= 20201005
    GROUP BY gid, user_id,DAY,game_key,host_id,platform
    ) as t0_watch_time
where first_watch_date >= date_add("2020-10-12",-7) and first_watch_date <="2020-10-12"
排序加索引

scala中涣脚,ml或milib中的模型特征需要topK排序加索引,我通常使用data.sortBy().zipWithIndex()組合來生存排序和索引寥茫。
hive中則需要用到row_number遣蚀、rank、dense_rank
RANK():返回?cái)?shù)據(jù)項(xiàng)在分組中的排名纱耻,在排名相等時(shí)會(huì)在名次中留下空位芭梯,造成排名不連續(xù)。
DENSE_RANK():同樣返回?cái)?shù)據(jù)項(xiàng)在分組中排名弄喘,不過在排名相等時(shí)不會(huì)留下名位空位玖喘。
ROW_NUMBER():為每一條分組記錄返回一個(gè)數(shù)字,注意不同于rownum偽列蘑志。
partition by相當(dāng)于group by累奈,按照第一個(gè)字段分組按照category_3字段降序排列贬派。
select *,DENSE_RANK() OVER(order by 字段) as 字段新名稱 from table_name
dense_rank函數(shù)的功能與rank函數(shù)類似,dense_rank函數(shù)在生成序號(hào)時(shí)是連續(xù)的澎媒,而rank函數(shù)生成的序號(hào)有可能不連續(xù)搞乏。

select *,dense_rank() over (order by category_3 desc) as label_3 --Level3
from table_name where title like '%戴森%'

select *    --多個(gè)字段標(biāo)號(hào)
,dense_rank() over  (order by category_1 desc) as label_1  --Level1                 
,dense_rank() over (partition by category_1 order by category_2 desc) as label_2 --Level2       
,dense_rank() over (partition by category_1,category_2 order by category_3 desc) as label_3 --Level3
from table_name

網(wǎng)上的例子看row_number、rank戒努、dense_rank的區(qū)別:
查看班級(jí)排名情況请敦,rn為排名次序字段
select *, rank() over (partition by class order by score desc) rn from t_score where term="201702";


三班的排名出現(xiàn)了兩個(gè)并列第一,然后緊接著就是第三名储玫,沒有第二名了侍筛。想要把第三名更正為第二名則需要用dense_rank
select *, dense_rank() over (partition by class order by score desc) from t_score where term="201702";

假使不想出現(xiàn)并列的情況,只打算排序缘缚,序號(hào)要唯一勾笆。

1. 首先按照成績排序
2. 成績相同的不要并列敌蚜,而是再按照姓名排序桥滨,姓氏靠后的認(rèn)倒霉吧
3. 對(duì)于成績和姓名都完全相同的情況,沒有指定就假裝不存在這種情況好啦

select *, row_number() over (partition by class order by score desc, name) from t_score where term="201702";
結(jié)果大概是這樣:

hive中的復(fù)合數(shù)據(jù)結(jié)構(gòu)

hive中的復(fù)合數(shù)據(jù)結(jié)構(gòu)有如下幾種

map
 (key1, value1, key2, value2, ...) Creates a map with the given key/value pairs
 struct  
 (val1, val2, val3, ...) Creates a struct with the given field values. Struct field names will be col1, col2, ...
 named_struct  
 (name1, val1, name2, val2, ...) Creates a struct with the given field names and values. (as of Hive 0.8.0)
 array  
 (val1, val2, ...) Creates an array with the given elements
 create_union  
 (tag, val1, val2, ...) Creates a union type with the value that is being pointed to by the tag parameter

常用的三種為array map struct
array的用法

hive中array可以通過索引來取出制定位置的元素
array[0]弛车,array[5]
判斷array是否含有某個(gè)元素
array_contains
用法示例:
SELECT array_CONTAINS(ARRAY(0,1),0) returns true
SELECT array_CONTAINS(split(‘0=1’,’=’),’0’) returns true
array大小
size(array)

有時(shí)候需要對(duì)array切片齐媒,比如需要取array中前top50的元素
網(wǎng)上通常是使用udf解決,hive使用udf比spark中的udf麻煩纷跛,個(gè)人不喜歡用喻括,可以把a(bǔ)rray轉(zhuǎn)成字符串曲線救國。
字符串中有substring_index函數(shù)贫奠,這個(gè)函數(shù)的作用是唬血,拿出某個(gè)字符串前面/后面的內(nèi)容substring_index(str,1)取str前面的內(nèi)容,(array_str,array[51],-1)取str后面的內(nèi)容唤崭。
如果數(shù)組中的元素是不重復(fù)的拷恨,那么可以利用這個(gè)函數(shù)來切片再轉(zhuǎn)化為數(shù)組。
比如某表數(shù)組需要取50個(gè)元素切片谢肾,不夠50全取腕侄,超過50取前50個(gè):
可以在后面加上array_size的數(shù)組元素個(gè)數(shù)字段,再加上數(shù)組轉(zhuǎn)字符串的字段array_str芦疏。
例子:select 
if (array_size<=50,concat(array_str,','),substring_index(array_str,array[51],1)) as array_string
from table
這樣就取出了前五十個(gè)元素+“,”冕杠,后面刪去最后一個(gè)逗號(hào)在用split切割成數(shù)組,就達(dá)到了目的酸茴。

map的用法

struct的用法

創(chuàng)建表分预,寫入表

RCFILE格式

創(chuàng)建表
create table if not exists table_name (col1 string, col2 int,col3 bigint,col4 string,col5 boolean,col6 double,col7 array<double>,col8 MAP<STRING,BIGINT>) 
partitioned by (stat_date bigint) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe' STORED AS RCFILE

把temp表寫入到創(chuàng)建的表
insert overwrite table table_name partition(stat_date = "20180811" )  select * from temp

OCFILE格式
ORC三種創(chuàng)建/使用方式:
1, STORED AS ORC;
2, ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' with serdeproperties('serialization.null.format' = '') STORED AS ORC;
3, ROW FORMAT DELIMITED NULL DEFINED AS '' STORED AS ORC;

創(chuàng)建表
create table if not exists table_name (col1 string, col2 int,col3 bigint,col4 string,col5 boolean,col6 double,col7 array<double>,col8 MAP<STRING,BIGINT>) 
partitioned by (stat_date bigint) STORED AS ORC

把temp表寫入到創(chuàng)建的表
insert overwrite table table_name partition(stat_date = "20180811" )  select * from temp

正則表達(dá)式:
LIKE
RLIKE
REGEXP
REGEXP_REPLACE
例如取出數(shù)字
select regexp_replace('6125公司名稱與aaa銀行名稱賬號(hào)是工商銀行3346464646466666','[^0-9]','');
REGEXP_EXTRACT

Hive 文件格式

hive文件存儲(chǔ)格式包括以下幾類:

1、TEXTFILE
2薪捍、SEQUENCEFILE
3笼痹、RCFILE
4魁淳、ORCFILE(0.11以后出現(xiàn))

其中TEXTFILE為默認(rèn)格式,建表時(shí)不指定默認(rèn)為這個(gè)格式与倡,導(dǎo)入數(shù)據(jù)時(shí)會(huì)直接把數(shù)據(jù)文件拷貝到hdfs上不進(jìn)行處理界逛;

SEQUENCEFILE,RCFILE纺座,ORCFILE格式的表不能直接從本地文件導(dǎo)入數(shù)據(jù)息拜,數(shù)據(jù)要先導(dǎo)入到textfile格式的表中, 然后再從表中用insert導(dǎo)入SequenceFile,RCFile,ORCFile表中净响。

一少欺、TEXTFILE

默認(rèn)格式,數(shù)據(jù)不做壓縮馋贤,磁盤開銷大赞别,數(shù)據(jù)解析開銷大。
可結(jié)合Gzip配乓、Bzip2使用(系統(tǒng)自動(dòng)檢查仿滔,執(zhí)行查詢時(shí)自動(dòng)解壓),但使用這種方式犹芹,hive不會(huì)對(duì)數(shù)據(jù)進(jìn)行切分崎页,
從而無法對(duì)數(shù)據(jù)進(jìn)行并行操作。

二腰埂、SEQUENCEFILE

SequenceFile是Hadoop API提供的一種二進(jìn)制文件支持飒焦,其具有使用方便、可分割屿笼、可壓縮的特點(diǎn)牺荠。
SequenceFile支持三種壓縮選擇:NONE,RECORD驴一,BLOCK休雌。Record壓縮率低,一般建議使用BLOCK壓縮蛔趴。

三挑辆、RCFILE

RCFILE是一種行列存儲(chǔ)相結(jié)合的存儲(chǔ)方式。首先孝情,其將數(shù)據(jù)按行分塊鱼蝉,保證同一個(gè)record在一個(gè)塊上,避免讀一個(gè)記錄需要讀取多個(gè)block箫荡。其次魁亦,塊數(shù)據(jù)列式存儲(chǔ),有利于數(shù)據(jù)壓縮和快速的列存取羔挡。

四洁奈、ORCFILE

然后是 ORC File(Optimized Row Columnar file)间唉,對(duì)RCFile做了一些優(yōu)化,克服 RCFile 的一些限制利术,主要參考這篇文檔呈野。 和RCFile格式相比,ORC File格式有以下優(yōu)點(diǎn):

  • 每個(gè)task只輸出單個(gè)文件印叁,這樣可以減少NameNode的負(fù)載被冒;
  • 支持各種復(fù)雜的數(shù)據(jù)類型,比如: datetime, decimal, 以及一些復(fù)雜類型(struct, list, map, and union)轮蜕;
  • 在文件中存儲(chǔ)了一些輕量級(jí)的索引數(shù)據(jù)昨悼;
  • 基于數(shù)據(jù)類型的塊模式壓縮:
    • integer類型的列用行程長度編碼(run-length encoding)
    • String類型的列用字典編碼(dictionary encoding);
  • 用多個(gè)互相獨(dú)立的RecordReaders并行讀相同的文件跃洛;
  • 無需掃描markers就可以分割文件率触;
  • 綁定讀寫所需要的內(nèi)存;
  • metadata的存儲(chǔ)是用 Protocol Buffers的汇竭,所以它支持添加和刪除一些列葱蝗。

總結(jié):
相比TEXTFILE和SEQUENCEFILE,RCFILE由于是列式存儲(chǔ)方式韩玩,數(shù)據(jù)加載時(shí)性能消耗較大垒玲,但是具有較好的壓縮比和查詢響應(yīng)。數(shù)據(jù)倉庫的特點(diǎn)是一次寫入找颓、多次讀取,因此叮贩,整體來看击狮,RCFILE相比其余兩種格式具有較明顯的優(yōu)勢(shì)。

hive常見錯(cuò)誤

FAILED: ParseException line 1:56 cannot recognize input near 'xxxx'  in constant (state=42000,code=40000)

遇見這種錯(cuò)誤主要是幾種情況益老,
1.某個(gè)hive字段名使用了end這樣的hive保留字段
2.某些地方不小心加了空格沒有發(fā)現(xiàn)
3.通shell腳本往sql中傳參數(shù)彪蓬,參數(shù)沒有上傳成功

HDFS基本操作

HDFS的設(shè)計(jì)目標(biāo)
巨大的分布式文件系統(tǒng)
運(yùn)行在普通廉價(jià)的硬件上
易擴(kuò)展、為用戶提供性能不錯(cuò)的文件存儲(chǔ)服務(wù)

HDFS架構(gòu)

1個(gè)Master(NameNode/簡稱NN)帶 N個(gè)Slaves(DataNode/簡稱DN)

1個(gè)文件會(huì)被拆分成多個(gè)Block
如果設(shè)定blocksize: 128M
130M ==> 2個(gè)Block: 128M 和 2M

NN
(1)負(fù)責(zé)客戶端請(qǐng)求的響應(yīng)
(2)負(fù)責(zé)元數(shù)據(jù)(文件的名稱捺萌、副本系數(shù)档冬、Block存放的DN)的管理

DN
(1)存儲(chǔ)用戶文件對(duì)應(yīng)的數(shù)據(jù)塊(Block)
(2)要定期向NN發(fā)送心跳信息,匯報(bào)本身及其所有的block信息桃纯,健康狀況酷誓。

一個(gè)典型的部署架構(gòu)是一臺(tái)機(jī)器上面運(yùn)行一個(gè)NameNode,每個(gè)其他機(jī)器上面都運(yùn)行一個(gè)DataNodes

NameNode + N個(gè)DataNode
建議: NN和DN是部署在不同的節(jié)點(diǎn)上

replication factor :副本系數(shù)态坦、副本因子
一個(gè)文件里所有的block除了最后一個(gè)可能大小不一樣盐数,其他的都是一樣的size。

軟件存放目錄
hadoop/hadoop
/home/hadoop
software:存放的是安裝的軟件包
app: 存放的是所有軟件的安裝目錄
data: 存放的是課程中的所有使用的測(cè)試數(shù)據(jù)目錄
source:存放的是軟件源碼目錄伞梯,spark

HDFS環(huán)境搭建
使用版本:hadoop-2.6.0-cdh5.7.0

(1)下載Hadoop

        http://archive.cloudera.com/cdh5/cdh/5/2.6.0-cdh5.7.0
wget http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0.tar.gz

(2)安裝JDK
安裝的版本:
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
下載
解壓到app目錄:tar -zxvf jdk-7u51-linux-x64.tar.gz -C ~/app/
驗(yàn)證安裝是否成功:~/app/jdk1.7.0_51/bin 執(zhí)行 ./java -version

建議把bin目錄配置到系統(tǒng)環(huán)境變量(~/.bash_profile)中
vi .bash_profile 編輯系統(tǒng)環(huán)境變量
添加兩行:

export JAVA_HOME=/home/hadoop/app/jdk1.7.0_51
export PATH=$JAVA_HOME/BIN:$PATH

保存以后:

source .bash_profile 讓系統(tǒng)環(huán)境變量立刻生效
echo $JAVA_HOME 輸出JAVA_HOME在哪里

(3)機(jī)器參數(shù)設(shè)置
hostname:hadoop001
修改機(jī)器名 vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=hadoop001

設(shè)置ip和hostname的映射關(guān)系:/etc/hosts
輸入 cat /etc/hosts 然后copy本機(jī)的ip地址
192.168.199.200 hadoop001
127.0.0.1 localhost

ssh 免密碼登錄(本步驟可以省略玫氢,但是后面重啟hadoop進(jìn)場(chǎng)時(shí)需要手工輸入密碼)
ssh-keygen -t rsa
cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

(4)Hadoop配置文件修改: ~/app/hadoop-2.6.0-cdh5.7.0/etc/hadoop
hadoop-env.sh
export JAVA_HOME= /home/hadoop/app/jdk1.7.0_51

core-site.xml

<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop001:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/app/tmp</value>
</property>
</configuration>

hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>

(5)格式化HDFS
注意:這一步操作帚屉,只是在第一次執(zhí)行,每次如果都格式化的話漾峡,那么HDFS上的數(shù)據(jù)會(huì)被清空
在bin目錄下執(zhí)行:./hdfs namenode -format

(6)啟停HDFS:
啟動(dòng)HDFS
在sbin目錄下執(zhí)行: ./start-dfs.sh

驗(yàn)證是否啟動(dòng)成功:
輸入: jps
SecondaryNameNode
DataNode
NameNode

停止HDFS
在sbin目錄下執(zhí)行: ./stop-dfs.sh

(7)HDFS攻旦,Hadoop shell常用命令和shell常用命令類似,很多只需要在常用shell命令前面加上"hadoop fs -"
即可生逸,下面給一些例子:

ls get mkdir rm put等等
hadoop fs 幫助命令敬特,可以查看所有可用命令
#ls
hadoop fs -ls 查看文件夾下的文件
hadoop fs -ls test 查看test文件夾下的文件
hadoop fs -ls -R   加上-R代表需要遞歸的執(zhí)行
hadoop fs -lsr  同上

#mkdir
hadoop fs -mkdir /user/root/dir 創(chuàng)建文件夾
hadoop fs -mkdir /user/root/dir1 /user/root/dir2   一次性創(chuàng)建多個(gè)文件夾
hadoop fs -mkdir -p a/b 創(chuàng)建多層文件夾

#put   把本地一個(gè)或多個(gè)文件上傳到hdfs中
hadoop fs -put <local_files> ... <hdfs_path>
hadoop fs -put Desktop/testfile.txt /user/root/dir1/
hadoop fs -put [文件] /[文件夾]/      把文件放入文件夾中
hadoop fs -put 1.tar /test 把當(dāng)前目錄的1.tar上傳到hdfs的test目錄,若test目錄中存在相同的文件牺陶,則會(huì)報(bào)錯(cuò)
hadoop fs -put -f 1.tar /test 把當(dāng)前目錄的1.tar上傳到hdfs的test目錄伟阔,若存在相同文件,會(huì)覆蓋該文件掰伸。

#copy
hadoop fs -copy [文件] /[文件夾]/      把文件放入文件夾中
hadoop fs -copy 1.tar /test 也能實(shí)現(xiàn)把本地文件傳到HDFS皱炉,和put一樣。

#rm
hadoop fs -rm [文件名]  刪除一個(gè)文件
hadoop fs -rm /test/1.tar
hadoop fs -rm -r [文件夾]  刪除文件夾需要遞歸的刪除文件 或者 hadoop fs -rmr(這是老版本代碼 )
hadoop fs -rmdir 刪除空目錄

#查看文件內(nèi)容
hadoop fs -text <paths>
hadoop fs -text [文件]  將源文件輸出為文本格式狮鸭。允許的格式是zip和TextRecordInputStream合搅。
hadoop fs -cat <paths>
hadoop fs -cat [文件] 這兩個(gè)都可以查看文件內(nèi)容

也可以用-text把文本文件保存,-text查看文件內(nèi)容以后再重定向到文件保存路徑中去
hadoop fs -text [文件歧蕉,例如:/apps/recommend/models/*]  > [保存路徑:$data_save_dir/tmp]
hadoop fs -cat [文件灾部,例如:/apps/recommend/models/*]  > [保存路徑:$data_save_dir/tmp]
hadoop fs -text /user/wangyao/data/*  > $data_save_dir/tmp

#chmod
hadoop fs -chmod -R 777 [文件夾]
hadoop fs -chmod 777 [文件]

#get 從hadoop上下載文件到本地
hadoop fs -get <hdfs_paths> <local_path>
hadoop fs -get [文件路徑]  [保存的文件路徑] 把文件下載到本地
hadoop fs -get /user/hadoop/file localfile

hadoop fs -get <hdfs_paths> <local_path>
hadoop fs -get hdfs://host:port/user/hadoop/file localfile
例如: hadoop fs -get /test/hdfs.java  code_java

#cp 復(fù)制文件
在Hadoop文件系統(tǒng)中將文件從一個(gè)地方復(fù)制到另一個(gè)地方與unix shell中的cp命令語法相同。
hadoop fs -cp <source_path> ... <destination_path>
示例:
hadoop fs -cp /user/root/dir1/testfile.txt /user/root/dir2

#mv 將文件從源移動(dòng)到目標(biāo)
以下是在Hadoop文件系統(tǒng)中將文件從一個(gè)目錄移動(dòng)到另一個(gè)目錄的語法和示例惯退。

hadoop fs -mv <source_path> <destination_path>
示例:
hadoop fs -mv /user/root/dir1/testfile.txt /user/root/dir2

##count
hadoop fs -count < hdfs path >
統(tǒng)計(jì)hdfs對(duì)應(yīng)路徑下的目錄個(gè)數(shù)赌髓,文件個(gè)數(shù),文件總計(jì)大小
顯示為目錄個(gè)數(shù)催跪,文件個(gè)數(shù)锁蠕,文件總計(jì)大小,輸入路徑

#du 顯示特定文件的總長度
為了檢查文件中內(nèi)容的總長度懊蒸,我們可以使用-du荣倾。 命令如下。 如果路徑是文件的路徑骑丸,則顯示文件的長度舌仍,如果它是目錄的路徑,則顯示的內(nèi)容的聚合大小顯示為包括所有文件和目錄通危。

hadoop fs -du <path>
示例:
hadoop fs -du /user/root/dir1/testfile.txt

#df 文件系統(tǒng)中的空間的詳細(xì)信息
要獲取Hadoop文件系統(tǒng)的所有空間相關(guān)詳細(xì)信息铸豁,我們可以使用df命令。 它提供有關(guān)當(dāng)前安裝的文件系統(tǒng)使用的空間量和可用空間量的信息
用法:
hadoop fs -df <path>
命令可以在沒有路徑URI或路徑URI的情況下使用黄鳍,當(dāng)不使用路徑URI時(shí)推姻,它提供關(guān)于整個(gè)文件系統(tǒng)的信息。 當(dāng)提供路徑URI id時(shí)框沟,它提供特定于路徑的信息藏古。

示例:
hadoop fs -df
hadoop fs -df /user/root

更多命令可以查閱 hadoop FS Shell使用指南

(8)HDFS的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
高容錯(cuò)
適合批處理
適合大數(shù)據(jù)處理
構(gòu)建在廉價(jià)的機(jī)器上

缺點(diǎn):
低延遲的數(shù)據(jù)訪問
小文件存儲(chǔ)

(9)把訓(xùn)練好的機(jī)器學(xué)習(xí)模型持久化到HDFS中(scala)

import org.apache.hadoop.fs.{FileSystem, Path}
   // 保存模型到hdfs
  def save_model(sparkSession: SparkSession, model: LogisticRegressionModel, save_dir: String) = {
    // 客戶端要構(gòu)造FileSystem對(duì)象可以使用FileSystem.get()方法增炭,使用FileSystem.get()方法獲取FileSystem對(duì)象
    val fs = FileSystem.get(new org.apache.hadoop.conf.Configuration())
    val p = new Path(save_dir)
    if (fs.exists(p)) {
      printf("\n====>>>> model file is already exists! delete it! %s", p.toString)
      fs.delete(p, true)
    }
    printf("\n====>>>> save model to %s", p.toString)
    // 保存模型
    model.save(sparkSession.sparkContext, p.toString)
  }

    // 從hdfs中讀取模型
  def load_model(sparkSession: SparkSession, model_path: String, job_date: String): LogisticRegressionModel = {
    LogisticRegressionModel.load(sparkSession.sparkContext, model_path)
  }
}

HDFS常見錯(cuò)誤:

Exception in thread "main" org.json4s.package$MappingException: Did not find value which can be converted into java.lang.String
本人遇見的情況是在HDFS上讀取保存好的文件時(shí)報(bào)錯(cuò),原因是保存的模型文件是mllib格式拧晕,而讀取的方式是ml格式隙姿,二者不兼容。

Hbase基本操作

HBase常用操作

建表
create 'Wordcount','result'
create 't1',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}

查看表結(jié)構(gòu)
describe 'Wordcount'

查看所有數(shù)據(jù)
scan 'Wordcount',{LIMIT=>10}

刪除指定rowkey
deleteall 'Wordcount','hello'

刪除所有數(shù)據(jù)
truncate 'Wordcount'

刪除表
disable 'Wordcount'
drop 'Wordcount'

加入數(shù)據(jù)
put 'Wordcount','test','result:count','2'

獲取數(shù)據(jù)
get 'Wordcount','hello','result:count'
get 'Wordcount','hello'獲取hello下所有的數(shù)據(jù)

刪除數(shù)據(jù)
delete 'Wordcount','hello','result:count'

查看表中的記錄總數(shù)
count  'table_name'

修改壓縮算法
disable 'table'
alter 'table',{NAME=>'info',COMPRESSION=>'snappy'} 
enable 'table'

刪除列族
disable 'table'
alter 'table',{NAME=>'info',METHOD=>'delete'}
enable 'table'
disable_all 和drop_all支持正則表達(dá)式厂捞,并列出當(dāng)前匹配的表
disable_all 'toplist.*' 
……
并給出確認(rèn)提示
Disable the above 25 tables (y/n)? 

分配權(quán)限
權(quán)限用五個(gè)字母表示: “RWXCA”.
READ(‘R’), WRITE(‘W’), EXEC(‘X’), CREATE(‘C’), ADMIN(‘A’)
 grant <user> <permissions> <table> <column family> <column qualifier> 參數(shù)間用逗號(hào)分隔
 grant 'test','RW','t1'

查看權(quán)限
user_permission 't1'

收回權(quán)限
revoke 'test','t1'
移動(dòng)region
encodeRegionName指的regioName后面的編碼输玷,ServerName指的是master-status的Region Servers列表
move 'encodeRegionName', 'ServerName'

開啟/關(guān)閉region
balance_switch true|false

手動(dòng)split
split 'regionName', 'splitKey'
手動(dòng)觸發(fā)major compaction
Compact all regions in a table:
hbase> major_compact 't1'
Compact an entire region:
hbase> major_compact 'r1'
Compact a single column family within a region:
hbase> major_compact 'r1', 'c1'
Compact a single column family within a table:
hbase> major_compact 't1', 'c1'

關(guān)于compaction
作用:
合并文件
清除刪除、過期靡馁、多余版本的數(shù)據(jù)
提高讀寫數(shù)據(jù)的效率
Minor Compaction
做部分文件的合并操作欲鹏,將幾個(gè)較小的相鄰StoreFiles重寫為一個(gè),會(huì)做minVersion=0并且設(shè)置ttl的過期版本清理臭墨,不做任何刪除數(shù)據(jù)浦楣、多版本數(shù)據(jù)的清理工作(major可以)
Major Compaction
將Region下的HStore下的所有StoreFile合并瘩将,Major Compaction之后每個(gè)HStore只有一個(gè)File

行轉(zhuǎn)列:
1)多行轉(zhuǎn)多列
假設(shè)數(shù)據(jù)表

row2col:
col1   col2    col3
a      c       1
a      d       2
a      e       3  
b      c       4
b      d       5
b      e       6

現(xiàn)在要將其轉(zhuǎn)化為:

col1   c      d      e
a      1      2      3
b      4      5      6

此時(shí)需要使用到max(case … when … then … else 0 end)衩椒,僅限于轉(zhuǎn)化的字段為數(shù)值類型楚殿,且為正值的情況。

HQL語句為:

select col1,
max(case col2 when 'c' then col3 else 0 end) as c,
max(case col2 when 'd' then col3 else 0 end) as d,
max(case col2 when 'e' then col3 else 0 end) as e
from row2col
group by col1;

列轉(zhuǎn)行:

References

http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.0.0.2/ds_Hive/orcfile.html
https://blog.csdn.net/Nougats/article/details/72722503

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末结缚,一起剝皮案震驚了整個(gè)濱河市损晤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌红竭,老刑警劉巖尤勋,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異德崭,居然都是意外死亡斥黑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門眉厨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兽狭,你說我怎么就攤上這事憾股。” “怎么了箕慧?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵服球,是天一觀的道長。 經(jīng)常有香客問我颠焦,道長斩熊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任伐庭,我火速辦了婚禮粉渠,結(jié)果婚禮上分冈,老公的妹妹穿的比我還像新娘。我一直安慰自己霸株,他們只是感情好雕沉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著去件,像睡著了一般坡椒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尤溜,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天倔叼,我揣著相機(jī)與錄音,去河邊找鬼宫莱。 笑死丈攒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梢睛。 我是一名探鬼主播肥印,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绝葡!你這毒婦竟也來了深碱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤藏畅,失蹤者是張志新(化名)和其女友劉穎敷硅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愉阎,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绞蹦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榜旦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幽七。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖溅呢,靈堂內(nèi)的尸體忽然破棺而出澡屡,到底是詐尸還是另有隱情,我是刑警寧澤咐旧,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布驶鹉,位于F島的核電站,受9級(jí)特大地震影響铣墨,放射性物質(zhì)發(fā)生泄漏室埋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望姚淆。 院中可真熱鬧孕蝉,春花似錦、人聲如沸肉盹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽上忍。三九已至骤肛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窍蓝,已是汗流浹背腋颠。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吓笙,地道東北人淑玫。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像面睛,于是被迫代替她去往敵國和親絮蒿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容