基于Hbase的微博案例

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 基于Hbase的微博案例

需求

1、 发布微博内容    

  a. 在微博内容表中 添加一条数据(发布者)

  b. 在微博内容接收邮件箱表对所有粉丝用户添加数据(订阅者)

      scan 'weibo:receive-content-email',{VERSIONS=>5}

2、添加关注用户

  a. 在微博用户关系表中 添加新的好友关注(attends)

  b. 从被关注用户角度来说, 新增粉丝用户(fans)

 

  c. 微博邮件箱表添加关注用户发布的微博内容

3、移除或者取消关注用户

  a. 在微博用户关系表中 移除新的好友关注(attends)

  b. 从被关注用户角度来说, 删除粉丝用户(fans)

  c. 微博邮件箱表删除关注用户发布的微博内容

4、获取关注用户发布的微博内容

 a. 从微博内容邮件表中获取该用户其关注用户的微博内容的rowkey

 b. 根据上面获取到的微博内容的rowkey 获取微博内容

 微博展示的内容信息:

 message: 发布者ID , 时间戳 , content

表的设计

分析微博:

  用户群体: 关注用户 和用户粉丝

  用户行为: 发布微博、添加或者移除关注用户

  数据存储: 分布式 mysql 数据库

             考虑因素:响应时间 妙级 无延迟

             对你的技术团队就是一个很大的考验

             引出hbase 数据库存储  来实现响应时间 妙级 无延迟 、

             hbase 是hadoop 的分布式数据库

使用数据库的时候  

  拦路虎: 表的设计(合理的来设计 因素多元化)

 

  命名空间(类似于传统关系型数据库中的schema): 区分不同的业务表

   namespace name:weibo

  设计那些表:

   a.微博内容表

         xxx 发布 xx 内容

         table name : weibo:content

         

         rowkey: 被关注用户ID_时间戳

         

         columnfamily: cf

         

         colunmnlabel: (任意变化的)

                      图片

                      内容

                      标题

         

         version:    只需要一个版本

    rowkey:

        a.唯一性  每条数据是唯一的

        b.长度 (<=64 kb 建议 10-100 byte 最佳 8-16 byte)表 rowkey 是hbase中数据产生冗余的因素

        c.散列原则

           举例:

              时间戳_用户ID 作为rowkey

              大量的用户在同一时刻 发布微博内容

              121_001

              121_002

              121_003

              121_004

              ===>

             集中到某个region 会造成单独几个region 负载量偏大 而其他 region 完全没有负载

         d. 业务相关的设计规范:

               方便查询 尽可能将查询知道放到 rowkey

    列簇设计:

        Hbase 是面向列簇存储 region start  rowkey 到 stop rowkey 范围内的一个列簇下的数据 对应一个hdfs file  称为StoreFile 也可以称为HFile 所以如果跨列查询 速度相对来说就会慢很多 so 设计hbase 表 列簇的是 一般1-2个,(1个最佳)

  b.用户关系表

        用户id fans attends

        table name : weibo:relations

         

         rowkey: 用户ID(发布者的用户ID)

         

         columnfamily: attends、fans

         

         colunmnlabel:

                      关注用户ID

                      粉丝用户ID

         colunmnvalue: 关注用户ID

                       粉丝用户ID

         

         version:    只需要一个版本

  c.用户微博内容接收邮件箱表

         table name : weibo:receive-content-email

         

         rowkey: 用户ID(粉丝用户ID)

         

         columnfamily: cf

         

         colunmnlabel:

                      用户ID(发布者ID 被关注用户ID)

         colunmnvalue:

                       取微博内容的rowkey

         

         version:     1000

         10001: cf_001_yyyyy

         10001: cf_001_xxxxx

hbase 常用命令:

         1. disable 'weibo:content': 禁用表

         2. drop 'weibo:content': 删除表

         3.truncate  'weibo:relations' :清空表数据

         - Disabling table...

         - Dropping table...

         - Creating table...

         list_namespace: 查看命名空间

         list: 查看表的列表信息

         default:  默认使用的命名空间                                                                                                    

         hbase : 系统默认使用命名空间

         drop_namespace 'weibo': 删除指定的命名空间

代码实现

package com.ibeifeng.hbase.weibo.hbase_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.MasterNotRunningException;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.client.HTableInterface;
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.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.util.Bytes;
public class WeiBo {
  private Configuration conf =HBaseConfiguration.create();
  private static final  byte[] CONTENT=Bytes.toBytes("weibo:content");
  private static final  byte[] RELATIONS=Bytes.toBytes("weibo:relations");
  private static final  byte[] RECEIVE_CONTENT_EMAIL=Bytes.toBytes("weibo:receive-content-email");
  //创建 命名空间(库)
  public void initNameSpace(){
    HBaseAdmin  admin=null;
    try {
      admin=new HBaseAdmin(conf);
      /**
       * 命名空间(类似于传统关系型数据库中的schema): 区分不同的业务表
          namespace name:weibo
       */
      NamespaceDescriptor weibo=NamespaceDescriptor.create("weibo")
          .addConfiguration("creator", "beifeng")//
          .addConfiguration("createTime", System.currentTimeMillis()+"")
          .build();
      admin.createNamespace(weibo);
    } catch (MasterNotRunningException e) {
      e.printStackTrace();
    } catch (ZooKeeperConnectionException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=admin){
        try {
          admin.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  // 建表
  public void initTable(){
    createContent();
    createRelations();
    createReceiveContentEmails();
  }
  private void createContent() {
    /**
     * a.微博内容表:  xxx 发布 xx 内容
        table name : weibo:content
        rowkey: 用户ID_时间戳
          columnfamily: cf
          colunmnlabel: 
                         图片
                         内容
                         标题
        version:  只需要一个版本
     */
    HBaseAdmin admin=null;
    try {
      admin=new HBaseAdmin(conf);
      HTableDescriptor content=new HTableDescriptor(TableName.valueOf(CONTENT));
      HColumnDescriptor c_cf=new HColumnDescriptor(Bytes.toBytes("cf"));
      c_cf.setBlockCacheEnabled(true);
      //推荐是计算后的值
      c_cf.setBlocksize(2097152);
      // 一定事先配置好
      //      c_cf.setCompressionType(Algorithm.SNAPPY);
      c_cf.setMaxVersions(1);
      c_cf.setMinVersions(1);
      content.addFamily(c_cf);
      admin.createTable(content);
    } catch (MasterNotRunningException e) {
      e.printStackTrace();
    } catch (ZooKeeperConnectionException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=admin){
        try {
          admin.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  private void createRelations() {
    /**
     * b.用户关系表:
                  用户id fans attends
           table name : weibo:relations
            rowkey: 用户ID
              columnfamily: attends、fans
              colunmnlabel: 
                           关注用户ID
                           粉丝用户ID
           colunmnvalue: 用户ID
           version: 只需要一个版本
     */
    HBaseAdmin admin=null;
    try {
      admin=new HBaseAdmin(conf);
      HTableDescriptor relations=new HTableDescriptor(TableName.valueOf(RELATIONS));
      HColumnDescriptor attends=new HColumnDescriptor(Bytes.toBytes("attends"));
      attends.setBlockCacheEnabled(true);
      attends.setBlocksize(2097152);
      attends.setMaxVersions(1);
      attends.setMinVersions(1);
      HColumnDescriptor fans=new HColumnDescriptor(Bytes.toBytes("fans"));
      fans.setBlockCacheEnabled(true);
      fans.setBlocksize(2097152);
      fans.setMaxVersions(1);
      fans.setMinVersions(1);
      relations.addFamily(attends);
      relations.addFamily(fans);
      admin.createTable(relations);
    } catch (MasterNotRunningException e) {
      e.printStackTrace();
    } catch (ZooKeeperConnectionException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=admin){
        try {
          admin.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  private void createReceiveContentEmails() {
    /**
     * c.用户微博内容接收邮件箱表:
          table name : weibo:receive-content-email
          rowkey: 用户ID
            columnfamily: cf
            colunmnlabel: 
                          用户ID 
            colunmnvalue:
                                                                          取微博内容的rowkey
             version:   1000
     */
    HBaseAdmin admin=null;
    try {
      admin=new HBaseAdmin(conf);
      HTableDescriptor receive_content_email=new HTableDescriptor(TableName.valueOf(RECEIVE_CONTENT_EMAIL));
      HColumnDescriptor rce_cf =new HColumnDescriptor(Bytes.toBytes("cf"));
      rce_cf.setBlockCacheEnabled(true);
      rce_cf.setBlocksize(2097152);
      rce_cf.setMaxVersions(1000);
      rce_cf.setMinVersions(1000);
      receive_content_email.addFamily(rce_cf);
      admin.createTable(receive_content_email);
    } catch (MasterNotRunningException e) {
      e.printStackTrace();
    } catch (ZooKeeperConnectionException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=admin){
        try {
          admin.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * 发布微博内容:
   *  a. 在微博内容表中 添加一条数据(发布者)
      b. 在微博内容接收邮件箱表对所有粉丝用户添加数据(订阅者)
   * @param uid 
   *          发布者ID
   * @param content
   *          发布微博内容
   */
  public void publishContent(String uid,String content){
    HConnection connection=null;
    try {
      connection=HConnectionManager.createConnection(conf);
      //a. 在微博内容表中 添加一条数据(发布者)
      HTableInterface contentTBL=connection.getTable(TableName.valueOf(CONTENT));
      long timestamp=System.currentTimeMillis();
      String rowkey=uid+"_"+timestamp;
      Put put = new Put(Bytes.toBytes(rowkey));
      //四个值分别代表colfamily,columnlabel,timestamp,value
      put.add(Bytes.toBytes("cf"), Bytes.toBytes("content"),timestamp, Bytes.toBytes(content));
      contentTBL.put(put);
      //b. 在微博内容接收邮件箱表对所有粉丝用户添加数据(订阅者)
      // 1. 查询 用户关系表 获取该用户的粉丝用户 
      HTableInterface relationsTBL=connection.getTable(TableName.valueOf(RELATIONS));
      // get 'tablename','rowkey','cf','cq'
      //rowkey
      Get get=new Get(Bytes.toBytes(uid));
      //cf
      get.addFamily(Bytes.toBytes("fans"));
      Result result = relationsTBL.get(get);
      List<byte[]> fans = new ArrayList<byte[]>();
      //设置uid用户下所有的粉丝
      for (Cell cell : result.rawCells()) {
        //RELATIONS表里的columnlabel成为RECEIVE_CONTENT_EMAIL的rowkey
        fans.add(CellUtil.cloneQualifier(cell));
      }
      // 数据判断
      if(fans.size() <= 0) return ;
      // 获取微博内容邮件箱表
      HTableInterface rceTBL=connection.getTable(RECEIVE_CONTENT_EMAIL);
      List<Put> puts=new ArrayList<Put>();
      for (byte[] fan : fans) {
        Put fanPut=new Put(fan); //设置rowkey
        fanPut.add(Bytes.toBytes("cf"), Bytes.toBytes(uid),timestamp, Bytes.toBytes(rowkey));
        puts.add(fanPut);
      }
      rceTBL.put(puts);
      /**
       *  cell :
          primary key         
         {rowkey       ,   column(family+label),version(timestamp)}:value
       */
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=connection){
        try {
          connection.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * 添加关注用户:
   *   a. 在微博用户关系表中 添加新的好友关注(attends)
       b. 从被关注用户角度来说, 新增粉丝用户(fans)
       c. 微博邮件箱表添加关注用户发布的微博内容
   * @param uid
   *           粉丝 ID
   * @param attends
   *       被关注用户ID  
   */
  public void addAttends(String uid, String ...attends){
    //参数过滤
    if(attends==null||attends.length<=0) return;
    /**
     * a.在微博用户关系表中 添加新的好友关注(attends)
     * (0001) ,(0002,0003)
     * rowkey   column      value
     * 0001    attends:0002,0002
     * 0001    attends:0003,0003
     * 
     * rowkey  column    value
     * 0003    fans:0001,0001
     * 0002    fans:0001,0001
     * 
     */
    HConnection connection=null;
    try {
      connection=HConnectionManager.createConnection(conf);
      HTableInterface realtionsTBL=connection.getTable(RELATIONS);
      List<Put> puts=new ArrayList<Put>();
      //a. 在微博用户关系表中 添加新的好友关注(attends)
      Put attendsPut=new Put(Bytes.toBytes(uid));
      for (String attend : attends) {
        attendsPut.add(Bytes.toBytes("attends"), Bytes.toBytes(attend), Bytes.toBytes(attend));
        //b. 从被关注用户角度来说, 新增粉丝用户(fans)
        Put fansPut=new Put(Bytes.toBytes(attend));
        fansPut.add(Bytes.toBytes("fans"), Bytes.toBytes(uid), Bytes.toBytes(uid));
        puts.add(fansPut);
      }
      puts.add(attendsPut);
      realtionsTBL.put(puts);
      //c. 微博邮件箱表添加关注用户发布的微博内容的rowkey
      /**
       * 1. 首先查询被关注用户ID发布的微博内容的rowkey
       *     单个被关注用户ID,  --查询content ->微博内容的rowkey
       *     0001_xxx
       *     0001_aaa
       *     0002_yyy
       *     0002_zzz
       * 2. 将前面获取的rowkey列表 遍历出来在微博内容邮件表中正式添加数据
       * 
       */
      HTableInterface contentTBL= connection.getTable(CONTENT);
      Scan scan =new Scan();
      List<byte[]> rowkeys=new ArrayList<byte[]>();
      for(String attend: attends){
        //扫描表的rowkey,含有字符串("被关注用户ID_")
        RowFilter filter=new RowFilter(CompareOp.EQUAL, new SubstringComparator(attend+"_"));
        scan.setFilter(filter);
        ResultScanner result=contentTBL.getScanner(scan);
        // 迭代器遍历
        Iterator<Result> itearor=result.iterator();
        while(itearor.hasNext()){
          Result r=itearor.next();
          for(Cell cell:r.rawCells()){
            rowkeys.add(CellUtil.cloneRow(cell));
          }
        }
      }
      if(rowkeys.size()<= 0) return;
      // 2. 将前面获取的rowkey列表 遍历出来在微博内容邮件表中正式添加数据
      HTableInterface rceTBL=connection.getTable(RECEIVE_CONTENT_EMAIL);
      List<Put> rcePuts=new ArrayList<Put>();
      for (byte[] rk : rowkeys) {
        Put put =new Put(Bytes.toBytes(uid));
        String rowkey=Bytes.toString(rk);
        // substring 包前不包后
        String attend=rowkey.substring(0, rowkey.indexOf("_"));
        long timestamp=Long.parseLong(rowkey.substring(rowkey.indexOf("_")+1));
        put.add(Bytes.toBytes("cf"), Bytes.toBytes(attend),timestamp, rk);
        rcePuts.add(put);
      } 
      rceTBL.put(rcePuts);
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=connection){
        try {
          connection.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   *移除或者取消关注用户
     a. 在微博用户关系表中 移除新的好友关注(attends)
     b. 从被关注用户角度来说, 删除粉丝用户(fans)
     c. 微博邮件箱表删除关注用户发布的微博内容
   * @param uid
   *      粉丝用户ID
   * @param attends
   *          被关注用户ID
   */
  public void removeAttends(String uid,String ...attends){
    //参数过滤
    if(attends==null||attends.length<=0) return;
    HConnection connection=null;
    try {
      connection=HConnectionManager.createConnection(conf);
      //a. 在微博用户关系表中 移除新的好友关注(attends)
      HTableInterface relationsTBL=connection.getTable(RELATIONS);
      List<Delete> deletes=new ArrayList<Delete>();
      Delete attendsDelete =new Delete(Bytes.toBytes(uid));
      for (String attend : attends) {
        attendsDelete.deleteColumn(Bytes.toBytes("attends"), Bytes.toBytes(attend));
        //b. 从被关注用户角度来说, 删除粉丝用户(fans)
        Delete fansDelete=new Delete(Bytes.toBytes(attend));
        fansDelete.deleteColumn(Bytes.toBytes("fans"), Bytes.toBytes(uid));
        deletes.add(fansDelete);
      }
      deletes.add(attendsDelete);
      relationsTBL.delete(deletes);
      //c. 微博邮件箱表删除关注用户发布的微博内容
      HTableInterface rceTBL=connection.getTable(RECEIVE_CONTENT_EMAIL);
      Delete rceDelete=new Delete(Bytes.toBytes(uid));
      for(String attend:attends){
        /**
         * Delete the latest version of the specified column.
         */
        // rceDelete.deleteColumn(Bytes.toBytes("cf"), Bytes.toBytes(attend));
        // Delete all versions of the specified column with a timestamp less than
        rceDelete.deleteColumns(Bytes.toBytes("cf"), Bytes.toBytes(attend), System.currentTimeMillis()+Integer.MAX_VALUE);
      }
      rceTBL.delete(rceDelete);
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=connection){
        try {
          connection.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * 粉丝用户 去获取关注用户发布的微博内容:
   *  a. 从微博内容邮件表中获取该用户其关注用户的微博内容的rowkey
      b. 根据上面获取到的微博内容的rowkey 获取微博内容
   * @param uid
   *      粉丝用户ID
   */
  public List<Message> getAttendsContens(String uid){
    HConnection connection=null;
    List<Message> messages=new ArrayList<Message>();
    try {
      connection=HConnectionManager.createConnection(conf);
      //a. 从微博内容邮件表中获取该用户其关注用户的微博内容的rowkey
      HTableInterface rceTBL=connection.getTable(RECEIVE_CONTENT_EMAIL);
      Get get=new Get(Bytes.toBytes(uid));
      get.setMaxVersions(5);
      List<byte[]> rowkeys=new ArrayList<byte[]>();
      Result result=rceTBL.get(get);
      for(Cell cell:result.rawCells()){
        //CellUtil.cloneValue      获取value
        //CellUtil.cloneRow        获取rowkey
        //CellUtil.cloneQualifier  获取列名
        //CellUtil.cloneFamily     获取到列族名
        rowkeys.add(CellUtil.cloneValue(cell));
      }
      //b. 根据上面获取到的微博内容的rowkey 获取微博内容
      HTableInterface contentTBL =connection.getTable(CONTENT);
      List<Get> gets=new ArrayList<Get>();
      for (byte[] rk : rowkeys) {
        Get g=new Get(rk);
        gets.add(g);
      }
      Result[] results=contentTBL.get(gets);
      for (Result res : results) {
        for(Cell cell:res.rawCells()){
          Message message=new Message();
          String rowkey=Bytes.toString(CellUtil.cloneRow(cell));
          String userid=rowkey.substring(0, rowkey.indexOf("_"));
          String timestamp=rowkey.substring(rowkey.indexOf("_")+1);
          String content=Bytes.toString(CellUtil.cloneValue(cell));
          message.setUid(userid);
          message.setTimestamp(timestamp);
          message.setContent(content);
          messages.add(message);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(null!=connection){
        try {
          connection.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return messages;
  }
  public static void testInit(WeiBo wb){
    wb.initNameSpace();
    wb.initTable();
  }
  public static  void testPublishContent(WeiBo wb){
    wb.publishContent("0001", "Tomorrow will be better!");
    wb.publishContent("0001", "Tomorrow will be better!");
  }
  public static void testAddAttends(WeiBo wb){
    wb.publishContent("0008", "今天天气真不错!!!");
    wb.publishContent("0009", "今天天气真不错!!!");
    wb.addAttends("0001","0008","0009");
  }
  public static void testRemoveAttends(WeiBo wb){
    wb.removeAttends("0001", "0009");
  }
  public static void testGetAttendsContents(WeiBo wb){
    List<Message> messages=wb.getAttendsContens("0001");
    for (Message message : messages) {
      System.out.println(message);
    }
  }
  public static void main(String[] args) {
    WeiBo wb=new WeiBo();
    //testInit(wb);
    //testPublishContent(wb);
    testAddAttends(wb);
    //testRemoveAttends(wb);
  }
}


相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
SQL 关系型数据库 MySQL
Sqoop【付诸实践 01】Sqoop1最新版 MySQL与HDFS\Hive\HBase 核心导入导出案例分享+多个WRAN及Exception问题处理(一篇即可学会在日常工作中使用Sqoop)
【2月更文挑战第9天】Sqoop【付诸实践 01】Sqoop1最新版 MySQL与HDFS\Hive\HBase 核心导入导出案例分享+多个WRAN及Exception问题处理(一篇即可学会在日常工作中使用Sqoop)
259 7
|
6月前
|
数据可视化 JavaScript 关系型数据库
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(五)FineBI可视化
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(五)FineBI可视化
128 0
|
6月前
|
SQL 消息中间件 关系型数据库
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(四)实时计算需求及技术方案
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(四)实时计算需求及技术方案
186 0
|
6月前
|
SQL 消息中间件 分布式数据库
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(三)离线分析
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(三)离线分析
126 0
|
6月前
|
消息中间件 存储 数据采集
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(二)数据源
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(二)数据源
105 0
|
6月前
|
存储 消息中间件 分布式数据库
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(一)案例需求
基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(一)案例需求
102 0
|
11月前
|
存储 SQL 分布式数据库
分布式数据恢复-hbase+hive分布式存储数据恢复案例
hbase+hive分布式存储数据恢复环境: 16台某品牌R730XD服务器节点,每台物理服务器节点上有数台虚拟机,虚拟机上配置的分布式,上层部署hbase数据库+hive数据仓库。 hbase+hive分布式存储故障&初检: 数据库文件被误删除,数据库无法使用。 通过现场对该分布式环境的初步检测,发现虚拟机还可以正常启动,虚拟机里面的数据库块文件丢失。好在块文件丢失之后没有对集群环境写入数据,底层数据损坏可能性比较小。
|
分布式计算 分布式数据库 Scala
Spark查询Hbase小案例
写作目的 1)正好有些Spark连接HBase的需求,当个笔记本,到时候自己在写的时候,可以看 2)根据rowkey查询其实我还是查询了好久才找到,所以整理了一下 3)好久没发博客了,水一篇
211 0
Spark查询Hbase小案例
|
分布式数据库 Hbase
《HBase 基本知识介绍及典型案例分析》电子版地址
HBase 基本知识介绍及典型案例分析
83 0
《HBase 基本知识介绍及典型案例分析》电子版地址
|
存储 SQL 分布式计算
BigData之Hbase:Hbase数据管理的简介、下载、案例应用之详细攻略
BigData之Hbase:Hbase数据管理的简介、下载、案例应用之详细攻略
BigData之Hbase:Hbase数据管理的简介、下载、案例应用之详细攻略