Hadoop技术(四)分布式、面向列的开源数据库HBase

本文详细介绍了HBase,一个基于Hadoop的分布式、面向列的开源数据库。从HBase的基本概念、架构、数据模型到安装步骤、API使用和性能优化策略,深入探讨了其特点和应用场景。特别强调了Row Key设计的重要性以及预分区、内存管理和Compaction策略在优化中的作用。同时,文章提到了与传统DBMS的区别,以及如何利用Protobuf进行数据序列化以提高性能。
摘要由CSDN通过智能技术生成

第一章 Hbase介绍

本阶段介绍HBase 是一个分布式的、面向列的开源数据库。是基于Google 开源的bigtable的实现,面向列的非关系型数据库点击查看HBase官方网站介绍

Hadoop生态系统图

在这里插入图片描述

非关系型数据库知识面扩展

HBase简介

  • HBase (Hadoop Database): 是一个高可靠性、高性能、面向列、可伸缩、实时读写的分布式非关系型数据库
  • 利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为其分布式协同服务。
  • 从技术上讲,HBase实际上更像是“数据存储”而不是“数据库”,因为它缺少RDBMS中的许多功能,例如字段型列,二级索引,触发器和高级查询语言等。
  • 主要用来存储非结构化和半结构化的松散数据(列式存储的NoSQL 数据库),但是他同样能够存储结构化数据

HBase架构

1. Client

  • 提供访问HBase的接口并维护cache(写缓存)来加快对HBase的访问

2. Zookeeper

前两点说明了ZK不仅有高可用功能 , 后两点还说明了ZK具有存储功能

  • 保证任何时候,集群中只有一个master(采取主备节点 .mater: 主节点)
  • 实时监控Region server的上线和下线信息。并实时通知Master( 类似心跳检测 ,健康检查 )
  • 存贮所有Region的寻址入口
  • 存储HBase的schema和table元数据

3. Master

主要是用于管理Region Server

  • 为Region server分配region
  • 负责Region server的负载均衡
  • 发现失效的Region server并重新分配其上的region
  • 管理用户对table的增删改操作

HBase架构图

4. RegionServer

  • Region server维护region处理对这些region的IO请求
  • Region server负责切分在运行过程中变得过大的region

5. Region

  • HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据
  • 每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region(裂变)
  • 当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。( 防止数据倾斜, 压力过大)

6. Memstore 与 storefile

  • 一个region由多个store组成,一个store对应一个CF(列族)
  • store包括位于内存中的memstore和位于磁盘的storefile写操作先写入memstore, 当memstore中的数据达到某个阈值,hregionserver会启动 flashcache 进程写入storefile每次写入形成单独的一个storefile (这里也可以通过flush 表名 手动写入storefile )
  • 当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction) 在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile
    minor compaction:自动合并 , 小范围合并 ,不会影响读写性能
    major compaction:手动触发 , 所有storefile合成一个storefile, 影响读写性能
  • 当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
  • 客户端检索数据,先在memstore找,找不到再找storefile

HRegion ( 即: Hbase架构图中的Region):

  • HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。
  • HRegion由一个或者多个Store组成,每个store保存一个列族columns family。
  • 每个Strore又由一个memStore和0至多个StoreFile组成。如图:StoreFile以HFile格式保存在HDFS上。

在这里插入图片描述

HBase 立体架构图

观看方式 : 从后往前看

在这里插入图片描述

如果面试问架构怎么办?
通过对上面架构图的理解, 最好能够手画架构图 , 如果在面试中由于紧张答不出来了可以自己画出来,如下图
在此类面试最好自备笔和纸

在这里插入图片描述

HBase数据模型

在这里插入图片描述

1. ROW KEY

  • 唯一标识一行数据( 类似MySQL中的主键 )
  • 按照字典顺序排序的。
  • Row key只能存储64k的字节数据

2. Timestamp时间戳

  • 在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面
  • 时间戳的类型是 64位整型。
  • 时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。
  • 时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。

3. Column Family列族 & qualifier列

  • HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;
  • 列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需、动态加入;
  • 权限控制、存储以及调优都是在列族层面进行的;
  • HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。
  • 定义表格时,可以不声明列, 但必须声明列族

4. Cell单元格

  • 由行和列的坐标交叉决定;
  • 单元格是有版本的;
  • 单元格的内容是未解析的字节数组;
  • 由{row key, column( = +), version} 唯一确定的单元。
  • cell中的数据是没有类型的,全部是字节码形式存贮。

5. Hlog(WAL log)

  • HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,
  • HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,
    timestamp是” 写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。(一旦数据被删除, 即可通过这里进行恢复 )
  • HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue

第二章 HBase安装

HBase 官方文档 :中文版

伪分布式搭建

在单机跑( 安装在node1主机上, 主要不要安装在zk中)

安装步骤

# 1.上传文件并解压(软件见底部分享)
tar -zxf hbase-0.98.12.1-hadoop2-bin.tar.gz 
mv hbase-0.98.12.1-hadoop2 /opt/hbase


# 2,配置环境变量( 追加或修改如下内容 ),然后 source /etc/profile
export HBASE_HOME=/opt/hbase
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_PREFIX/bin:$HADOOP_PREFIX/sbin:$ZOOKEEPER_HOME/bin:$HIVE_HOME/bin:$HBASE_HOME/bin


# 3.测试是否安装成功(1)
hbase +tab+tab

# 4.修改配置文件 hbase-env.sh (复制自己java的java_home,添加到文件中)
export JAVA_HOME=/usr/local/jdk1.8.0_11

# 5.修改配置文件 hbase-site.sh ( 添加如下内容,指定了hbase数据存放目录 )
<property>
<name>hbase.rootdir</name>
<value>file:///home/testuser/hbase</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/testuser/zookeeper</value>
</property>


# 6.测试hbase服务能否启动 
##注意:hbase内嵌了zookeeper,因此不能在有zk启动的节点安装,建议新建一个节点
[root@node1 opt]# start-hbase.sh
[root@node1 opt]# jps
7177 HMaster

##访问图形化界面
http://node1:60010/
## 进入hbase的命令行窗口
hbase shell  

图1
在这里插入图片描述

hbase help中的显示的所有hbase命令

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, get_splits, incr, put, scan, truncate, truncate_preserve

  Group name: tools
  Commands: assign, balance_switch, balancer, catalogjanitor_enabled, catalogjanitor_run, catalogjanitor_switch, close_region, compact, compact_rs, flush, hlog_roll, major_compact, merge_region, move, split, trace, unassign, zk_dump

  Group name: replication
  Commands: add_peer, disable_peer, disable_table_replication, enable_peer, enable_table_replication, list_peers, list_replicated_tables, remove_peer, set_peer_tableCFs, show_peer_tableCFs

  Group name: snapshots
  Commands: clone_snapshot, delete_all_snapshot, delete_snapshot, list_snapshots, restore_snapshot, snapshot

  Group name: security
  Commands: grant, revoke, user_permission

  Group name: visibility labels
  Commands: add_labels, clear_auths, get_auths, list_labels, set_auths, set_visibility

基础语法

# ctr+BackSpace 删除命令单词	
#help 查看 hbase 使用( 显示相关语法信息)
#list  列出所欲当前数据表
#describe 查看表描述
#scan  列出当前数据表中记录数
#create 创建表
#disable 将表设置成禁用
#drop  删除表
#put    增加记录
#delete  删除记录

# 举例
## 创建 emp表,列族分别是eno,ename
create 'emp','eno','empname'
## 描述表(1)
describ 'emp'
## 删除表(2)
## 添加数据到表,通过row key 获取对应列族信息,查看表的所有信息 (3)
## 更改表( 通过row key进行数据的覆盖) ,flush 将 inmemstore 中数据写入 storefile(4)
flush 表名
##根据row+列族名 ,使用delete 删除相关信息(4)

图1
在这里插入图片描述

图2
在这里插入图片描述
图3
在这里插入图片描述

图4

在这里插入图片描述
图5

在这里插入图片描述

完全分布式搭建

原本搭建模式图
在这里插入图片描述
因为本人机器性能的原因, 改成如下架构
在这里插入图片描述

搭建步骤

前提: Hadoop集群必须准备好 Hadoop HDFS集群搭建步骤

1、环境准备

  • hostname (主机名:node1,2,3,…)
  • hosts (地址映射,将主机名与对应的虚拟机id配置映射)
  • iptables (关闭防火墙,可使用永久关闭防火墙命令)
  • 网络 (查看相互之间能否ping通)

2、时间同步 时间服务器

yum install ntp -y
ntpdate 202.120.2.101

3 免秘钥

简单免密钥配置

主-备 ,主-从,备-从(需要进行免密钥设置)
例如node1主,node5备(mater),node2,3,4从(region server)
node1需要配置免密钥到node2,3,4,5
mpde5需要配置免密钥到node1,2,3,4

# 免密钥配置方式如下
ssh-keygen #然后一直回车
ssh-copy-id -i  .ssh/id_rsa.pub node_x  # 然后根据提示输入node_x的密码,node_x为当前节点名称或ip
ssh node_x  
exit

4、jdk环境变量
5、解压hbase,并配置hbase环境变量
6、修改配置文件

# 1. 修改配置文件 hbase-env.sh (添加如下内容) 
 		export JAVA_HOME=/usr/local/jdk1.8.0_11
		export HBASE_MANAGES_ZK=true

# 2. 修改配置文件 hbase.site.xml( hdfs://mycluster为hadoop集群名称 )
## hadoop集群名称可通过 cat /opt/hbase/conf/hdfs-site.xml 命令,找到name为dfs.nameservices的值就是集群名称
		<property>
		  <name>hbase.cluster.distributed</name>
		  <value>true</value>
		</property>
		<property>
		  <name>hbase.rootdir</name>
		  <value>hdfs://mycluster:8020/hbase</value>
		</property>
		<property>
		  <name>hbase.zookeeper.quorum</name>
		  <value>node2,node3,node4</value>
		</property>

# 3, 修改配置文件regionservers
	node2
	node3
	node4

# 4. 创建并修改文件 backup-masters ,内容是备用Master的位置
 	node4

# 5. 将hdfs 中的hdfs-site.xml文件拷贝到当前目录
cp /opt/chy/hadoop/etc/hadoop/hdfs-site.xml ./


# 6.将配置好的hbase分发到其他主机节点
scp -r hbase/ root@node2:/opt
scp -r hbase/ root@node3:/opt
scp -r hbase/ root@node4:/opt


# 7.启动Hbase集群
start-hbase.sh
## 计入hbase的命令行
hbase shell
## 关闭集群
stop-hbase.sh

## 利用jps查看master是否启动成功(1,2)
## 访问图形化界面,查看主备配置是否完成(3) 很重要!!!
node1:60010

图1
在这里插入图片描述
图2
在这里插入图片描述
图3
在这里插入图片描述

第三章 HBase-API

重点 : rowkey 设计

环境搭建

Demo案例

创建 hbase-demo 普通 java 项目,并导入 hadoop 和 hbase 相关依赖 jar 包,并发布到类路径上

  1. 创建 HBaseDemo

  2. 添加jar包

    所需要的有hbase的相关jar, 可以通过hbase软件的lib包下找,也可以通过末尾分享的Demo案例的lib包下复制
    还需要Hdfs的相关jar包 ,可以从hadoop的lib目录下找,也可以通过本人 Hadoop-Hdfs中分享的资料中找
    找到后build path到jar项目中

    # hbase的相关jar
    hbase-annotations-0.98.12.1-hadoop2.jar
    hbase-checkstyle-0.98.12.1-hadoop2.jar
    hbase-client-0.98.12.1-hadoop2.jar
    hbase-common-0.98.12.1-hadoop2-tests.jar
    hbase-common-0.98.12.1-hadoop2.jar
    hbase-examples-0.98.12.1-hadoop2.jar
    hbase-hadoop-compat-0.98.12.1-hadoop2.jar
    hbase-hadoop2-compat-0.98.12.1-hadoop2.jar
    hbase-it-0.98.12.1-hadoop2-tests.jar
    hbase-it-0.98.12.1-hadoop2.jar
    hbase-prefix-tree-0.98.12.1-hadoop2.jar
    hbase-protocol-0.98.12.1-hadoop2.jar
    hbase-rest-0.98.12.1-hadoop2.jar
    hbase-server-0.98.12.1-hadoop2-tests.jar
    hbase-server-0.98.12.1-hadoop2.jar
    hbase-shell-0.98.12.1-hadoop2.jar
    hbase-testing-util-0.98.12.1-hadoop2.jar
    hbase-thrift-0.98.12.1-hadoop2.jar
    high-scale-lib-1.1.1.jar
    htrace-core-2.04.jar
    netty-3.6.6.Final.jar
    
  3. 从虚拟机中下载hbase的配置文件文件到Hadoop(下图)
    在这里插入图片描述

  4. 编写Demo代码

    public class HbaseDemo {
         
    
    	HBaseAdmin admin;//hbase的admin角色
    	HTable htable;
    	String TN = "phone";//设置表名
    
    	@Before
    	public void init() throws Exception {
         
    		Configuration conf = new Configuration();
    		//设置读取zookeeper配置
    		conf.set("hbase.zookeeper.quorum", "node2,node3,node4");
    		admin = new HBaseAdmin(conf);
    		htable = new HTable(conf, TN.getBytes());
    	}
    	
    	/**
    	 * 1.创建表
    	 * @throws Exception
    	 */
    	@Test
    	public void creatTable() throws Exception {
         
    
    		if (admin.tableExists(TN)) {
         
    			admin.disableTable(TN);
    			admin.deleteTable(TN);
    		}
    
    		// 表描述
    		HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(TN));
    		HColumnDescriptor cf = new HColumnDescriptor("cf".getBytes());
    		desc.addFamily(cf);
    		admin.createTable(desc);
    	}
    	
    	/**
    	 * 2.插入数据
    	 * @throws Exception
    	 */
    	@Test
    	public void insertDB() throws Exception {
         
    		//设置row key
    		String rowKey = "1231231312";
    		Put put = new Put(rowKey.getBytes());
    		//列族,列名,列下的值
    		put.add("cf".getBytes(), "name".getBytes(), "xiaohai".getBytes());
    		put.add("cf".getBytes(), "age".getBytes(), "19".getBytes());
    		put.add("cf".getBytes(), "sex".getBytes(), "man".getBytes());
    		htable.put(put);
    	}
    	/**
    	 * 3.获取指定单元格信息
    	 * @throws Exception
    	 */
    	@Test
    	public void getDB() throws Exception {
         
    		String rowKey = "1231231312";
    		Get get = new Get(rowKey.getBytes());//根据row key取得一行记录数据
    		get.addColumn("cf".getBytes(), "name".getBytes());
    		get.addColumn("cf".getBytes(), "age".getBytes());
    		get.addColumn("cf".getBytes(), "sex".getBytes());
    		Result rs = htable.get(get);
    		Cell cell = rs.getColumnLatestCell("cf".getBytes(), "name".getBytes());//根据列族+列,获取对应的单元格对象
    		Cell cell2 = rs.getColumnLatestCell("cf".getBytes(), "age".getBytes());
    		Cell cell3 = rs.getColumnLatestCell("cf".getBytes(), "sex".getBytes());
    		// System.out.println(new String(cell.getValue()));
    		System.out.println(new String(CellUtil.cloneValue(cell)));//获取每个单元格的值
    		System.out.println(new String(CellUtil.cloneValue(cell2)));
    		System.out.println(new String(CellUtil.cloneValue(cell3)));
    
    	}
    	    
        	@After
    	public void close() throws Exception {
         
    		if (admin != null) {
         
    			admin.close();
    		}
        }
    }
    

    注意: 如果有不会的方法例如删除操作, 可以通过官方的API手册来查看 ,文档在hbase然健压缩包的docs目录下(图3)
    图1
    在这里插入图片描述
    图2
    注意: 这里是一行数据 , row key相同的数据在表中都是一行数据!!!
    在这里插入图片描述
    图3
    在这里插入图片描述

模拟通话数据的产生和处理

执行本步骤操作时,需将上一个Demo创建的表删除 (即先disable表,然后drop表,或者直接运行创建表的方法( 覆盖原表))
然后依次执行下面代码

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import ah.szxy.hbase.Phone.PhoneDetail;
/**
 * @author chy
 *
 */
public class HBaseDemo {
   

	HBaseAdmin admin;//hbase的admin角色
	HTable htable;
	String TN = "phone";//设置表名

	@Before
	public void init() throws Exception {
   
		Configuration conf = new Configuration();
		//设置读取zookeeper配置
		conf.set("hbase.zookeeper.quorum", "node2,node3,node4")
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间静止不是简史

感谢你的肯定, 我将继续努力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值