1、索引概念

  • 举例
    • 一本新华字典,从里面找一个字
    • 有索引:这本新华字典有拼音检索的目录,可以按照拼音找字
    • 没有索引:没有目录,一页一页翻来找这个字
  • 问题
    • Hbase中rowkey是唯一索引
  • 假设:rowkey设计:时间_用户id
20200101_001
20200101_002
20200102_002
20200103_003
……
  • 走索引的查询
    • 根据日期查询
      • 查询2020年数据
    • 根据日期和用户id
      • 查询20200101,002的数据
  • 需求:查询002所有的数据
    • 只知道用户的id,怎么查询?
  • 全表扫描
    • 对所有数据的用户id进行过滤,将用户id=002的数据过滤出来
    • SingleColumnValueFilter
    • 性能非常差
  • 只要查询的 条件不是rowkey的前缀,就只能走全表扫描
  • 解决
    • 构建二级索引
    • 一级索引:rowkey
    • 二级索引:通过二级索引找到需要的一级索引

2、二级索引

  • 需求:查询002所有的数据
  • 举例
    • 原表:用于存储数据
      • rowkey的设计:时间_用户id
rowkey              userid          serverTime      username ip     url     ……
20200101_001        001             20200101
20200101_002        002             20200101
20200102_002        002             20200102
20200103_003        003             20200103
20200104_004        004             20200104
……
  • rowkey是唯一索引
  • 全表扫描
    • 对所有的rowkey的userid这一列进行比较
    • 如果是002,就返回
    • 不是就过滤
  • 索引表:用于存储原表的rowkey的
    • 二级索引表
    • rowkey:用户id_时间
rowkey              source_rk
001_20200101        20200101_001
002_20200101        20200101_002
002_20200102        20200102_002
003_20200103        20200103_003

二级索引检索过程

  • 第一步:先检索索引表,根据用户id,得到所有符合的原表的rowkey
    • 走索引
    • 根据前缀匹配返回两条
002_20200101        20200101_002
002_20200102        20200102_002
  • 第二步:再根据原表的rowkey到原表中进行查询
    • 走索引
20200101_002        002             20200101
20200102_002        002             20200102
  • 功能:基于一级索引构建二级索引,加快读取数据的速度
  • 应用场景:将不能满足rowkey前缀查询的条件作为索引表的rowkey,走两次索引来实现数据查询
    • 解决有些条件不在rowkey中或者不是前缀,依旧希望查询比较快

问题:原表数据如何与索引表保持一致,实现数据同步?

  • 如果不同步,查询结果就是不准确的
  • 问题举例
    • 原表:有004用户的数据
    • 索引表:没有这个映射关系
    • 通过二级索引查询:没有004的数据
  • 解决方案
    • 往Hbase中写入数据都是通过程序来处理的
    • 方案一:在客户端程序中往原表中插入数据以后,往索引也插入一条
      • 可以实现
      • 但是性能非常差:客户端本来只要写一条数据,但是提交了两个写入请求
      • 一般不用
    • 方案二:使用Hbase的协处理器来实现
      • 类似于UDF或者Mysql触发器
      • 开发一个程序,监听原表,只要用户往原表中写入数据,Hbase就自动往索引表写入一条数据
    • 方案三:使用第三方工具实现【主要】
      • ==Phoenix:==在底层封装了 大量的Hbase的协处理器,不用你自己开发
  • 你可以用SQL写:create index - 自动帮你创建一张索引表,自动帮你维护数据同步
  • ES:ELK中的搜索引擎,可以构建索引
  • Solr:也是搜索引擎

总结

Rowkey的设计

  • 业务原则:必须非常贴合业务设计rowkey
  • 唯一原则:每个rowkey唯一标识一行
  • 组合原则:将查询频率比较高的查询条件封装组合成rowkey
    • 可以利用rowkey进行索引查询
  • 散列原则构建随机散列的rowkey,避免有序的rowkey
    • region的范围就是有序的,如果rowkey也是有序的写入,就会写入同一个region,导致热点
  • 长度原则满足业务需求的情况下,越短越好
    • rowkey的存储是冗余的,在底层检索时,需要进行比较
  • 列族的设计
    • 长度原则
    • 个数原则:不建议超过3个
  • 列标签
    • 标识性

预分区

  • 先设计rowkey
  • 根据rowkey的格式来进行预分区创建表

二级索引

  • 什么是二级索引?
    • 基于一级索引之上构建一层索引
  • 为什么要构建二级索引?
    • 因为Hbase中rowkey是唯一的索引,并且只能做前缀匹配
    • 在查询时,如果查询的条件不是rowkey的前缀,只能全表扫描,性能比较差
    • 可以构建二级索引,经过两次索引来解决查询性能问题
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐