需求
在社交网站,社交APP上会存储有大量的用户数据以及用户之间的关系数据,比如A用户的好友列表会展示出他所有
的好友,现有一张Hbase表,存储就是当前注册用户的好友关系数据,如下
需求
- 使用Hbase相关API创建一张结构如上的表
- 删除好友操作实现(好友关系双向,一方删除好友,另一方也会被迫删除好友)
例如:uid1用户执行删除uid2这个好友,则uid2的好友列表中也必须删除uid1
分析:
1.创建如上结构的表
2.分析,当uid1用户执行删除uid2这个好友,则uid2的好友列表中也必须删除uid1,使用协处理器完成。
3. 通过java生成一个对象继承协处理器BaseRegionObserver,重写postDelete。
创建
package com.lagou.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class RelationShipData {
Configuration configuration =null;
Connection connection =null;
@Before
public void init() throws IOException {
configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum","linux131,linux132");
configuration.set("hbase.zookeeper.property.clientPort","2181");
connection = ConnectionFactory.createConnection(configuration);
}
@Test
public void createTable() throws IOException {
HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();
HTableDescriptor relations = new HTableDescriptor(TableName.valueOf("relations"));
relations.addFamily(new HColumnDescriptor("friends"));
admin.createTable(relations);
}
@Test
public void putRelationData() throws IOException {
Table table = connection.getTable(TableName.valueOf("relations"));
List<Put> puts = new ArrayList<Put>();
// rowkey user1
Put put12 = new Put(Bytes.toBytes("user1"));
Put put13 = new Put(Bytes.toBytes("user1"));
Put put14 = new Put(Bytes.toBytes("user1"));
put12.addColumn(Bytes.toBytes("friends"),Bytes.toBytes("user2"),Bytes.toBytes("user2"));
put13.addColumn(Bytes.toBytes("friends"),Bytes.toBytes("user3"),Bytes.toBytes("user3"));
put14.addColumn(Bytes.toBytes("friends"),Bytes.toBytes("user4"),Bytes.toBytes("user4"));
puts.add(put12);
puts.add(put13);
puts.add(put14);
// rowkey user2
Put put21 = new Put(Bytes.toBytes("user2"));
Put put23 = new Put(Bytes.toBytes("user2"));
put21.addColumn(Bytes.toBytes("friends"),Bytes.toBytes("user1"),Bytes.toBytes("user1"));
put23.addColumn(Bytes.toBytes("friends"),Bytes.toBytes("user3"),Bytes.toBytes("user3"));
puts.add(put21);
puts.add(put23);
table.put(puts);
table.close();
}
@After
public void release(){
if(connection!=null){
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
结果
协处理器
package com.lagou.hbase.processor;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CollectionUtils;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
public class RelationShipProcessor extends BaseRegionObserver {
@Override
public void postDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete, WALEdit edit,
Durability durability) throws IOException {
//获取表对象
HTableWrapper relations = (HTableWrapper)e.getEnvironment().getTable(TableName.valueOf("relations"));
//获取执行删除的列族队列集合
NavigableMap<byte[], List<Cell>> familyCellMap = delete.getFamilyCellMap();
//通过队列集合
Set<Map.Entry<byte[], List<Cell>>> entries = familyCellMap.entrySet();
//循环队列获取cells对象
for (final Map.Entry<byte[], List<Cell>> entry : entries) {
System.out.println(Bytes.toString(entry.getKey()));
List<Cell> cells = entry.getValue();
//循环cells对象获取每个cell的rowkey以及列族
for (final Cell cell : cells) {
byte[] rowkey = CellUtil.cloneRow(cell);
byte[] qualifier = CellUtil.cloneQualifier(cell);
//判断是否存在删除的rowkey的cell
boolean flag = relations.exists(new Get(qualifier).addColumn(Bytes.toBytes("friends"), rowkey));
if (flag){
//生成一个delete对象对需要删除的列族进行删除
Delete delQualifier = new Delete(qualifier).addColumn(Bytes.toBytes("friends"), rowkey);
relations.delete(delQualifier);
}
}
}
}
}
打包上传至hdfs并挂载
[root@linux133 ~]# hdfs dfs -put relationship.jar
[root@linux133 ~]# hdfs dfs -put relationship.jar /processor
alter 'relations',METHOD =>'table_att','Coprocessor'=>'hdfs://linux131:9000/processor/relationship.jar|com.lagou.hbase.processor.RelationShipProcessor|1001|'
结果