利用 HBase 模拟微博的实例

该实例中需要建立的四张表:

微博表:用来存贮所有的人发布的所有微博;

关注人表:用来存贮自己所关注的人;

粉丝表:用来存贮自己的粉丝;

收信箱表:用来存贮关注的人所发布的微博。


在Hbase模拟微博的实例中,行键的设计如下:

表名行键
微博表用户ID+时间戳
关注人表用户ID
粉丝表用户ID
收信箱表用户ID

对于关注人表中用户的关注人的存贮采用的是宽表的形式,即一个被关注的人占一列,这样的好处是只需get一行数据就可以获得所有的关注人,且增删关注人都是原子操作,粉丝表的设计同理。

收信箱记录关注人所发表的微博的行键,即其用户ID+时间戳,对于同一用户人发表的多条微博的记录也是采用的宽表的设计形式,用户每发表一条微博都会在收信箱表其粉丝行里增加一列。


操作HBase数据库的类:

package mblog;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellScanner;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
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.util.Bytes;

public class HBase {
	static Configuration cfg = HBaseConfiguration.create();

	public static int create(String tablename, String [] columnFamilys)
			throws MasterNotRunningException, ZooKeeperConnectionException,
			IOException {
		HBaseAdmin admin = new HBaseAdmin(cfg);
		int retflag  = 0;
		if (admin.tableExists(tablename)) {
			System.out.println("table exists!");
			retflag = 1;
		} else {
			HTableDescriptor tableDescriptor = new HTableDescriptor(tablename);
			for(String s : columnFamilys){
				HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(s);
				hColumnDescriptor.setMinVersions(1000);
				tableDescriptor.addFamily(hColumnDescriptor);
			}
			admin.createTable(tableDescriptor);
			System.out.println("create table successfully!");
			retflag = 0;
		}
		admin.close();
		return retflag;
	}

	public static void put(String tableName, String row, String familyName,
			String column, String value) throws IOException {
		HTable table = new HTable(cfg, tableName);
		Put p1 = new Put(Bytes.toBytes(row));
		p1.add(Bytes.toBytes(familyName), Bytes.toBytes(column), Bytes.toBytes(value));
		table.put(p1);
		System.out.println("put ok");
		table.close();
		
	}
	
	public static void get(String tablename, String row) throws IOException{
		HTable table = new HTable(cfg, tablename);
		Get g1 = new Get(Bytes.toBytes(row));
		Result result = table.get(g1);
//		List list = (List) result.getColumn("f1".getBytes(), "c1".getBytes());
//		Iterator it = list.iterator();
//		while(list.){
//			System.out.println(o);
//		}
		System.out.println("get: " + result);
		table.close();
	}
	
	public static ArrayList<String> getAllColumns(String tablename, String row, String family) throws IOException{
		HTable table = new HTable(cfg, tablename);
		Get g1 = new Get(Bytes.toBytes(row));
		g1.addFamily(Bytes.toBytes(family));
		Result result = table.get(g1);
		
		ArrayList<String> arrayList = new ArrayList<String>();
		if(result.listCells() != null){
			for(Cell cell : result.listCells()){
				arrayList.add(new String(cell.getValue()));
			}
		}
		table.close();
		return arrayList;
	}
	
	public static void scan(String tableName) throws IOException{
		HTable table = new HTable(cfg, tableName);
		Scan scan = new Scan();
		ResultScanner res = table.getScanner(scan);
		for(Result r : res){
			System.out.println(r);
		}
		table.close();
	}
	
	public static boolean delete(String tablename) throws MasterNotRunningException, ZooKeeperConnectionException, IOException{
		HBaseAdmin admin = new HBaseAdmin(cfg);
		if(admin.tableExists(tablename)){
			try{
				admin.disableTable(tablename);
				admin.deleteTable(tablename);
				
			}
			catch (Exception e){
				e.printStackTrace();
				return false;
			}
		}
		
		return true;
	}
}

模拟微博的类,重点时row key的设计:

package mblog;

import hadoop.Hbase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.map.HashedMap;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.util.Bytes;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;


public class Mblog {
	
	public static String tmblog = "tmblog";
	public static String tfocus = "tfocus";
	public static String tfans = "tfans";
	public static String trcvbox = "trcvbox";

	public static int createTable() throws MasterNotRunningException, ZooKeeperConnectionException, IOException{
		int retflag = 0;
		//创建微博表
		String [] columnFamilys = new String[2];
		columnFamilys[0] = "f1";
		columnFamilys[1] = "f2";
		retflag += HBase.create(tmblog, columnFamilys);
		
		//创建关注人表
		retflag += HBase.create(tfocus, columnFamilys);
		
		//创建粉丝表
		retflag += HBase.create(tfans, columnFamilys);
		
		//创建收信箱
		retflag += HBase.create(trcvbox, columnFamilys);
		
		return retflag;
	}
	
	public static void publish(String uid, String content) throws IOException{
		String tableName = tmblog;
		String row = uid + "_" + System.currentTimeMillis();
		String columnFamily = "f1";
		String column = "cont";
		HBase.put(tableName, row, columnFamily, column, content);
		
		//向uid的fans收信箱中发送row
		ArrayList<String> fans = getFans(uid);
		for(String fan : fans){
			sendMessage(fan, row);
		}
		
	}
	
	public static void addFocus(String uid, String who) throws IOException{
		String columnFamily = "f1";
		HBase.put(tfocus, uid, columnFamily, who, who);
		HBase.put(tfans, who, columnFamily, uid, uid);
	}
	
	public static ArrayList<String> getFans(String uid) throws IOException{
		return HBase.getAllColumns(tfans, uid, "f1");
	}
	
	public static void sendMessage(String uid, String column) throws IOException{
		HBase.put(trcvbox, uid, "f1", column, column);
	}
	
	public static Multimap<String, String> getMessage(String uid) throws IOException{
		Multimap<String, String> multimap = ArrayListMultimap.create();
		ArrayList<String> blogs = HBase.getAllColumns(trcvbox, uid, "f1");
		for(String blog : blogs){
			ArrayList<String> tmp = HBase.getAllColumns(tmblog, blog, "f1");
			String [] sz = blog.split("_");
			multimap.putAll(sz[0], tmp);
		}
		
		Iterator it = multimap.entries().iterator();
		while(it.hasNext()){
			Map.Entry<String, String> entry = (Entry<String, String>) it.next();
			System.out.println(entry.getKey() + ": " + entry.getValue());
		}
		return multimap;
	}
	
	public static void main(String [] args){
		try{
			int ret = createTable();
			addFocus("xiaoming", "xiaohong");
			addFocus("xiaoming", "xiaoqiang");
			addFocus("xiaoming", "xiaozhang");
			addFocus("x1", "xiaoming");
			addFocus("x2", "xiaoming");
			addFocus("x3", "xiaoming");
			
			publish("xiaoming", "today is rainning day!");
			publish("xiaohong", "My shirt is beautiful!");
			publish("xiaoqiang", "I will climb tomorrow!");
			publish("xiaohong", "The cake is very nice!");
			publish("xiaoming", "I like socker!");
			
			System.out.println("=======xiaoming's blog=======");
			getMessage("xiaoming");
			System.out.println();
			
			System.out.println("=======x1's blog=======");
			getMessage("x1");
			System.out.println();
			
			
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值