利用 HBase 模拟微博的实例

来源:互联网 发布:php详解socket select 编辑:程序博客网 时间:2024/06/07 06:41

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

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

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

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

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


在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收信箱中发送rowArrayList<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();}}}