什么是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 ' ' 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分隔符区分