HBase安装及使用

第一部分:搭建
一、伪分布式:

  • 1.依赖java环境,所以jdk必须先安装
  • 2.conf先的hbase-env.sh 下的java_home的路径需要修改
  • 3.修改hbase-site.xml
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///home/testuser/hbase</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/home/testuser/zookeeper</value> //hbase 自带有zookeeper。
  </property>
</configuration>

开启:start-hbase.sh 关闭:stop-hbase.sh

  • 1.文本页测试访问:http://node01:60010
  • 2.启动命令行:hbase shell
  • 3.查看表:list
  • 4.创建表:create ‘chen’,’cf1’
  • 5.放数据:
put 'table01','111','cf1:age','22'

获取信息的方式:

  • 1.全盘扫描:scan ‘table01’ (生产环境慎重)
  • 2.可用:get ‘table01’,’111’,’cf1:name’

hbase shell 客户端基本用法:
建完表放完数据后,需要刷写才可以到磁盘。flush ‘table’
备注:
如果想同时放多个列簇到表中是不可以的。一个一个放入。
命令通过help 提示操作即可。

二、完全分布式:
搭建计划:
node01作为Hmaster node02作为backupMaster
其中node02,node03,node04作为region Server 。

步骤:

1.检查 hosts jdk  iptables
2.免密钥
3.上传/解压
4.配置相关配置文件
a.配置JAVA_HOME  到 hbase-env.hs
b.配置:hbase-site.xml
c.配置:regionserver
d.配置:back-master
e:复制:hdfs-site.xml 到hbase的conf下

具体操作:
4.hbase-site.xml 配置如下:

<property>
 25     <name>hbase.rootdir</name>
 26     <value>hdfs://mycluster/hbase</value> // hdfs 的连接逻辑入口
 27   </property>
 28   <property>
 29     <name>hbase.cluster.distributed</name>
 30     <value>true</value> // 设置可分区
 31   </property>
 32   <property>
 33     <name>hbase.zookeeper.quorum</name>
 34     <value>node02,node03,node04</value> // zk的位置
 35   </property>

修改:hbase-env.sh

 export JAVA_HOME=/usr/java/jdk1.7.0_79/ //jdk的实际路径

 export HBASE_MANAGES_ZK=false // 设置支持多节点zookeeper

修改:regionservers 表示自己的regionserver在哪儿。

  1 node02
  2 node03
  3 node04

修改: backup-masters(若无则新建) 备master的位置

node02 

测试:启动集群,先启动hadoop。启动前需要先启动zookeeper,
对node02,node03,node04进行:zkServer.sh start
然后对node01启动start-all.sh 启动整个集群。
最后单独启动yarn。对node03和node04进行,yarn-deamon.sh start resourcemanager
最后启动hbase。start-hbase.sh
检查端口使用情况,ss -nal 的端口。其中node01 必须包含2181(hbase自带的zk的),以及60010,hbase提供的webUI的端口。
测试:访问http://node01:60010
备注:几个集群时间需要同步。如果不同步会出现看不到regionserver的情况。

第二部分:HBase的使用:
一.基本的用法

  • 1.创建表
    create 'table01', 'cf1','cf2' // 表名 列簇1 列簇2
  • 2.删除表
    删除前设置表为disable
    1.disable 'table01'
    2.drop 'table01'

    3.查看表属性
    desc 'table01'
    4.强制分区
    split 'tab'

分析:

  • BLOCKSIZE => ‘65536’, IN_MEMORY => ‘false’, BLOCKCACHE => ‘true’
    BLOCKCACHE 为读缓存 IN_MEMORY:是否放入缓存
  • TTL => ‘FOREVER’ 含义:time to alived 有效期设置

4.放入数据
put 'table01', '121','cf1:name','chenx'
注意:只可以一个列簇一个列簇的放
5.对生成的文件分析
对伪分布式搭建完成后创建的hbase下的目录下文件进行分析:
cd /home/testuser/hbase/data/default/table01
发现有文件:5dfa5a1b17160b22ec60ad078f0f7a62
此文件就是region 再跟进去就会发现cf1 列簇。或者在webUI上看。
再进入列簇后如果刷写了,可发现hfile文件(如果未满128M,手动刷写:flush ‘table’),刷写后打开hfile文件的方式:hbase hfile -p -f ‘fileName’

第三部分:HBase的介绍及设计思想:
一.HBase 简介

  • 1.Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、实时读写的分布式数据库

  • 2.利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为其分布式协同服务

  • 3.主要用来存储非结构化和半结构化的松散数据(列存 NoSQL 数据库)

二.HBase的数据模型:
这里写图片描述
具体分析:

ROW KEY

  • 1.决定一行数据
  • 2.按照字典顺序排序的。
  • 3.Row key只能存储64k的字节数据

Timestamp时间戳

  • 1.在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。超过版本书后再次插入新数据,最下面的数据就会别标记为失效。后期被处理掉。多版本类似:update 操作。

  • 2.时间戳的类型是 64位整型。

  • 3.时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。

  • 4.时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。

Column Family列族 & qualifier列

  • 1.HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;

  • 2.列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需、动态加入;

  • 3.权限控制、存储以及调优都是在列族层面进行的;

  • 4.HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。

Cell单元格

  • 1.由行和列的坐标交叉决定;

  • 2.单元格是有版本的;

  • 3.单元格的内容是未解析的字节数组;
    由{row key, column( = +), version} 唯一确定的单元。
    cell中的数据是没有类型的,全部是字节码形式存贮。

HLog(WAL log)
HBase 里只有2种文件,日志文件和数据文件。日志文件为了提高数据可靠性。
如果写操作,日志文件如果完成了,说明写操作无误。

  • 1.HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是” 写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。

  • 2.HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue。

HBase 架构
这里写图片描述

整体分析: 主节点:Hmaster (对regionServer做负载均衡)

Client
包含访问HBase的接口并维护cache来加快对HBase的访问

Zookeeper

  • 1.保证任何时候,集群中只有一个master
  • 2.存贮所有Region的寻址入口。
  • 3.实时监控Region server的上线和下线信息。并实时通知Master
    存储HBase的schema和table元数据

Master

  • 1.为Region server分配region
  • 2.负责Region server的负载均衡(5min/次)
  • 3.发现失效的Region server并重新分配其上的region
  • 4.管理用户对table的增删改操作

RegionServer

  • 1.Region server维护region,处理对这些region的IO请求
  • 2.Region server负责切分在运行过程中变得过大的region

Region

  • 1.HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据

  • 2.每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region(裂变)

  • 3.table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。

Memstore 与 storefile

  • 1.一个region由多个store组成,一个store对应一个CF(列族)
    store包括位于内存中的memstore和位于磁盘的storefile写操作先写入memstore,当memstore中的数据达到某个阈值,hregionserver会启动flashcache进程写入storefile,每次写入形成单独的一个storefile

  • 2.当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction),在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile

  • 3.当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
    客户端检索数据,先在memstore找,找不到再找storefile

Hfile文件:
由索引+数据,先加载索引数据到内存,再根据索引去查。把索引器交给hdfs客户端去查。

备注:

  • 0.客户端通过zookeeper访问Master分配其到具体的哪个regionserver上。(从zookeeper里的一个.mete的文件里查)zookeeper里存放客户端请求时到达的位置信息。当到达regionserver上的region的时候,会先记录下Hlog上,然后直接将Hlog落地到HDFS上,然后再把数据写到memstore内存缓冲区上。

  • 1.当bigtable的数据达到10G(可设置)后会自动拆分成多个region。

  • 2.当zookeeper检测到regionSever和Hmaster断开连接1.5分钟的时候会告诉Hmaster启动其他regionserver,并通过日志文件恢复。
  • 3.memstore满128M的时候会溢写然后落地磁盘。每个列簇里超过3个文件就会进行一次小合并。7天进行一次大合并,把集群里的所有的列簇进行合并。
  • 4.对HLog文件而言,有进程检测其如果已经被刷写到磁盘上了,就会把它放在一个较old的文件夹里。再此检查被刷写的文件超过10分钟后自动删除它。

  • 5.一个stroefile对应着HDFS上一个文件。

  • 6.memstore作为写缓存操作。其实也有一部分作为读缓存,比如,当memstore里的数据达到一定阈值的时候,就会溢写,在溢写完缓存区还有一部分缓存,客户端访问会先访问memstore的缓存里读取,如果没有再去storefile文件里读。但是memstore主要就是做写缓存的操作。读缓存有专门的部分去做(blockcache),一般先从memcache写缓存里找,没有再去读缓存里找。最后落实到hdfs上。

第四部分:Protobuf工具:
一、简介

  • 1.Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。
  • 2.Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

二、安装
整体的安装步骤:

 1.tar -xzf protobuf-2.1.0.tar.gz 
 2.cd protobuf-2.1.0 
 3.   ./configure --prefix=$INSTALL_DIR 
 4.make 
 5.make check 
 6.make install

对第三步,的configure会检查软硬件环境并生成相应的文件。编译需要工具。如下
编译环境准备yum groupinstall -y Development tools

三、使用
检查protoc的位置。whereis protoc
/usr/local/bin/protoc

  1 package com.jw.hbase;
  2 message phoneDetil{
  3 required string dum=1;
  4 required string date=2;
  5 required string type=3;
  6 }
  9 message dayPhoneDetils{
 10 repeated phoneDetil phonoeDetils=1;
 11 }

运行:/usr/local/bin/protoc phone.proto --java_out=./
在当前目录下会看到对应的,com/jw/hbase的文件夹里的文件。

第五部分:案例代码分析:
以下为对hbase基本的ddl以及dml等操作。

public class HBaseDemoTest {
    Configuration conf = null;
    HBaseAdmin admin = null;
    String cx = "chenshixingkong";
    HTable tab = null;
    Random r = new Random();

    @Before
    public void before() throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
        conf = new Configuration();
        conf.set("hbase.zookeeper.quorum", "node02,node03,node04");
        admin = new HBaseAdmin(conf);
        tab = new HTable(conf, cx.getBytes());
    }

    @After
    public void end() throws IOException {
        if (admin != null) {
            admin.close();
        }
    }

    /**
     * 创建表
     * 
     * @throws IOException
     */
    @Test
    public void createTable() throws IOException {
        HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(cx.getBytes()));
        HColumnDescriptor cf = new HColumnDescriptor("cf".getBytes());
        cf.setInMemory(true); // 放入内存
        desc.addFamily(cf);
        admin.createTable(desc);
    }

    /**
     * 插入数据 如果插入多条,创建多个put对象即可。
     * 
     * @throws InterruptedIOException
     * @throws RetriesExhaustedWithDetailsException
     */
    @Test
    public void put() throws RetriesExhaustedWithDetailsException, InterruptedIOException {
        Put put = new Put("001".getBytes()); // 添加表名
        put.add("cf".getBytes(), "name".getBytes(), "chenxiao".getBytes()); // 添加列簇、列簇key和value
        tab.put(put);
    }

    /**
     * get 查询
     * 
     * @throws IOExceptio
     */
    @Test
    public void getDB() throws IOException {
        Get get = new Get("001".getBytes());
        get.addFamily("cf".getBytes());
        Result result = tab.get(get);
        Cell cell = result.getColumnLatestCell("cf".getBytes(), "name".getBytes()); // 获取最新版本
        byte[] clone = CellUtil.cloneValue(cell); // 将单元格转换成字节数组
        System.out.println(new String(clone));
    }

    /**
     * 生成数据操作:10个用户,每个用户100条
     * 
     * @throws ParseException
     * @throws InterruptedIOException
     * @throws RetriesExhaustedWithDetailsException
     */
    @Test
    public void insertDB() throws ParseException, RetriesExhaustedWithDetailsException, InterruptedIOException {
        List<Put> list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            String pNum = getPhoneNum("186");
            for (int j = 0; j < 100; j++) {
                /** ===================rowkey等属性的准备Begin=================== **/
                // 对方手机号
                String dNum = getPhoneNum("177");
                // 通话日期
                String dateStr = getDate("2017");
                // 主被叫类型
                String type = r.nextInt(2) + "";
                // rowkey
                SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
                String rowkey = pNum + "_" + (Long.MAX_VALUE - format.parse(dateStr).getTime());
                /** ===================rowkey等属性的准备End=================== **/
                /** ---1:处理rowkey,将rowkey放入put中--- **/
                Put put = new Put(rowkey.getBytes());
                /** ---2:处理列簇--- **/
                put.add("cf".getBytes(), "dNum".getBytes(), dNum.getBytes());
                put.add("cf".getBytes(), "type".getBytes(), type.getBytes());
                put.add("cf".getBytes(), "date".getBytes(), dateStr.getBytes());
                /** ---3:put对象放入list集合中--- **/
                list.add(put);
            }
        }
        /** ---4:集合放入表中--- **/
        tab.put(list);
    }

    /**
     * 根据手机号查询某个月的通话记录 按rowkey的开始和结束查找
     * 
     * @throws IOException
     * @throws ParseException
     */
    @Test
    public void scan() throws IOException, ParseException {
        /** 1.设置起始点 **/
        Scan scan = new Scan();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String startRow = "18610663898" + "_" + (Long.MAX_VALUE - format.parse("20170301000000").getTime());
        String stopRow = "18610663898" + "_" + (Long.MAX_VALUE - format.parse("20170201000000").getTime());
        scan.setStartRow(startRow.getBytes());
        scan.setStopRow(stopRow.getBytes());
        /** 2.查询 **/
        ResultScanner scanner = tab.getScanner(scan);
        /** 2.遍历查询的结果 **/
        for (Result r : scanner) {
            System.out
                        .print(new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
            System.out.print(
                    " - " + new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "dNum".getBytes()))));
            System.out.println(
                    " - " + new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
        }
    }

    /**
     * 某个用户 所有主叫通话记录 过滤器的使用
     * 
     * @throws IOException
     */
    @Test
    public void scan2() throws IOException {
        Scan scan = new Scan();
        FilterList list = new FilterList(Operator.MUST_PASS_ALL);
        PrefixFilter prefixFilter = new PrefixFilter("18699440769".getBytes());
        SingleColumnValueFilter filter = new SingleColumnValueFilter("cf".getBytes(), "type".getBytes(),
                CompareOp.EQUAL, "1".getBytes());
        list.addFilter(prefixFilter);
        list.addFilter(filter);
        scan.setFilter(list);
        ResultScanner scanner = tab.getScanner(scan);
        for (Result r : scanner) {
            System.out.print(new String(CellUtil.cloneRow(r.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
            System.out.print(
                    "-" + new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
            System.out.print(
                    " - " + new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "dNum".getBytes()))));
            System.out.println(
                    " - " + new String(CellUtil.cloneValue(r.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
        }
    }

    /**
     * 获取电话号码
     * 
     * @param prefix
     * @return
     */
    public String getPhoneNum(String prefix) {
        return prefix + String.format("%08d", r.nextInt(99999999));
    }

    /**
     * 获取日期
     * 
     * @param year
     * @return
     */
    public String getDate(String year) {
        return year + String.format("%02d%02d%02d%02d%02d",
                new Object[] { r.nextInt(12) + 1, r.nextInt(28) + 1, r.nextInt(24), r.nextInt(60), r.nextInt(60) });
    }

}

序列化和反序列化操作:

public class HBasedemo_new {

    String TN = "phone";

    HBaseAdmin admin;
    HTable htable;

    @Before
    public void before() throws Exception {
        Configuration conf = new Configuration();
        // 完全分布式HBase集群 指定ZooKeeper集群地址
        // 伪分布式 单独指定那一台HBase节点
        conf.set("hbase.zookeeper.quorum", "node02,node03,node04");

        admin = new HBaseAdmin(conf);
        htable = new HTable(conf, TN);
    }

    @After
    public void end() throws Exception {
        if (admin != null) {
            admin.close();
        }
        if (htable != null) {
            htable.close();
        }
    }

    @Test
    public void createTable() throws Exception {
        if (admin.tableExists(TN)) {
            admin.disableTable(TN);
            admin.deleteTable(TN);
        }

        HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(TN));

        HColumnDescriptor cf = new HColumnDescriptor("cf".getBytes());
        cf.setInMemory(true);
        cf.setMaxVersions(1);

        desc.addFamily(cf);

        admin.createTable(desc);
    }

    /**
     * 添加数据
     * 
     * @throws Exception
     */
    @Test
    public void put() throws Exception {
        Put put = new Put("1111".getBytes());
        put.add("cf".getBytes(), "name".getBytes(), "xiaoming".getBytes());
        put.add("cf".getBytes(), "age".getBytes(), "31".getBytes());

        htable.put(put);
    }

    /**
     * 读取数据 get方式
     * 
     * @throws Exception
     */
    @Test
    public void getData() throws Exception {
        Get get = new Get("1111".getBytes());
        get.addColumn("cf".getBytes(), "name".getBytes());

        Result rs = htable.get(get);
        Cell cell = rs.getColumnLatestCell("cf".getBytes(), "name".getBytes());

        System.out.println(new String(CellUtil.cloneValue(cell)));
    }

    /**
     * 十个用户, 每个产生一百条通话记录
     */
    @Test
    public void insertDB1() throws Exception {

        List<Put> puts = new ArrayList<Put>();

        for (int i = 0; i < 10; i++) {
            // 自己、用户的手机号码
            String pNum = getPhoneNum("186");

            for (int j = 0; j < 100; j++) {
                // 对方手机号
                String dNum = getPhoneNum("177");
                // 通话时间
                String dateStr = getDate("2017");
                // 主叫、被叫类型
                String type = r.nextInt(2) + "";

                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

                // rowkey: 手机号_(大数-时间戳)
                String rowkey = pNum + "_" + (Long.MAX_VALUE - sdf.parse(dateStr).getTime());

                Put put = new Put(rowkey.getBytes());
                put.add("cf".getBytes(), "dnum".getBytes(), dNum.getBytes());
                put.add("cf".getBytes(), "date".getBytes(), dateStr.getBytes());
                put.add("cf".getBytes(), "type".getBytes(), type.getBytes());

                puts.add(put);
            }
        }

        htable.put(puts);
    }

    /**
     * 十个用户, 每个用户 当天产生了 一百条通话记录
     */
    @Test
    public void insertDB2() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        List<Put> puts = new ArrayList<Put>();

        for (int i = 0; i < 10; i++) {
            // 自己、用户的手机号码
            String pNum = getPhoneNum("186");

            String dateStr = "20170818000000";

            String rowkey = pNum + "_" + (Long.MAX_VALUE - sdf.parse(dateStr).getTime());

            // 每个用户一个大盒子
            Phone.dayPhoneDetail.Builder dayPhone = Phone.dayPhoneDetail.newBuilder();

            for (int j = 0; j < 100; j++) {
                // 对方手机号
                String dNum = getPhoneNum("177");
                // 通话时间
                String date = getDate2("20170818");
                // 主叫、被叫类型
                String type = r.nextInt(2) + "";
                // 当天一条通话记录
                Phone.phoneDetail.Builder phone = Phone.phoneDetail.newBuilder();

                phone.setDate(date);
                phone.setDnum(dNum);
                phone.setType(type);

                dayPhone.addPhoneDetails(phone);
            }

            Put put = new Put(rowkey.getBytes());
            put.add("cf".getBytes(), "dayPhone".getBytes(), dayPhone.build().toByteArray());

            puts.add(put);
        }

        htable.put(puts);
    }

    /**
     * 查询 18693457181 该用户 这一天产生 的所有通话记录
     * 
     * @throws Exception
     */
    @Test
    public void getDB2() throws Exception {
        Get get = new Get("18698524438_9223370533869175807".getBytes());
        get.addColumn("cf".getBytes(), "dayPhone".getBytes());

        Result rs = htable.get(get);
        Cell cell = rs.getColumnLatestCell("cf".getBytes(), "dayPhone".getBytes());
        // 反序列化 CellUtil.cloneValue(cell) 对象->二进制序列 二进制序列 -> 对象 一天一个集合
        Phone.dayPhoneDetail dayPhone = Phone.dayPhoneDetail.parseFrom(CellUtil.cloneValue(cell));

        for (Phone.phoneDetail phone : dayPhone.getPhoneDetailsList()) {
            System.out.println(phone.getDate() + " - " + phone.getDnum() + " - " + phone.getType());
        }
    }

    /**
     * 查询某个用户 某月 产生的所有通话记录
     * 
     * 18678525661 一月份
     */
    @Test
    public void scanDB2() throws Exception {
        Scan scan = new Scan();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        String startRow = "18678525661_" + (Long.MAX_VALUE - sdf.parse("20170201000000").getTime());
        String stopRow = "18678525661_" + (Long.MAX_VALUE - sdf.parse("20170101000000").getTime());

        scan.setStartRow(startRow.getBytes());
        scan.setStopRow(stopRow.getBytes());

        ResultScanner rs = htable.getScanner(scan);

        for (Result result : rs) {
            System.out.print(
                    new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
            System.out.print(" - "
                    + new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
            System.out.println(" - "
                    + new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
        }
    }

    /**
     * 查询某个用户 所有主叫被叫 通话记录 过滤器
     * 
     * @throws Exception
     */
    @Test
    public void scanDB3() throws Exception {
        Scan scan = new Scan();

        FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ALL);

        // 前缀过滤器
        PrefixFilter filter1 = new PrefixFilter("18678525661".getBytes());
        list.addFilter(filter1);

        // 值过滤器 找到 所有的type=0 主叫的 通话记录
        SingleColumnValueFilter filter2 = new SingleColumnValueFilter("cf".getBytes(), "type".getBytes(),
                CompareOp.EQUAL, "0".getBytes());
        list.addFilter(filter2);

        scan.setFilter(list);

        ResultScanner rs = htable.getScanner(scan);

        for (Result result : rs) {
            System.out.print(
                    new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
            System.out.print(" - "
                    + new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
            System.out.println(" - "
                    + new String(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
        }
    }

    // 练习: 实现 删除某个Cell

    Random r = new Random();

    /**
     * 随机生成测试手机号码 prefix: 手机号码前缀 eq:186
     */
    public String getPhoneNum(String prefix) {
        return prefix + String.format("%08d", r.nextInt(99999999));
    }

    /**
     * 随机生成时间
     * 
     * @param year年
     * @return 时间 格式:yyyyMMddHHmmss
     */
    public String getDate(String year) {
        return year + String.format("%02d%02d%02d%02d%02d",
                new Object[] { r.nextInt(12) + 1, r.nextInt(28) + 1, r.nextInt(24), r.nextInt(60), r.nextInt(60) });
    }

    /**
     * 随机生成时间
     * 
     * @param prefix年月日
     *            2017-8-1
     * @return 时间 格式:yyyyMMddHHmmss
     */
    public String getDate2(String prefix) {
        return prefix + String.format("%02d%02d%02d", new Object[] { r.nextInt(24), r.nextInt(60), r.nextInt(60) });
    }

附录:

描述:负载均衡器启动周期  5分钟
<property>

   <name>hbase.balancer.period
    </name>

   <value>300000</value>
</property>

描述:region拆分阈值   10g

 <property>

    <name>hbase.hregion.max.filesize</name>

    <value>10737418240</value>


</property>


描述:memstore溢写阈值  128M
<property>

    <name>hbase.hregion.memstore.flush.size</name>

    <value>134217728</value>


</property>

描述:溢写检查线程检查间隔  10秒
<property>

     <name>hbase.server.thread.wakefrequency</name>

    <value>10000</value>

</property>

描述:minor合并的最大文件数  10个

<property>

    <name>hbase.hstore.compaction.max</name>

    <value>10</value>

</property>

描述:触发mionr合并的阈值(hsotrefile文件个数)3个

<property>

    <name>hbase.hstore.compactionThreshold</name>

    <value>3</value>

</property>

描述:major的合并周期 7天

<property>

    <name>hbase.hregion.majorcompaction</name>

    <value>604800000</value>

</property>

描述:hlog文件在old目录中最长的生命周期 10分钟

<property>

    <name>hbase.master.logcleaner.ttl</name>

     <value>600000</value>

</property>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值