文章目录
- 前言
- 一、HBase
- 1、Region
- 2、RegionServer
- 3、Master
- 4、Zookeeper
- 二、HBases的Standalone安装
- 1、解压配置环境变量
- 1.下载
- 2.解压
- 3.配置环境变量
- 2、修改配置文件信息
- 1.hbase-env.sh
- 2.hbase-site.xml
- 3.启动HBase
- 4.验证启动是否成功
- 三、HBase完全分布式搭建
- 四、HBase常见shell指令
- 1、基本指令
- 1.打开HBase shell
- 2. 获取帮助
- 3. 查看服务器状态
- 4.查看版本信息
- 5.创建命名空间
- 6.描述命名空间
- 7.删除namespace
- 2、表操作
- 1. 查看所有表
- 2.创建表
- 3.查看表的基本信息
- 4.表的启用/禁用
- 5.检查表是否存在
- 6.删除表
- 3、增删改
- 1.添加列族
- 2.删除列族
- 3.更改列族存储版本的限制
- 4.插入数据
- 5.获取指定行、指定行中的列族、列的信息
- 6.删除指定行、指定行中的列
- 4、查询
- 1.Get查询
- 2.查询整表数据
- 3.查询指定列簇的数据
- 4.条件查询
- 5. 条件过滤
- 五、Java API
- 1、pom.xml
- 2、HBaseClient
- 3、创建表
- 4、添加行列数据数据
- 5、添加行列数据数据
- 6、删除行
- 7、查询所有数据
- 8、根据rowId查询
- 9、根据列条件查询
- 10、多条件查询
- 11、删除表
前言 HBase作为一个列式存储的数据存储框架,其广泛应用于OLAP 。前面介绍了大数据组件之HIve,其访问量很高,因此本文主要介绍HBase的shell命令和java操作,希望对于学习大数据或者从事大数据的你有些帮助 。
一、HBase HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统” 。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力 。HBase是Apache的Hadoop项目的子项目 。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库 。另一个不同的是HBase基于列的而不是基于行的模式 。
HBase只有新增操作,通过操作类型和时间戳建立版本管理,按照时间的先后顺序0,1,2,…
可以通过切换版本追踪历史数据
可以设置最大的保留实例记录数
- 基于列式存储模型,对于数据实现了高度压缩,节省存储成本
- 采用 LSM 机制而不是B(+)树,这使得HBase非常适合海量数据实时写入的场景
- 高可靠,一个数据会包含多个副本(默认是3副本),这得益于HDFS的复制能力,由RegionServer提供自动故障转移的功能
- 高扩展,支持分片扩展能力(基于Region),可实现自动、数据均衡
- 强一致性读写,数据的读写都针对主Region上进行,属于CP型的系统
- 易操作,HBase提供了Java API、RestAPI/Thrift API等接口
- 查询优化,采用Block Cache 和 布隆过滤器来支持海量数据的快速查找
1. Region不能跨服务器,一个RegionServer上有一个或者多个 Region 。2. 数据量小的时候,一个Region足以存储所有数据;但是,当数据 量大的时候,HBase会拆分Region 。3. 当HBase在进行负载均衡的时候,也有可能会从一台 RegionServer上把Region移动到另一台RegionServer上 。4. Region是基于HDFS的,它的所有数据存取操作都是调用了HDFS的 客户端接口来实现的 。 2、RegionServer RegionServer就是存放Region的容器,直观上说就是服务器上的一 个服务 。当客户端从ZooKeeper获取RegionServer的地址后,它会直接从 RegionServer获取数据 。3、Master Master只负责各种协调工作,比如建表、删表、 移动Region、合并等操作 。
4、Zookeeper Zookeeper 对于 HBase的作用是至关重要的 。
- Zookeeper 提供了 HBase Master 的高可用实现,并保证同一时刻有且仅有一个主 Master 可用 。
- Zookeeper 保存了 Region 和 Region Server 的关联信息(提供寻址入口),并保存了集群的元数据(Schema/Table) 。
- Zookeeper 实时监控Region server的上线和下线信息,并实时通知Master 。
#利用wget进行HBase安装包下载wget https://hbase.apache.org/downloads.html 2.解压 #tar解压tar -zxvf hbase-2.1.4-bin.tar.gz -C /opt/software 3.配置环境变量 #编辑环境变量vim /etc/profile.d/my.sh#-------------------------------------export HBASE_HOME=/opt/software-2.1.4export PATH=$HBASE_HOME/bin:$PATH#-------------------------------------# 生效环境变量source /etc/profile 2、修改配置文件信息 1.hbase-env.sh #打开文件vim /opt/software-2.1.4/conf/hbase-env.sh#-----------------------------------------export JAVA_HOME=/opt/software/jdk1.8.0_201#----------------------------------------- 2.hbase-site.xml #打开编辑文件,新增以下内容vim /opt/software-2.1.4/conf/hbase-site.xml 新增以下内容:hbase.rootdirfile:///home/hbase/rootdir hbase.zookeeper.property.dataDir/home/zookeeper/dataDir hbase.unsafe.stream.capability.enforcefalse 配置信息介绍:- hbase.rootdir: 配置 hbase 数据的存储路径;
- hbase.zookeeper.property.dataDir: 配置 zookeeper 数据的存储路径;
- hbase.unsafe.stream.capability.enforce: 使用本地文件系统存储,不使用 HDFS 的情况下需要禁用此配置,设置为 false 。
#启动HBasestart-hbase.sh 4.验证启动是否成功 验证方式一 :使用 jps 命令查看 HMaster 进程是否启动 。[root@hadoop001 hbase-2.1.4]# jps16336 Jps15500 HMaster 验证方式二 :访问 HBaseWeb UI 页面,默认端口为 16010。三、HBase完全分布式搭建
#默认无,必须手动创建vim conf/backup-masters #---------#backup状态master02#--------start-hbase.sh HMaster 溢写64MB#DDLlistlist_namespacecreate_namespace 'kb16nb'list_namespace_tables 'kb16nb'#create 'kb16nb:student','base','score'describe 'kb16nb:student'#----------------------------------------------------------------------------------------Table kb16nb:student is ENABLEDkb16nb:studentCOLUMN FAMILIES DESCRIPTION{NAME => 'base', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}{NAME => 'score', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', COMPRESSION => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} #----------------------------------------------------------------------------------------#DMLis_enabled 'kb16nb:student' #查看表是否可用is_disabled 'kb16nb:student' #查看表示是否禁用drop 'kb16nb:student' #删除表,删除前需要禁用enable 'kb16nb:student' #启用表disable 'kb16nb:student'#禁用表truncate 'kb16nb:student' #删除数据delete 'kb16nb:student','rowkey','columnfamily:colname' #删除某行某列(最新的版本)deleteall 'kb16nb:student','rowkey' #删除某行(删除所有版本)put 'kb16nb:student','1','base:name','zhangsan' #插入数据scan 'kb16nb:student' #查看全表#----------------------------------------------------------------------------------------hbase(main):014:0> scan 'kb16nb:student'ROWCOLUMN+CELL1column=base:name, timestamp=2022-01-28T10:23:06.333, value=https://tazarkount.com/read/zhangsan#----------------------------------------------------------------------------------------get'kb16nb:student','2','base:name'scan 'kb16nb:student',{COLUMN=>'base'} #查询列簇scan 'kb16nb:student',{COLUMN=>'base:name'} #查询指定列scan 'kb16nb:student',{COLUMN=>'base:name',LIMIT=>2}scan 'kb16nb:student',{COLUMN=>'base:name',LIMIT=>2,STARTKEY=>'2'} #开始下标(包含)scan 'kb16nb:student',{COLUMN=>'base:name',LIMIT=>2,STARTKEY=>'2',STARTROW=>'2'} #Row下标不包含#BLOCKCACHE的页面置换算法是最近最少使用LRUcreate 'kb16nb:'#shell执行HBase命令echo "shell指令"|hbase shell -necho "list_namespace_tables 'kb16nb'"|hbase shell -n#布隆过滤器出现误码后怎么处理#预分区create_namespace 'kb16'create 'kb16:pre_split_n1','cf',SPLITS=>['10','20','30']hbase org.apache.hadoop.hbase.util.RegionSplitter kb16:pre_split_hsp1 HexStringSplit -c 3 -f base,scorescreate 'kb16:pre_split_pdp','base',{NUMREGIONS=>4,SPLITALGO=>'DecimalStringSplit'} 四、HBase常见shell指令 HBase为什么这么快1、基本指令 1.打开HBase shell
#进入HBase的命令hbase shell 2. 获取帮助 # 获取帮助help# 获取命令的详细信息help 'status' 3. 查看服务器状态 #查看服务器状态status 4.查看版本信息 #查看HBase版本信息version 5.创建命名空间 #创建命名空间create_namespace '命名空间'create_namespace 'ns1' 6.描述命名空间 #描述命名空间describe_namespace '命名空间'describe_namespace 'ns1' 7.删除namespace #删除namespacedrop_namespace 'ns1' 2、表操作 1. 查看所有表 #查看HBase的所有表list 2.创建表 命令格式: create ‘表名称’, ‘列族名称 1’,‘列族名称 2’,‘列名称 N’# 创建一张名为Student的表,包含基本信息(baseInfo)、学校信息(schoolInfo)两个列族create 'ns1:t1',{NAME => 'f1',VERSION => 5},{NAME => 'f2'}create 'Student','baseInfo','schoolInfo' 3.查看表的基本信息 命令格式:desc ‘表名’#查看表的基本信息describe 'Student' 4.表的启用/禁用 enable 和 disable 可以启用/禁用这个表,is_enabled 和 is_disabled 来检查表是否被禁用# 禁用表disable 'Student'# 检查表是否被禁用is_disabled 'Student'# 启用表enable 'Student'# 检查表是否被启用is_enabled 'Student' 5.检查表是否存在 指令格式: exits ‘表名’#检查表是否存在exists 'Student' 6.删除表 删除表前需要先禁用表# 删除表前需要先禁用表disable 'Student'# 删除表drop 'Student' 3、增删改 1.添加列族 命令格式: alter ‘表名’, ‘列族名’alter 'Student', 'teacherInfo' 2.删除列族 命令格式:alter ‘表名’, {NAME => ‘列族名’, METHOD => ‘delete’}alter 'Student', {NAME => 'teacherInfo', METHOD => 'delete'} 3.更改列族存储版本的限制 默认情况下,列族只存储一个版本的数据,如果需要存储多个版本的数据,则需要修改列族的属性 。修改后可通过 desc 命令查看 。alter 'Student',{NAME=>'baseInfo',VERSIONS=>3} 4.插入数据 命令格式:put ‘表名’, ‘行键’,‘列族:列’,‘值’注意:如果新增数据的行键值、列族名、列名与原有数据完全相同,则相当于更新操作
put 'Student', 'rowkey1','baseInfo:name','tom'put 'Student', 'rowkey1','baseInfo:birthday','1990-01-09'put 'Student', 'rowkey1','baseInfo:age','29'put 'Student', 'rowkey1','schoolInfo:name','Havard'put 'Student', 'rowkey1','schoolInfo:localtion','Boston'put 'Student', 'rowkey2','baseInfo:name','jack'put 'Student', 'rowkey2','baseInfo:birthday','1998-08-22'put 'Student', 'rowkey2','baseInfo:age','21'put 'Student', 'rowkey2','schoolInfo:name','yale'put 'Student', 'rowkey2','schoolInfo:localtion','New Haven'put 'Student', 'rowkey3','baseInfo:name','maike'put 'Student', 'rowkey3','baseInfo:birthday','1995-01-22'put 'Student', 'rowkey3','baseInfo:age','24'put 'Student', 'rowkey3','schoolInfo:name','yale'put 'Student', 'rowkey3','schoolInfo:localtion','New Haven'put 'Student', 'wrowkey4','baseInfo:name','maike-jack' 5.获取指定行、指定行中的列族、列的信息 # 获取指定行中所有列的数据信息get 'Student','rowkey3'# 获取指定行中指定列族下所有列的数据信息get 'Student','rowkey3','baseInfo'# 获取指定行中指定列的数据信息get 'Student','rowkey3','baseInfo:name' 6.删除指定行、指定行中的列 # 删除指定行delete 'Student','rowkey3'# 删除指定行中指定列的数据delete 'Student','rowkey3','baseInfo:name' 4、查询 hbase 中访问数据有两种基本的方式:- 按指定 rowkey 获取数据:get 方法;
- 按指定条件获取数据:scan 方法 。
scan 可以设置 begin 和 end 参数来访问一个范围内所有的数据 。get 本质上就是 begin 和 end 相等的一种特殊的 scan 。1.Get查询
# 获取指定行中所有列的数据信息get 'Student','rowkey3'# 获取指定行中指定列族下所有列的数据信息get 'Student','rowkey3','baseInfo'# 获取指定行中指定列的数据信息get 'Student','rowkey3','baseInfo:name' 2.查询整表数据 指令格式: scan ‘表名’#查询整表数据scan 'Student' 3.查询指定列簇的数据 #查看指定列簇数据scan 'Student', {COLUMN=>'baseInfo'} 4.条件查询 # 查询指定列的数据scan 'Student', {COLUMNS=> 'baseInfo:birthday'} 除了列 (COLUMNS) 修饰词外,HBase 还支持 Limit(限制查询结果行数),STARTROW(ROWKEY 起始行,会先根据这个 key 定位到 region,再向后扫描)、STOPROW(结束行)、TIMERANGE(限定时间戳范围)、VERSIONS(版本数)、和 FILTER(按条件过滤行)等 。如下代表从
rowkey2 这个 rowkey 开始,查找下两个行的最新 3 个版本的 name 列的数据:scan 'Student', {COLUMNS=> 'baseInfo:name',STARTROW => 'rowkey2',STOPROW => 'wrowkey4',LIMIT=>2, VERSIONS=>3} 5. 条件过滤 Filter 可以设定一系列条件来进行过滤 。如我们要查询值等于 24 的所有数据:scan 'Student', FILTER=>"ValueFilter(=,'binary:24')" 值包含 yale 的所有数据:scan 'Student', FILTER=>"ValueFilter(=,'substring:yale')" 列名中的前缀为 birth 的:scan 'Student', FILTER=>"ColumnPrefixFilter('birth')" FILTER 中支持多个过滤条件通过括号、AND 和 OR 进行组合:# 列名中的前缀为birth且列值中包含1998的数据scan 'Student', FILTER=>"ColumnPrefixFilter('birth') AND ValueFilter ValueFilter(=,'substring:1998')" PrefixFilter 用于对 Rowkey 的前缀进行判断:scan 'Student', FILTER=>"PrefixFilter('wr')" 五、Java API 1、pom.xml org.apache.hbase hbase-client2.0.0 2、HBaseClient import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.client.Connection;import org.apache.hadoop.hbase.client.ConnectionFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class HbaseClient {// config zookeeperstatic private org.apache.hadoop.conf.Configuration configuration = null;static private Connection connection = null;private static Logger logger = LoggerFactory.getLogger(HbaseClient.class);static private Lock lock = new ReentrantLock();static Connection getConnectionInstance() {if (null == connection) {lock.lock();try {if (null == connection) {configuration = HBaseConfiguration.create();configuration.set("hbase.zookeeper.quorum", "zk1:2182,zk2:2182,zk3:2182");configuration.set("hbase.client.keyvalue.maxsize", "100000000");connection = ConnectionFactory.createConnection(configuration);}} catch (IOException e) {logger.error("create hbase error ", e);} finally {lock.unlock();}}return connection;}} 3、创建表 /*** 创建表** @param tableName*/public static void createTable(String tableStr, String[] familyNames) { System.out.println("start create table ......"); try {Admin admin = connection.getAdmin();TableName tableName = TableName.valueOf(tableStr);if (admin.tableExists(tableName)) {// 如果存在要创建的表,那么先删除,再创建admin.disableTable(tableName);admin.deleteTable(tableName);System.out.println(tableName + " is exist,detele....");}HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);// 添加表列信息if (familyNames != null && familyNames.length > 0) {for (String familyName : familyNames) {tableDescriptor.addFamily(new HColumnDescriptor(familyName));}}admin.createTable(tableDescriptor); } catch (MasterNotRunningException e) {e.printStackTrace(); } catch (ZooKeeperConnectionException e) {e.printStackTrace(); } catch (IOException e) {e.printStackTrace(); } System.out.println("end create table ......");} 4、添加行列数据数据 【大数据组件之HBase】/*** 添加行列数据数据** @param tableName* @throws Exception*/public static void insertData(String tableName, String rowId, String familyName,String qualifier, String value) throws Exception { System.out.println("start insert data ......"); Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(rowId.getBytes());// 一个PUT代表一行数据,再NEW一个PUT表示第二行数据,每行一个唯一的ROWKEY,此处rowkey为put构造方法中传入的值 put.addColumn(familyName.getBytes(), qualifier.getBytes(), value.getBytes());// 本行数据的第一列 try {table.put(put); } catch (IOException e) {e.printStackTrace(); }System.out.println("end insert data ......");} 5、添加行列数据数据 /*** 添加行列数据数据** @param tableName* @throws Exception*/public static void batchInsertData(String tableName, String rowId, List> familyNames,String qualifier, List> values) throws Exception { if (null == qualifier) qualifier = "tmp"; Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(rowId.getBytes());// 一个PUT代表一行数据,再NEW一个PUT表示第二行数据,每行一个唯一的ROWKEY,此处rowkey为put构造方法中传入的值 for (int i = 0; i < familyNames.size(); ++i) {put.addColumn(familyNames.get(i).getBytes(),qualifier.getBytes(), values.get(i).getBytes());// 本行数据的第一列 } try {table.put(put); } catch (IOException e) {e.printStackTrace(); }} 6、删除行 /*** 删除行** @param tablename* @param rowkey*/public static void deleteRow(String tablename, String rowkey) { try {Table table = connection.getTable(TableName.valueOf(tablename));Delete d1 = new Delete(rowkey.getBytes());table.delete(d1);//d1.addColumn(family, qualifier);d1.addFamily(family);System.out.println("删除行成功!"); } catch (IOException e) {e.printStackTrace(); }} 7、查询所有数据 /*** 查询所有数据** @param tableName* @throws Exception*/public static void queryAll(String tableName) throws Exception { Table table = connection.getTable(TableName.valueOf(tableName)); try {ResultScanner rs = table.getScanner(new Scan());for (Result r : rs) {System.out.println("获得到rowkey:" + new String(r.getRow()));for (Cell keyValue : r.rawCells()) {System.out.println("列:" + new String(CellUtil.cloneFamily(keyValue))+":"+new String(CellUtil.cloneQualifier(keyValue)) + "====值:" + new String(CellUtil.cloneValue(keyValue)));}}rs.close(); } catch (IOException e) {e.printStackTrace(); }} 8、根据rowId查询 /*** 根据rowId查询** @param tableName* @throws Exception*/public static void queryByRowId(String tableName, String rowId) throws Exception { Table table = connection.getTable(TableName.valueOf(tableName)); try {Get scan = new Get(rowId.getBytes());// 根据rowkey查询Result r = table.get(scan);System.out.println("获得到rowkey:" + new String(r.getRow()));for (Cell keyValue : r.rawCells()) {System.out.println("列:" + new String(CellUtil.cloneFamily(keyValue))+":"+new String(CellUtil.cloneQualifier(keyValue)) + "====值:" + new String(CellUtil.cloneValue(keyValue)));} } catch (IOException e) {e.printStackTrace(); }} 9、根据列条件查询 /*** 根据列条件查询** @param tableName*/public static void queryByCondition(String tableName, String familyName,String qualifier,String value) { try {Table table = connection.getTable(TableName.valueOf(tableName));Filter filter = new SingleColumnValueFilter(Bytes.toBytes(familyName),Bytes.toBytes(qualifier), CompareOp.EQUAL, Bytes.toBytes(value)); // 当列familyName的值为value时进行查询Scan s = new Scan();s.setFilter(filter);ResultScanner rs = table.getScanner(s);for (Result r : rs) {System.out.println("获得到rowkey:" + new String(r.getRow()));for (Cell keyValue : r.rawCells()) {System.out.println("列:" + new String(CellUtil.cloneFamily(keyValue))+":"+new String(CellUtil.cloneQualifier(keyValue)) + "====值:" + new String(CellUtil.cloneValue(keyValue)));}}rs.close(); } catch (Exception e) {e.printStackTrace(); }} 10、多条件查询 /*** 多条件查询** @param tableName*/public static void queryByConditions(String tableName, String[] familyNames, String[] qualifiers,String[] values) { try {Table table = connection.getTable(TableName.valueOf(tableName));List filters = new ArrayList();if (familyNames != null && familyNames.length > 0) {int i = 0;for (String familyName : familyNames) {Filter filter = new SingleColumnValueFilter(Bytes.toBytes(familyName),Bytes.toBytes(qualifiers[i]), CompareOp.EQUAL,Bytes.toBytes(values[i]));filters.add(filter);i++;}}FilterList filterList = new FilterList(filters);Scan scan = new Scan();scan.setFilter(filterList);ResultScanner rs = table.getScanner(scan);for (Result r : rs) {System.out.println("获得到rowkey:" + new String(r.getRow()));for (Cell keyValue : r.rawCells()) {System.out.println("列:" + new String(CellUtil.cloneFamily(keyValue))+":" +new String(CellUtil.cloneQualifier(keyValue)) +"====值:" + new String(CellUtil.cloneValue(keyValue)));}}rs.close(); } catch (Exception e) {e.printStackTrace(); }} 11、删除表 // 懒加载单例模式static private Connection connection = HbaseClient.getConnectionInstance();/*** 删除表** @param tableName*/public static void dropTable(String tableStr) { try {Admin admin = connection.getAdmin();TableName tableName = TableName.valueOf(tableStr);admin.disableTable(tableName);admin.deleteTable(tableName);admin.close(); } catch (MasterNotRunningException e) {e.printStackTrace(); } catch (ZooKeeperConnectionException e) {e.printStackTrace(); } catch (IOException e) {e.printStackTrace(); }}
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
