千家信息网

HBase的安装和使用方法

发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,本篇内容主要讲解"HBase的安装和使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"HBase的安装和使用方法"吧!1 Hbase基本介绍Hbase
千家信息网最后更新 2025年12月03日HBase的安装和使用方法

本篇内容主要讲解"HBase的安装和使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"HBase的安装和使用方法"吧!

1 Hbase基本介绍

Hbase是一个分布式数据库,可以提供数据的实时随机读写。

Hbasemysqloralcedb2sqlserver等关系型数据库不同,它是一个NoSQL数据库(非关系型数据库),并且有如下特点:

  • Hbase的表模型与关系型数据库的表模型不同:

  • Hbase的表没有固定的字段定义;

  • Hbase的表中每行存储的都是一些key-value

  • Hbase的表中有列族的划分,用户可以指定将哪些kv插入哪个列族

  • Hbase的表在物理存储上,是按照列族来分割的,不同列族的数据一定存储在不同的文件中

  • Hbase的表中的每一行都固定有一个行键,而且每一行的行键在表中不能重复

  • Hbase中的数据,包含行键,包含key,包含value,都是byte[ ]类型,hbase不负责为用户维护数据类型

  • Hbase对事务的支持很差

HBASE相比于其他nosql数据库(mongodbrediscassendrahazelcast)的特点: 因为Hbase的表数据存储在HDFS文件系统中,所以存储容量可以线性扩展; 数据存储的安全性可靠性极高!

2 Hbase的表结构

rowkey:行键base_infoextra_info
001name:zs,age:22,sex:malehobbiy:read,addr:beijing
002name:laowang,sex:male

hbase的表模型跟mysql之类的关系型数据库的表模型差别巨大

hbase的表模型中有:行的概念;但没有字段的概念

行中存的都是key-value对,每行中的key-value对中的key可以是各种各样的。

hbase表模型的要点

  • 一个表,有表名

  • 一个表可以分为多个列族(不同列族的数据会存储在不同文件中)

  • 表中的每一行有一个"行键rowkey",而且行键在表中不能重复

  • 表中的每一对key-value叫做一个cell

  • hbase可以对数据存储多个历史版本(历史版本数量可配置),默认取最新的版本

  • 整张表由于数据量过大,会被横向切分成若干个region(用rowkey范围标识),不同region的数据也存储在不同文件中

hbase会对插入的数据按顺序存储:

  • 首先会按行键排序

  • 同一行里面的kv会按列族排序,再按k排序

hbase的表数据类型:

hbase中只支持byte[] ,此处的byte[] 包括了: rowkey,key,value,列族名,表名。 表划分为不同的region。

3 Hbase工作机制

[图片上传失败...(image-ec30fc-1561887883664)]

Hbase分布式系统包含两个角色

  • 管理角色:HMaster(一般2台,一台active,一台standby)

  • 数据节点角色:HRegionServer(多台,和datanode在一起)

Hbase不做数据处理的话,不需要yarnyarn是复制Mapreduce计算的,Hbase只是负责数据管理

4 Hbase安装

4.1 安装准备

首先,要有一个HDFS集群,并正常运行; Hbaseregionserver应该跟hdfs中的datanode在一起 其次,还需要一个zookeeper集群,并正常运行,所以安装Hbase要先安装zookeeperzookeeper前面已经安装过了。 然后,安装Hbase

4.2 节点安排

各个节点角色分配如下:

节点安装的服务
Masternamenode datanode regionserver hmaster zookeeper
Slave01datanode regionserver zookeeper
Slave02datanode regionserver zookeeper

4.3 安装Hbase

解压hbase安装包 hbase-2.0.5-bin.tar.gz

修改hbase-env.sh

export JAVA_HOME=/usr/local/bigdata/java/jdk1.8.0_211# 不启动hbase自带的zookeeper,我们自己已经装了export HBASE_MANAGES_ZK=false

修改hbase-site.xml

                                hbase.rootdir                hdfs://Master:9000/hbase                                        hbase.cluster.distributed                true                                        hbase.zookeeper.quorum                Master:2181,Slave01:2181,Slave02:2181        

修改 regionservers

MasterSlave01Slave02

修改完成后,将安装文件夹放到三个节点的/usr/local/bigdata/目录下

6 启动Hbase集群

先检查hdfszookeeper是否正常启动, Master:

hadoop@Master:~$ jps4918 DataNode2744 QuorumPeerMain4748 NameNode9949 Jps5167 SecondaryNameNodehadoop@Master:~$ /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh statusJMX enabled by defaultUsing config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfgMode: follower

Slave01:

hadoop@Slave1:~$ jps3235 QuorumPeerMain3779 DataNode5546 Jpshadoop@Slave1:~$  /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh statusJMX enabled by defaultUsing config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfgMode: leader

Slave02:

hadoop@Slave2:~$ jps11958 DataNode13656 Jps11390 QuorumPeerMainhadoop@Slave2:~$  /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh statusJMX enabled by defaultUsing config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfgMode: follower

然后执行start-hbase.sh

$ bin/start-hbase.sh

上面的命令会启动配置文件regionserver里添加的所有机器,如果想手动启动其中一台可以用:

$ bin/hbase-daemon.sh start regionserver

启动完成后在Master上会启动HRegionServerHMaster两个服务,Slave01Slave02会启动HMaster服务。

高可用Hbase集群应配置两台master一台处于active状态一台处于standby状态,用于监听regionserver

可以再从另外两条机器中再启动一个HRegionServer服务。

$ bin/hbase-daemon.sh start master

新启的这个master会处于backup状态

7 启动Hbase的命令行客户端

使用命令hbase shell

bin/hbase shellHbase> list     // 查看表Hbase> status   // 查看集群状态Hbase> version  // 查看集群版本
问题
ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not running yet        at org.apache.hadoop.hbase.master.HMaster.checkServiceStarted(HMaster.java:2932)        at org.apache.hadoop.hbase.master.MasterRpcServices.isMasterRunning(MasterRpcServices.java:1084)        at org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos$MasterService$2.callBlockingMethod(MasterProtos.java)        at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:413)        at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:130)        at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:324)        at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:304)
解决
$ hdfs dfsadmin -safemode leave

8 Hbase命令行客户端操作

8.1 建表

create 't_user_info','base_info','extra_info'         表名      列族名   列族名            

8.2 插入数据:

hbase(main):011:0> put 't_user_info','001','base_info:username','zhangsan'0 row(s) in 0.2420 secondshbase(main):012:0> put 't_user_info','001','base_info:age','18'0 row(s) in 0.0140 secondshbase(main):013:0> put 't_user_info','001','base_info:sex','female'0 row(s) in 0.0070 secondshbase(main):014:0> put 't_user_info','001','extra_info:career','it'0 row(s) in 0.0090 secondshbase(main):015:0> put 't_user_info','002','extra_info:career','actoress'0 row(s) in 0.0090 secondshbase(main):016:0> put 't_user_info','002','base_info:username','liuyifei'0 row(s) in 0.0060 seconds

8.3 查询数据方式一:scan 扫描

hbase(main):017:0> scan 't_user_info'ROW                               COLUMN+CELL                                                                                      001                              column=base_info:age, timestamp=1496567924507, value=18                                          001                              column=base_info:sex, timestamp=1496567934669, value=female                                      001                              column=base_info:username, timestamp=1496567889554, value=zhangsan                               001                              column=extra_info:career, timestamp=1496567963992, value=it                                      002                              column=base_info:username, timestamp=1496568034187, value=liuyifei                               002                              column=extra_info:career, timestamp=1496568008631, value=actoress                               2 row(s) in 0.0420 seconds

8.4 查询数据方式二:get 单行数据

hbase(main):020:0> get 't_user_info','001'COLUMN                            CELL                                                                                             base_info:age                    timestamp=1496568160192, value=19                                                                base_info:sex                    timestamp=1496567934669, value=female                                                            base_info:username               timestamp=1496567889554, value=zhangsan                                                          extra_info:career                timestamp=1496567963992, value=it                                                               4 row(s) in 0.0770 seconds

8.5 删除一个kv数据

hbase(main):021:0> delete 't_user_info','001','base_info:sex'0 row(s) in 0.0390 seconds删除整行数据:hbase(main):024:0> deleteall 't_user_info','001'0 row(s) in 0.0090 secondshbase(main):025:0> get 't_user_info','001'COLUMN                            CELL                                                                                            0 row(s) in 0.0110 seconds3.4.1.6.        删除整个表:hbase(main):028:0> disable 't_user_info'0 row(s) in 2.3640 secondshbase(main):029:0> drop 't_user_info'0 row(s) in 1.2950 secondshbase(main):030:0> listTABLE                                                                                                                             0 row(s) in 0.0130 seconds=> []

8.6 Hbase重要特性--排序特性(行键)

插入到hbase中去的数据,hbase会自动排序存储: 排序规则: 首先看行键,然后看列族名,然后看列(key)名; 按字典顺序

Hbase的这个特性跟查询效率有极大的关系

比如:一张用来存储用户信息的表,有名字,户籍,年龄,职业....等信息 然后,在业务系统中经常需要: 查询某个省的所有用户 经常需要查询某个省的指定姓的所有用户

思路:如果能将相同省的用户在hbase的存储文件中连续存储,并且能将相同省中相同姓的用户连续存储,那么,上述两个查询需求的效率就会提高!!!

做法:将查询条件拼到rowkey

9 HBASE客户端API操作

9.1 DDL操作

代码流程:

  • 创建一个连接:Connection conn = ConnectionFactory.createConnection(conf);

  • 拿到一个DDL操作器:表管理器:adminAdmin admin = conn.getAdmin();

  • 用表管理器的api去建表、删表、修改表定义:admin.createTable(HTableDescriptor descriptor);

@Beforepublic void getConn() throws Exception{        // 构建一个连接对象        Configuration conf = HBaseConfiguration.create(); // 会自动加载hbase-site.xml        conf.set("hbase.zookeeper.quorum", "192.168.233.200:2181,192.168.233.201:2181,192.168.233.202:2181");                conn = ConnectionFactory.createConnection(conf);}/** * DDL * @throws Exception  */@Testpublic void testCreateTable() throws Exception{        // 从连接中构造一个DDL操作器        Admin admin = conn.getAdmin();                // 创建一个表定义描述对象        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("user_info"));                // 创建列族定义描述对象        HColumnDescriptor hColumnDescriptor_1 = new HColumnDescriptor("base_info");        hColumnDescriptor_1.setMaxVersions(3); // 设置该列族中存储数据的最大版本数,默认是1                HColumnDescriptor hColumnDescriptor_2 = new HColumnDescriptor("extra_info");                // 将列族定义信息对象放入表定义对象中        hTableDescriptor.addFamily(hColumnDescriptor_1);        hTableDescriptor.addFamily(hColumnDescriptor_2);                        // 用ddl操作器对象:admin 来建表        admin.createTable(hTableDescriptor);                // 关闭连接        admin.close();        conn.close();        }/** * 删除表 * @throws Exception  */@Testpublic void testDropTable() throws Exception{                Admin admin = conn.getAdmin();                // 停用表        admin.disableTable(TableName.valueOf("user_info"));        // 删除表        admin.deleteTable(TableName.valueOf("user_info"));                        admin.close();        conn.close();}// 修改表定义--添加一个列族@Testpublic void testAlterTable() throws Exception{                Admin admin = conn.getAdmin();                // 取出旧的表定义信息        HTableDescriptor tableDescriptor = admin.getTableDescriptor(TableName.valueOf("user_info"));                        // 新构造一个列族定义        HColumnDescriptor hColumnDescriptor = new HColumnDescriptor("other_info");        hColumnDescriptor.setBloomFilterType(BloomType.ROWCOL); // 设置该列族的布隆过滤器类型                // 将列族定义添加到表定义对象中        tableDescriptor.addFamily(hColumnDescriptor);                        // 将修改过的表定义交给admin去提交        admin.modifyTable(TableName.valueOf("user_info"), tableDescriptor);                        admin.close();        conn.close();        }

9.2 DML操作

HBase的增删改查

    Connection conn = null;                @Before        public void getConn() throws Exception{                // 构建一个连接对象                Configuration conf = HBaseConfiguration.create(); // 会自动加载hbase-site.xml                conf.set("hbase.zookeeper.quorum", "Master:2181,Slave01:2181,Slave02:2181");                                conn = ConnectionFactory.createConnection(conf);        }                        /**         * 增         * 改:put来覆盖         * @throws Exception          */        @Test        public void testPut() throws Exception{                                // 获取一个操作指定表的table对象,进行DML操作                Table table = conn.getTable(TableName.valueOf("user_info"));                                // 构造要插入的数据为一个Put类型(一个put对象只能对应一个rowkey)的对象                Put put = new Put(Bytes.toBytes("001"));                put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("张三"));                put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes("18"));                put.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("北京"));                                                Put put2 = new Put(Bytes.toBytes("002"));                put2.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("李四"));                put2.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes("28"));                put2.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("上海"));                                        ArrayList puts = new ArrayList<>();                puts.add(put);                puts.add(put2);                                                // 插进去                table.put(puts);                                table.close();                conn.close();                        }                        /**         * 循环插入大量数据         * @throws Exception          */        @Test        public void testManyPuts() throws Exception{                                Table table = conn.getTable(TableName.valueOf("user_info"));                ArrayList puts = new ArrayList<>();                                for(int i=0;i<100000;i++){                        Put put = new Put(Bytes.toBytes(""+i));                        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("张三"+i));                        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes((18+i)+""));                        put.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("北京"));                                                puts.add(put);                }                                table.put(puts);                        }                /**         * 删         * @throws Exception          */        @Test        public void testDelete() throws Exception{                Table table = conn.getTable(TableName.valueOf("user_info"));                                // 构造一个对象封装要删除的数据信息                Delete delete1 = new Delete(Bytes.toBytes("001"));                                Delete delete2 = new Delete(Bytes.toBytes("002"));                delete2.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"));                                ArrayList dels = new ArrayList<>();                dels.add(delete1);                dels.add(delete2);                                table.delete(dels);                                                table.close();                conn.close();        }                /**         * 查         * @throws Exception          */        @Test        public void testGet() throws Exception{                                Table table = conn.getTable(TableName.valueOf("user_info"));                                Get get = new Get("002".getBytes());                                Result result = table.get(get);                                // 从结果中取用户指定的某个key的value                byte[] value = result.getValue("base_info".getBytes(), "age".getBytes());                System.out.println(new String(value));                                System.out.println("-------------------------");                                // 遍历整行结果中的所有kv单元格                CellScanner cellScanner = result.cellScanner();                while(cellScanner.advance()){                        Cell cell = cellScanner.current();                                                byte[] rowArray = cell.getRowArray();  //本kv所属的行键的字节数组                        byte[] familyArray = cell.getFamilyArray();  //列族名的字节数组                        byte[] qualifierArray = cell.getQualifierArray();  //列名的字节数据                        byte[] valueArray = cell.getValueArray(); // value的字节数组                                                System.out.println("行键: "+new String(rowArray,cell.getRowOffset(),cell.getRowLength()));                        System.out.println("列族名: "+new String(familyArray,cell.getFamilyOffset(),cell.getFamilyLength()));                        System.out.println("列名: "+new String(qualifierArray,cell.getQualifierOffset(),cell.getQualifierLength()));                        System.out.println("value: "+new String(valueArray,cell.getValueOffset(),cell.getValueLength()));                                        }                                table.close();                conn.close();                        }                        /**         * 按行键范围查询数据         * @throws Exception          */        @Test        public void testScan() throws Exception{                                Table table = conn.getTable(TableName.valueOf("user_info"));                                // 包含起始行键,不包含结束行键,但是如果真的想查询出末尾的那个行键,那么,可以在末尾行键上拼接一个不可见的字节(\000)                Scan scan = new Scan("10".getBytes(), "10000\001".getBytes());                                ResultScanner scanner = table.getScanner(scan);                                Iterator iterator = scanner.iterator();                                while(iterator.hasNext()){                                                Result result = iterator.next();                        // 遍历整行结果中的所有kv单元格                        CellScanner cellScanner = result.cellScanner();                        while(cellScanner.advance()){                                Cell cell = cellScanner.current();                                                                byte[] rowArray = cell.getRowArray();  //本kv所属的行键的字节数组                                byte[] familyArray = cell.getFamilyArray();  //列族名的字节数组                                byte[] qualifierArray = cell.getQualifierArray();  //列名的字节数据                                byte[] valueArray = cell.getValueArray(); // value的字节数组                                                                System.out.println("行键: "+new String(rowArray,cell.getRowOffset(),cell.getRowLength()));                                System.out.println("列族名: "+new String(familyArray,cell.getFamilyOffset(),cell.getFamilyLength()));                                System.out.println("列名: "+new String(qualifierArray,cell.getQualifierOffset(),cell.getQualifierLength()));                                System.out.println("value: "+new String(valueArray,cell.getValueOffset(),cell.getValueLength()));                        }                        System.out.println("----------------------");                }        }                @Test        public void test(){                String a = "000";                String b = "000\0";                                System.out.println(a);                System.out.println(b);                                                byte[] bytes = a.getBytes();                byte[] bytes2 = b.getBytes();                                System.out.println("");                        }               

到此,相信大家对"HBase的安装和使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

数据 存储 对象 查询 不同 字节 用户 数据库 文件 数组 模型 集群 排序 信息 版本 类型 节点 方法 命令 状态 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 计算机网络安全检查检测整改 传奇安全通服务器 河南有软件开发的大学吗 电脑后台数据库怎么连接 守护网络安全要铸就三把利剑 数据库驱动包和数据库版本不对应 数据库基础书籍推荐 上海华为软件开发工作体验 网络安全 信创市场规模 日照颖钨网络技术 企业开展网络安全管理工作情况 合同软件开发合同纠纷 telnet数据库端口不通 服务器包传到另一个服务器上 数据库打开根目录命令 泗洪网络技术 公司软件开发没有流程 中国国家网络安全法实施时间 数据库体系结构分哪三级 下载隐隐显示未受软件开发 软件开发前台与前端的区别 腐蚀游戏服务器怎么区分 中国网络安全周郑州 合同软件开发合同纠纷 软件开发系统建设方案文档 计算机网络技术毕业设计源码 30天学会软件开发 互联网大会2017新科技 软件开发公司运维的工作职责 联通杭州分公司软件开发
0