Hbase增删改查、关联查询、关系型数据库转化

来源:互联网 发布:哪个yy协议软件好 编辑:程序博客网 时间:2024/05/09 01:29

写在前面

主要的目的是想直接通过Hbase 将上面上面的Mysql 替换成Hbase, 这样能够对我们维护的负担压力减轻更多(调研), 实际过程中遇到了非常多的问题.

  1. 处理多表之间的问题的时候出现了很多问题. 主要是在列式数据库中 对每一行的定义都是非结构化的, 只是对column family 进行严格的规定而已.这样一来我们就没有了我们需要的外键/相关联的, 更多的操作都是通过全表扫描.
  2. 对rowKey 的设计需要有非常高要求. 学习OpenTSDB 中rowKey的巧妙设计, 虽然丢弃了版本号的使用,但是能够更加快的找到timeseries data,这也是一个非常好的一种设计之一.

Hbase 实践

CRUD 操作

1.增加一条记录

public void testPut() throws IOException {    HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("people"));    HTable table = (HTable) conn.getTable(TableName.valueOf("people"));    //设置rowkey 为 rk0001    Put put = new Put(Bytes.toBytes("rk0001"));    //在info 的column family----> name:zhangsan    put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"),      Bytes.toBytes("zhangsan"));    //在info column family -----> age:25    put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"),      Bytes.toBytes("25"));    //在info column family -----> money:10w    put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("money"),      Bytes.toBytes("10w"));    table.put(put);  }

2.删除一条记录

public void testDelete() throws IOException {    HTable table = (HTable) conn.getTable(TableName.valueOf("people"));    //通过指定某行的rowkey 来删除整行的数据. (Q:是否将所有版本的删除?还是将最新版本删除?)    Delete delete = new Delete(Bytes.toBytes("rk9999"));    table.delete(delete);    table.close();}

3.修改一条记录

因为hbase底层实现是hdfs 在保证高并发的同时, 会牺牲一些一致性, 只需要保证了最终的一致性即可, 所以更新的操作可以看做为通过对某个行直接覆盖写, 同时利用时间戳来保证获取到的数据是最新的.

4.查询一条记录

查询就是重点. 虽然看着没有join 的操作.但是丰富的api能够快速的实现join并且这个也是hbase的优势. 列式存储的优势能够在join 的时候体现出来.(具体从文件存储、索引、实现 需要认真考证)

4.1 通过Rowkey 进行查询

这个操作非常简单, 直接知道 RowKey 然后就能够提取出来所在的行

public void testScan() throws IOException {    HTable table = (HTable) conn.getTable(TableName.valueOf("people"));    //这里需要写出 rowkey的一个范围, 也可以直接写.    Scan scan = new Scan(Bytes.toBytes("rk29990"), Bytes.toBytes("rk30000"));    ResultScanner resultScaner = table.getScanner(scan);    for (Result result : resultScaner) {      System.out.println(Bytes.toString(result.getRow()));      //String str = Bytes.toString(result.getValue(Bytes.toBytes("info"),Bytes.toBytes("money")));      //System.out.println(str);    }    table.close();  }

4.2 通过正则来查询Rowkey

实现的方式是 在scan 的时候同时做filter (RowFilter)

//代码片段Scan scan = new Scan();Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new RegexStringComparator(login+"_"+"*"));scan.setFilter(filter);ResultScanner scanner = table.getScanner(scan);for (Result res : scanner) {    u = new User(res);}

4.3 单列查询

很多时候我们并不知道我们的rowkey是什么, 但是我们知道我们现在要找到某一列的某一个值.在哪一行. 这个时候就需要用到单列查询 SingleColumnValueFilter
同理在hbase 里面的所有操作都是通过scan & filter 找到, 如果没有设计 Secondary Index 这样scan 的结果在效率上是比较慢的.

Filter filter = new SingleColumnValueFilter(Bytes.toBytes("info"),Bytes.toBytes(column), CompareFilter.CompareOp.EQUAL,Bytes.toBytes(query));

5.思考

整个重构项目写了一半, 但是发现有非常多的问题, 从关系型数据库迁移到hbase 不是说不可能, 但是又很多东西需要重新写.比如一些最简单的join count 等等都是人工的api 操作. 虽然可操作性非常高, 但是非常不利于我的快速迭代和开发, 维护成本也不低. 另外关系型数据库有很多非常友好和成熟的操作 不是hbase所擅长的, 尤其是事务型数据.

之后应该也会有更多的对hbase方面的学习,会一直更加认真的写一些分享.
写总结不是一件容易的事情.

1 0
原创粉丝点击