`
dalan_123
  • 浏览: 83666 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

HBase系列一

阅读更多
关于hbase
一、客户端类
HTable 和 HTablePool: (1)、HTable用于一个线程创建一个HTable;最好只创建唯一一个HTable对象;因为每次创建HTable实例都需要付出代价;检查meta.表对应的表是否存在,是否可用以及其他
                             的一些操作;对性能的损耗不可忽视的;同时HBase所有的修改操作都是保证行级别的原子性;
   (2)、若是需要多个HTable对象,则考虑使用HTablePool类;操作同一行的记录 最好使用batch操作;以减少单独操作该行的次数
二、CRUD操作
(1)、put方法
    1、void put(Put put) throws IOException;将一个put或者存储在列表中的一组put作为输入参数
   注:构建Put对象
   Put(byte[] row);
   Put(byte[] row, RowLock rowlock);
   Put(byte[] row, long ts);
   Put(byte[] long ts, RowLock rowLock);
   参数说明:RowKey---》row 提供唯一的行键 RowLock--》行级锁  ts---》时间戳
2、byte转换类 Bytes
    static byte[] toBytes(ByteBuffer bb);
static byte[] toBytes(String s);
static byte[] toBytes(boolean b);
static byte[] toBytes(long val);
static byte[] toBytes(float f);
static byte[] toBytes(int val);
3、put的add方法
    Put add(byte[] family, byte[] qualifier,byte[] value);
Put add(byte[] family,byte[] qualifier,long ts, byte[] value);
Put add(KeyValue kv) throws IOException;
    可以通过行键+列族+列限定符+时间戳定位具体的内容
关于ts参数,在通过add进行数据添加时,不指定ts参数内容时,则使用构造函数的ts对应的内容;若是在
构造实例也没有指定ts参数,则有region机器指定
(1)、KeyValue = 行键+列族+列限定符+时间戳
    List<KeyValue> get(byte[] family,byte[] qualifier);
            Map<byte[],List<KeyValue>> getFamilyMap();
(2)、检查单元格是否存在
    boolean has(byte[] family,byte[] qualifier);
boolean has(byte[] family,byte[] qualifier, long ts);
boolean has(byte[] family,byte[] qualifier,byte[] value);
boolean has(byte[] family,byte[] qualifier,long ts,byte[]);
    4、HBase使用
  // 1、创建所需配置
  Configuration conf = HBaseConfiguration.create();
  // 2、实例化客户端
  HTable table = new HTable(conf,"table name");
  // 3、创建put存放数据记录
  // 创建row key
  Put put = new Put(Bytes.toBytes("row_key"));
  // 创建column family
  put.add(Bytes.toBytes("colfam1"),Bytes.toBytes("qual1"));
  put.add(Bytes.toBytes("colfam2"),Bytes.toBytes("qual2"));
  // 4、添加记录到指定的表
  table.put(put);
  以上代码Configuration对应HBase的hbase-site.xml文件(默认情况下程序会从classpath下直接尝试读取
  hbase-default.xml 和 hbase-site.xml)再程序获取到Configuration一般是默认+用户自定义参数合并之后的结果
5、说明
   (a)、关于hbase中的时间戳
    在hbase中有一个特殊的功能,同一个列单元格(特定类的值)可以存在多个版本。就是通过使用时间戳按照降序来存储的,单位为毫秒;该参数可以通过客户端api进行指定,也可以忽略
让服务器端来完成。主要根据实际情况来完成的。这样获取指定的数据时,根据执行的参数可以获取多个。默认情况下只显示最新的那个版本
   (b)、RowLock类
在构造Put实例时会存在一个RowLock参数,特别在某一行记录需要频繁修改时,可以在客户端创建RowLock实例防止用户的修改该行
   (c)、KeyValue类
    数据和坐标都是以byte[]形式存储;目的主要是为了允许存储任意类型的数据,并有效存储所需的字节,保证最少的
内部结构开销;并且每一个字节数据组都有一个offset和length参数,允许用户提交存在的字节数据,并进行高效率的
字节操作。
KeyValue(byte[] row,int offset,int rlength,   -------RowKey
byte[] family, int foffset,int flength, ----Column Family
byte[] qualifier , int qoffset,int qlength,--Qualifier Column
long timestamp,Type type,                  -- Version
byte[] value,int voffset, int vlength)     -- Value
byte[] getRow()
byte[] getKey() 行---》行键  键---指的是单元格的坐标
三、客户端write buffer
由于每一个put操作就是RPC操作;将client数据传输到server后返回,只适合小量数据操作;因而减少RPC调用就需要限制往返时间(round-trip time);也即是
client发送一个request到server,然后server进行网络response的时间。同时消息大小也会影响rpc性能;尽量使用批量处理,减少请求次数。
(1)、开启客户端的写缓冲区
      void setAutoFlush(boolean autoFlush);
  boolean isAutoFlush();
  默认客户端缓存区是禁用的,可以通过设定为false开启缓冲区;不过一旦开启客户端缓冲区,数据进行写入时,需要手动执行
  void flushCommits() throws IOException;
  同时客户端可以手动调整缓冲区;不过更多是通过hbase-site.xml
  <property>
<name>hbase.client.write.buffer</name>
<value>20971520</value>
  </property>
  缓冲区刷写
  1、显示刷写 flushCommits
  2、隐式刷写 通过将当前的缓冲区大小和用户配置大小作比较;若是超出限制则会调用flushCommits方法;若是禁用则需通过setAutoFlush(true)来开启
注:close方法也会触发隐式刷写
        一旦客户端关闭自动刷写;没有手动执行flushCommits那么通过put操作的内容就不会被提交到server端
        ArrayList<Put> getWriteBuffer() 获取添加到缓冲区中的Put实例列表;该列表在HTable不是线程安全的;
        不能在程序运行期终止程序,否则会导致尚未刷写的数据丢失,
  (2)、put 列表
  // 1、put list
      List<Put> puts = new ArrayList<Put>();
  // 2、create put
      Put put1 = new Put(Bytes.toBytes("ROW1"));
      put1.add(Bytes.toBytes("Column1"),Bytes.toBytes("qual1"),Bytes.toBytes("val1"));
  // 3、add put to put list
  puts.add(put1);
 
  Put put2 = new Put(Bytes.toBytes("ROW2"));
      put1.add(Bytes.toBytes("Column1"),Bytes.toBytes("qual1"),Bytes.toBytes("val2"));
  puts.add(put2);
  // 4、执行put操作
  table.put(puts);
  原子性操作 compare-and-set(CAS)
  boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,byte[] value,Put put)
throws IOException;
五、Scan的使用
    类似RDBMS的游标
    (1)、创建Scan及应用
// 创建Scan
Scan scan = new Scan();
// 指定扫描范围
scan.addColumn(Bytes.toBytes("colfam1"),
   Bytes.toBytes("col-5").addColumn(Bytes.toBytes("colfam1"))
   Bytes.toBytes("col-33").setStartRow(Bytes.toBytes("row-11")).setStopRow(Bytes.toBytes("row-20"))
   );
// 获取ResultScanner
ResultScanner scanner = table.getScanner(scan);
// 迭代变量scanner
for(Result result : scanner){
System.out.println(result);
}
// scanner关闭
scanner.close();
注:获取的内容进行匹配的时候都是按照字典顺序排序的
六、缓存与批量处理
1、设定scanner的缓存
   hbase-site.xml配置
   <property>
<name>hbase.client.scanner.caching</name>
<value>10</value>
   </property>
   程序配置
   void setCaching(int caching);
   int getCaching();
缓存针对的行级的操作
批量是面向列级的操作
RPC请求次数 = (行数 * 每行的列数) / Min(每行列数,批量大小) / 扫描缓存次数(额外加上打开和关闭scanner)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics