hbase使用MapReduce操作2(微博表实现)
package com.yjsj.weibo; import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.util.Bytes; /**
* 发布微博
* 互粉
* 取关
* 查看微博
* @author Z
*
*/
public class WeiBo {
//HBase的配置对象
private Configuration conf = HBaseConfiguration.create(); //创建weibo这个业务的命名空间,3张表
private static final byte[] NS_WEIBO = Bytes.toBytes("ns_weibo");
private static final byte[] TABLE_CONTENT = Bytes.toBytes("ns_weibo:content");
private static final byte[] TABLE_RELATION = Bytes.toBytes("ns_weibo:relation");
private static final byte[] TABLE_INBOX = Bytes.toBytes("ns_weibo:inbox");
public WeiBo(){
conf.set("hbase.zookeeper.quorum", "master,node1,node2");
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.master", "master:60000");
}
private void init() throws IOException{
//创建微博业务命名空间
initNamespace();
//创建微博内容表
initTableContent();
//创建用户关系表
initTableRelation();
//创建收件箱表
initTableInbox();
} //创建微博业务命名空间
private void initNamespace() throws IOException {
//Connection connection = ConnectionFactory.createConnection(conf);
//conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "master,node1,node2");
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.master", "master:60000"); Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin();
//创建命名空间描述器
NamespaceDescriptor ns_weibo = NamespaceDescriptor
.create("ns_weibo")
.addConfiguration("creator", "JinJI")
.addConfiguration("create_time", String.valueOf(System.currentTimeMillis()))
.build();
admin.createNamespace(ns_weibo);
admin.close();
connection.close();
} /**
* 表名:ns_weibo:content
* 列族名:info
* 列名:content
* rowkey:用户id_时间戳
* value:微博内容(文字内容,图片URL,视频URL,语音URL)
* versions:1
* @throws IOException
*/
private void initTableContent() throws IOException {
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin(); //创建表描述器
HTableDescriptor contentTableDescriptor = new HTableDescriptor(TableName.valueOf(TABLE_CONTENT));
//创建列描述器
HColumnDescriptor infoColumnDescriptor = new HColumnDescriptor("info");
//设置块缓存
infoColumnDescriptor.setBlockCacheEnabled(true);
//设置块缓存大小 2M
infoColumnDescriptor.setBlocksize(2 * 1024 * 1024);
//设置版本确界
infoColumnDescriptor.setMinVersions(1);
infoColumnDescriptor.setMaxVersions(1); //将列描述器添加到表描述器中
contentTableDescriptor.addFamily(infoColumnDescriptor);
//创建表
admin.createTable(contentTableDescriptor);
admin.close();
connection.close();
}
/**
* 表名:ns_weibo:relation
* 列族名:attends,fans
* 列名:用户id
* value:用户id
* rowkey:当前操作人的用户id
* versions:1
* @throws IOException
*/
private void initTableRelation() throws IOException {
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin();
//创建用户关系表描述器
HTableDescriptor relationTableDescriptor = new HTableDescriptor(TableName.valueOf(TABLE_RELATION)); //创建attends列描述器
HColumnDescriptor attendsColumnDescriptor = new HColumnDescriptor("attends");
//设置块缓存
attendsColumnDescriptor.setBlockCacheEnabled(true);
//设置块缓存大小 2M
attendsColumnDescriptor.setBlocksize(2 * 1024 * 1024);
//设置版本
attendsColumnDescriptor.setMinVersions(1);
attendsColumnDescriptor.setMaxVersions(1); //创建fans列描述器
HColumnDescriptor fansColumnDescriptor = new HColumnDescriptor("fans");
//设置块缓存
fansColumnDescriptor.setBlockCacheEnabled(true);
//设置块缓存大小 2M
fansColumnDescriptor.setBlocksize(2 * 1024 * 1024);
//设置版本
fansColumnDescriptor.setMinVersions(1);
fansColumnDescriptor.setMaxVersions(1); //将两个列描述器添加到表描述器中
relationTableDescriptor.addFamily(attendsColumnDescriptor);
relationTableDescriptor.addFamily(fansColumnDescriptor); //创建表
admin.createTable(relationTableDescriptor);
admin.close();
connection.close();
} /**
* 表名:ns_weibo:inbox
* 列族:info
* 列:当前用户所关注的人的用户id
* value:微博rowkey
* rowkey:用户id
* versions:100
* @throws IOException
*/
private void initTableInbox() throws IOException {
Connection connection = ConnectionFactory.createConnection(conf);
Admin admin = connection.getAdmin(); HTableDescriptor inboxTableDescriptor = new HTableDescriptor(TableName.valueOf(TABLE_INBOX));
HColumnDescriptor infoColumnDescriptor = new HColumnDescriptor("info");
//设置块缓存
infoColumnDescriptor.setBlockCacheEnabled(true);
//设置块缓存大小 2M
infoColumnDescriptor.setBlocksize(2 * 1024 * 1024);
//设置版本
infoColumnDescriptor.setMinVersions(100);
infoColumnDescriptor.setMaxVersions(100); inboxTableDescriptor.addFamily(infoColumnDescriptor);
admin.createTable(inboxTableDescriptor);
admin.close();
connection.close();
} /**
* 发布微博
* a、向微博内容表中添加刚发布的内容,多了一个微博rowkey
* b、向发布微博人的粉丝的收件箱表中,添加该微博rowkey
* @throws IOException
*/
public void publishContent(String uid, String content) throws IOException{
Connection connection = ConnectionFactory.createConnection(conf);
//得到微博表对象
Table contentTable = connection.getTable(TableName.valueOf(TABLE_CONTENT));
//a
//组装rowkey
long ts = System.currentTimeMillis();
String rowkey = uid + "_" + ts;
//添加微博内容到微博表
Put contentPut = new Put(Bytes.toBytes(rowkey));
contentPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes("content"), Bytes.toBytes(content));
contentTable.put(contentPut);
//b
//查询用户关系表,得到当前用户的fans用户id
Table relationTable = connection.getTable(TableName.valueOf(TABLE_RELATION));
//获取粉丝的用户id
Get get = new Get(Bytes.toBytes(uid));
get.addFamily(Bytes.toBytes("fans")); //先取出所有fans的用户id,存放于一个集合之中
List<byte[]> fans = new ArrayList<>(); Result result = relationTable.get(get);
Cell[] cells = result.rawCells();
for(Cell cell: cells){
//取出当前用户所有的粉丝uid
fans.add(CellUtil.cloneValue(cell));
} //如果没有粉丝,则不需要操作粉丝的收件箱表
if(fans.size() <= 0) return; //开始操作收件箱表
Table inboxTable = connection.getTable(TableName.valueOf(TABLE_INBOX)); //封装用于操作粉丝收件箱表的Put对象集合
List<Put> puts = new ArrayList<>();
for(byte[] fansRowKey : fans){
Put inboxPut = new Put(fansRowKey);
inboxPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes(uid), ts, Bytes.toBytes(rowkey));
puts.add(inboxPut);
}
//向收件箱表放置数据
inboxTable.put(puts); //关闭表与连接器,释放资源
inboxTable.close();
relationTable.close();
contentTable.close();
connection.close();
} /**
* a、在用户关系表中,对当前主动操作的用户id进行添加关注的操作
* b、在用户关系表中,对被关注的人的用户id,添加粉丝操作
* c、对当前操作的用户的收件箱表中,添加他所关注的人的最近的微博rowkey
* //@param args
* @throws IOException
*/
public void addAttends(String uid, String... attends) throws IOException{
//参数过滤:如果没有传递关注的人的uid,则直接返回
if(attends == null || attends.length <= 0 || uid == null) return;
//a
Connection connection = ConnectionFactory.createConnection(conf);
Table relationTable = connection.getTable(TableName.valueOf(TABLE_RELATION));
List<Put> puts = new ArrayList<>();
//在微博用户关系表中,添加新关注的好友
Put attendPut = new Put(Bytes.toBytes(uid));
for(String attend: attends){
//为当前用户添加关注人
attendPut.addColumn(Bytes.toBytes("attends"), Bytes.toBytes(attend), Bytes.toBytes(attend));
//b
//被关注的人,添加粉丝(uid)
Put fansPut = new Put(Bytes.toBytes(attend));
fansPut.addColumn(Bytes.toBytes("fans"), Bytes.toBytes(uid), Bytes.toBytes(uid));
puts.add(fansPut);
}
puts.add(attendPut);
relationTable.put(puts);
//c
//取得微博内容表
Table contentTable = connection.getTable(TableName.valueOf(TABLE_CONTENT));
Scan scan = new Scan();
//用于存放扫描出来的我所关注的人的微博rowkey
List<byte[]> rowkeys = new ArrayList<>(); for(String attend: attends){
//1002_152321283837374
//扫描微博rowkey,使用rowfilter过滤器
RowFilter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator(attend + "_"));
scan.setFilter(filter);
//通过该scan扫描结果
ResultScanner resultScanner = contentTable.getScanner(scan);
Iterator<Result> iterator = resultScanner.iterator();
while(iterator.hasNext()){
Result result = iterator.next();
rowkeys.add(result.getRow());
}
}
//将取出的微博rowkey放置于当前操作的这个用户的收件箱表中
//如果所关注的人,没有一条微博,则直接返回
if(rowkeys.size() <= 0) return; //操作inboxTable
Table inboxTable = connection.getTable(TableName.valueOf(TABLE_INBOX));
Put inboxPut = new Put(Bytes.toBytes(uid));
for(byte[] rowkey: rowkeys){
String rowkeyString = Bytes.toString(rowkey);
String attendUID = rowkeyString.split("_")[0];
String attendWeiboTS = rowkeyString.split("_")[1];
inboxPut.addColumn(Bytes.toBytes("info"), Bytes.toBytes(attendUID), Long.valueOf(attendWeiboTS), rowkey);
}
inboxTable.put(inboxPut); //关闭,释放资源
inboxTable.close();
contentTable.close();
relationTable.close();
connection.close();
} /**
* a、在用户关系表中,删除你要取关的那个人的用户id
* b、在用户关系表中,删除被你取关的那个人的粉丝中的当前操作用户id
* c、删除微博收件箱表中你取关的人所发布的微博的rowkey
* 取关操作
* @throws IOException
*/
public void removeAttends(String uid, String... attends) throws IOException{
//参数过滤:如果没有传递关注的人的uid,则直接返回
if(attends == null || attends.length <= 0 || uid == null) return; Connection connection = ConnectionFactory.createConnection(conf);
//a
//得到用户关系表
Table relationTable = connection.getTable(TableName.valueOf(TABLE_RELATION));
Delete attendDelete = new Delete(Bytes.toBytes(uid));
List<Delete> deletes = new ArrayList<>();
for(String attend: attends){
//b 在对面用户关系表中移除粉丝
attendDelete.addColumn(Bytes.toBytes("attends"), Bytes.toBytes(attend));
Delete delete = new Delete(Bytes.toBytes(attend));
delete.addColumn(Bytes.toBytes("fans"), Bytes.toBytes("uid"));
deletes.add(delete);
}
deletes.add(attendDelete);
relationTable.delete(deletes); //c
Table inboxTable = connection.getTable(TableName.valueOf(TABLE_INBOX)); Delete delete = new Delete(Bytes.toBytes(uid));
for(String attend: attends){
delete.addColumns(Bytes.toBytes("info"), Bytes.toBytes(attend));
}
inboxTable.delete(delete); //释放资源
inboxTable.close();
relationTable.close();
connection.close();
} /**
* 查看微博内容
* a、从微博收件箱中获取所有关注的人发布的微博的微博rowkey
* b、根据得到的微博rowkey,去微博内容表中得到数据
* c、将取出的数据解码然后封装到Message对象中
* @throws IOException
*/
public List<Message> getAttendsContent(String uid) throws IOException{
//a
Connection connection = ConnectionFactory.createConnection(conf);
Table inboxTable = connection.getTable(TableName.valueOf(TABLE_INBOX));
//从收件箱表中获取微博rowkey
Get inboxGet = new Get(Bytes.toBytes(uid));
inboxGet.addFamily(Bytes.toBytes("info"));
//每个Cell中存储了100个版本,我们只取出最新的5个版本
inboxGet.setMaxVersions(5); Result inboxResult = inboxTable.get(inboxGet);
//准备一个存放所有微博rowkey的集合
List<byte[]> rowkeys = new ArrayList<>();
Cell[] inboxCells = inboxResult.rawCells();
//组装rowkes集合
for(Cell cell: inboxCells){
rowkeys.add(CellUtil.cloneValue(cell));
} //b
//根据微博rowkeys,去内容表中取得微博实际内容的数据
Table contentTable = connection.getTable(TableName.valueOf(TABLE_CONTENT));
//用于批量获取所有微博数据
List<Get> contentGets = new ArrayList<>();
for(byte[] rowkey: rowkeys){
Get contentGet = new Get(rowkey);
contentGets.add(contentGet);
}
//所有的结果数据
List<Message> messages = new ArrayList<>();
Result[] contentResults = contentTable.get(contentGets);
for(Result r: contentResults){
Cell[] cs = r.rawCells();
for(Cell c: cs){
//取得contentTable中的rowkey
String rk = Bytes.toString(r.getRow());
//发布微博人的UID
String publishUID = rk.split("_")[0];
long publishTS = Long.valueOf(rk.split("_")[1]); Message msg = new Message();
msg.setUid(publishUID);
msg.setTimestamp(publishTS);
msg.setContent(Bytes.toString(CellUtil.cloneValue(c))); messages.add(msg);
}
} contentTable.close();
inboxTable.close();
connection.close(); return messages;
} /**
* 测试用例
* //@param args
* @throws IOException
*/ //发布微博
public static void publishWeiBoTest(WeiBo weiBo, String uid, String content) throws IOException{
weiBo.publishContent(uid, content);
}
//关注
public static void addAttendTest(WeiBo weiBo, String uid, String... attends) throws IOException{
weiBo.addAttends(uid, attends);
}
//取关
public static void removeAttendTest (WeiBo weiBo, String uid, String... attends) throws IOException{
weiBo.removeAttends(uid, attends);
} //刷微博
public static void scanWeiBoContentTest(WeiBo weiBo, String uid) throws IOException{
List<Message> list = weiBo.getAttendsContent(uid);
System.out.println(list);
} public static void main(String[] args) throws IOException {
WeiBo wb = new WeiBo();
//wb.init(); //publishWeiBoTest(wb, "1002", "哦,我的上帝,我要踢爆他的屁股");
/*
publishWeiBoTest(wb, "1002", "哦,我的上帝,我还要踢爆他的屁股");
publishWeiBoTest(wb, "1002", "哦,我的上帝,我非要踢爆他的屁股");
publishWeiBoTest(wb, "1003", "哦,我的上帝,我也要踢爆他的屁股");
*/
//addAttendTest(wb, "1001", "1002", "1003");
//removeAttendTest(wb, "1001", "1002");
//scanWeiBoContentTest(wb, "1001");
/*
addAttendTest(wb, "1003", "1002", "1001");
scanWeiBoContentTest(wb, "1003"); publishWeiBoTest(wb, "1001", "嘿嘿嘿11");
publishWeiBoTest(wb, "1001", "嘿嘿嘿22");
publishWeiBoTest(wb, "1001", "嘿嘿嘿33");
publishWeiBoTest(wb, "1001", "嘿嘿嘿44");
publishWeiBoTest(wb, "1001", "嘿嘿嘿55");
publishWeiBoTest(wb, "1001", "嘿嘿嘿66");
scanWeiBoContentTest(wb, "1003");
*/
}
}
hbase使用MapReduce操作2(微博表实现)的更多相关文章
- hbase使用MapReduce操作4(实现将 HDFS 中的数据写入到 HBase 表中)
实现将 HDFS 中的数据写入到 HBase 表中 Runner类 package com.yjsj.hbase_mr2; import com.yjsj.hbase_mr2.ReadFruitFro ...
- hbase使用MapReduce操作3(实现将 fruit 表中的一部分数据,通过 MR 迁入到 fruit_mr 表中)
Runner类 实现将 fruit 表中的一部分数据,通过 MR 迁入到 fruit_mr 表中. package com.yjsj.hbase_mr; import org.apache.hadoo ...
- hbase使用MapReduce操作1(基本增删改查)
操作代码 import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; import org.apach ...
- Mapreduce操作HBase
这个操作和普通的Mapreduce还不太一样,比如普通的Mapreduce输入可以是txt文件等,Mapreduce可以直接读取Hive中的表的数据(能够看见是以类似txt文件形式),但Mapredu ...
- Hbase理论&&hbase shell&&python操作hbase&&python通过mapreduce操作hbase
一.Hbase搭建: 二.理论知识介绍: 1Hbase介绍: Hbase是分布式.面向列的开源数据库(其实准确的说是面向列族).HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hb ...
- HBase 相关API操练(三):MapReduce操作HBase
MapReduce 操作 HBase 在 HBase 系统上运行批处理运算,最方便和实用的模型依然是 MapReduce,如下图所示. HBase Table 和 Region 的关系类似 HDFS ...
- 7.MapReduce操作Hbase
7 HBase的MapReduce HBase中Table和Region的关系,有些类似HDFS中File和Block的关系.由于HBase提供了配套的与MapReduce进行交互的API如 Ta ...
- Mybatis 多表实现多对多查询、添加操作
Mybatis 多表实现多对多查询.添加操作 学习内容: 1. 多对多之添加操作 1.1.需求 1.2.数据库表(多对多数据库设计需要设计中间表) 1.3.类设计 1.4.Mapper 接口和 Map ...
- Mybatis 多表实现多对一查询、添加操作
Mybatis 多表实现多对一查询.添加操作 学习内容: 1. 多对一之添加操作 1.1.需求 1.2.数据库表(多对一或一对多,数据库外键都是设置在多的一方) 1.3.类设计 1.4.Mapper ...
随机推荐
- jstl遍历list的jsp
jstl,核心标签库,使用,<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%& ...
- scala private 和 private[this] 的区别
class PackageStudy { private var a = 0 private[this] var b = 1 // 只能在类内部使用,对象都不能直接使用 def getb(): Int ...
- java-- 的子类/父类构造方法 转
前提:父类和子类同时都有有参的构造函数和无参构造函数. Java中的子类初始化时初值为空.调用顺序为先调用父类无参构造函数,然后调用子类无参构造函数. java中的子类初始化时初值不为空.调用顺序为先 ...
- MVC 发布到IIS中的配置方法
MVC 发布到IIS中的配置方法 http://msdn.microsoft.com/zh-cn/library/gg703322(v=vs.98).aspx
- scala sparseVetor, SprseMatrix 实现
def rand(seed:Int):Double={ val rand=new Random(seed) rand.nextDouble()} def rand2(size:Int,seed:Int ...
- Conductor Task Workers
由远程worker执行的conductor任务通过HTTP端点进行通信以轮询任务并更新执行状态. conductor提供了轮询任务的框架,管理执行线程并将执行状态更新回服务器.该框架提供了Java和P ...
- Android通过DeepLink方式跳转其他App传递参数
网上对于安卓DeepLink方式跳转传递参数的例子较少,说的也不客观,实践之后发现还是有一些坑.其实为什么要用DeepLink方式跳转,有些是因为引流的原因,他们希望通过网页就能直接跳转到App的界面 ...
- tf.unstack\tf.unstack
tf.unstack 原型: unstack( value, num=None, axis=0, name='unstack' ) 官方解释:https://tensorflow.google.cn/ ...
- X_PU
通俗易懂告诉你CPU/GPU/TPU/NPU...XPU都是些什么鬼?[附把妹秘籍] 2017-10-27 19:54移动芯片/谷歌 作者:iot101君 物联网智库 原创 转载请注明来源和出处 现在 ...
- MYSQL错误:You can't specify target table for update in FROM clause
这句话意思是:不能先select再更新(修改)同一个表. 可以再外嵌套多一层,这个问题只有mysql有,mssql和oracle都没有. # 出错delete from Person where Id ...