HBase之api的基本运用(三)

来源:互联网 发布:java对称加密算法 编辑:程序博客网 时间:2024/05/23 16:35

直接上代码如下:

package com.hbase.demo;/** * Hbase 版本号:1.2.4 */import java.io.IOException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.*;import org.apache.hadoop.hbase.client.*;import org.apache.hadoop.hbase.util.Bytes;public class HBaseTest {    public static Configuration conf = null;    public static Admin admin;    public static Connection connection;    public static Table table;    static {        try {            conf = HBaseConfiguration.create();            connection = ConnectionFactory.createConnection(conf);            // -----这两个在hbase-site.xml的配置文件中配置好便不需要在这里进行重新配置了            // conf.set("hbase.zookeeper.quorum", "centosm");            // conf.set("hbase.rootdir", "hdfs://centosm:9000/hbase");            admin = connection.getAdmin();        } catch (IOException e) {            e.printStackTrace();        }    }    // 关闭连接    public static void close() {        try {            if (admin != null) {                admin.close();            }            if (null != connection) {                connection.close();            }            if (table != null){                table.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 创建一张表     * @param myTableName     * @param colFamily     * @param deleteFlag  true:存在则删除再重建     * @throws Exception     */    public static void creatTable(String myTableName, String[] colFamily, boolean deleteFlag) throws Exception {        TableName tableName = TableName.valueOf(myTableName);        if (admin.tableExists(tableName)) {            if (!deleteFlag) {                System.out.println(myTableName + " table exists!");            } else {                HBaseTest.deleteTable(myTableName); // 先删除原先的表                HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);                for (String str : colFamily) {                    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);                    hTableDescriptor.addFamily(hColumnDescriptor);                }                admin.createTable(hTableDescriptor);                System.out.println(myTableName + "表创建成功。。。");            }        } else {            HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);            for (String str : colFamily) {                HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);                hTableDescriptor.addFamily(hColumnDescriptor);            }            admin.createTable(hTableDescriptor);            System.out.println(myTableName + "表创建成功。。。");        }        //close();    }    /**     * 往表中添加数据(单条添加)     */    public static void inserData(String myTableName, String rowKey, String colFamily, String col, String val) {        try {            table = connection.getTable(TableName.valueOf(myTableName));            Put put = new Put(Bytes.toBytes(rowKey));            put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(val));            table.put(put);            System.out.println("数据插入成功。。。rowkey为:" + rowKey);        } catch (IOException e) {            e.printStackTrace();        } finally {            //close();        }    }    /**     * 往表中批量添加数据     */    public static void batchInserData(String myTableName, String colFamily, String col, int insertNum) {        try {            table = connection.getTable(TableName.valueOf(myTableName));            List<Put> list = new ArrayList<Put>();            Put put;            for (int i = 0; i < insertNum; i++) {                put = new Put(Bytes.toBytes("rowKey" + i));                put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes("110804" + i));                list.add(put);            }            table.put(list);            System.out.println("数据插入成功。。。");        } catch (IOException e) {            e.printStackTrace();        } finally {            // close();        }    }    /**     * 获取数据(根据行键获取其整行数据)     */    public static void getDataFromRowKey(String myTableName, String rowKey) {        try {            table = connection.getTable(TableName.valueOf(myTableName));            Get get = new Get(Bytes.toBytes(rowKey));            Result re = table.get(get);            List<Cell> listCells = re.listCells();            for (Cell cell : listCells) {                System.out.println(new String(CellUtil.cloneRow(cell)) + "\t" + new String(CellUtil.cloneFamily(cell))                        + "\t" + new String(CellUtil.cloneQualifier(cell)) + "\t"                        + new String(CellUtil.cloneValue(cell)) + "\t" + cell.getTimestamp());            }        } catch (IOException e) {            e.printStackTrace();        } finally {            //close();        }    }    /**     * 根据表名与行键及列簇获取数据     * @param myTableName     * @param rowKey     * @param colFamily     * @param Col     * @throws IOException     */    private static void getData(String myTableName, String rowKey, String colFamily, String col) throws IOException {        table = connection.getTable(TableName.valueOf(myTableName));        Get get = new Get(Bytes.toBytes(rowKey));        get.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col));        Result re = table.get(get);        if (re.isEmpty()){            System.out.println("查询结果为空。。。。");            return;        }        List<Cell> listCells = re.listCells();        for (Cell cell : listCells) {            System.out.println(new String(CellUtil.cloneRow(cell)) + "\t" + new String(CellUtil.cloneFamily(cell))                    + "\t" + new String(CellUtil.cloneQualifier(cell)) + "\t"                    + new String(CellUtil.cloneValue(cell)) + "\t" + cell.getTimestamp());        }       // close();    }    /**     * 根据表名查询整张表的数据(当然同样可根据列簇,列分割符等进行scan的查询,这里不进行细写了)     * @param tablename     * @throws IOException     */    private static void getScanData(String tablename) throws IOException {        table = connection.getTable(TableName.valueOf(tablename));        ResultScanner scanner = table.getScanner(new Scan());        Iterator<Result> it = scanner.iterator();        while(it.hasNext()) {            Result re = it.next();            List<Cell> listCells = re.listCells();            for (Cell cell : listCells) {                System.out.println(new String(CellUtil.cloneRow(cell)) + "\t" + new String(CellUtil.cloneFamily(cell))                        + "\t" + new String(CellUtil.cloneQualifier(cell)) + "\t"                        + new String(CellUtil.cloneValue(cell)) + "\t" + cell.getTimestamp());            }        }    }    /**     * 删除数据     * @param tableName     * @param rowKey     * @throws IOException      */    private static void delDByRowKey(String tableName, String rowKey) {        try {            table = connection.getTable(TableName.valueOf(tableName));            Delete delete = new Delete(Bytes.toBytes(rowKey));            table.delete(delete);        } catch (IOException e) {            e.printStackTrace();        }        System.out.println(tableName + " 表中rowKey为 " + rowKey + " 的数据已被删除....");    }    /**     * 删除一张表     *      * @param args     */    public static void deleteTable(String myTableName) {        try {            TableName tableName = TableName.valueOf(myTableName);            admin.disableTable(tableName); // 删除表前先对表进行disable            admin.deleteTable(tableName);            System.out.println(tableName + " 表已被删除。。。");        } catch (IOException e) {            e.printStackTrace();        }  finally {            close();        }    }    /**     * 删除列簇     *      * @param args     */    public static void deleteColumnFamily(String myTableName, byte[] colFamily) {        try {            TableName tableName = TableName.valueOf(myTableName);            admin.disableTable(tableName); // 删除前先对表进行disable            admin.deleteColumn(tableName, colFamily);            System.out.println(tableName + " 表 " + colFamily + " 列已被删除。。。");        } catch (IOException e) {            e.printStackTrace();        } finally {            close();        }    }    public static void main(String[] args) {        try {                // 创建表                String tablename = "student"; //              String[] familys = { "grade","course" };//              boolean booleanFlog = true;//              HBaseTest.creatTable(tablename, familys, booleanFlog);//           //              /**//               * 往表中插入数据:插入数据的时候指定数据所属的列簇与列分割符//               *///              //               String rowKey = "ycb"; //               String colFamily = "course"; //               String col = "English"; //               String val = "88";//               //               String rowKey2 = "hehe"; //               String val2 = "89";//               //               HBaseTest.inserData(tablename, rowKey, colFamily, col, val);//               HBaseTest.inserData(tablename, rowKey2, colFamily, col, val2);//               ////              /**//               * 根据表名与行键查询整行数据//               *///              //               HBaseTest.getDataFromRowKey(tablename, rowKey);//               HBaseTest.getDataFromRowKey(tablename, rowKey2);//               //              //              /**//               * 根据表名与行键及列簇获取数据//               *///              colFamily = "course";//              col = "English";//              HBaseTest.getData(tablename, rowKey, colFamily, col);//              /**//               * 查询整张表的数据//               *///              HBaseTest.getScanData(tablename);//              //              /**//               * 根据rowkey删除指定数据//               *///              String rowKey = "ycb";//              HBaseTest.delDByRowKey(tablename, rowKey);//              /**//               * 批量插入数据//               *///              String colFamily = "grade"; //              String col = "sid";//              int inserNum = 10;//              HBaseTest.batchInserData(tablename, colFamily, col, inserNum);//              //              /**//               * 删除列簇//               *///              /*//               * String tablename = "scores3"; //               * byte[] colFamily = Bytes.toBytes("course"); //               * HBaseTest.deleteColumnFamily(tablename, colFamily);//               *///              /**//                * 删除表//                *///            String tablename = "scores"; //            HBaseTest.deleteTable(tablename);        } catch (Exception e) {            e.printStackTrace();        }    }}

Hbase 在Eclipse中环境的搭建步骤如下:
一、前提环境:
特别注意:在win系统下将集群主机名与ip地址写到hosts中
路径:C:\Windows\System32\drivers\etc 下的HOSTS文件
如下将集群的ip与主机名追加到win 的 HOSTS文件
192.168.2.125 centosm

  在虚拟机中搭建的伪分布集群,主机名为centosm  启动hadoop与hbase  在浏览器中访问hbase看否启动成功  地址如下:http://centosm:16010/master-status 

这里写图片描述

二、开始调在Eclipse中调用Hbase的Api

1、在eclipse里新建一个Java项目HBaseDemo,由于只是测试,就简单一点,将所有的集群中Hbase Lib 目录下的JAR选上都放到Java项目中。2、在项目HBaseDemo 下增加一个文件夹conf,将Hbase集群的配置文件hbase-site.xml复制到该目录,然后选择项目属性在Libraries->Add Class Folder,将刚刚增加的conf目录选上。hbase-site.xml
<configuration> <property>   <name>hbase.rootdir</name>  <!-- <value>file:///home/centosm/hbase/data</value> -->       <value>hdfs://centosm:9000/hbase</value> </property> <property>    <name>hbase.zookeeper.quorum</name>    <value>centosm</value> </property></configuration>
3、完成上述便可以像普通项目开发了(笔者的集群是在linux下搭建的伪分布集群,Eclipse是在win10下的)

==============================================

在开发过程遇到的一些小问题及解决方法
1、运行程序时输入如下错误:
org.apache.hadoop.hbase.client.RetriesExhaustedException
Caused by: java.net.UnknownHostException: centosm

解决:
如下将集群的ip与主机名追加到win 的 HOSTS文件
192.168.2.125 centosm

2、在linux中运行时出现如下错:

hbase(main):002:0> listTABLE                                                                                                                                                                                  ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not running yet    at org.apache.hadoop.hbase.master.HMaster.checkServiceStarted(HMaster.java:2286)    at org.apache.hadoop.hbase.master.MasterRpcServices.isMasterRunning(MasterRpcServices.java:931)    at org.apache.hadoop.hbase.protobuf.generated.MasterProtos$MasterService$2.callBlockingMethod(MasterProtos.java:55654)    at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2180)    at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:112)    at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(RpcExecutor.java:133)    at org.apache.hadoop.hbase.ipc.RpcExecutor$1.run(RpcExecutor.java:108)    at java.lang.Thread.run(Thread.java:745)Here is some help for this command:List all tables in hbase. Optional regular expression parameter couldbe used to filter the output. Examples:  hbase> list  hbase> list 'abc.*'  hbase> list 'ns:abc.*'  hbase> list 'ns:.*'

解决:hdfs dfsadmin -safemode leave 退出安全模式
查看安全模式状态相关的命令如下:

[centosm@centosm ~]$ hdfs dfsadmin -safemode get Safe mode is ON[centosm@centosm ~]$ hdfs dfsadmin -safemode leaveSafe mode is OFF[centosm@centosm ~]$ hdfs dfsadmin -safemode enterSafe mode is ON[centosm@centosm ~]$ hdfs dfsadmin -safemode leaveSafe mode is OFF[centosm@centosm ~]$ hdfs dfsadmin -safemode get Safe mode is OFF 

3、
hbase(main):002:0> list 出现下列错误

ERROR: Can't get master address from ZooKeeper; znode data == nullHere is some help for this command:List all tables in hbase. Optional regular expression parameter couldbe used to filter the output. Examples: 

出现此问题可能是zookeeper不稳定造成的,采用的是虚拟机,经常挂起的状态,使用Hbase的list命令出现下面错误,这个可能是hbase的稳定性造成的,解决办法有两种。这里使用第一种办法就解决了。

解决方法:

方法1.重启hbase
问题解决。

方法2:格式化namenode
将namenode的信息删除,重新格式化
重新启动,hbase正常

4、在Eclipse 运行程序出现的错误

ERROR org.apache.hadoop.hbase.client.AsyncProcess  - Failed to get region location   java.io.IOException: Failed to get result within timeout, timeout=60000ms      at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas.call(ScannerCallableWithReplicas.java:206)      at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas.call(ScannerCallableWithReplicas.java:60)      at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithoutRetries(RpcRetryingCaller.java:210)  

笔者在虚拟机上搭了一个hadoop伪分布式的环境,在虚拟服务器上 /etc/hosts 配置如下:
[centosm@centosm ~]$ more /etc/hosts
192.168.0.108 centosm
192.168.22.125 centosm

在win10 中的hosts方件最后加像linux中的添加了这两个地址,如下所示:
192.168.22.125 centosm
192.168.0.108 centosm

注意:因为笔者的在公司环境与在家里的环境的ip地址不一样,所以上面不同 ip 地址对应的主机名是一样的,这样配置在linux环境中是没有任何问题的,但是win10是支持这么配置的。
解决方式:暂时将win10上用不上的ip与主机名注释掉便可。

原创粉丝点击