Hadoop 存档

每个文件均按块存储,每个块的元数据存储在namenode的内存中,因此hadoop存储小文件会非常低效。因为大量的小文件会耗尽namenode中的大部分内存。但注意,存储小文件所需要的磁盘容量和存储这些文件原始内容所需要的磁盘空间相比也不会增多。例如,一个1MB的文件以大小为128MB的块存储,使用的是1MB的磁盘空间,而不是128MB。

Hadoop存档文件或HAR文件,是一个更高效的文件存档工具,它将文件存入HDFS块,在减少namenode内存使用的同时,允许对文件进行透明的访问。具体说来,Hadoop存档文件可以用作MapReduce的输入。

start-yarn.sh

归档成一个叫做xxx.har的文件夹,该文件夹下有相应的数据文件。Xx.har目录是一个整体,该目录看成是一个归档文件即可。

bin/hadoop archive -archiveName myhar.har -p /user/liucw /user/my

查看归档

hadoop fs -lsr /user/my/myhar.har

hadoop fs -lsr har:///myhar.har

解归档

hadoop fs -cp har:/// user/my/myhar.har /* /user/liucw

HDFS 快照管理

快照相当于对目录做一个备份。并不会立即复制所有文件,而是指向同一个文件。当写入发生时,才会产生新文件。

基本语法

1.hdfs dfsadmin -allowSnapshot 路径 (功能描述:开启指定目录的快照功能)

2.hdfs dfsadmin -disallowSnapshot 路径 (功能描述:禁用指定目录的快照功能,默认是禁用)

3.hdfs dfs -createSnapshot 路径 (功能描述:对目录创建快照)

4.hdfs dfs -createSnapshot 路径 名称 (功能描述:指定名称创建快照)

5.hdfs dfs -renameSnapshot 路径 旧名称 新名称 (功能描述:重命名快照)

6.hdfs lsSnapshottableDir (功能描述:列出当前用户所有可快照目录)

7.hdfs snapshotDiff 路径1 路径2 (功能描述:比较两个快照目录的不同之处)

8.hdfs dfs -deleteSnapshot (功能描述:删除快照)

HDFS 回收站

1.默认回收站
  默认值fs.trash.interval=0,0表示禁用回收站,可以设置删除文件的存活时间。
  默认值fs.trash.checkpoint.interval=0,检查回收站的间隔时间。
  要求fs.trash.checkpoint.interval<=fs.trash.interval。

2.启用回收站
  修改core-site.xml,配置垃圾回收时间为1分钟

<property>
name>fs.trash.interval</name>
value>1</value>
</property>


 

3)查看回收站
  回收站在集群中的;路径:/user/liucw/.Trash/….

4)修改访问垃圾回收站用户名称
  进入垃圾回收站用户名称,默认是dr.who,修改为liucw用户
  [core-site.xml]

<property>
name>hadoop.http.staticuser.user</name>
value>liucw</value>
</property>


5)通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站

Trash trash = New Trash(conf);
trash.moveToTrash(path);


6)恢复回收站数据
hadoop fs -mv /user/liucw/.Trash/Current/user/liucw/input /user/liucw/input

7)清空回收站
hdfs dfs -expunge

多目录配置 NameNode和DataNode

Namenode故障后,可以采用如下两种方法恢复数据。
  方法一:将SecondaryNameNode中数据拷贝到namenode存储数据的目录;
  方法二:使用-importCheckpoint选项启动namenode守护进程,从而将SecondaryNameNode中数据拷贝到namenode目录中。

手动拷贝SecondaryNameNode数据:

模拟namenode故障,并采用方法一,恢复namenode数据

1.kill -9 namenode进程

2.删除namenode存储的数据

rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

3.拷贝SecondaryNameNode中数据到原namenode存储数据目录

scp -r liucw@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/

4.重新启动namenode

sbin/hadoop-daemon.sh start namenode

采用importCheckpoint命令拷贝SecondaryNameNode数据

模拟namenode故障,并采用方法二,恢复namenode数据

0)修改hdfs-site.xml中的

<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
 
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>


1)kill -9 namenode进程

2)删除namenode存储的数据
[liucw@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

3)如果SecondaryNameNode不和Namenode在一个主机节点上,需要将SecondaryNameNode存储数据的目录拷贝到Namenode存储数据的平级目录,并删除in_use.lock文件。

scp -r liucw@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./

 rm -rf in_use.lock

4)导入检查点数据(等待一会ctrl+c结束掉)

bin/hdfs namenode -importCheckpoint

5)启动namenode

sbin/hadoop-daemon.sh start namenode

DataNode 服役和退役

服役新节点具体步骤

1.在namenode的/opt/module/hadoop-2.7.2/etc/hadoop目录下创建dfs.hosts文件

vi dfs.hosts

添加如下主机名称(包含新服役的节点)

hadoop102
hadoop103
hadoop104
hadoop105

2.在namenode的hdfs-site.xml配置文件中增加dfs.hosts属性

<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
</property>

3.刷新namenode

hdfs dfsadmin -refreshNodes

4.更新resourcemanager节点

yarn rmadmin -refreshNodes

5.在namenode的slaves文件中增加新主机名称

增加105 不需要分发

hadoop102
hadoop103
hadoop104
hadoop105

6.单独命令启动新的数据节点和节点管理器

sbin/hadoop-daemon.sh start datanode

sbin/yarn-daemon.sh start nodemanager

7.在web浏览器上检查是否ok

8.如果数据不均衡,可以用命令实现集群的再平衡

./start-balancer.sh

退役旧数据节点

1.在namenode下创建dfs.hosts.exclude文件

vi dfs.hosts.exclude

添加如下主机名称(要退役的节点)

hadoop105

2.在namenode配置hdfs-site.xml

<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
</property>

3.刷新namenode、resourcemanager

hdfs dfsadmin -refreshNodes

yarn rmadmin -refreshNodes

4.检查web浏览器
  退役节点的状态为 decommission in progress(退役中),说明数据节点正在复制块到其他节点。

5.停止该节点及节点资源管理器
  等待退役节点状态为 decommissioned(所有块已经复制完成),停止该节点及节点资源管理器。
注意:如果副本数是3,服役的节点小于等于3,是不能退役成功的,需要修改副本数后才能退役。

sbin/hadoop-daemon.sh stop datanode

sbin/yarn-daemon.sh stop nodemanager

6.从include文件中删除退役节点,再运行刷新节点的命令
  1)从namenode的dfs.hosts文件中删除退役节点hadoop105

 

hadoop102

 

hadoop103

 

hadoop104

2)刷新namenode,刷新resourcemanager

hdfs dfsadmin -refreshNodes

yarn rmadmin -refreshNodes

7.从namenode的slave文件中删除退役节点hadoop105

hadoop102

hadoop103

hadoop104

8.如果数据不均衡,可以用命令实现集群的再平衡

sbin/start-balancer.sh

Hive 函数

系统自带的函数

1)查看系统自带的函数:hive> show functions;2)显示自带的函数的用法: hive> desc function upper;3)详细显示自带的函数的用法: hive> desc function extended upper;

行转列

person_info.tsv

孙悟空 白羊座 A

大海 射手座 A

宋宋 白羊座 B

猪八戒 白羊座 A

凤姐 射手座 A

1.创建表及数据导入:
hive (default)> create table person_info(
name string,
constellation string,
blood_type string)
row format delimited fields terminated by "\t";
 
hive (default)> load data local inpath “person_info.tsv” into table person_info;
 
2.把星座和血型一样的人归类到一起
如白羊座,A 猪八戒|孙悟空
select t1.base, concat_ws('|', collect_set(t1.name)) name
from
(select name, concat(constellation, ",", blood_type) base
from person_info) t1
group by t1.base;
 
t1.base name
射手座,A 大海|凤姐
白羊座,A 孙悟空|猪八戒
白羊座,B 宋宋
 
collect_set UDAF
concat_ws 用法concat_ws(',', '1', '2') -> 1,2


列转行

movie_info.tsv

《疑犯追踪》 悬疑,动作,科幻,剧情

《Lie to me》 悬疑,警匪,动作,心理,剧情

《战狼 2》 战争,动作,灾难

1.创建表及导入数据:
hive (default)>create table movie_info(
movie string,
category array<string>)
row format delimited fields terminated by "\t"
collection items terminated by ",";
 
hive (default)> load data local inpath "movie_info.tsv" into table movie_info;
 
2.例如:将电影分类中的数组数据展开
select movie,category_name
from movie_info lateral view explode(category) table_tmp as category_name;
 
movie category_name
《疑犯追踪> 悬疑
《疑犯追踪> 动作
《疑犯追踪> 科幻
《疑犯追踪> 剧情
《Lie to me> 悬疑
《Lie to me> 警匪
《Lie to me> 动作
《Lie to me> 心理
《Lie to me> 剧情
《战狼 2> 战争
《战狼 2> 动作
《战狼 2> 灾难
 
lateral: 测面
explode UDTF函数(一进多出)
 
数组操作
“fields terminated by”:字段与字段之间的分隔符。
“collection items terminated by”:一个字段中各个子元素 item 的分隔符。



自定义函数描述

1)Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。

2)当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)

3)根据用户自定义函数类别分为以下三种:
  1)UDF(User-Defined-Function): 一进一出
  2)UDAF(User-Defined Aggregation Function): (aggregation 聚集)聚集函数,多进一出. 类似于:count/max/min
  3)UDTF(User-Defined Table-Generating Functions): 一进多出, 如lateral view explore()

4)官方文档地址: https://cwiki.apache.org/confluence/display/Hive/HivePlugins5)编程步骤

(1)继承org.apache.hadoop.hive.ql.UDF

 

(2)需要实现evaluate函数;evaluate函数支持重载;

 

(3)在hive的命令行窗口创建函数

1.添加jar

add jar linux_jar_path

 

2.创建function

create [emporary] function [dbname.] function_name AS class_name;

 

(4)在hive的命令窗口删除函数

drop [temporary] function [if exists] [dbname.] function_name

 

6)注意事项
  1)UDF必须要有返回类型,可以返回null,但是返回类型不能为void;
  2)UDF中常用Text/LongWritable等类型,不推荐使用java类型;

自定义函数开发案例

1)创建一个java工程,并创建一个lib文件夹

2)将hive的jar包解压后,将apache-hive-1.2.1-bin\lib文件下的jar包都拷贝到java工程中。

3)创建一个类

package com.liucw.hive;
import org.apache.hadoop.hive.ql.exec.UDF;
 
public class Lower extends UDF {
    public String convert(final String s) {
        if (s == null) {
            return null;
        }
        return s.toString().toLowerCase();
    }
}


 

4)打成jar包上传到服务器/opt/module/jars/udf.jar

5)将jar包添加到hive的classpath
hive (default)> add jar /opt/module/jars/udf.jar;

6)创建临时函数与开发好的java class关联
hive (default)> create temporary function my_lower as "com.liucw.hive.Lower";

7)即可在hql中使用自定义的函数strip
hive (default)> select ename, my_lower(ename) lowername from emp;

Hive 操作

DDL数据定义

  DDL(data definition language)数据库定义语言:其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。
  DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上

创建数据库

  数据库在HDFS上的默认存储路径是/user/hive/warehouse/*.db。

1)创建一个数据库
hive (default)> create database db_hive;
 
2)避免要创建的数据库已经存在错误,增加if not exists判断。(标准写法)
hive (default)> create database if not exists db_hive;
 
3)创建一个数据库,指定数据库在HDFS上存放的位置
hive (default)> create database db_hive2 location '/db_hive2.db';


 

修改数据库

  用户可以使用ALTER DATABASE命令为某个数据库的DBPROPERTIES设置键-值对属性值,来描述这个数据库的属性信息。
  数据库的其他元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置。

hive (default)> alter database db_hive set dbproperties('createtime'='20170830');
 
// 在mysql中查看修改结果
hive> desc database extended db_hive;
db_name comment location        owner_name      owner_type      parameters
db_hive         hdfs://hadoop102:8020/user/hive/warehouse/db_hive.db    liucw USER    {createtime=20170830}


 

查询数据库

1 显示数据库
    1)显示数据库:hive> show databases;
    2)过滤显示查询的数据库: hive> show databases like 'db_hive*';
 
2 查看数据库详情
    1)显示数据库信息: hive> desc database db_hive;
    2)显示数据库详细信息: hive> desc database extended db_hive;
 
3.使用数据库: hive> use db_hive;


删除数据库

1)删除空数据库:hive>drop database db_hive2;
 
2)如果删除的数据库不存在,最好采用 if exists判断数据库是否存在
hive> drop database if exists db_hive2;
 
3)如果数据库不为空,可采用cascade命令,强制删除
hive> drop database db_hive cascade;


创建表

内部表

1)理论
  默认创建的表都是所谓的管理表,有时也被称为内部表。
  因为这种表,Hive会(或多或少地)控制着数据的生命周期。
  Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。
  当我们删除一个管理表时,Hive也会删除这个表中数据。
  管理表不适合和其他工具共享数据。

2)案例实操

(1)普通创建表
hive >create table if not exists student2(
id int, name string
)
row format delimited fields terminated by '\t'
stored as textfile
location '/user/hive/warehouse/student2';
 
 
(2)根据查询结果创建表(查询的结果会添加到新创建的表中)
hive >create table if not exists student3
as select id, name from student;
 
 
(3)根据已经存在的表结构创建表,只有表结构
hive >create table if not exists student4 like student3;
 
 
(4)查询表的类型
hive > desc formatted student2;
Table Type:             MANAGED_TABLE  
 
delimited  划定…的界限
terminated  终止

 

外部表

1)理论

  因为表是外部表,所有Hive并非认为其完全拥有这份数据(hdfs上的数据)。

  删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉。

2)管理表和外部表的使用场景:
  每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。

3)案例实操
分别创建部门和员工外部表,并向表中导入数据。

dept.txt
10  ACCOUNTING  1700
20  RESEARCH    1800
30  SALES   1900
40  OPERATIONS  1700
emp.txt
7369    SMITH   CLERK   7902    1980-12-17  800.00      20
7499    ALLEN   SALESMAN    7698    1981-2-20   1600.00 300.00  30
7521    WARD    SALESMAN    7698    1981-2-22   1250.00 500.00  30
7566    JONES   MANAGER 7839    1981-4-2    2975.00     20
7654    MARTIN  SALESMAN    7698    1981-9-28   1250.00 1400.00 30
7698    BLAKE   MANAGER 7839    1981-5-1    2850.00     30
7782    CLARK   MANAGER 7839    1981-6-9    2450.00     10
7788    SCOTT   ANALYST 7566    1987-4-19   3000.00     20
7839    KING    PRESIDENT       1981-11-17  5000.00     10
7844    TURNER  SALESMAN    7698    1981-9-8    1500.00 0.00    30
7876    ADAMS   CLERK   7788    1987-5-23   1100.00     20
7900    JAMES   CLERK   7698    1981-12-3   950.00      30
7902    FORD    ANALYST 7566    1981-12-3   3000.00     20
7934    MILLER  CLERK   7782    1982-1-23   1300.00     10

 

(2)建表语句
// 创建部门表
create external table if not exists default.dept(
deptno int,
dname string,
loc int
)
row format delimited fields terminated by '\t';
 
// 创建员工表
create external table if not exists default.emp(
empno int,
ename string,
job string,
mgr int,
hiredate string, 
sal double, 
comm double,
deptno int)
row format delimited fields terminated by '\t';
 
 
(3)查看创建的表
hive (default)> show tables;
OK
tab_name
dept
emp
 
 
(4)向外部表中导入数据
// 导入数据
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept;
hive (default)> load data local inpath '/opt/module/datas/emp.txt' into table default.emp;
 
// 查询结果
hive (default)> select * from emp;
hive (default)> select * from dept;
 
(5)查看表格式化数据
hive (default)> desc formatted dept;
Table Type:             EXTERNAL_TABLE


分区表

修改表

重命名表
(1)语法
ALTER TABLE table_name RENAME TO new_table_name
 
(2)实操案例
hive (default)> alter table dept_partition2 rename to dept_partition3;


增加、修改和删除表【分区】

详见分区表基本操作。

增加/修改/替换【列信息】

1)语法
  更新列: ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]  增加和替换列: ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)  注:ADD是代表新增一字段,字段位置在所有列后面(partition列前),REPLACE则是表示替换表中所有字段。

2)实操案例

(1)查询表结构
hive>desc dept_partition;
 
(2)添加列
hive (default)> alter table dept_partition add columns(deptdesc string);
 
hive>desc dept_partition;
 
(4)更新列
hive (default)> alter table dept_partition change column deptdesc desc int;
 
hive>desc dept_partition;
 
(6)替换列:全部替换,数据不会变,变的是表结构
hive (default)> alter table dept_partition replace columns(deptno string, dname string, loc string);
 
hive>desc dept_partition;


 

删除表

hive (default)> drop table dept_partition;


DML数据操作

  DML(data manipulation language)数据操纵语言:就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。

数据导入

向表中装载数据(Load)

1)语法

hive>load data [local] inpath '/opt/module/datas/student.txt' [overwrite] into table student [partition (partcol1=val1,…)];
(1)load data:表示加载数据
(2)local:表示从本地加载数据到hive表;否则从HDFS加载数据到hive表
(3)inpath:表示加载数据的路径
(4)into table:表示加载到哪张表
(5)student:表示具体的表
(6)overwrite:表示覆盖表中已有数据,否则表示追加
(7)partition:表示上传到指定分区


 

2)实操案例

(0)创建一张表
hive (default)> create table student(id string, name string) row format delimited fields terminated by '\t';
 
(1)加载本地文件到hive
hive (default)> load data local inpath '/opt/module/datas/student.txt' into table default.student;
 
(2)加载HDFS文件到hive中
上传文件到HDFS
hive (default)> dfs -put /opt/module/datas/student.txt /user/liucw/hive;
 
加载HDFS上数据
hive (default)>load data inpath '/user/liucw/hive/student.txt' into table default.student;
 
 
(3)加载数据覆盖表中已有的数据
上传文件到HDFS
hive (default)> dfs -put /opt/module/datas/student.txt /user/liucw/hive;
 
加载数据覆盖表中已有的数据
hive (default)>load data inpath '/user/liucw/hive/student.txt' overwrite into table default.student;


 

通过查询语句向表中插入数据(Insert)
1)创建一张分区表
hive (default)> create table student(id int, name string) partitioned by (month string) row format delimited fields terminated by '\t';
 
2)基本插入数据
hive (default)> insert into table  student partition(month='201709') values(1,'wangwu');
 
3)基本模式插入(根据单张表查询结果)
hive (default)> insert overwrite table student partition(month='201708')
             select id, name from student where month='201709';
 
4)多插入模式(根据多张表查询结果)
hive (default)> from student
              insert overwrite table student partition(month='201707')
              select id, name where month='201709'
              insert overwrite table student partition(month='201706')
              select id, name where month='201709';


查询语句中创建表并加载数据(As Select)
根据查询结果创建表(查询的结果会添加到新创建的表中)
create table if not exists student3
as 
select id, name from student;
 
 
// like是创建表结构


创建表时通过Location指定加载数据路径

1)创建表,并指定在hdfs上的位置

hive (default)> create table if not exists student5(
              id int, name string
              )
              row format delimited fields terminated by '\t'
              location '/user/hive/warehouse/student5';


2)上传数据到hdfs上
hive (default)> dfs -put /opt/module/datas/student.txt /user/hive/warehouse/student5;

3)查询数据
hive (default)> select * from student5;

Import数据到指定Hive表中

先用export导出后,再将数据导入。
hive (default)> import table student2 partition(month='201709') from '/user/hive/warehouse/export/student';


数据导出

Insert导出
1)将查询的结果导出到本地
hive (default)> insert overwrite local directory '/opt/module/datas/export/student'
            select * from student;
 
 
2)将查询的结果格式化导出到本地
hive (default)> insert overwrite local directory '/opt/module/datas/export/student1'
             ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '\n'
             select * from student;
 
 
3)将查询的结果导出到HDFS上(没有local)
hive (default)> insert overwrite directory '/user/liucw/hive/warehouse/student2'
             ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '\n'
             select * from student;


Hadoop命令导出到本地

hive (default)> dfs -get /user/hive/warehouse/student/month=201709/000000_0 /opt/module/datas/export/student3.txt;

Hive Shell 命令导出

[liucw@hadoop102 hive]$ bin/hive -e 'select * from default.student;' > /opt/module/datas/export/student4.txt;

Export导出到HDFS上

hive (default)> export table default.student to '/user/hive/warehouse/export/student';

Sqoop导出

清除表中数据(Truncate)

hive (default)> truncate table student;注意:Truncate只能删除管理表,不能删除外部表中数据

删除表drop


Hive 部署

1)Hive官网地址:http://hive.apache.org/2)文档查看地址:https://cwiki.apache.org/confluence/display/Hive/GettingStarted3)下载地址:http://archive.apache.org/dist/hive/4)github地址:https://github.com/apache/hive

前提

  1.hadoop要先启动
  2.在HDFS上创建/tmp和/user/hive/warehouse两个目录并修改他们的同组权限可写

[liucw@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -mkdir /tmp
[liucw@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -mkdir -p /user/hive/warehouse
 
[liucw@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -chmod g+w /tmp
[v@hadoop102 hadoop-2.7.2]$ bin/hadoop fs -chmod g+w /user/hive/warehouse


 


Hive安装及配置

1)解压到/opt/module/目录下面
  $ tar -zxvf apache-hive-1.2.1-bin.tar.gz -C /opt/module/

2)conf目录
  $ mv hive-env.sh.template hive-env.sh

3)配置hive-env.sh文件

export HADOOP_HOME=/opt/module/hadoop-2.7.2
export HIVE_CONF_DIR=/opt/module/hive/conf



将本地文件导入Hive案例

需求:将/opt/module/datas/student.txt这个目录下的数据导入到hive的student(id int, name string)表中。

1)数据准备:在/opt/module/datas/student.txt这个目录下准备数据

1)在/opt/module/目录下创建datas   
[liucw@hadoop102 module]$ mkdir datas
 
2)在/opt/module/datas/目录下创建student.txt文件并添加数据
[liucw@hadoop102 module]$ touch student.txt
[liucw@hadoop102 module]$ vi student.txt
1001    zhangshan
1002    lishi
1003    zhaoliu
 
注意以tab键间隔。


 

2)hive实际操作

[liucw@hadoop102 hive]$ bin/hive
hive>show databases;
hive>use default;
hive>show tables;   // 显示default数据库中的表
hive> drop table student; // 删除已创建的student
 
6)创建student表, 并声明文件分隔符’\t’
hive> create table student(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
 
7)加载/opt/module/datas/student.txt 文件到student数据库表中。
hive> load data local inpath '/opt/module/datas/student.txt' into table student;
 
hive> select * from student;
OK
1001  zhangshan
1002  lishi
1003  zhaoliu
Time taken: 0.266 seconds, Fetched: 3 row(s)


 

3)遇到的问题

再打开一个客户端窗口启动hive,会产生java.sql.SQLException异常。

原因是,Metastore默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore;


MySql安装

安装包准备

1)查看mysql是否安装,如果安装了,卸载mysql
  a)查看:rpm -qa|grep mysql
  b)卸载: rpm -e –nodeps mysql-libs-5.1.73-7.el6.x86_64

2)并设置当前用户执行权限

[root@hadoop102 mysql-libs]# ll
总用量 76048
-rw-r--r--. 1 root root 18509960 3月  26 2015 MySQL-client-5.6.24-1.el6.x86_64.rpm
-rw-r--r--. 1 root root  3575135 12月  1 2013 mysql-connector-java-5.1.27.tar.gz
-rw-r--r--. 1 root root 55782196 3月  26 2015 MySQL-server-5.6.24-1.el6.x86_64.rpm
 
[root@hadoop102 mysql-libs]# chmod u+x ./*
[root@hadoop102 mysql-libs]# ll
总用量 76048
-rwxr--r--. 1 root root 18509960 3月  26 2015 MySQL-client-5.6.24-1.el6.x86_64.rpm
-rwxr--r--. 1 root root  3575135 12月  1 2013 mysql-connector-java-5.1.27.tar.gz
-rwxr--r--. 1 root root 55782196 3月  26 2015 MySQL-server-5.6.24-1.el6.x86_64.rpm


 

安装MySql服务器

1)安装mysql服务端
[root@hadoop102 mysql-libs]# rpm -ivh MySQL-server-5.6.24-1.el6.x86_64.rpm

2)查看产生的随机密码!!
[root@hadoop102 mysql-libs]# cat /root/.mysql_secretOEXaQuS8IWkG19Xs

3)查看mysql状态
[root@hadoop102 mysql-libs]# service mysql status

4)启动mysql
[root@hadoop102 mysql-libs]# service mysql start

安装MySql客户端

1)安装mysql客户端
[root@hadoop102 mysql-libs]# rpm -ivh MySQL-client-5.6.24-1.el6.x86_64.rpm

2)链接mysql
[root@hadoop102 mysql-libs]# mysql -uroot -pOEXaQuS8IWkG19Xs

3)修改密码
mysql>SET PASSWORD=PASSWORD('000000');

4)退出mysql
mysql>exit

MySql中user表中主机配置

配置只要是root用户+密码,在任何主机上都能登录MySQL数据库。
1)进入mysql

[root@hadoop102 mysql-libs]# mysql -uroot -p000000
 
mysql>show databases;
mysql>use mysql;
mysql>show tables;
mysql>desc user;
mysql>select User, Host, Password from user;


 

2)修改user表,把Host表内容修改为%
mysql>update user set host='%' where host='localhost';

3)删除root用户的其他host

mysql>delete from user where Host='hadoop102 ';
mysql>delete from user where  Host='127.0.0.1';
mysql>delete from user where  Host='::1';


 

4)刷新并退出
mysql>flush privileges;mysql> quit;


Hive元数据配置到MySql

驱动拷贝

1)在/opt/software/mysql-libs目录下解压mysql-connector-java-5.1.27.tar.gz驱动包
[root@hadoop102 mysql-libs]# tar -zxvf mysql-connector-java-5.1.27.tar.gz
 
2)拷贝/opt/software/mysql-libs/mysql-connector-java-5.1.27目录下的mysql-connector-java-5.1.27-bin.jar到/opt/module/hive/lib/
[root@hadoop102 mysql-connector-java-5.1.27]# cp mysql-connector-java-5.1.27-bin.jar /opt/module/hive/lib/


配置Metastore到MySql

1)在/opt/module/hive/conf目录下创建一个hive-site.xml
[root@hadoop102 conf]# vi hive-site.xml

2)根据官方文档配置参数,拷贝数据到hive-site.xml文件中。
https://cwiki.apache.org/confluence/display/Hive/AdminManual+MetastoreAdmin

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://hadoop102:3306/metastore?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>
        <!-- mysql的密码-->
      <value>000000</value>
      <description>password to use against metastore database</description>
    </property>
 
<!--实现显示当前数据库,以及查询表的头信息配置-->
<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
</property>
 
</configuration>


 

3)配置完毕后,如果启动hive异常,可以重新启动虚拟机。(重启后,别忘了启动hadoop集群)

多窗口启动Hive测试

1)先启动MySQL

[liucw@hadoop102 mysql-libs]$ mysql -uroot -p000000
    查看有几个数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql             |
| performance_schema |
| test               |
+--------------------+


 

2)再次打开多个窗口,分别启动hive
[liucw@hadoop102 hive]$ bin/hive

3)启动hive后,回到MySQL窗口查看数据库,显示增加了metastore数据库

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| metastore          |   <-----
| mysql             |
| performance_schema |
| test               |
+--------------------+


 


Hive命令操作

Hive基本操作

1)启动hive $ bin/hive2)查看数据库: hive>show databases;3)打开默认数据库: hive>use default;4)显示default数据库中的表: hive>show tables;5)创建一张表: hive> create table student(id int, name string);6)显示数据库中有几张表: hive>show tables;7)查看表的结构: hive>desc student;8)向表中插入数据: hive> insert into student values(1000,"ss");9)查询表中数据: hive> select * from student;10)退出hive: hive> quit;  在新版的oracle中没区别了,在以前的版本是有的:
  exit:先隐性提交数据,再退出;
  quit:不提交数据,退出;

11)查看在hive中输入的所有历史命令
  (1)进入到当前用户的根目录/root或/home/liucw
  (2)查看. hivehistory文件
[liucw@hadoop102 ~]$ cat .hivehistory

12)查看hdfs文件系统: hive>dfs -ls /;13)查看hdfs本地系统: hive>! ls /opt/module/datas;

Hive常用交互命令

$ bin/hive -help
hive> create table student(id int, name string) row format delimited fields terminated by ‘\t’;

1)“-e”不进入hive的交互窗口执行sql语句
[liucw@hadoop102 hive]$ bin/hive -e "select id from default.student;"

2)“-f”执行脚本中sql语句

(1)在/opt/module/datas目录下创建hivef.sql文件
[liucw@hadoop102 datas]$ touch hivef.sql
文件中写入正确的sql语句
select *from student;
 
s
(2)执行文件中的sql语句
[liucw@hadoop102 hive]$ bin/hive -f /opt/module/datas/hivef.sql
 
(3)执行文件中的sql语句并将结果写入文件中
[liucw@hadoop102 hive]$ bin/hive -f /opt/module/datas/hivef.sql  > /opt/module/datas/hive_result.txt


 


Hive常见属性配置

Hive数据仓库位置配置

1).Default数据仓库的最原始位置是在hdfs上的:/user/hive/warehouse路径下

2).在仓库目录下,没有对默认的数据库default创建文件夹。如果某张表属于default数据库,直接在数据仓库目录下创建一个文件夹。
(3)修改default数据仓库原始位置(将hive-default.xml.template如下配置信息拷贝到hive-site.xml文件中)

<property>
        <name>hive.metastore.warehouse.dir</name>
        <value>/user/hive/warehouse</value>
        <description>location of default database for the warehouse</description>
</property>


 

配置同组用户有执行权限 bin/hdfs dfs -chmod g+w /user/hive/warehouse

显示当前数据库,以及查询表的头信息配置

1)在hive-site.xml文件中添加如下配置信息,就可以实现显示当前数据库,以及查询表的头信息配置。

<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
 
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
</property>


 

2)重新启动hive,对比配置前后差异

1)配置前
hive> select * from student
1001 xiaoli
1002 libingbing
 
2)配置后
hive(db_hive)> select * from student
student.id      student.name
1001            xiaoli
1002            libingbing


 

Hive运行日志信息配置

1)Hive的log默认存放在/tmp/liucw/hive.log目录下(当前用户名下)

2)修改hive的log存放日志到/opt/module/hive/logs

(1)修改/opt/module/hive/conf/hive-log4j.properties.template文件名称为hive-log4j.properties
 
[liucw@hadoop102 conf]$ pwd
/opt/module/hive/conf
 
[liucw@hadoop102 conf]$ mv hive-log4j.properties.template hive-log4j.properties
 
 
(2)在hive-log4j.properties文件中修改log存放位置
hive.log.dir=/opt/module/hive/logs


 

Kafka Manager部署安装


先安装sbt

1.下载网页http://www.scala-sbt.org/download.html

2.解压并创建脚本

$ tar zxvf /media/psf/Home/Documents/install_jar/sbt-1.2.8.tgz -C /opt/module/
 
[liucw@localhost sbt]$ pwd /opt/module/sbt
 
[liucw@localhost sbt]$ vim sbt
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"
java $SBT_OPTS -jar /opt/module/sbt/bin/sbt-launch.jar "$@"
 
/×修改sbt文件权限×/
[liucw@localhost sbt]$ chmod u+x sbt


 

3.配置PATH环境变量,保证在控制台中可使用sbt命令

$ vim  /etc/profile
# sbt
export PATH=/opt/module/sbt/:$PATH
 
/*使配置文件立刻生效*/
$ source  /etc/profile


 

4.测试sbt是否安装成功
第一次执行时,会下载一些包,然后才能正常使用
$ sbt version


Kafka Manager 部署

重编译

1.Git或者直接从Releases中下载:https://github.com/yahoo/kafka-manager/releases

2.解压
$ tar -zxvf /media/psf/Home/Documents/install_jar/kafka-manager-1.3.3.18.tar.gz -C /opt/module/

3.重编译

[liucw@hadoop102 kafka-manager-1.3.3.18]$./sbt clean dist
[info] Your package is ready in /opt/module/kafka-manager-1.3.3.18/target/universal/kafka-manager-1.3.3.18.zip
[info] 
[success] Total time: 1960 s, completed Feb 18, 2019 11:09:53 AM
 
[liucw@hadoop102 module]$ mv kafka-manager-1.3.3.18/ bak_kafka-manager-1.3.3.18


 

用重编译的包

1.解压
  [liucw@hadoop102 module]$ unzip /media/psf/Home/Documents/install_jar/kafka-manager-1.3.3.18.zip -d /opt/module/

2.修改conf/application.properties
  修改kafka-manager.zkhosts列表为自己的zk节点
  manager.zkhosts="hadoop102:2181,hadoop103:2181,hadoop104:2181"

3启动
  nohup bin/kafka-manager &  启动完毕后可以查看端口是否启动,由于启动过程需要一段时间,端口起来的时间可能会延后。

  nohup bin/kafka-manager -Dconfig.file=conf/application.conf -Dhttp.port=8080 &  默认的端口是9000,可通过 -Dhttp.port,指定端口;
  -Dconfig.file=conf/application.conf指定配置文件:

4.浏览器访问
  http://hadoop102:9000/如果启动时有设置端口,这里的端口也要修改

 

 

Kafka 命令行操作

发送消息

[liucw@hadoop102 kafka]$ bin/kafka-console-producer.sh \
--broker-list hadoop102:9092 \
--topic first
 
>hello world
>hello liucw


消费消息

[liucw@hadoop103 kafka]$ bin/kafka-console-consumer.sh \
--zookeeper hadoop102:2181 \
--from-beginning \
--topic first
 
--from-beginning:会把first主题中以往所有的数据都读取出来。根据业务场景选择是否增加该配置。


查看某个Topic的详情

[liucw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--describe \
--topic first


查看.log或者.index文件内容

bin/kafka-run-class.sh kafka.tools.DumpLogSegments \
--files /tmp/kafka-logs/test3-0/00000000000000000000.log  \
--print-data-log
 
# 验证日志片段00000.log索引文件的正确性
bin/kafka-run-class.sh kafka.tools.DumpLogSegments \
--files /tmp/kafka-logs/test3-0/00000000000000000000.log,/tmp/kafka-logs/test3-0/00000000000000000000.index  \
--index-sanity-check


Topic操作

创建topic
[liucw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--create \
--topic first \
--replication-factor 3 \
--partitions 1
 
 
选项说明:
--topic 定义topic名
--replication-factor  定义副本数
--partitions  定义分区数
 
 
[liucw@hadoop102 kafka]$ bin/kafka-topics.sh --zookeeper hadoop102:2181 \
--create \
--topic second \
--replication-factor 3 \
--partitions 3


增加分区
[liucw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--alter \
--topic first \
--partitions 3  # 将分区数量增加到3
 
 
    这里使用--if-exists参数,主题不存在的错误就会被忽略,不建议使用


减少分区数量

  我们无法减少主题的分区数量。
  因为如果删除了分区,分区里的数据也一并被删除,导致数据不一致,我们也无法将这些数据分配给其他分区,因为这样做很难,而且会出现消息乱序。
  所以,如果一定要减少分区数量,只能删除整个主题,然后重新创建它

删除topic
[liucw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--delete \
--topic first
 
需要server.properties中设置delete.topic.enable=true否则只是标记删除或者直接重启。
 
    删除主题会丢弃主题里的所有数据。这是一个不可逆的操作,所以在执行时要十分小心。


查看当前服务器中的所有topic
[cw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--list


列出主题详情信息
[cw@hadoop102 kafka]$ bin/kafka-topics.sh \
--zookeeper hadoop102:2181 \
--describe
 
describe命令还提供了一些参数,用于过滤输出结果
    --topic:指定特定的主题
 
    下面两个参数可找出问题的分区:
    --under-replicated-partitions: 列出所有包含不同步副本的分区
    --unavailable-partitions:列出所有没有首领的分区,这些分区已经处于离线状态,对于生产者和消费者来说是必不可用的。
 
 
这些参数无法与list命令一起使用



消费者群组

保存消费者群组信息的地方
  对旧版本的消费者来说,它们的信息保存在Zookeeper上;
  对新版本的消费者来说,它们的信息保存在broker上

列出群组
# 列出旧版本的消费都群组
$ bin/kafka-consumer-groups.sh \
--zookeeper hadoop102:2181 \
--list
 
 
# 列出新版本的消费都群组
$ bin/kafka-consumer-groups.sh \
--new-consumer \
--bootstrap-server hadoop102:2181/kafka-cluster \
--list


描述群组
使用--describe代替--list
    --group 指定特定的群组
 
如,获取旧版本消费者群组信息
$ bin/kafka-consumer-groups.sh \
--zookeeper hadoop102:2181/kafka-cluster \
--describe \
--group testgroup


输出结果中的字段
  group: 消费者群组的名字
  topic: 正在被读取的主题名字
  partition: 正在被读取的分区ID
  current-offset: 消费者群组最近提交的偏移盏, 也就是消费者在分区里读取的当前位置
  log-end-offset: 当前高水位偏移量, 也就是最近一个被读取消息的偏移量,同时也是最近一个被提 交到集群的偏移是
  lag: 消费者的 CURRENT-OFFSET 和 broker 的 LOG-END-OFFSET 之间的 差距
  owner: 消费者群组里正在读取该分区的消费者。这是一个消费者的 田, 不一定包含消费 者的主机名

删除群组

  只有旧版本的消费者客户端才支持删除群组操作。在进行删除操作之前,需要先关闭消费者,或者不要让它们读取即将被删除的主题

Kafka 集群部署

1).3台主机分别关闭防火墙:chkconfig iptables off
2).安装jdk
3).安装Zookeeper

1)解压安装包
[liucw@hadoop102 software]$ tar -zxvf kafka_2.11-0.11.0.0.tgz -C /opt/module/

2)修改解压后的文件名称
[liucw@hadoop102 module]$ mv kafka_2.11-0.11.0.0/ kafka

3)在/opt/module/kafka目录下创建logs文件夹
[liucw@hadoop102 kafka]$ mkdir logs

4)修改配置文件
[liucw@hadoop102 config]$ vi config/server.properties输入以下内容:

##### server basic ### 
#broker的全局唯一编号,不能重复
broker.id=0
#是否允许删除topic
delete.topic.enable=true
 
 
num.network.threads=3   #处理网络请求的线程数量
num.io.threads=8    #用来处理磁盘IO的线程数量
socket.send.buffer.bytes=102400 #发送套接字的缓冲区大小
socket.receive.buffer.bytes=102400  #接收套接字的缓冲区大小
socket.request.max.bytes=104857600  #请求套接字的最大缓冲区大小
 
#kafka运行日志存放的路径
log.dirs=/opt/module/kafka/logs
 
num.partitions=1    #topic在当前broker上的分区个数
num.recovery.threads.per.data.dir=1 #用来恢复和清理data下数据的线程数量
log.retention.hours=168 #segment文件保留的最长时间,超时将被删除
 
#配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181


 

5)配置环境变量

[root@hadoop102 module]# vi /etc/profile
#KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
 
[root@hadoop102 module]# source /etc/profile


 

6)分发安装包

[root@hadoop102 etc]# xsync profile
[liucw@hadoop102 module]$ xsync kafka/


 

7)分别在hadoop103和hadoop104上修改配置文件/opt/module/kafka/config/server.properties中的broker.id=1、broker.id=2
  注:broker.id不得重复

8)启动集群
在后台依次在hadoop102、hadoop103、hadoop104节点上启动kafka

[liucw@hadoop102 kafka]$ bin/kafka-server-start.sh config/server.properties &
[liucw@hadoop103 kafka]$ bin/kafka-server-start.sh config/server.properties &
[liucw@hadoop104 kafka]$ bin/kafka-server-start.sh config/server.properties &
 
bin/kafka-server-start.sh -daemon ../config/server.properties

 

9)关闭集群

[liucw@hadoop102 kafka]$ bin/kafka-server-stop.sh stop
[liucw@hadoop103 kafka]$ bin/kafka-server-stop.sh stop
[liucw@hadoop104 kafka]$ bin/kafka-server-stop.sh stop


 

Hadoop 完全分布式部署


前期准备

SSH无密码登录

1)ssh连接时出现Host key verification failed

[liucw@hadoop102 opt] $ ssh 192.168.1.103 
The authenticity of host '192.168.1.103 (192.168.1.103)' can't be established.
RSA key fingerprint is cf:1e:de:d7:d0:4c:2d:98:60:b4:fd:ae:b1:2d:ad:06.
Are you sure you want to continue connecting (yes/no)? 
Host key verification failed.
 
直接输入yes后,再输入密码,可以通过


 

2)无密钥配置

(1)进入到我的家目录
[liucw@hadoop102 opt]$ cd ~/.ssh 
 
(2)生成公钥和私钥:
[liucw@hadoop102 .ssh]$ ssh-keygen -t rsa 
 
然后敲(三个回车),就会生成两个文件id_rsa(私钥)、id_rsa.pub(公钥)
 
(3)将公钥拷贝到要免密登录的目标机器上
[liucw@hadoop102 .ssh]$ ssh-copy-id hadoop103
[liucw@hadoop102 .ssh]$ ssh-copy-id hadoop104


3).ssh文件夹下的文件功能解释
  1)~/.ssh/known_hosts :记录ssh访问过计算机的公钥(public key)
  2)id_rsa :生成的私钥
  3)id_rsa.pub :生成的公钥
  4)authorized_keys :存放授权过得无秘登录服务器公钥

脚本xsync:利用rsync命令编写集群分发

rsync 与 scp

1).rsync
-r 递归
rsync -rvl /opt/tmp root@hadoop103:/opt

2).scp
scp -r root@hadoop101:/opt/software root@hadoop102:/opt/

3).rsync和scp区别
  rsync做文件的复制要比scp的速度快,rsync只对差异文件做更新。
  scp是把所有文件都复制过去。

集群分发脚本xsync

1.需求
  1.需求分析:循环复制文件到所有节点的相同目录下。
  2.原始拷贝:rsync -rvl /opt/module root@hadoop103:/opt/
  3.在/usr/local/bin这个目录下存放的脚本,可以在系统任何地方直接执行。

2.编写脚本
1).在/usr/local/bin目录下创建xsync文件

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
param_count=$#
if test $[param_count] -eq 0; then
    echo no args;
    exit;
fi
 
#2 获取文件名称
p1=$1
filename=`basename ${p1}`
echo filename=${filename}
 
#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir
 
#4 获取当前用户名称
user=`whoami`
 
#5 循环
for((host=103; host<105; host++)); do
    # echo ${pdir}/${filename} ${user}@hadoop${host}:${pdir}
    echo --------------- hadoop${host} ----------------
    rsync -rvl ${pdir}/${filename} ${user}@hadoop${host}:${pdir}
done


2).修改脚本 xsync 具有执行权限
[root@hadoop102 bin]# chmod 777 xsync
[root@hadoop102 bin]# chown liucw:liucw xsync

3).测试
[liucw@hadoop102 opt]$ xsync tmp/

结果会有另外两台机器上看到复制成功!

脚本xcall:在所有主机上同时执行相同的命令

1.在/usr/local/bin目录下创建xcall文件
[root@hadoop102 bin]# touch xcall
[root@hadoop102 bin]# vi xcall
#!/bin/bash
pcount=$#
if((pcount==0));then
        echo no args;
        exit;
fi
 
echo -------------localhost----------
$@
for((host=102; host<=104; host++)); do
        echo ----------hadoop$host---------
        ssh hadoop$host $@
done
 
 
2.修改脚本 xcall 具有执行权限
[root@hadoop102 bin]# chmod 777 xcall
[root@hadoop102 bin]# chown liucw:liucw xcall
 
 
3.测试: xcall+操作命令
[root@hadoop102 ~]# xcall rm -rf /opt/tmp/



配置集群

规划集群

1.生产环境NameNode与SecondaryNameNode要单独放到一台服务器上,测试数据少可以放一起.
2.ResourceManager也很耗资源,需要跟NameNode,SecondaryNameNode在不同的服务器上

hadoop102               hadoop103                   hadoop104       
NameNode                
DataNode                DataNode                DataNode    
ResourceManager
NodeManager             NodeManager             NodeManager


 

配置文件

[liucw@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop

core-site.xml
[liucw@hadoop102 hadoop]$ vi core-site.xml
    <!-- 指定HDFS中NameNode的地址,hadoop2.5的默认端口为8020 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop102:9000</value>
    </property>
 
    <!-- hadoop运行时产生文件的存储目录 ,可指定多个 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-2.7.2/data/tmp</value>
    </property>
 
    <!--    ++++++++++++++++  Oozie 配置  ++++++++++++++++ -->
    <!-- 可以不配置-->
    <!-- Oozie Server 的 Hostname -->
    <property>
        <name>hadoop.proxyuser.liucw.hosts</name>
        <!-- 可以指定用户 -->
        <value>*</value>
    </property>
    <!-- 默认是不允许操作Oozie的 -->
    <!-- 允许被 Oozie 代理的用户组 -->
    <property>
        <name>hadoop.proxyuser.liucw.groups</name>
        <value>*</value>
    </property>


Hdfs配置

1)hadoop-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_181

2)slaves

hadoop102
hadoop103
hadoop104


 

不能写一行,不同回车多一行

3)hdfs-site.xml

<!-- 指定HDFS副本的数量,本地测试值为1就行了,节约空间 -->
<property>
    <name>dfs.replication</name>
    <value>3</value>
</property>
 
<!-- 如果不配置,secondary会跟NameNode在同一台服务器-->
<property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>hadoop104:50090</value>
</property>
<property>
    <name>dfs.namenode.http-address</name>
    <value>hadoop102:50070</value>
</property>
 
<!-- 浏览hdfs,UI网站展示用的 -->
<property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
</property>


 

yarn配置

1)yarn-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_181

2)yarn-site.xml

<!-- reducer获取数据的方式 -->
  <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
  </property>
 
  <!-- 指定YARN的ResourceManager的地址-->
  <property>
      <name>yarn.resourcemanager.hostname</name>
      <value>hadoop103</value>
  </property>
 
  <!— 日志聚集:应用运行完成后,将日志信息上传到HDFS系统上-->
  <!-- 日志聚集功能开启 -->
  <property>
      <name>yarn.log-aggregation-enable</name>
      <value>true</value>
  </property>
  <!-- 日志保留时间设置7天 -->
  <property>
      <name>yarn.log-aggregation.retain-seconds</name>
      <value>604800</value>
  </property>
 
  <!-- 任务历史服务 页面配置:这个19888跟mapred-site.xml的要一致 -->
  <property>
      <name>yarn.log.server.url</name>
      <value>http://hadoop102:19888/jobhistory/logs/</value>
  </property>
 
  <!-- 防止在执行mapReduce时内存溢出 -->
  <property>
      <name>yarn.scheduler.maximum-allocation-mb</name>
      <value>2048</value>
  </property>
  <property>
      <name>yarn.nodemanager.vmem-pmem-ratio</name>
      <value>2.1</value>
  </property>
  <property>
      <name>mapred.child.java.opts</name>
      <value>-Xmx1024m</value>
  </property>


 

mapreduce配置

1)mapred-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_181

2)mapred-site.xml

[liucw@hadoop102 hadoop]$ mv mapred-site.xml.template  mapred-site.xml
[liucw@hadoop102 hadoop]$ vi mapred-site.xml
    <!-- 指定mr运行在yarn上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
 
    <!-- 配置 MapReduce JobHistory Server 地址 ,默认端口10020 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop102:10020</value>
    </property>
 
    <!-- 配置 MapReduce JobHistory Server web ui 地址, 默认端口19888 ,这个端口跟yarn-site.xml一致-->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop102:19888</value>
    </property>


 


在集群上分发以上所有文件

[liucw@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop
 
[liucw@hadoop102 hadoop]$ xsync /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml
[liucw@hadoop102 hadoop]$ xsync /opt/module/hadoop-2.7.2/etc/hadoop/yarn-site.xml
[liucw@hadoop102 hadoop]$ xsync /opt/module/hadoop-2.7.2/etc/hadoop/slaves
……



集群启动及测试

  补充:hadoop-cdh版本的lib/native是空的,需要从正常的下复制过来,不然启动不了
  如果集群是第一次启动,需要格式化namenode。

  如果删除logs/ data/了,也要格式化

启动hdfs并测试

1.启动

[liucw@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[liucw@hadoop102 hadoop-2.7.2]$ jps
4166 NameNode
4482 Jps
4263 DataNode
 
[liucw@hadoop103 hadoop-2.7.2]$ jps
3218 DataNode
3288 Jps
 
[liucw@hadoop104 hadoop-2.7.2]$ jps
3221 DataNode
3283 SecondaryNameNode
3364 Jps


 

2.测试

[liucw@hadoop102 hadoop-2.7.2]$ vim testdata.txt
[liucw@hadoop102 hadoop-2.7.2]$ bin/hdfs dfs -put testdata.txt /
 
bin/hdfs dfs -rm /testdata.txt


 

  在http://hadoop102:50070/explorer.html#/可看到数据即成功

启动yarn并测试

1.启动
[liucw@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

2.测试
[liucw@hadoop102 hadoop-2.7.2]$ bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0-cdh5.3.6.jar wordcount /testdata.txt /output

1.yarn的浏览器页面查看:http://hadoop103:8088/cluster2.hdfs: 在http://hadoop102:50070/explorer.html#/ 可看到数据即成功
3.历史服务和日志的聚集查看 http://hadoop102:19888/jobhistory

启动历史服务并测试

[liucw@hadoop103 hadoop-2.7.2]$ sbin/mr-jobhistory-daemon.sh start historyserver

http://hadoop103:8088/cluster的history打开有页面即成功

默认端口及浏览器页面查看

1.默认端口及其含义
  1)fs.defaultFS:8020 或者9000
  2)dfs.namenode.http-address:50070
  3)dfs.datanode.address:50010
  4)SecondaryNameNode辅助名称节点端口号:50090
  5)yarn.resourcemanager.webapp.address:8088
  6) yarn历史服务器19888

2.浏览器页面查看
  1)hdfs的浏览器页面查看:http://hadoop102:50070/explorer.html#/  2)yarn的浏览器页面查看:http://hadoop103:8088/cluster  3)历史服务和日志的聚集查看 http://hadoop102:19888/jobhistory


集群时间同步

  时间同步的方式:找一个机器,作为时间服务器,所有的机器与这台集群时间进行定时的同步,比如,每隔十分钟,同步一次时间。

配置时间同步实操:

时间服务器配置(必须root用户)

(1)检查ntp是否安装

[root@hadoop102 桌面]# rpm -qa|grep ntp
ntp-4.2.6p5-10.el6.centos.x86_64
fontpackages-filesystem-1.41-1.1.el6.noarch
ntpdate-4.2.6p5-10.el6.centos.x86_64


 

(2)修改ntp配置文件

[root@hadoop102 桌面]# vi /etc/ntp.conf
修改内容如下
        a)修改1(设置本地网络上的主机不受限制。)
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap为
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
        b)修改2(设置为不采用公共的服务器)
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst为
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
        c)添加3(添加默认的一个内部时钟数据,使用它为局域网用户提供服务。)
server 127.127.1.0
fudge 127.127.1.0 stratum 10


 

(3)修改/etc/sysconfig/ntpd 文件

[root@hadoop102 桌面]# vim /etc/sysconfig/ntpd
增加内容如下(让硬件时间与系统时间一起同步)
SYNC_HWCLOCK=yes


 

(4)重新启动ntpd

[root@hadoop102 桌面]# service ntpd status
ntpd 已停
 
[root@hadoop102 桌面]# service ntpd start
正在启动 ntpd:


 

(5)执行:
[root@hadoop102 桌面]# chkconfig ntpd on

其他机器配置(必须root用户)

(1)在其他机器配置10分钟与时间服务器同步一次
[root@hadoop103 hadoop-2.7.2]# crontab -e  (回车)
编写脚本
*/10 * * * * /usr/sbin/ntpdate hadoop102
 
(2)修改任意机器时间
[root@hadoop103 hadoop]# date -s "2017-9-11 11:11:11"
 
(3)十分钟后查看机器是否与时间服务器同步
[root@hadoop103 hadoop]# date



配置集群常见问题

1)防火墙没关闭、或者没有启动yarn
INFO client.RMProxy: Connecting to ResourceManager at hadoop108/192.168.10.108:8032

2)ssh没有配置好
  root用户,为了使用xsync脚本
  liucw用户,为了集群启动

3)root用户和liucw两个用户启动集群不统一

4)datanode不被namenode识别问题
  Namenode在format初始化的时候会形成两个标识,blockPoolId和clusterId。新的datanode加入时,会获取这两个标识作为自己工作目录中的标识。
  一旦namenode重新format后,namenode的身份标识已变,而datanode如果依然持有原来的id,就不会被namenode识别。
  解决办法,删除datanode节点中的数据后,再次重新格式化namenode。

6)datanode和namenode进程同时只能工作一个
  1)第一次启动时没有问题
  2)第二次启动时,原来的datanode数据并没有删除掉,它在与新namenode通信时连接不上。导致集群不能正常启动。
  3)解决办法:在格式化之前,删除datanode里面的信息(默认在/tmp,如果配置了该目录,那就去你配置的目录下删除数据)

7)jps发现进程已经没有,但是重新启动集群,提示进程已经开启
  原因是在linux的根目录下/tmp目录中存在启动的进程临时文件,将集群相关进程删除掉,再重新启动集群。

8)8088端口连接不上

vi /etc/hosts
 
注释掉如下代码
#127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
#::1         hadoop102


 

9)错误Name node is in safe mode的解决方法?
  将本地文件拷贝到hdfs上去,结果上错误:Name node is in safe mode
  这是因为在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束。安全模式主要是为了系统启动的时候检查各个DataNode上数据块的有效性,同时根据策略必要的复制或者删除部分数据块。运行期通过命令也可以进入安全模式。在实践过程中,系统启动的时候去修改和删除文件也会有安全模式不允许修改的出错提示,只需要等待一会儿即可。
  可以通过以下命令来手动离开安全模式:
  bin/hadoop dfsadmin -safemode leave  用户可以通过dfsadmin -safemode value 来操作安全模式,参数value的说明如下:
  enter -进入安全模式
  leave -强制NameNode离开安全模式
  get -返回安全模式是否开启的信息
  wait -等待,一直到安全模式结束。

10) 各个datanode的storageID不一样,导致启动datanode不成功
  删除data/tmp/dfs/data/current目录

 

 

Hadoop 运行环境搭建

虚拟机网络模式设置为NAT

克隆虚拟机

修改为静态ip

1)修改IP地址

[liucw@hadoop102 hadoop]$ vi /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
#BOOTPROTO=dhcp
# 从dhcp改成static
BOOTPROTO=static
 
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=eth0
UUID=9410076c-bee9-4886-af6c-537c17bcfee0
DEVICE=eth0
ONBOOT=yes
 
# 设置IP地址
IPADDR=192.168.1.102
# 设置子网掩码
NETMASK=255.255.255.0
# 设置网关
GATEWAY=192.168.1.1


如果不用static, 就可以联网

2)执行
[root@hadoop102 /]# service network restart

3)如果报错,reboot,重启虚拟机。
[root@hadoop102 /]# reboot

修改主机名

vi /etc/hosts
192.168.1.101 hadoop101
192.168.1.102 hadoop102
192.168.1.103 hadoop103


关闭防火墙

1.iptables防火墙
1)查看防火墙开机启动状态: chkconfig iptables –list
2)关闭防火墙:
service iptables stop (临时关闭防火墙)
chkconfig iptables off (关闭防火墙开机启动)

2.firewall防火墙:
查看防火墙规则 firewall-cmd –list-all

systemctl stop firewalld.service(关闭防火墙)
systemctl disable firewalld.service(防火墙开机禁用)

3.vi /etc/sysconfig/selinux 将设置改为禁用:
SELINUX=disabled

在opt目录下创建文件

1)创建liucw用户
在root用户里面执行如下操作

[root@hadoop101 opt]# adduser liucw
[root@hadoop101 opt]# passwd liucw


 

2)设置liucw用户具有root权限
修改 /etc/sudoers 文件,找到下面一行,在root下面添加一行,如下所示:

[root@hadoop101 liucw]# vi /etc/sudoers
## Allow root to run any commands anywhere
root    ALL=(ALL)     ALL
liucw   ALL=(ALL)     ALL


 

修改完毕,现在可以用liucw帐号登录,然后用命令 su - ,即可获得root权限进行操作。

3)在/opt目录下创建文件夹
(1)在root用户下创建module、software文件夹

[root@hadoop101 opt]# mkdir module
[root@hadoop101 opt]# mkdir software


 

(2)修改module、software文件夹的所有者

[root@hadoop101 opt]# chown liucw:liucw module
[root@hadoop101 opt]# chown liucw:liucw sofrware
[root@hadoop101 opt]# ls -al
总用量 16


 

安装jdk

1)卸载现有jdk
(1)查询是否安装java软件:[root@hadoop101 opt]# rpm -qa|grep java(2)如果安装的版本低于1.7,卸载该jdk:[root@hadoop101 opt]# rpm -e 软件包

2)解压jdk到/opt/module目录下
[root@hadoop101software]# tar -zxvf jdk-8u144-linux-x64.tar.gz -C /opt/module/

3)配置jdk环境变量
(1)打开配置/etc/profile文件:

[root@hadoop101 jdk1.8.0_144]# vi /etc/profile
##JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin


 

(2)让修改后的文件生效:
[root@hadoop101 jdk1.7.0_79]# source /etc/profile

4)测试jdk安装成功
[root@hadoop101 jdk1.8.0_144]# java -version
java version “1.8.0_144”

(如果java –version不可以用就要重启):
[root@hadoop101 jdk1.8.0_144]# sync
[root@hadoop101 jdk1.8.0_144]# reboot

安装Hadoop

1)解压安装文件到/opt/module下面
[root@hadoop101 software]# tar -zxf hadoop-2.7.2.tar.gz -C /opt/module/

2)在/opt/module/hadoop-2.7.2/etc/hadoop路径下配置hadoop-env.sh
(1)Linux系统中获取jdk的安装路径:
$ echo $JAVA_HOME
/opt/module/jdk1.8.0_144

(2)修改hadoop-env.sh文件中JAVA_HOME 路径:
[root@hadoop101 hadoop]# vi hadoop-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144

3)将hadoop添加到环境变量
(1)打开/etc/profile文件:

root@ hadoop101 hadoop-2.7.2]# vi /etc/profile
##HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-2.7.2
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin


 

(2)让修改后的文件生效:
root@ hadoop101 hadoop-2.7.2]# source /etc/profile

(3)重启(如果hadoop命令不能用再重启):
hadoop version
[root@ hadoop101 hadoop-2.7.2]# sync
[root@ hadoop101 hadoop-2.7.2]# reboot

4)修改/opt目录下的所有文件所有者为 liucw
[root@hadoop101 opt]# chown liucw:liucw -R /opt/

5)切换到liucw 用户
[root@hadoop101 opt]# su liucw

 

 

Hadoop 编译源码


前期准备工作

1)CentOS联网
  配置CentOS能连接外网。Linux虚拟机ping www.baidu.com 是畅通的
  注意:采用root角色编译,减少文件夹权限出现问题

2)jar包准备(hadoop源码、JDK7 、 maven、 ant 、protobuf)
(1)hadoop-2.7.2-src.tar.gz
(2)jdk-8u144-linux-x64.tar.gz
(3)apache-ant-1.9.9-bin.tar.gz
(4)apache-maven-3.0.5-bin.tar.gz
(5)protobuf-2.5.0.tar.gz


jar包安装

0)注意:所有操作必须在root用户下完成
1)JDK解压、配置环境变量 JAVA_HOME和PATH,验证java-version(如下都需要验证是否配置成功)

[root@hadoop101 software] # tar -zxf jdk-8u144-linux-x64.tar.gz -C /opt/module/
[root@hadoop101 software]# vi /etc/profile
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin
 
[root@hadoop101 software]#source /etc/profile
 
验证命令:java -version


 

2)Maven解压、配置 MAVEN_HOME和PATH。

[root@hadoop101 software]# tar -zxvf apache-maven-3.0.5-bin.tar.gz -C /opt/module/
[root@hadoop101 apache-maven-3.0.5]#  vi /etc/profile
#MAVEN_HOME
export MAVEN_HOME=/opt/module/apache-maven-3.0.5
export PATH=$PATH:$MAVEN_HOME/bin
 
[root@hadoop101 software]#source /etc/profile
验证命令:mvn -version


 

3)ant解压、配置 ANT _HOME和PATH

[root@hadoop101 software]# tar -zxvf apache-ant-1.9.9-bin.tar.gz -C /opt/module/
[root@hadoop101 apache-ant-1.9.9]# vi /etc/profile
#ANT_HOME
export ANT_HOME=/opt/module/apache-ant-1.9.9
export PATH=$PATH:$ANT_HOME/bin
 
[root@hadoop101 software]#source /etc/profile
验证命令:ant -version


 

4)安装 glibc-headers 和 g++ 命令如下:

[root@hadoop101 apache-ant-1.9.9]# yum install glibc-headers
[root@hadoop101 apache-ant-1.9.9]# yum install gcc-c++


 

5)安装make和cmake

[root@hadoop101 apache-ant-1.9.9]# yum install make
[root@hadoop101 apache-ant-1.9.9]# yum install cmake


 

6)解压protobuf ,进入到解压后protobuf主目录,/opt/module/protobuf-2.5.0
然后相继执行命令:

[root@hadoop101 software]# tar -zxvf protobuf-2.5.0.tar.gz -C /opt/module/
[root@hadoop101 opt]# cd /opt/module/protobuf-2.5.0/
 
[root@hadoop101 protobuf-2.5.0]#./configure 
[root@hadoop101 protobuf-2.5.0]# make 
[root@hadoop101 protobuf-2.5.0]# make check 
[root@hadoop101 protobuf-2.5.0]# make install 
[root@hadoop101 protobuf-2.5.0]# ldconfig 
 
[root@hadoop101 hadoop-dist]# vi /etc/profile
#LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/module/protobuf-2.5.0
export PATH=$PATH:$LD_LIBRARY_PATH
 
[root@hadoop101 software]#source /etc/profile
验证命令:protoc --version


7)安装openssl库
[root@hadoop101 software]#yum install openssl-devel

8)安装 ncurses-devel库:
[root@hadoop101 software]#yum install ncurses-devel

到此,编译工具安装基本完成。

编译源码

1)解压源码到/opt/目录
[root@hadoop101 software]# tar -zxvf hadoop-2.7.2-src.tar.gz -C /opt/

2)进入到hadoop源码主目录

[root@hadoop101 hadoop-2.7.2-src]# pwd
/opt/hadoop-2.7.2-src


3)通过maven执行编译命令
[root@hadoop101 hadoop-2.7.2-src]#mvn package -Pdist,native -DskipTests -Dtar等待时间30分钟左右,最终成功是全部SUCCESS。

4)成功的64位hadoop包在/opt/hadoop-2.7.2-src/hadoop-dist/target下。

[root@hadoop101 target]# pwd
/opt/hadoop-2.7.2-src/hadoop-dist/target

 

常见的问题及解决方案

1)MAVEN install时候JVM内存溢出
  处理方式:在环境配置文件和maven的执行文件均可调整MAVEN_OPT的heap大小。(详情查阅MAVEN 编译 JVM调优问题,如:http://outofmemory.cn/code-snippet/12652/maven-outofmemoryerror-method)

2)编译期间maven报错。可能网络阻塞问题导致依赖库下载不完整导致,多次执行命令(一次通过比较难):
  [root@hadoop101 hadoop-2.7.2-src]#mvn package -Pdist,native -DskipTests -Dtar

3)报ant、protobuf等错误,插件下载未完整或者插件版本问题,最开始链接有较多特殊情况,同时推荐
  2.7.0版本的问题汇总帖子 http://www.tuicool.com/articles/IBn63qf

 

 

Zookeeper 客户端命令行

操作zookeeper

1)启动zookeeper
[liucw@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start

2)查看进程是否启动

[liucw@hadoop102 zookeeper-3.4.10]$ jps
4020 Jps
4001 QuorumPeerMain


 

3)查看状态:

[liucw@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: standalone  # 单结点,就是本地模式运行


 

4)启动客户端:
[liucw@hadoop102 zookeeper-3.4.10]$ bin/zkCli.sh

5)退出客户端:
[zk: localhost:2181(CONNECTED) 0] quit

6)停止zookeeper
[liucw@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh stop


客户端命令行操作

1)启动客户端
[liucw@hadoop103 zookeeper-3.4.10]$ bin/zkCli.sh

2)显示所有操作命令:help
[zk: localhost:2181(CONNECTED) 1] help

3)查看当前znode中所包含的内容: ls

[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]


 

4)查看当前节点数据并能看到更新次数等数据: ls2

[zk: localhost:2181(CONNECTED) 1] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1


 

5)创建普通节点:create

[zk: localhost:2181(CONNECTED) 2] create /app1 "hello app1"
Created /app1
 
[zk: localhost:2181(CONNECTED) 4] create /app1/server101 "192.168.1.101"
Created /app1/server101


 

6)获得节点的值: get

[zk: localhost:2181(CONNECTED) 6] get /app1
hello app1
cZxid = 0x20000000a
ctime = Mon Jul 17 16:08:35 CST 2017
mZxid = 0x20000000a
mtime = Mon Jul 17 16:08:35 CST 2017
pZxid = 0x20000000b
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 10
numChildren = 1
 
[zk: localhost:2181(CONNECTED) 8] get /app1/server101
192.168.1.101
cZxid = 0x20000000b
ctime = Mon Jul 17 16:11:04 CST 2017
mZxid = 0x20000000b
mtime = Mon Jul 17 16:11:04 CST 2017
pZxid = 0x20000000b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0


 

7)创建短暂节点: create -e

[zk: localhost:2181(CONNECTED) 9] create -e /app-emphemeral 8888
 
(1)在当前客户端是能查看到的
[zk: localhost:2181(CONNECTED) 10] ls /
[app1, app-emphemeral, zookeeper]
 
(2)退出当前客户端然后再重启启动客户端
    [zk: localhost:2181(CONNECTED) 12] quit
[liucw@hadoop104 zookeeper-3.4.10]$ bin/zkCli.sh
 
(3)再次查看根目录下短暂节点已经删除
    [zk: localhost:2181(CONNECTED) 0] ls /
[app1, zookeeper]


8)创建带序号的节点:create -s
编号默认是有000开始的

(1)先创建一个普通的根节点app2
    [zk: localhost:2181(CONNECTED) 11] create /app2 "app2"
 
(2)创建带序号的节点
    [zk: localhost:2181(CONNECTED) 13] create -s /app2/aa 888
Created /app2/aa0000000000
 
[zk: localhost:2181(CONNECTED) 14] create -s /app2/bb 888
Created /app2/bb0000000001
 
[zk: localhost:2181(CONNECTED) 15] create -s /app2/cc 888
Created /app2/cc0000000002
 
如果原节点下有1个节点,则再排序时从1开始,以此类推。
[zk: localhost:2181(CONNECTED) 16] create -s /app1/aa 888
Created /app1/aa0000000001


 

9)修改节点数据值:set
[zk: localhost:2181(CONNECTED) 2] set /app1 999

10)节点的值变化监听:watch
只会监听一次
WatchedEvent state:SyncConnected type:NodeDataChanged path:/app1

(1)在104主机上注册监听/app1节点数据变化
[zk: localhost:2181(CONNECTED) 26] get /app1 watch
 
    (2)在103主机上修改/app1节点的数据
[zk: localhost:2181(CONNECTED) 5] set /app1  777
 
    (3)观察104主机收到数据变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/app1


11)节点的子节点变化监听(路径变化)
只会监听一次
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/app1

(1)在104主机上注册监听/app1节点的子节点变化
[zk: localhost:2181(CONNECTED) 1] ls /app1 watch
[aa0000000001, server101]
 
    (2)在103主机/app1节点上创建子节点
[zk: localhost:2181(CONNECTED) 6] create /app1/bb 666
Created /app1/bb
 
    (3)观察104主机收到子节点变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/app1


 

12)删除节点:delete
[zk: localhost:2181(CONNECTED) 4] delete /app1/bb

13)递归删除节点:rmr
[zk: localhost:2181(CONNECTED) 7] rmr /app2

14)查看节点状态:stat

[zk: localhost:2181(CONNECTED) 12] stat /app1
cZxid = 0x20000000a
ctime = Mon Jul 17 16:08:35 CST 2017
mZxid = 0x200000018
mtime = Mon Jul 17 16:54:38 CST 2017
pZxid = 0x20000001c
cversion = 4
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 2


 

Zookeeper分布式安装部署使用

集群规划
  在hadoop102、hadoop103和hadoop104三个节点上部署Zookeeper。

解压安装

chmod u+x zookeeper-3.4.10.tar.gz

1)解压zookeeper安装包到/opt/module/目录下
[liucw@hadoop102 software]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/

2)在/opt/module/zookeeper-3.4.10/这个目录下创建zkData
mkdir zkData

3)重命名/opt/module/zookeeper-3.4.10/conf这个目录下的zoo_sample.cfg为zoo.cfg
mv zoo_sample.cfg zoo.cfg


配置zoo.cfg文件

dataDir=/opt/module/zookeeper-3.4.10/zkData
 
#######################cluster##########################
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888


1)server.2=hadoop102:2888:3888 配置参数解读
Server.A=B:C:D
  A是一个数字,表示这个是第几号服务器;
  B是这个服务器的ip地址;
  C是这个服务器与集群中的Leader服务器交换信息的端口;
  D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

2)解读zoo.cfg 文件中参数含义
  1)tickTime=2000
  1)tickTime:通信心跳数,Zookeeper服务器心跳时间,单位毫秒.
  Zookeeper使用的基本时间,服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳,时间单位为毫秒。
  它用于心跳机制,并且设置最小的session超时时间为两倍心跳时间。(session的最小超时时间是2*tickTime)

  2)initLimit=10:LF初始通信时限
  2)initLimit:LF初始通信时限
  集群中的follower跟随者服务器(F)与leader领导者服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量),用它来限定集群中的Zookeeper服务器连接到Leader的时限。
  投票选举新leader的初始化时间
  Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。
  Leader允许F在initLimit时间内完成这个工作。
初始化要干的事多,所以比同步时间要长一点

  3)syncLimit=5:LF同步通信时限
  3)syncLimit:LF同步通信时限
  集群中Leader与Follower之间的最大响应时间单位,
  假如响应超过syncLimit * tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。
  在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。如果L发出心跳包在syncLimit之后,还没有从F那收到响应,那么就认为这个F已经不在线了。

  4)dataDir:数据文件目录+数据持久化路径
  保存内存数据库快照信息的位置,如果没有其他说明,更新的事务日志也保存到数据库。

  5)clientPort=2181:客户端连接端口
  监听客户端连接的端口

集群操作

1)在/opt/module/zookeeper-3.4.10/zkData目录下创建一个myid的文件
vi myid在文件中添加与server对应的编号:hadoop102 为1, hadoop103为2, hadoop103 为3

3)拷贝配置好的zookeeper到其他机器上
  scp -r zookeeper-3.4.10/ root@hadoop103.liucw.com:/opt/app/  scp -r zookeeper-3.4.10/ root@hadoop104.liucw.com:/opt/app/  并分别修改myid文件中内容为3、4

4)分别启动zookeeper

[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop103 zookeeper-3.4.10]# bin/zkServer.sh start
[root@hadoop104 zookeeper-3.4.10]# bin/zkServer.sh start


 

5)查看状态

[root@hadoop102 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
 
[root@hadoop103 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: leader
 
[root@hadoop104 zookeeper-3.4.5]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower


 

HBase 与 Sqoop 的集成

Sqoop supports additional import targets beyond HDFS and Hive. Sqoop can also import records into a table in HBase.
之前我们已经学习过如何使用 Sqoop 在 Hadoop 集群和关系型数据库中进行数据的导入导出 工作,接下来我们学习一下利用 Sqoop 在 HBase 和 RDBMS 中进行数据的转储。

案例

目标:将 RDBMS 中的数据抽取到 HBase 中

1).配置 sqoop-env.sh,添加如下内容:
export HBASE_HOME=/opt/module/hbase-1.3.1

(2-1) 在 Mysql 中新建一个数据库 db_library,一张表 book

$ mysql -uroot -proot
mysql> create database db_library;
mysql> CREATE TABLE db_library.book(
id int(4) PRIMARY KEY NOT NULL AUTO_INCREMENT, 
name VARCHAR(255) NOT NULL,
price VARCHAR(255) NOT NULL);


 

(2-2) 向表中插入一些数据

mysql> use db_library;
INSERT INTO db_library.book (name, price) VALUES('Lie Sporting', '30');
INSERT INTO db_library.book (name, price) VALUES('Pride & Prejudice', '70');
INSERT INTO db_library.book (name, price) VALUES('Fall of Giants', '50');


(3) 执行 Sqoop 导入数据的操作

[liucw@hadoop102 sqoop-1.4.6.bin__hadoop-2.0.4-alpha]$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/db_library \
--username root \
--password root \
--table book \
--columns "id,name,price" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_book" \
--num-mappers 1 \
--split-by id
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V
    at org.apache.sqoop.mapreduce.HBaseImportJob.jobSetup(HBaseImportJob.java:222)
 
尖叫提示:sqoop1.4.6 只支持 HBase1.0.1 之前的版本的自动创建 HBase 表的功能 
 
解决方案:手动创建 HBase 表
hbase> create 'hbase_book','info'

 

(4) 在 HBase 中 scan 这张表得到如下内容

hbase> scan ‘hbase_book’
hbase(main):003:0> scan 'hbase_book'
ROW                        COLUMN+CELL                                                              
 1                         column=info:name, timestamp=1539422269162, value=Lie Sporting            
 1                         column=info:price, timestamp=1539422269162, value=30                     
 2                         column=info:name, timestamp=1539422269162, value=Pride & Prejudice       
 2                         column=info:price, timestamp=1539422269162, value=70                     
 3                         column=info:name, timestamp=1539422269162, value=Fall of Giants          
 3                         column=info:price, timestamp=1539422269162, value=50


思考:尝试使用复合键作为导入数据时的 rowkey。

 

HBase 与 Hive 集成使用


  尖叫提示:HBase 与 Hive 的集成在最新的两个版本中无法兼容。所以,我们只能含着泪勇 敢的重新编译:hive-hbase-handler-1.2.2.jar!!好气!!

环境准备

  因为我们后续可能会在操作 Hive 的同时对 HBase 也会产生影响,所以 Hive 需要持有操作 HBase 的 Jar,那么接下来拷贝 Hive 所依赖的 Jar 包(或者使用软连接的形式)。

$ export HBASE_HOME=/opt/module/hbase-1.3.1
$ export HIVE_HOME=/opt/module/hive


 

注意如果更新版本,最好先把老的软链接删除
$ ln -s $HBASE_HOME/lib/hbase-common-1.3.1.jar $HIVE_HOME/lib/hbase-common-1.3.1.jar
$ ln -s $HBASE_HOME/lib/hbase-server-1.3.1.jar $HIVE_HOME/lib/hbase-server-1.3.1.jar
$ ln -s $HBASE_HOME/lib/hbase-client-1.3.1.jar $HIVE_HOME/lib/hbase-client-1.3.1.jar
$ ln -s $HBASE_HOME/lib/hbase-protocol-1.3.1.jar $HIVE_HOME/lib/hbase-protocol-1.3.1.jar
$ ln -s $HBASE_HOME/lib/hbase-it-1.3.1.jar $HIVE_HOME/lib/hbase-it-1.3.1.jar
$ ln -s $HBASE_HOME/lib/htrace-core-3.1.0-incubating.jar $HIVE_HOME/lib/htrace-core-3.1.0-incubating.jar
$ ln -s $HBASE_HOME/lib/hbase-hadoop2-compat-1.3.1.jar $HIVE_HOME/lib/hbase-hadoop2-compat-1.3.1.jar
$ ln -s $HBASE_HOME/lib/hbase-hadoop-compat-1.3.1.jar $HIVE_HOME/lib/hbase-hadoop-compat-1.3.1.jar
如果zookeeper版本不对,也需要copy过来

同时在 hive-site.xml 中修改 zookeeper 的属性,如下:

<!—整合Hbase用到—>
<property>
    <name>hive.zookeeper.quorum</name>
    <value>hadoop102,hadoop103,hadoop104</value>
</property>
 
<property>
    <name>hive.zookeeper.client.port</name>
    <value>2181</value>
</property>


 


案例一

目标:建立 Hive 表,关联 HBase 表,插入数据到 Hive 表的同时能够影响 HBase 表。
(0)前期准备
$ sudo service mysqld restart

hbase_emp_table表不能提前存在

(1) 在 Hive 中创建表同时关联 HBase

[liucw@hadoop102 hive]$ bin/hive
CREATE TABLE hive_hbase_emp_table( 
empno int,
ename string, 
job string,mgr int, 
hiredate string, 
sal double, 
comm double, 
deptno int)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' 
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno") 
TBLPROPERTIES ("hbase.table.name" = “hbase_emp_table");
 
# 出现这个错误,需要重新编译Hive源码
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V


尖叫提示:完成之后,可以分别进入 Hive 和 HBase 查看,都生成了对应的表

(2) 在 Hive 中创建临时中间表,用于 load 文件中的数据
尖叫提示:不能将数据直接 load 进 Hive 所关联 HBase 的那张表中

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';


(3) 向 Hive 中间表中 load 数据
hive> load data local inpath '/home/admin/softwares/data/emp.txt' into table emp;

(4) 通过 insert 命令将中间表中的数据导入到 Hive 关联 HBase 的那张表中
hive> insert into table hive_hbase_emp_table select * from emp;

(5) 查看 Hive 以及关联的 HBase 表中是否已经成功的同步插入了数据
Hive: hive> select * from hive_hbase_emp_table;HBase: hbase> scan ‘hbase_emp_table’


案例二

  目标:在 HBase 中已经存储了某一张表 hbase_emp_table,然后在 Hive 中创建一个外部表来 关联 HBase 中的 hbase_emp_table 这张表,使之可以借助 Hive 来分析 HBase 这张表中的数 据。
  注:该案例 2 紧跟案例 1 的脚步,所以完成此案例前,请先完成案例 1。

分步实现:
1).在 Hive 中创建外部表

CREATE EXTERNAL TABLE relevance_hbase_emp( empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int)
STORED BY
'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno") 
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");


 

2).关联后就可以使用 Hive 函数进行一些分析操作了
hive (default)> select * from relevance_hbase_emp;

 

 

HBase Shell命令


进入与退出hbase shell命令行窗口

[root@repo ~]# hbase shell
hbase(main):001:0>
 
hbase(main):001:0> exit
[root@repo ~]#


help

(1) 查看hbase中有哪些命令
hbase(main):015:0> help
...
COMMAND GROUPS:
  Group name: general
  Commands: status, table_help, version, whoami
 
  Group name: ddl
  Commands: alter, alter_async, alter_status, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, show_filters
 
  Group name: namespace
  Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables
 
  Group name: dml
  Commands: append, count, delete, deleteall, get, get_counter, incr, put, scan, truncate, truncate_preserve
 
(2) 查看某一组命令的下的所有命令的简介和简单示范
hbase(main):002:0> help  'ddl'
 
(3) 查看某个命令的详细使用
hbase(main):003:0> help  'create'


general组中命令

--(1) 查看集群状态
hbase(main):078:0> status
1 active master, 0 backup masters, 1 servers, 0 dead, 3.0000 average load
 
--(2) 查看集群版本
hbase(main):079:0> version
0.98.6-cdh5.3.6, rUnknown, Tue Jul 28 15:17:11 PDT 2015
 
--(3) 当前登录用户角色信息
hbase(main):080:0> whoami
root (auth:SIMPLE)
    groups: root
 
--(4) 查看对某张表进行操作的基本命令
hbase(main):081:0> table_help


ddl组中命令

查看数据库中有哪些表

hbase(main):005:0> list
TABLE
person


建表

语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
 
# create '表名', '列族1', '列族2'...
hbase(main):002:0> create 'person','cf1','cf2'
# 等价于
hbase(main):002:0> create 'person',{NAME=>'cf1' },{NAME=>'cf2'}
 
# 建表时可以指定表属性信息
# VERSIONS 当想要用HBase存储历史几个版本的数据是 (达到类似于git的效果时)可以设定版本号,版本号为几 就是存储几个版本的数据
hbase(main):005:0> create 'user_info',{NAME=>'base_info',VERSIONS=>3 },{NAME=>'extra_info',IN_MEMORY=>'true'}


alter 修改表

(1) 增加列族

alter 'table_name', 'add_family'
# 或者
alter 'table_name', {NAME => 'add_family'}
 
# 当然,新增加的列可以设置属性,比如
alter 'table_name', {NAME => 'add_family', VERSIONS => 3}
 
hbase(main):010:0> alter 'person','cf3'
Updating all regions with the new schema...
0/1 regions updated.
1/1 regions updated.


 

(2) 删除列族

alter 'table_name', {NAME => 'delete_family', METHOD => 'delete'}
或者
alter 'table_name', 'delete' => 'delete_family'


 

(3) 添加列族f1同时删除列族f2

1

alter 'user', {NAME => 'f1'}, {NAME => 'f2', METHOD => 'delete'}

alter 'user', {NAME => 'f1'}, {NAME => 'f2', METHOD => 'delete'}

(4) 修改列族

# 将user表的f1列族版本号改为5
alter 'user', NAME => 'f1', VERSIONS => 5


 

(5) 将 cf1 列族中的数据存放 3 个版本:

hbase(main):042:0> alter 'person',{NAME=>'cf1',VERSIONS=>3}


 

判断表是否存在exists

exists ‘table_name’

禁用表与启用表

--(1) 禁用表
disable 'table_name'
--(2) 查看表是否禁用
is_disabled 'table_name'
--(3) 启用表
enable 'table_name'
--(4) 查看表是否启用
is enabled 'table_name'


删除表disable&&drop

# hbase的某些版本,在删除表前,需要先禁用表
disable 'table_name'
drop 'table_name'


查看表属性信息desc

hbase(main):007:0> describe 'person'
# 或者
hbase(main):007:0> desc 'person'
 
Table person is ENABLED
person
COLUMN FAMILIES DESCRIPTION
{
NAME => 'age', 
BLOOMFILTER => 'ROW', 
VERSIONS => '1', 
IN_MEMORY => 'false', 
KEEP_DELETED_CELLS => 'FALSE', 
DATA_BLOCK_ENCODING => 'NONE', 
TTL => 'FOREVER', 
COMPRESSION => 'NONE', 
MIN_VERSIONS => '0', 
BLOCKCACHE => 'true', 
BLOCKSIZE => '65536', 
REPLICATION_SCOPE => '0'
}                                                     
 
# 其中的属性的意义:
NAME:列族名
VERSIONS:最大版本号
MIN_VERSIONS:最小版本号
TTL(Time To Live):存活时间
IN_MEMORY:是否开启缓存,默认false,应该开启,否则与BLOCKCACHE冲突
BLOCKCACHE:读缓存是否开启,默认开启,64M


dml组中命令

插入数据put

--(1)  put '表名','rowkey','列族名:列名','值'
put 'person','0001','cf1:name','liucw'
put 'person','0001','cf1:sex','male'
put 'person','0001','cf1:age','18'
 
put 'person','0002','cf1:name','changwen'
put 'person','0002','cf1:sex','female'
put 'person','0002','cf1:age','20'
 
put 'person','0001','cf2:name','liucw'
put 'person','0001','cf2:sex','male'
put 'person','0001','cf2:age','18'
 
-- 统计表数据行数 注意:只有2行
hbase(main):033:0> count 'person'
2 row(s) in 0.0460 seconds
 
hbase(main):031:0> scan 'person'
ROW                               COLUMN+CELL                                                                                      
 0001                             column=cf1:age, timestamp=1551768727762, value=18                                                
 0001                             column=cf1:name, timestamp=1551768650325, value=liucw                                            
 0001                             column=cf1:sex, timestamp=1551768722507, value=male                                              
 0001                             column=cf2:age, timestamp=1551768824538, value=18                                                
 0001                             column=cf2:name, timestamp=1551768804735, value=liucw                                            
 0001                             column=cf2:sex, timestamp=1551768819896, value=male                                              
 0002                             column=cf1:age, timestamp=1551768767803, value=20                                                
 0002                             column=cf1:name, timestamp=1551768750437, value=changwen                                         
 0002                             column=cf1:sex, timestamp=1551768757424, value=female                                            
2 row(s) in 0.0200 seconds
 
--(2) 可以指定时间戳,否则默认为系统当前时间
put 'person','0002','info:age',20,1482077777778


查询某行get

(1) 查看“指定行”

hbase(main):032:0> get 'person','0001'
COLUMN                            CELL                                                                                             
 cf1:age                          timestamp=1551768727762, value=18                                                                
 cf1:name                         timestamp=1551768650325, value=liucw                                                             
 cf1:sex                          timestamp=1551768722507, value=male                                                              
 cf2:age                          timestamp=1551768824538, value=18                                                                
 cf2:name                         timestamp=1551768804735, value=liucw                                                             
 cf2:sex                          timestamp=1551768819896, value=male


 

(2) 查看指定列族的消息

hbase(main):041:0> get 'person','0001','cf1'
COLUMN                            CELL                                                                                             
 cf1:age                          timestamp=1551769193444, value=10                                                                
 cf1:name                         timestamp=1551768650325, value=liucw                                                             
 cf1:sex                          timestamp=1551768722507, value=male


 

(3) 查询某行,指定列名

hbase(main):034:0> get 'person','0001','cf1:age'
COLUMN                            CELL                                                                                             
 cf1:age                          timestamp=1551768727762, value=18 
 
--(3) 查询某行,添加其他限制条件
# 查询person表中,rowkey为'0001'的这一行,只显示cf2:age这一列,并且只显示最新的3个版本
hbase(main):076:0> get 'person','0001',{COLUMNS=>'cf2:age',VERSIONS=>3}
COLUMN                            CELL                                                                                             
 cf2:age                          timestamp=1551770366619, value=15                                                                
 cf2:age                          timestamp=1551770364161, value=14                                                                
 cf2:age                          timestamp=1551770361190, value=13  
 
# 查看指定列的内容,并限定显示最新的3个版本和时间范围 
get 'person', '0001', {COLUMN => 'cf1:age', VERSIONS => 3, TIMERANGE => [1392368783980, 1392380169184]}
 
# 查询person表中,rowkey为'rk0001',且某列的内容为'中国'的记录
hbase(main):041:0> put 'person','rk0001','cf1:age','70'
scan'person', 'rk0001', {FILTER => "ValueFilter(=, 'binary:中国')"}
 
# 查看指定行中 字段名称中含有 a的字段
get 'person’,’0001’,{FILTER=>”(QualifierFilter(=,’substring:a’))”}
 
# 返回字段的value值是指定的值的字段
get ‘person’,’0001’,{FILTER=>”ValueFilter(=,’binary:liucw’)”}


 

全表扫描scan

--(1) 扫描全表
scan 'person'
 
--(2) 扫描时指定列族
scan 'person', {COLUMNS => 'cf1'}
 
--(3) 扫描时指定列族,并限定显示最新的5个版本的内容
scan 'person', {COLUMNS => 'cf1', VERSIONS => 5}
 
--(4) 设置开启Raw模式,开启Raw模式会把那些已添加删除标记但是未实际删除的数据也显示出来
scan 'person', {COLUMNS => 'cf1', RAW => true}
 
--(5) 列的过滤
# 查询person表中列族为cf1和cf2的信息
scan 'person',{COLUMNS=>['cf1','cf2']}
 
# 查询person表中列族为cf1,列名为name、列族为cf2,列名为age的信息
scan 'person', {COLUMNS => ['cf1:name', 'cf2:age']}
 
# 查询person表中列族为cf1,列名为name的信息,并且版本最新的5个
scan 'person', {COLUMNS => 'cf1:name', VERSIONS => 5}
hbase(main):072:0> scan 'person',{COLUMNS=>'cf2:age',VERSIONS=>3}
ROW                               COLUMN+CELL                                                                                      
 0001                             column=cf2:age, timestamp=1551770366619, value=15                                                
 0001                             column=cf2:age, timestamp=1551770364161, value=14                                                
 0001                             column=cf2:age, timestamp=1551770361190, value=13 
 
# 查询person表中列族为cf1和cf2且列名含有a字符的信息
scan 'person', {COLUMNS => ['cf1', 'cf2'], FILTER => "(QualifierFilter(=,'substring:a'))"}
 
# 查询person表中列族为cf1,rk范围是[rk0001, rk0003)的数据
scan 'people', {COLUMNS => 'cf1', STARTROW => 'rk0001', ENDROW => 'rk0003'}
 
# 查询person表中row key以rk字符开头的
scan 'person',{FILTER=>"PrefixFilter('rk')"}
 
# 查询person表中指定时间范围的数据
scan 'person', {TIMERANGE => [1392368783980, 1392380169184]}
 
scan的用法很多,参数,过滤条件可以很多,各种组合, 在此不列举过多的例子,参考 help 'scan'


删除数据

删除某 rowkey 的全部数据:
hbase(main) > deleteall 'student','1001'
 
删除某 rowkey 的某一列数据:
hbase(main) > delete 'student','1002','info:sex'


清空表

清空表的操作顺序为先 disable,然后再 truncating。
truncate 'table_name'


namespace

在HBase中,namespace命名空间指对一组表的逻辑分组,类似RDBMS中的database,方便对表在业务上划分。Apache HBase从0.98.0, 0.95.2两个版本开始支持namespace级别的授权操作,HBase全局管理员可以创建、修改和回收namespace的授权。

HBase系统默认定义了两个缺省的namespace
hbase:系统内建表,包括namespace和meta表
default:用户建表时未指定namespace的表都创建在此

创建namespace
hbase>create_namespace 'nametest'  
 
删除namespace
hbase>drop_namespace 'nametest'  
 
查看namespace
hbase>describe_namespace 'nametest'  
 
列出所有namespace
hbase>list_namespace  
 
在namespace下创建表
hbase>create 'nametest:testtable', 'fm1'  
 
查看namespace下的表
hbase>list_namespace_tables 'nametest'


 


其他

--(1) 查看命名空间
hbase(main):015:0> list_namespace
NAMESPACE
 
default # 用户创建的表放在这里
hbase # 系统表空间
 
--(2) 把表中数据强制写到磁盘
flush 'table_name'


 

 

HBase部署


  HBase 一种是作为存储的分布式文件系统,另一种是作为数据处理模型的 MR 框架。因为日常开发人员比较熟练的是结构化的数据进行处理,但是在 HDFS 直接存储的文件往往不具有结构化,所以催生出了 HBase 在 HDFS 上的操作。如果需要查询数据,只需要通过键值便可以成功访问。

前提准备

1.Zookeeper 正常部署
2.Hadoop 正常部署

HBase部署

HBase 的解压

$ tar -zxf ~/softwares/installations/hbase-1.3.1-bin.tar.gz -C ~/modules/

HBase 的配置文件

  1)hbase-env.sh 修改内容

export JAVA_HOME=/opt/module/jdk1.8.0_181
export HBASE_MANAGES_ZK=false  # 是否使用hbase自己的zookeeper


 

  2).hbase-site.xml 修改内容:

<configuration>
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://hadoop102:9000/hbase</value>
    </property>
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
    <!-- 0.98 后的新变动,之前版本没有.port,默认端口为 60000 -->
    <property>
        <name>hbase.master.port</name>
        <value>16000</value>
    </property>
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
    </property>
    <property>
        <name>hbase.zookeeper.property.dataDir</name>
        <value>/opt/module/zookeeper-3.4.10/zkData</value>
    </property>
</configuration>


 

  3).regionservers

hadoop102
hadoop103
hadoop104


 

补充:如果同时还部署了CDH版本,记得修改/etc/profile里的HBASE_HOME的路径,因为在hbase-env.sh是用的HBASE_HOME的路径

$ source /etc/profile
$ echo $HBASE_HOME
/opt/module/cdh/hbase-0.98.6-cdh5.3.6

HBase 需要依赖的 Jar 包

由于 HBase 需要依赖 Hadoop,所以替换 HBase 的 lib 目录下的 jar 包,以解决兼容问题:
1) 删除原有的 jar:
$ rm -rf /home/admin/modules/hbase-1.3.1/lib/hadoop-*
$ rm -rf /home/admin/modules/hbase-1.3.1/lib/zookeeper-3.4.6.jar

2) 拷贝新 jar,涉及的 jar 有:

hadoop-annotations-2.7.2.jar
hadoop-auth-2.7.2.jar
hadoop-client-2.7.2.jar
hadoop-common-2.7.2.jar
hadoop-hdfs-2.7.2.jar
hadoop-mapreduce-client-app-2.7.2.jar
hadoop-mapreduce-client-common-2.7.2.jar
hadoop-mapreduce-client-core-2.7.2.jar
hadoop-mapreduce-client-hs-2.7.2.jar
hadoop-mapreduce-client-hs-plugins-2.7.2.jar
hadoop-mapreduce-client-jobclient-2.7.2.jar
hadoop-mapreduce-client-jobclient-2.7.2-tests.jar
hadoop-mapreduce-client-shuffle-2.7.2.jar
hadoop-yarn-api-2.7.2.jar
hadoop-yarn-applications-distributedshell-2.7.2.jar
hadoop-yarn-applications-unmanaged-am-launcher-2.7.2.jar
hadoop-yarn-client-2.7.2.jar
hadoop-yarn-common-2.7.2.jar
hadoop-yarn-server-applicationhistoryservice-2.7.2.jar
hadoop-yarn-server-common-2.7.2.jar
hadoop-yarn-server-nodemanager-2.7.2.jar
hadoop-yarn-server-resourcemanager-2.7.2.jar
hadoop-yarn-server-tests-2.7.2.jar
hadoop-yarn-server-web-proxy-2.7.2.jar
zookeeper-3.4.5.jar

提示:这些 jar 包的对应版本应替换成你目前使用的 hadoop 版本,具体情况具体分析。
查找 jar 包举例:
$ find /home/admin/modules/hadoop-2.7.2/ -name hadoop-annotations*
然后将找到的 jar 包复制到 HBase 的 lib 目录下即可。

HBase 软连接 Hadoop 配置

$ ln -s ~/modules/hadoop-2.7.2/etc/hadoop/core-site.xml
~/modules/hbase-1.3.1/conf/core-site.xml
$ ln -s ~/modules/hadoop-2.7.2/etc/hadoop/hdfs-site.xml ~/modules/hbase-1.3.1/conf/hdfs-site.xml

HBase 远程 scp 到其他集群

$ scp -r /home/admin/modules/hbase-1.3.1/ linux02:/home/admin/modules/
$ scp -r /home/admin/modules/hbase-1.3.1/ linux03:/home/admin/modules/
7.Hbase 的master高可用
1) 关闭 HBase 集群(如果没有开启则跳过此步)
$ bin/stop-hbase.sh
2) 在 conf 目录下创建 backup-masters 文件
$ vi conf/backup-masters

配置高可用 HMaster 节点,备份节点再另一台服务器(可选)

hadoop103

3) 将整个 conf 目录 scp 到其他节点
$ scp -r conf/ linux02:/opt/modules/cdh/hbase-0.98.6-cdh5.3.6/
$ scp -r conf/ linux03:/opt/modules/cdh/hbase-0.98.6-cdh5.3.6/

4) 打开页面测试查看
0.98 版本之前:http://hadoop102:600100.98 版本之后:http://hadoop102:16010

http://hadoop102:16010/master-statushttp://hadoop103:16010/master-status

HBase 服务的启动

启动方式 2:
$ bin/start-hbase.sh
对应的停止服务:
$ bin/stop-hbase.sh
尖叫提示:如果使用的是 JDK8 以上版本,则应在 hbase-evn.sh 中移除 “HBASE_MASTER_OPTS”和“HBASE_REGIONSERVER_OPTS”配置。

启动方式 1:
$ bin/hbase-daemon.sh start master
$ bin/hbase-daemon.sh start regionserver

尖叫提示:如果集群之间的节点时间不同步,会导致 regionserver 无法启动,抛出 ClockOutOfSyncException 异常。
修复提示:
  a、同步时间服务
  b、属性:hbase.master.maxclockskew 设置更大的值

<property>
	<name>hbase.master.maxclockskew</name>
	<value>180000</value>
	<description>Time difference of regionserver from master</description> 
</property>


 

访问 HBase 管理页面

  查看 Hbse 页面 启动成功后,可以通过“host:port”的方式来访问 HBase 管理页面,例如
  http://linux01:16010

启动后问题

1)Node /hbase/namespace/default already exists and this is not a retry
  删除HDFS的数据,再重新启动

2).如果多次启动失败
  a).删除hdfs的初始目录
  b).zookeeper 删除 rmr /hbase

3).问题:Hbase上的表不存在,但还会提示“表已经存在”
在虚拟机上玩Hbase,过了一段时间之后,创建’testtable’ 时总报异常 table already exists,不管是用代码还是在Hbase Shell里都一样。
解决办法:转自 http://www.aboutyun.com/thread-9507-1-1.html  1、执行 zkCli.sh 进入zookeeper,
  2、在zk client模式下输入ls /hbase/table命令看到zombie table,
  3、使用rmr /hbase/table/TABLE_NAME命令删除zombie table,
  4、 重启hbase即可