网站快速优化排名/品牌seo推广
HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowKey中显然不太可能),或者全表扫描再结合过滤器筛选出目标数据(太低效),所以通过设计HBase的二级索引来解决这个问题。
多个查询条件构成了多维度的组合查询,需要根据不同组合查询出符合条件的数据。
例如:
按照电影维度查询数据适合,但是按照uid就不适合 , 使用二级索引分两步查询实现高效获取数据,因为两次都是通过ROWKEY查询的数据
创建代码实现
思路 在插入数据的时候 , 如果遇到uid属性 , 那么就在二级索引表中插入 K: uid 和 V:主表的rowkey
/*** 使用协处理器为电影表建立索引表* 目的是为了快速的按照uid查询数据**/
public class Demo implements RegionCoprocessor , RegionObserver{// 获取协处理器的对象@Overridepublic Optional<RegionObserver> getRegionObserver() {// TODO Auto-generated method stubreturn Optional.of(this);}/*** 在put之前执行的方法* 操作put对象 获取put的值*/@Overridepublic void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability)throws IOException {Configuration configuration = HBaseConfiguration.create();configuration.set("hbase.zookeeper.quorum", "doit001:2181,doit002:2181,doit003:2181");Connection connection = ConnectionFactory.createConnection(configuration);Table table = connection.getTable(TableName.valueOf("index"));// (一行) 获取put中的单元格对应的所有的列族NavigableMap<byte[],List<Cell>> map = put.getFamilyCellMap();// 遍历所有的单元格 ,获取属性名 , 如果属性名是uid 将uid插入到index表中Set<Entry<byte[],List<Cell>>> set = map.entrySet();for (Entry<byte[], List<Cell>> entry : set) {List<Cell> cells = entry.getValue();// 获取插入的所有的单元格for (Cell cell : cells) {// 获取属性byte[] cloneQualifier = CellUtil.cloneQualifier(cell);// 当属性值是uid的时候 将数据插入到index表中 uid的值(rk) 行建if("uid".equals(Bytes.toString(cloneQualifier))) {// uid的值 index表的keybyte[] rk = CellUtil.cloneValue(cell);String uid = Bytes.toString(rk);long timeMillis = System.currentTimeMillis();String index_rk = uid +"_"+timeMillis ;// index表的值byte[] rowkey = CellUtil.cloneRow(cell);// 创建新的put 将put 插入到index表中Put p = new Put(index_rk.getBytes());p.addColumn("f".getBytes(), "mid_time".getBytes(), rowkey);// index表的对象table.put(p);}}}}// 开启region@Overridepublic void start(CoprocessorEnvironment env) throws IOException {}// 关闭@Overridepublic void stop(CoprocessorEnvironment env) throws IOException {}}
示例:
添加协处理器:
删除协处理器: