实验二十三 新建HBase表

4 篇文章 0 订阅
3 篇文章 0 订阅

实验指导:

23.1 实验目的

1. 掌握HBase数据模型(逻辑模型及物理模型);

2. 掌握如何使用Java代码获得HBase连接,并熟练Java对HBase数据库的基本操作,进一步加深对HBase表概念的理解。

23.2 实验要求

通过Java代码实现与HBase数据库连接,然后用Java API创建HBase表,向创建的表中写数据,最后将表中数据读取出来并展示。

23.3 实验原理

逻辑模型:HBase以表的形式存储数据,每个表由行和列组成,每个列属于一个特定的列族(Column Family)。表中的行和列确定的存储单元称为一个元素(Cell),每个元素保存了同一份数据的多个版本,由时间戳(Time Stamp)来标识。行健是数据行在表中的唯一标识,并作为检索记录的主键。在HBase中访问表中的行只有三种方式:通过单个行健访问、给定行键的范围扫描、全表扫描。行健可以是任意字符串,默认按字段顺序存储。表中的列定义为: :(<列族>:<限定符>),通过列族和限定符两部分可以唯一指定一个数据的存储列。元素由行健、列(<列族>:<限定符>)和时间戳唯一确定,元素中的数据以字节码的形式存储,没有类型之分。

物理模型:HBase是按照列存储的稀疏行/列矩阵,其物理模型实际上就是把概念模型中的一个行进行分割,并按照列族存储。

23.4 实验步骤

本实验主要演示HBase Java API的一些基本操作,包括取得链接,创建表,写数据,查询等几个步骤,具体内容如下:

首先,启动HBase集群(参考实验二十二)。

其次,从HBase安装包的lib目录导入如下jar包到开发工具(jar包的版本号以实际的安装中的版本号为主):

commons-codec-1.4.jar
commons-collections-3.2.2.jar
commons-configuration-1.6.jar
commons-lang-2.6.jar
commons-logging-1.2.jar
guava-12.0.1.jar
hadoop-auth-2.7.2.jar
hadoop-common-2.7.2.jar
hadoop-hdfs-2.7.2.jar
hbase-client-1.1.2.jar
hbase-common-1.1.2.jar
hbase-protocol-1.1.2.jar
htrace-core-3.1.0-incubating.jar
httpclient-4.4.jar
httpcore-4.4.jar
libfb303-0.9.2.jar
log4j-1.2.17.jar
metrics-core-2.2.0.jar
netty-all-4.0.23.Final.jar
protobuf-java-2.5.0.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.6.4.jar
zookeeper-3.4.6.jar

然后,获得HBase连接,代码实现:

Configuration configuration = HBaseConfiguration.create();
Connection connection;
configuration.set("hbase.zookeeper.quorum", "slave1:2181,slave2:2181,slave3:2181");
configuration.set("zookeeper.znode.parent", "/hbase");
connection = ConnectionFactory.createConnection(configuration);

然后,通过连接实现对HBase数据库的一些基本操作,如下:

新建HBase表,代码实现:

//获得HBaseAdmin对象
Admin admin = connection.getAdmin();
//表名称
String tn = "mytable";
TableName tableName = TableName.valueOf(tn);
//表不存在时创建表
if(!admin.tableExists(tableName))
{
   //创建表描述对象
   HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
   //列簇1
   HColumnDescriptor columnDescriptor1 = new HColumnDescriptor("c1".getBytes());
   tableDescriptor.addFamily(columnDescriptor1);
   //列簇2
   HColumnDescriptor columnDescriptor2 = new HColumnDescriptor("c2".getBytes());
   tableDescriptor.addFamily(columnDescriptor2);
   //用HBaseAdmin对象创建表
   admin.createTable(tableDescriptor);
}
//关闭HBaseAdmin对象
admin.close();

向表put数据,代码实现:

//获得table接口
Table table = connection.getTable(TableName.valueOf("mytable"));
//添加的数据对象集合
List<Put> putList = new ArrayList<Put>();
//添加10行数据
for(int i=0; i<10; i++)
{
   //put对象(rowkey)
   String rowkey = "mykey" + i;
   Put put = new Put(rowkey.getBytes());
   //列簇 , 列名, 值
   put.addColumn("c1".getBytes(), "c1tofamily1".getBytes(), ("aaa"+i).getBytes());
   put.addColumn("c1".getBytes(), "c2tofamily1".getBytes(), ("bbb"+i).getBytes());
   put.addColumn("c2".getBytes(), "c1tofamily2".getBytes(), ("ccc"+i).getBytes());
   putList.add(put);
}
table.put(putList);
table.close();

查询数据,代码实现:

//获得table接口(这行代码注意取舍,如果查询的代码和插入代码在同一个类中,则可以不要下面的这行)
Table table = connection.getTable(TableName.valueOf("mytable"));
//Scan 对象
Scan scan = new Scan();
//限定rowkey查询范围
scan.setStartRow("mykey0".getBytes());
scan.setStopRow("mykey9".getBytes());
//只查询c1:c1tofamily1列
scan.addColumn("c1".getBytes(), "c1tofamily1".getBytes());
//过滤器集合
FilterList filterList = new FilterList();
//查询符合条件c1:c1tofamily1==aaa7的记录
Filter filter1 = new SingleColumnValueFilter("c1".getBytes(), "c1tofamily1".getBytes(), 
CompareFilter.CompareOp.EQUAL, "aaa7".getBytes());
filterList.addFilter(filter1);
scan.setFilter(filterList);
ResultScanner results = table.getScanner(scan);
for (Result result : results) {  
    System.out.println("获得到rowkey:" + new String(result.getRow()));
    for (Cell cell : result.rawCells()) {
        System.out.println("列簇:" + 
            Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength()) + "列:" + 
            Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength()) + "值:" +
            Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
    }
}
results.close();
table.close();

最后,将Java代码打成jar包,并上传到客户端执行。

java -jar HbaseTest.jar

附件:完整代码如下:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        Configuration configuration = HBaseConfiguration.create();
        Connection connection;
        configuration.set("hbase.zookeeper.quorum", "slave1:2181,slave2:2181,slave3:2181");
        configuration.set("zookeeper.znode.parent", "/hbase");
        try {
            connection = ConnectionFactory.createConnection(configuration);
            //获得HBaseAdmin对象
            Admin admin = connection.getAdmin();
            //表名称
            String tn = "mytable";
            TableName tableName = TableName.valueOf(tn);
            //表不存在时创建表
            if (!admin.tableExists(tableName)) {
                //创建表描述对象
                HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
                //列簇1
                HColumnDescriptor columnDescriptor1 = new HColumnDescriptor("c1".getBytes());
                tableDescriptor.addFamily(columnDescriptor1);
                //列簇2
                HColumnDescriptor columnDescriptor2 = new HColumnDescriptor("c2".getBytes());
                tableDescriptor.addFamily(columnDescriptor2);
                //用HBaseAdmin对象创建表
                admin.createTable(tableDescriptor);
            }
            //关闭HBaseAdmin对象
            admin.close();
            //向表put数据,代码实现:
            //获得table接口
            Table table = connection.getTable(TableName.valueOf("mytable"));
            //添加的数据对象集合
            List<Put> putList = new ArrayList<Put>();
            //添加10行数据
            for (int i = 0; i < 10; i++) {
                //put对象(rowkey)
                String rowkey = "mykey" + i;
                Put put = new Put(rowkey.getBytes());
                //列簇 , 列名, 值
                put.addColumn("c1".getBytes(), "c1tofamily1".getBytes(), ("aaa" + i).getBytes());
                put.addColumn("c1".getBytes(), "c2tofamily1".getBytes(), ("bbb" + i).getBytes());
                put.addColumn("c2".getBytes(), "c1tofamily2".getBytes(), ("ccc" + i).getBytes());
                putList.add(put);
            }
            table.put(putList);
            table.close();
            //查询数据,代码实现:
            //获得table接口
            //Scan 对象
            Scan scan = new Scan();
            //限定rowkey查询范围
            scan.setStartRow("mykey0".getBytes());
            scan.setStopRow("mykey9".getBytes());
            //只查询c1:c1tofamily1列
            scan.addColumn("c1".getBytes(), "c1tofamily1".getBytes());
            //过滤器集合
            FilterList filterList = new FilterList();
            //查询符合条件c1:c1tofamily1==aaa7的记录
            Filter filter1 = new SingleColumnValueFilter("c1".getBytes(), "c1tofamily1".getBytes(), CompareFilter.CompareOp.EQUAL, "aaa7".getBytes());
            filterList.addFilter(filter1);
            scan.setFilter(filterList);
            ResultScanner results = table.getScanner(scan);
            for (Result result : results) {
                System.out.println("获得到rowkey:" + new String(result.getRow()));
                for (Cell cell : result.rawCells()) {                    
                    System.out.println("列簇:" +
                        Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()) + "列:" +
                        Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()) + "值:" +
                        Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                }
            }
            results.close();
            table.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

23.5 实验结果

表创建完,然后添加数据后,可以通过shell查看mytable表数据,共插入10条数据,数据内容如图23-1所示。

图23-1 HBase Shell界面图

客户端提交jar包后,运行Java代码打印的日志信息如图23-2所示(日志中可能会出现乱码,这个没有关系,不影响实验结果的查看)。

图23-2 Java代码执行结果图

实验操作:

步骤1:搭建HBase集群

本实验主要演示HBase的安装部署过程,因HBase依赖于HDFS和Zookeeper,所以该实验需要分为四个步骤。

首先,配置SSH无密钥登录(参考实验1)。

其次,安装Hadoop集群(参考实验2)。

然后,安装Zookeeper集群(参考实验20)。

最后,修改HBase配置文件,具体内容如下:

将HBase 安装包hbase.1.1.2.tar.gz解压到/usr/cstor目录,并将hbase.1.1.2目录改名为hbase,且所属用户改成root:root。

[root@master ~]#tar -zxvf hbase.1.1.2.tar.gz -c /usr/cstor/hbase
[root@master ~]#mv /usr/cstor/hbase.1.1.2 /usr/cstor/hbase
[root@master ~]#chown -R root:root /usr/cstor/hbase

进入解压目录下,配置conf目录下的/usr/cstor/hbase/conf/hbase-env.sh文件,设置如下:

#Java安装路径 export JAVA_HOME=/usr/local/jdk1.7.0_79 (需根据实际情况指定) #不使用HBase自带的Zookeeper

export HBASE_MANAGES_ZK=false

配置conf目录下的hbase-site.xml文件,设置如下:

<configuration>
   <property>
      <name>hbase.rootdir</name>
      <value>hdfs://master:8020/hbase</value>
   </property>
   <property>
      <name>hbase.cluster.distributed</name>
      <value>true</value>
   </property>
   <property>
      <name>hbase.zookeeper.quorum</name>
      <value>slave1,slave2,slave3</value>
   </property>
   <property>
      <name>hbase.tmp.dir</name>
      <value>/usr/cstor/hbase/data/tmp</value>
   </property>
</configuration>

配置conf目录下的regionservers文件,设置如下:

slave1
slave2
slave3

配置完成后,将hbase目录传输到集群的其它节点。

scp -r /usr/cstor/hbase root@slave1:/usr/cstor
scp -r /usr/cstor/hbase root@slave2:/usr/cstor
scp -r /usr/cstor/hbase root@slave3:/usr/cstor

接着,启动HBase,并简单验证HBase,如下:

在主节点master进入hbase解压目录的bin目录,启动HBase服务进程(已启动Zookeeper):

[root@master ~]#cd /usr/cstor/hbase/bin
[root@master ~]#./start-hbase.sh

步骤2:编写HBase建表程序

步骤3:打包程序(打包一定注意要先执行一次代码,再打成Runnable JAR file包)

步骤4:运行程序

步骤5:验证运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值