Hbase连接与数据处理

2023-01-11 11:37:47 浏览数 (1)

启动和停止

先启动Zookeeper和Hadoop

启动Hbase

代码语言:javascript复制
$HBASE_HOME/bin/start-hbase.sh

停止Hbase

代码语言:javascript复制
$HBASE_HOME/bin/stop-hbase.sh

HMaster 的 Web 接口

http://192.168.7.101:16010

http://192.168.7.102:16010

HRegionServer 的 Web 接口

http://192.168.7.101:16030

http://192.168.7.102:16030

http://192.168.7.103:16030

HBase的操作

下面的操作主要是在hbase的shell中操作的,进入hbase shell

代码语言:javascript复制
hbase shell

命名空间

查看所有namespace

代码语言:javascript复制
list_namespace

创建namespace

代码语言:javascript复制
create_namespace 'zns'

删除namespace

代码语言:javascript复制
drop_namespace 'zns'

注意

删除命名空间前要删除命名空间下的所有表

删除命名空间下的表

代码语言:javascript复制
disable 'zns:ztable'
drop 'zns:ztable'

查看namespace

代码语言:javascript复制
describe_namespace 'zns'

在namespace下创建表

代码语言:javascript复制
create 'zns:ztable','s_name','s_sex'

查看namespace下的表

代码语言:javascript复制
list_namespace_tables 'zns'

表操作

创建表

代码语言:javascript复制
create 'student','s_name','s_sex','s_age','s_dept','s_course'

# 创建表示指定保存的版本数
create 'teacher',{NAME=>'username',VERSIONS=>5}

查看表详情

代码语言:javascript复制
describe 'student'

显示所有的表

代码语言:javascript复制
list

插入数据

代码语言:javascript复制
put 'student','95001','s_name','LiYing'
put 'student','95001','s_sex','Male'
put 'student','95001','s_course:math','80'
put 'student','95001','s_course:english','90'

put 'student','95002','s_name','XiaoHong'
put 'student','95002','s_sex','Femal'
put 'student','95002','s_course:math','90'
put 'student','95002','s_course:english','70'

注意:一次只能为一个表的一行数据的一个列,也就是一个单元格添加一个数据,所以直接用shell命令插入数据效率很低,在实际应用中,一般都是利用编程操作数据。

当运行命令:put ‘student’,’95001’,’s_name’,’LiYing’时,即为student表添加了学号为95001,名字为LiYing的一行数据,其行键为95001。

查询数据 HBase中有两个用于查看数据的命令:

  1. get命令,用于查看表的某一行数据;
  2. scan命令用于查看某个表的全部数据

示例

代码语言:javascript复制
get 'student','95001'
get 'student','95001','s_course'
get 'student','95001','s_course:math'

scan 'student'

scan 'student', {FORMATTER => 'toString'}

删除数据 在HBase中用delete以及deleteall命令进行删除数据操作,它们的区别是: ① delete用于删除一个数据,是put的反向操作; ② deleteall操作用于删除一行数据。

代码语言:javascript复制
delete 'student','95001','s_sex'
deleteall 'student','95001'

修改数据 在添加数据时,HBase会自动为添加的数据添加一个时间戳,故在需要修改数据时,只需直接添加数据,HBase即会生成一个新的版本,从而完成“改”操作,旧的版本依旧保留,系统会定时回收垃圾数据,只留下最新的几个版本,保存的版本数可以在创建表的时候指定。下面是一个操作的例子:

代码语言:javascript复制
hbase(main):034:0> get 'student','95001'
COLUMN                             CELL                                                                                             
 s_name:                            timestamp=1537497681798, value=LiYing                                                           
 s_sex:                             timestamp=1537497682400, value=Male                                                            
 s_course:english                    timestamp=1537497872225, value=90                                                             
 s_course:math                       timestamp=1537497681859, value=80                                                               
4 row(s) in 0.0310 seconds

hbase(main):035:0> put 'student','95001','s_course:english','100'
0 row(s) in 0.0130 seconds

hbase(main):036:0> get 'student','95001'
COLUMN                             CELL                                                                                             
 s_name:                            timestamp=1537497681798, value=LiYing                                                           
 s_sex:                             timestamp=1537497682400, value=Male                                                             
 s_course:english                    timestamp=1537498062541, value=100                                                             
 s_course:math                       timestamp=1537497681859, value=80                                                               
4 row(s) in 0.0130 seconds

删除表 删除表有两步,第一步先让该表不可用,第二步删除表。直接drop未disable的表会失败。

代码语言:javascript复制
disable 'student'
drop 'student'

查询历史的表

代码语言:javascript复制
create 'teacher',{NAME=>'username',VERSIONS=>5}

put 'teacher','91001','username','Mary'
put 'teacher','91001','username','Mary1'
put 'teacher','91001','username','Mary2'
put 'teacher','91001','username','Mary3'
put 'teacher','91001','username','Mary4'  
put 'teacher','91001','username','Mary5'

get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}

hbase(main):064:0> get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}
COLUMN                             CELL                                                                                             
 username:                         timestamp=1537498459746, value=Mary5                                                             
 username:                         timestamp=1537498455244, value=Mary4                                                             
 username:                         timestamp=1537498455193, value=Mary3                                                             
 username:                         timestamp=1537498455174, value=Mary2                                                             
 username:                         timestamp=1537498455149, value=Mary1                                                             
5 row(s) in 0.0110 seconds

退出hbase

代码语言:javascript复制
exit

授权

具备Create权限的namespace Admin可以对表创建和删除、生成和恢复快照

具备Admin权限的namespace Admin可以对表splits或major compactions

授权命名空间

授权zuser01用户对zns下的写权限

代码语言:javascript复制
grant 'zuser01' 'W' '@zns'

回收zuser01用户对zns的所有权限

代码语言:javascript复制
revoke 'zuser01''@zns'

当前用户:hbase

代码语言:javascript复制
namespace_create 'ns_hbase' 
grant 'zuser02', 'W', '@ns_hbase'

授权表

当前用户:zuser02

代码语言:javascript复制
create 'ns_hbase.ztable01', 'name' 
create 'ns_hbase.ztable02', 'name'

zuser02创建了两张表ztable01和ztable02,同时成为这两张表的owner,意味着有RWXCA权限

此时,zuser02团队的另一名成员zuser03也需要获得ns_hbase下的权限,hbase管理员操作如下

如果希望zuser03可以访问已经存在的表,则hbase管理员操作如下

当前用户:hbase

代码语言:javascript复制
grant 'zuser03', 'RW', 'ns_hbase.ztable01' 
grant 'zuser03', 'RW', 'ns_hbase.ztable02'

不要只设置写权限

当前用户:hbase

代码语言:javascript复制
grant 'zuser03', 'W', '@ns_hbase'

此时zuser03可以在ns_hbase下创建表,但是无法读、写、修改和删除ns_hbase下已存在的表

当前用户:zuser03

代码语言:javascript复制
scan 'ns_hbase:ztable01'

报错AccessDeniedException

在HBase中启用授权机制

hbase-site.xml

代码语言:javascript复制
<property>  
  <name>hbase.security.authorization</name>  
  <value>true</value>  
</property>  
<property>  
  <name>hbase.coprocessor.master.classes</name>  
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>  
</property>  
<property>  
  <name>hbase.coprocessor.region.classes</name>  
  <value>org.apache.hadoop.hbase.security.token.TokenProvider,org.apache.hadoop.hbase.security.access.AccessController</value>  
</property>

配置完成后需要重启HBase集群

Java操作

添加依赖

代码语言:javascript复制
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-client</artifactId>
  <version>2.1.10</version>
</dependency>

Java代码

代码语言:javascript复制
package cn.psvmc;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.net.URISyntaxException;

public class HbaseTest {
    public static Connection getConn() throws IOException, URISyntaxException {

        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.property.clientPort", "2181");
        conf.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
        /*
        conf.addResource(new Path(ClassLoader.getSystemResource("hbase-site.xml").toURI()));
        conf.addResource(new Path(ClassLoader.getSystemResource("core-site.xml").toURI()));
        */
        return ConnectionFactory.createConnection(conf);
    }

    public static void close(Connection conn) throws IOException {
        if (null != conn)
            conn.close();
    }

    public static Table getTable(Connection conn, String tablename, String namespace) throws IOException {
        TableName tableName1 = TableName.valueOf(namespace, tablename);
        return conn.getTable(tableName1);
    }

    /**
     * 添加值
     * @param conn 连接
     * @param tablename 表名
     * @param namespace 命名空间
     * @param rowkey 行键
     * @param cf 列簇
     * @param lie 列标识
     * @param value 值
     * @throws IOException
     */
    public static void put(Connection conn, String tablename, String namespace, String rowkey, String cf, String lie, String value) throws IOException {
        Table table = getTable(conn, tablename, namespace);
        Put put = new Put(Bytes.toBytes(rowkey));
        put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(lie), Bytes.toBytes(value));
        table.put(put);
        table.close();
    }

    /**
     * 获取数据
     * @param conn 连接
     * @param tablename 表名
     * @param namespace 命名空间
     * @param rowkey 行键
     * @throws IOException
     */
    public static void get(Connection conn, String tablename, String namespace, String rowkey) throws IOException {
        Table table = getTable(conn, tablename, namespace);
        Get get = new Get(Bytes.toBytes(rowkey));
        Result result = table.get(get);
        if (result != null) {
            Cell[] cells = result.rawCells();
            for (Cell cell : cells) {
                String row = Bytes.toString(CellUtil.cloneRow(cell));
                String family = Bytes.toString(CellUtil.cloneFamily(cell));
                String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
                String value = Bytes.toString(CellUtil.cloneValue(cell));
                System.out.printf("行:%s  列族: %s  列名:  %s 值: %s%n", row, family, qualifier, value);
            }
        }
        table.close();
    }

    /**
     * 获取数据
     * @param conn 连接
     * @param tablename 表名
     * @param rowkey 行键
     * @throws IOException
     */
    public static void get(Connection conn, String tablename, String rowkey) throws IOException {
        get(conn,tablename,null,rowkey);
    }

    public static void main(String[] args) throws IOException, URISyntaxException {
        Connection conn = HbaseTest.getConn();
        HbaseTest.put(conn,"student","default","95001","s_course","yw","100");
        HbaseTest.put(conn,"student","default","95001","s_name","zw","小明");
        HbaseTest.get(conn,"student","95001");
    }
}

0 人点赞