Hbase的三种索引_全局索引,覆盖索引,本地索引(七)
文章目录
[*]分布式NoSQL列存储数据库Hbase(七)
[*]
[*]知识点02:课程目标
[*]知识点03:Phoenix二级索引设计
[*]知识点04:二级索引:全局索引设计
[*]知识点05:二级索引:全局索引实现
[*]知识点06:二级索引:覆盖索引设计
[*]知识点07:二级索引:覆盖索引实现
[*]知识点08:二级索引:本地索引设计
[*]知识点09:二级索引:本地索引实现
[*]知识点10:二级索引:函数索引【了解】
[*]知识点11:集群角色功能:Master
[*]知识点12:集群角色功能:RegionServer
[*]知识点13:集群角色功能:HDFS与ZK
[*]知识点14:Hbase读写流程:写入流程
[*]知识点15:Hbase读写流程:meta表
[*]知识点14:Hbase读写流程:写入流程
[*]知识点15:Hbase读写流程:meta表
分布式NoSQL列存储数据库Hbase(七)
[*] 如何培养解决错误的能力
[*] Hbase启动以后,进程会自动消失?
[*] 运行程序时的一些报错?
[*] 所有错误都是有日志的
[*] 软件的错误:找到软件的日志
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2aGqsq2h-1616590200777)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324092337557.png)]
tail -100f logs/hbase-root-master-node1.log
[*] Java的程序错误:都是Exception
[*]根据Exception的错误,分析原因
[*]ArrayOutOfIndexException:数据越界异常
[*]引用了一个不存在的下标
[*]排查:引用元素的位置
[*]ConnectionException:Connection Refused:连接拒绝异常
[*]请求地址:hostname:port
[*]主机名不正确
[*]端口不对
[*]进程没有正常启动,端口没有开放
[*]NullException:空指针异常
[*]变量的值为null
[*]OutOfMemoryException:内存溢出异常
[*]内存空间存储不足
[*]ClassNotFoundException:类找不到
[*]缺少jar包,jar包有问题
[*]jar包冲突
[*]CastClassException:转换异常
[*] 建议
[*]第一:先百度,查询Exception
[*]第二:如果第一步解决不了,超过5分钟咨询老师
[*]第三:总结错误
[*]现象
[*]分析
[*]解决
知识点02:课程目标
[*]Phoenix实现二级索引
[*]为什么要构建二级索引?
[*]如何构建二级索引?【重点】
[*]全局索引
[*]覆盖索引
[*]本地索引
[*]三种索引区别和各自的应用场景
[*]Hbase整体读写流程
[*]集群中每个角色的具体功能
[*]Master
[*]RegionServer
[*]Hbase读写数据中:元数据的内容和检索过程==【重点】==
知识点03:Phoenix二级索引设计
[*] 目标
[*]基于Phoenix构建Hbase二级索引并维护二级索引
[*] 分析
[*]为什么需要构建二级索引?
[*]因为Hbase使用Rowkey作为唯一索引,无法满足大部分的查询走索引,导致性能较差
[*]构建二级索引:通过走两次索引代替全表扫描
[*]Phoenix如何实现二级索引?
[*]Phoenix底层构建了大量的协处理器,来实现二级索引的构建
[*] 实现
[*] step1:根据数据存储需求,创建原始数据表,将数据写入原始数据表
rowkey:idnameage
[*] step2:根据数据查询需求,构建二级索引,Phoenix自动创建索引表
create index indexName on tbName(colName);
rowkey:name_id
[*] step3:查询数据时,Phoenix根据过滤条件是否存在二级索引,优先判断走二级索引代替全表扫描
[*] step4:原始数据表发生数据变化时,Phoenix会自动更新索引表的数据
[*] 总结
[*]在Phoenix中二级索引实现完全由Phoenix自主实现
[*]不需要关心底层的实现,只需要使用语法创建索引即可
[*]http://phoenix.apache.org/secondary_indexing.html
知识点04:二级索引:全局索引设计
[*] 目标
[*]了解二级索引中全局索引的设计思想
[*] 分析
[*]什么是全局索引?
[*]当为某一列创建全局索引时,Phoenix自动创建一张索引表,将创建索引的这一列加上原表的rowkey作为新的rowkey
[*] 实现
[*] 原始数据表
rowkey:idnameage
[*] 需求:根据name进行数据查询
[*] 创建全局索引
create index index01 on tbname(name);
[*] 自动构建索引表
rowkey:name_idcol:占位值
[*] 查询
[*]先查询索引表:通过rowkey获取名称对应的id
[*]再查询数据表:通过id查询对应的数据
[*] 总结
[*] **特点:**默认只能对构建索引的字段做索引查询,如果查询中包含了不是索引的字段或者条件不是索引字段,不走索引
[*] 走索引
select name from table
select name from table where name = value
[*] 不走索引
select * from table where name = value
[*] **应用:**写少读多
[*]当原表的数据发生更新操作提交时,会被拦截
[*]先更新所有索引表,然后再更新原表
知识点05:二级索引:全局索引实现
[*] 目标
[*]基于Phoenix实现全局索引的测试
[*] 分析
[*]step1:先创建原始数据表
[*]step2:基于查询条件创建索引
[*]step3:实现索引查询
[*] 实现
[*] 不构建索引,先查询,查看执行计划
select "user_id" from ORDER_DTL where "user_id" = '8237476';
explain select "user_id" from ORDER_DTL where "user_id" = '8237476';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DCGxHMk7-1616590200779)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324102219687.png)]
[*] 基于user_id构建全局索引
create index GBL_IDX_ORDER_DTL on ORDER_DTL(C1."user_id");
[*] 查看索引表
!tables
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dmsKS7ME-1616590200780)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324102348151.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HLoZolzn-1616590200781)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324102530846.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TQk7O8T7-1616590200782)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324102548631.png)]
[*] 查询数据及查询计划
select "user_id" from ORDER_DTL where "user_id" = '8237476';
explain select "user_id" from ORDER_DTL where "user_id" = '8237476';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rr9tNjVj-1616590200783)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324102631657.png)]
[*] 如果查询条件不是索引字段
explain select "user_id" from ORDER_DTL where "money" = 9390.0;
[*] 如果查询内容不是索引字段,查看执行计划
explain select "user_id", "id", "money" from ORDER_DTL where "user_id" = '8237476';
[*] 强制走索引
explain select /*+ INDEX(ORDER_DTL GBL_IDX_ORDER_DTL) */ * from ORDER_DTL where "user_id" = '8237476';
[*] 删除索引
drop index GBL_IDX_ORDER_DTL on ORDER_DTL;
[*] 总结
[*]全局索引是最常用的基础二级索引类型
[*]索引表结构
[*]rowkey:查询条件字段 + 原表rowkey
[*]应用:适合于读多写少的场景
[*]特点:如果查询条件或者查询内容中包含非索引字段,将不走索引,可以强制走索引
知识点06:二级索引:覆盖索引设计
[*] 目标
[*]了解二级索引中覆盖索引的设计思想
[*] 分析
[*]什么是覆盖索引?
[*]在构建全局索引时,将经常作为查询条件的列放入索引表中,直接通过索引表来返回数据结果
[*] 实现
[*] 原始数据表
rowkey:idnameageaddrphone
[*] 需求:根据name进行数据查询
[*] 创建全局索引
create index index01 on tbname(name);
[*] 自动构建索引表
rowkey:name_idcol:占位值
[*] 如果需求发生改变,查询name和age,上面的全局索引会失效
[*] 创建全局+覆盖:include(age)
create index index01 on tbname(name) include(age);
[*] 自动构建索引表
rowkey:name_idcol:age
select name from table;
select name from table where age = 20
select name , age from table
[*] 总结
[*]**特点:**基于全局索引构建,将常用的查询结果放入索引表中,直接从索引表返回结果
[*]**应用:**适合于查询条件比较固定,数据量比较小的场景下
[*]注意:不建议将大部分列都放入覆盖索引,导致索引表过大,性能降低
知识点07:二级索引:覆盖索引实现
[*] 目标
[*]基于Phoenix实现覆盖索引的测试
[*] 分析
[*]step1:先创建原始数据表
[*]step2:基于查询条件创建覆盖索引
[*]step3:实现索引查询
[*] 实现
[*] 不构建索引,先查询,查看执行计划
select "user_id", "id", "money" from ORDER_DTL where "user_id" = '8237476';
explain select "user_id", "id", "money" from ORDER_DTL where "user_id" = '8237476';
[*] 基于user_id构建全局索引,运行通过user_id查询订单id和支付金额
create index GBL_IDX_ORDER_DTL on ORDER_DTL(C1."user_id") INCLUDE("id", C1."money");
[*] 查看索引表
!tables
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeyeOlZG-1616590200784)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324104259966.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJodnjuq-1616590200784)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324104408082.png)]
[*] 查询数据
select "user_id", "id", "money" from ORDER_DTL where "user_id" = '8237476';
[*] 查看执行计划
explain select "user_id", "id", "money" from ORDER_DTL where "user_id" = '8237476';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oWBK8XF7-1616590200785)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324104452747.png)]
[*] 如果查询条件不是索引字段
explain select “user_id”, “id”, “money” from ORDER_DTL where “pay_way” = 1;
- 如果查询内容不是索引字段,查看执行计划
```sql
explain select "user_id", "id", "pay_way" from ORDER_DTL where "user_id" = '8237476';
[*] 使用HINT强制走索引
explain select /*+ INDEX(ORDER_DTL GBL_IDX_ORDER_DTL) */ * from ORDER_DTL where "user_id" = '8237476';
[*] 删除索引
drop index GBL_IDX_ORDER_DTL on ORDER_DTL;
[*] 总结
[*] 覆盖索引是基于全局索引实现的
[*] 目的是将常用的查询结果放入索引表中,直接从索引表返回数据
知识点08:二级索引:本地索引设计
[*] 目标
[*]了解二级索引中本地索引的设计思想
[*] 分析
[*]什么是本地索引?
[*]将索引数据与对应的原始数据放在同一台机器,避免了跨网络传输,提高了写的性能
[*] 实现
[*]构建索引数据时,将索引数据直接存储在原表中,用一个列族来实现
[*] 总结
[*]特点
[*]即使查询数据中包含了非索引字段,也会走本地索引
[*]本地索引会修改原始数据
[*]如果构建了本地索引,不能通过Hbase的API来读写数据的,必须通过Phoenix来实现读写
[*]本地索引对盐表不生效的
[*]应用:写多读少
[*]提高构建索引时对写的性能的影响
[*]最终所有索引都是为了提高读的性能的
知识点09:二级索引:本地索引实现
知识点10:二级索引:函数索引【了解】
[*] 目标
[*]了解Hbase中的函数索引的概念
[*] 分析
[*]本地、覆盖、全局:都是基于查询的列构建索引
[*]什么是函数索引?
[*]可以基于一个函数表达式去构建索引
[*] 实现
[*] 查询:过滤的条件是一个函数
SELECT EMP_ID FROM EMP WHERE UPPER(FIRST_NAME||' '||LAST_NAME)='JOHN DOE'
[*] 构建索引
CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))
[*] Hive中
[*] SQL:语法
[*] 函数
[*] 字符串
[*]substr
[*] replace_regex
[*] concat/concat_ws
[*]concat:直接拼接每个字符串,只有有1列为null,整个结果为null
concat(str1,str2,str3……)
[*] concat_ws:可以指定分隔符,只要有1列不为null,整个结果不为null
concat(分隔符,str1,str2,str3……)
[*] instr
[*] ……
[*] 日期
[*]转换类:from_unix,unix_timestamp
[*]获取:year、ceil、quator、month、day、hour
[*] 条件
[*]if
[*]case when
[*] JSON处理:json_tuple,get_json_object
[*] 窗口函数:重点:row_number,rank,dense_rank,lead,lag,sum
[*] URL解析:parse_url_tuple
[*] 总结
[*]函数索引就是基于函数表达式创建索引,当执行相同的函数表达式查询时,可以通过索引实现快速查询
[*]一般不用
知识点11:集群角色功能:Master
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5qsDzwNT-1616590200786)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210323223056968.png)]
[*] 管理所有从节点:RegionServer
[*] 监听Regionserver的状态,如果RegionServer发生故障,会实现这台RegionServer的数据恢复
[*] 基本原理:所有RegionServer会在ZK中注册一个临时节点,Master会监听Zookeeper中的这些节点
[*]类似于HA选举的原理
[*] 数据是如何恢复的?
[*] 数据存储的位置
[*] 内存:RegionServer的内存中
[*] 如果RegionServer断电故障,内存中的数据丢失
[*] 解决:通过持久化日志来实现
[*] WAL:HLog,write ahead log:预写日志
[*]数据在写入内存之前,会将这个操作记录在WAL中
[*]如果内存数据丢失,可以通过WAL进行恢复
[*]存储在HDFS上
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JK77zwSO-1616590200786)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324113740340.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGdmPWuF-1616590200786)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324113753586.png)]
[*] 磁盘:HDFS中
[*]如果RegionServer故障,不影响HDFS的数据
[*] 管理元数据
[*]Master会接受所有DDL请求
[*]Master启动时会加载meta表和namespace的数据,获取元数据记录在ZK中
[*]Master会将所有管理类的元数据存储在ZK中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lohj84Ke-1616590200787)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210324114021119.png)]
[*] 管理Region的分配
[*]创建表、分配region
[*]regionserver故障,重新分配region到别的regionserver上
[*]region分裂,将新的region分配到regionserver上
知识点12:集群角色功能:RegionServer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9prEEpeU-1616590200787)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210323223219354.png)]
[*]负责管理所有Region的数据读写,接受客户端对于region的读写请求
[*]维护所有存储角色
[*] WAL:write ahead log:预写日志
[*] Region:存储分区
[*] Store:列族,存储单元
[*] Memstore:写缓存,数据先写入MemStore
[*] BlockCache:读缓存,如果第一次从HDFS中读取,可以配置将读取的结果放入读缓存,下次直接从读缓存中读取
[*] 读的顺序
[*] 先读memstore
[*] 如果没有,数据在HDFS的文件中:怎么能让Hbase读HDFS文件能很快?
[*]Rowkey是有序的
[*]列族的设计
[*]二进制文件
[*] 可以指定对列族的数据是否开启读缓存,如果开启了读缓存
[*] 第一次从HDFS读取完成以后,将结果放入读缓存BlockCache:内存区域
[*] 第二次开始
[*] 先读memstore
[*] 再读Blockcache
[*] 再读HDFS
[*] StoreFile:如果MemStore存储的容量达到一定条件,将MEMStore中的数据写入HDFS
[*]实现分布式内存存储
知识点13:集群角色功能:HDFS与ZK
[*] HDFS功能
[*]用于实现HBASE大量数据的持久化存储
[*]当MemStore中的数据过多,就会进行Flush【Spill】:将数据从内存溢写到HDFS上
[*] ZooKeeper功能
[*]用于实现HMaster的HA,辅助选举
[*]用于存储核心元数据:管理元数据
[*]供Master实现管理操作
[*]Hbase中有哪些ns、哪些表、哪些rs、master是谁,正在执行的操作
[*]表的元数据不在Zookeeper中
[*]表的元数据在meta表中
[*]表的元数据:表有几个region,每个region的范围、region所在的地址
知识点14:Hbase读写流程:写入流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iB5AlLvh-1616590200788)(20210324_分布式NoSQL列存储数据库Hbase(七).assets/image-20210323223403690.png)]
[*] 目标
[*] 掌握Hbase数据写入的流程
[*] 当执行一条Put操作,数据是如何写入Hbase的?
put 表名rowkey列族:列值
[*] 分析
[*] step1:根据表名获取这张表对应的所有Region的信息
[*] step2:根据Rowkey判断具体写入哪个Region
[*] step3:将put操作提交给这个Region所在的RegionServer
[*] step4:RegionServer将数据写入Region,根据列族判断写入哪个Store
[*] 总结
知识点15:Hbase读写流程:meta表
[*] 目标
[*]了解hbase:meta表的存储内容及功能
[*]问题1:如何知道这张表对应的region有哪些?
[*]问题2:如何知道每个Region的范围的?
[*]问题3:如何知道Region所在的RegionServer地址的?
[*] 分析
[*]肯定有个地方存储了表与Region的关系以及Region的信息
[*] 实现
[*]hbase:meta表
[*] 总结
中的数据过多,就会进行Flush【Spill】:将数据从内存溢写到HDFS上
[*] ZooKeeper功能
[*]用于实现HMaster的HA,辅助选举
[*]用于存储核心元数据:管理元数据
[*]供Master实现管理操作
[*]Hbase中有哪些ns、哪些表、哪些rs、master是谁,正在执行的操作
[*]表的元数据不在Zookeeper中
[*]表的元数据在meta表中
[*]表的元数据:表有几个region,每个region的范围、region所在的地址
知识点14:Hbase读写流程:写入流程
[外链图片转存中…(img-iB5AlLvh-1616590200788)]
[*] 目标
[*] 掌握Hbase数据写入的流程
[*] 当执行一条Put操作,数据是如何写入Hbase的?
put 表名rowkey列族:列值
[*] 分析
[*] step1:根据表名获取这张表对应的所有Region的信息
[*] step2:根据Rowkey判断具体写入哪个Region
[*] step3:将put操作提交给这个Region所在的RegionServer
[*] step4:RegionServer将数据写入Region,根据列族判断写入哪个Store
[*] 总结
知识点15:Hbase读写流程:meta表
[*] 目标
[*]了解hbase:meta表的存储内容及功能
[*]问题1:如何知道这张表对应的region有哪些?
[*]问题2:如何知道每个Region的范围的?
[*]问题3:如何知道Region所在的RegionServer地址的?
[*] 分析
[*]肯定有个地方存储了表与Region的关系以及Region的信息
[*] 实现
[*]hbase:meta表
[*] 总结
页:
[1]