首页 > 其他分享 >Hbase的表设计

Hbase的表设计

时间:2024-07-23 19:52:12浏览次数:12  
标签:列族 Bytes 用户 关注 设计 Hbase config hbase

Hbase的表设计

一、应用背景

微博:用户表users、微博表weibos、用户关系表relations,和具体哪个公司的微博没关系。

微博中的用户想关注其他用户的微博,首先要维护一个特定用户的关注列表,例如张三关注了李四和王五。

为了要的得到张三应该看到的所有微博,你需要查找列表{李四、王五},然后读出列表中每个用户的所有微博,这个信息需要保存在hbase中。

二、表模式(Schema)设计应该考虑的问题

  • 这个表应该保存多少个列族
  • 列族使用什么数据
  • 每个列族应该有多少列
  • 列名应该是什么
  • 每个单元(Cell)存储多少时间版本
  • 行健结构是什么?应该包括什么信息?

三、问题建模

问题分析:关系表需要存储一个特定用户关注什么用户的数据。

表的访问模式:

  • 读出全部用户列表。张三关注人的列表
  • 查询某指定用户是否在列表里。如张三是否关注了李四

需要几个列族呢?

   张三的关注对象里的所有用户,都有可能被确认是否存在,从访问模式看无法区分彼此,不能假定一个用户比其他用户的被访问的可能性大,推断被关注用户需要同一个列族。

  原因:同一个列族的数据存储在同一个物理存储(store)里面,这个物理存储被分为多个Hfile,理想情况下合并为一个Hfile。一个列族的所有列在物理上存在一起,使用这种模式可以把不同访问模式的列放在不同的列族,以便隔离他们。即Hbase被称为是面向列族存储的。

    初始表设计为:

           说明:follws:1--->TheRealMT.

 

三、定义访问模式(读模式,写模式)

这张表用来干嘛?

  • 张三关注了谁?
  • 张三关注李四了吗?
  • 谁关注了张三?
  • 李四关注张三了吗?

表创建脚本:

1.创建关系表
create 'relation',{NAME => 'follows', VERSIONS => 2}
2.添加数据
put 'relation','zhansan','follows:1','lisi'
put 'relation','zhansan','follows:2','wangwu'

回答第一个问题:张三关注了谁?

复制代码
  @Test
       public void demo2() throws Exception{
           Configuration config = HBaseConfiguration.create();
           config.set("hbase.zookeeper.quorum", "node1,node2,node3");
           HTable table = new HTable(config, "relation");
           String rowKey = "zhansan";
           Get get = new Get(Bytes.toBytes(rowKey));
           List<String> fllowed = new ArrayList<String>();
           Result rs = table.get(get);
           List<KeyValue> list = rs.list();
           Iterator<KeyValue> it = list.iterator();
           while(it.hasNext()){
               KeyValue kv = it.next();
               System.out.println(Bytes.toString(kv.getValue()));
               fllowed.add(Bytes.toString(kv.getValue()));
          }
           table.close();
       }
复制代码

回答第二个问题:张三关注李四了谁?

复制代码
     public static boolean  demo3() throws Exception{
           Configuration config = HBaseConfiguration.create();
           config.set("hbase.zookeeper.quorum", "node1,node2,node3");
           HTable table = new HTable(config, "relation");
           String rowKey = "zhansan";
        Get get = new Get(Bytes.toBytes(rowKey));
        //要查询的对象
        String followUser = "lisi";
           Result rs = table.get(get);
        List<KeyValue> list = rs.list();
        Iterator<KeyValue> it = list.iterator();
        while(it.hasNext()){
            KeyValue kv = it.next();
            System.out.println(followUser.equals(Bytes.toString(kv.getValue())));
            //followUser
            if(followUser.equals(Bytes.toString(kv.getValue())));
                return true;
        }
        return false;
       }
复制代码

现在我们这样的回答能简单回答第一个和第二个问题,另外另个不确定,但是这两个问题的回答都属于表的读模式。

让我么来看看表的写模式:以下应用场景会引发hbase表的写模式

  • 一个用户关注了某人
  • 一个用户取消关注了某人

当用户新增一个新的关注的时候,需要在用户的关注列表里新增一个对象,如之前的表设计,TheFakeMT新增一个关注用户的时候,需要知道这个

用户是用户列表里的第5个,如果不查询hbase客户端并不知道这个信息,还有不指定列限定符,也没办法要求Hbase在已有的行上增加一个单元。

不清楚要插入的列的位置,会出现数据覆盖。

解决办法:

         在同一行维护一个计数器。如下图所示;

  

优点:count列能有效的让任何用户知道所关注的用户数量,避免遍历整个关注列表。

基于现在的表设计,插入关注用户的步骤如下:

这种表设计的确定:

  • 增加了客户端代码的复杂性,写入需要四步
  • hbase不支持事务,线程不安全

怎么解决????--->去掉count计数器

新的表设计如下:

表设计说明:

  • 列限定符设计为被关注人的用户名(用户id)
  • cell的内容可以随便存储内容,可以存储1
  • hbase把一切数据存储为byte[](字节数组),可以存储任意数量的列
  • 这就是传说中的宽表设计,宽表的设计会便于检索数据
  • 由于用户id的是唯一的,所以不会出现数据覆盖

客户端代码:

复制代码
public static void  demo4() throws Exception{
           Configuration config = HBaseConfiguration.create();
           config.set("hbase.zookeeper.quorum", "node1,node2,node3");
           HTable table = new HTable(config, "relation");
           String rowKey = "zhansan";
           Put put = new Put(Bytes.toBytes(rowKey));
          //要存储的对象
           String followUser = "chaosju";
           put.add(Bytes.toBytes("follows"),
                Bytes.toBytes(followUser), 
                Bytes.toBytes(1));
           table.put(put);
           table.close();
       }
复制代码 复制代码
hbase(main):018:0> scan 'relation'
ROW                                COLUMN+CELL                                                                                       
 zhansan                           column=follows:1, timestamp=1442106287998, value=lisi                                             
 zhansan                           column=follows:2, timestamp=1442106352630, value=wangwu                                           
 zhansan                           column=follows:chaosju, timestamp=1442109774792, value=\x00\x00\x00\x01                           
1 row(s) in 0.1640 seconds
复制代码

学到的东西:

  • hbase没有跨行事务的概念,避开客户端使用复杂的业务逻辑

四、均衡分布数据和负载

背景分析:基于上述的表设计

  • 一个人可能关注很多人,这个表会特别长,这本身不是问题,但会影响读模式。如TheFakeMT关注了TheRealMT吗?如何使用这个表回答这个问题呢,行健指定TheFakeMT,列限定符指定TheRealMT,一个Get请求即可。

follows表的另一种设计——高表(high table)设计

优点:

  • 短的列族和列限定名,减少网络io和磁盘空间占用

具体的存储数据样式:

回答张三是否关注了李四???

      先进性一次索引查找,先找到第一个以张三为前缀的第一个数据块,然后以张三开头的行健对所有数据行进行最后一次扫描。

优化设计,及高表的优点:

  • MD5(user1ID)MD5(user2ID)作为rowkey,使得数据均匀的分布在region上,避免热点问题
  • rowkey长度统一,便于预测读写性能
  • 去掉分隔符,更容易扫描计算起始和停止键

hbase热点问题???数据倾斜

热点:数据集中分布在一小部分region上。

例如插入时间序列数据,行健开头是时间戳,因为任何写入的数据的时间戳都是大于之前写入的时间戳,数据总是追加在表的尾部,最后的region会成为热点。

基于MD5_rowkey的设计

如果需要查找,用户id,客户把用户id保存为列限定符。  

 表设计总结:

原文链接:https://www.cnblogs.com/ChaosJu/p/4807607.html

标签:列族,Bytes,用户,关注,设计,Hbase,config,hbase
From: https://www.cnblogs.com/sunny3158/p/18319457

相关文章

  • Vue 在大型项目中的架构设计和最佳实践
    前面分享了很多八股和算法,现在开始慢慢进入项目搭建随着项目规模的扩大,合理的架构设计和最佳实践变得尤为重要。一个良好的架构能够提高开发效率、维护性和可扩展性。本文将探讨在大型Vue项目中,如何进行架构设计并遵循最佳实践。一、项目结构一个清晰的项目结构有助于代码的......
  • 在设计电子产品时,如何平衡抗震和抗振需求以确保产品的整体性能?
            在电子产品的设计中,抗震和抗振需求是两个重要的考量因素,它们虽然在目标上有所重叠,即都是为了确保产品在各种使用环境下的可靠性和稳定性,但它们的侧重点和应对措施有所不同:抗震需求:定义:抗震需求通常指的是电子产品在设计时需要考虑到的抵抗外部冲击和震动的......
  • hbase 增加列簇 api
    hbase增加列簇apiHBase增加列簇APIHBase是一个分布式、可扩展、高性能的NoSQL数据库,常用于存储大量结构化数据。在HBase中,数据以行和列族的形式存储。每行可以包含多个列族,每个列族可以包含多个列。在实际应用中,有时候需要在已有的表中增加新的列族来存储额外的数据,这......
  • C语言程序设计第三讲:选择结构程序设计
    1.选择结构概述定义与重要性:选择结构使得程序可以根据不同的条件执行不同的代码段。2.if语句详解基本形式:if(表达式)语句;:当表达式为真时执行语句。基本形式示例:inta=10;if(a>5){printf("aisgreaterthan5\n");}扩展形式:if(表......
  • java毕业设计-基于微信小程序的蛋糕订购商城系统设计与实现,基于springboot+vue+微信小
    文章目录前言演示视频项目背景项目架构和内容获取(文末获取)具体实现截图用户微信小程序端管理后台技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站项目相关文件前言博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • oss模块设计之适配器模式改造minio
    在进行本节的笔记之前,我们先进行对oss服务与minio做一个简单介绍,方便大家更便于理解;OSS服务(ObjectStorageService)OSS服务,即对象存储服务,是一种用于云端的大规模、高可用、安全、低成本的数据存储服务。它主要用于存储非结构化的数据,如图片、音频、视频、文档等文件。OSS服务具......
  • 500个计算机毕业设计项目分享(源码+论文+PPT)
    计算机毕业设计项目分享(源码+论文+PPT)需要链接请私信我哦!部分选题参考基于生鲜仓储管理系统的设计与实现基于Java的电竞酒店管理系统设计与实现基于Javaweb的电动车租借的信息管理系统的设计与实现基于微信小程序的小说阅读系统基于Android平台的广州二手手机商城设计......
  • 【java计算机毕设】在线教学平台MySQL springboot vue HTML maven小组设计项目源代码+
    目录1项目功能2项目介绍3项目地址1项目功能【java计算机毕设】在线教学平台MySQLspringbootvueHTMLmaven小组设计项目源代码+文档寒暑假作业 2项目介绍系统功能:在线教学平台包括管理员、用户、教师三种角色。管理员功能包括个人中心模块用于修改个人信息......
  • 计算机组成实验——运算器的设计
    要求采用原理图输入方式设计顶层文件,实现ALU与寄存器组的集成。将8位ALU和寄存器组设计文件分别进行编译,将ALU和寄存器组设计文件生成两个模块符号。新建一个原理图设计文件,调入ALU和寄存器组的符号模块,把这两个模块进行连接,加上输入端和输出端,实现二者的集成。ALU......
  • 【设计模式】建造者模式
    设计模式的分类:        创建型模式:这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用new运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。        工厂模式、抽象工厂模式、单例模式、建造者模式......