1. 创建两个表
2. 编写代码
import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionObserver;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.wal.WALEdit;
/**
* 使用协处理器为电影表建立索引表
* 目的是为了快速的按照uid查询数据
*
*/
public class Demo implements RegionCoprocessor , RegionObserver{
// 获取协处理器的对象
@Override
public Optional<RegionObserver> getRegionObserver() {
// TODO Auto-generated method stub
return Optional.of(this);
}
/**
* 在put之前执行的方法
* 操作put对象 获取put的值
*/
@Override
public 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表的key
byte[] 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
@Override
public void start(CoprocessorEnvironment env) throws IOException {
}
// 关闭
@Override
public void stop(CoprocessorEnvironment env) throws IOException {
}
}
3. 打jar包上传到HDFS上
4. 禁用操作表
5. 添加协处理器
alter 'users', METHOD => 'table_att', 'Coprocessor'=>'hdfs://linux01:8021/demo.jar|com._51doit.observer.SecondaryIndex|1001|
6. 启用表
7. 测试
8. 实现思路
在操作前一定要拍摄快照