HBase之api的基本运用(三)

直接上代码如下:

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> list
TABLE                                                                                                                                                                                  

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 could
be 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 leave
Safe mode is OFF
[centosm@centosm ~]$ hdfs dfsadmin -safemode enter
Safe mode is ON
[centosm@centosm ~]$ hdfs dfsadmin -safemode leave
Safe 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 == null
Here is some help for this command:
List all tables in hbase. Optional regular expression parameter could
be 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与主机名注释掉便可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值