Hbase的三种索引_全局索引,覆盖索引,本地索引(七)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Hbase的三种索引_全局索引,覆盖索引,本地索引(七)

分布式NoSQL列存储数据库Hbase(七)

  1. 如何培养解决错误的能力
  • 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:课程目标

  1. Phoenix实现二级索引
  • 为什么要构建二级索引?
  • 如何构建二级索引?【重点】
  • 全局索引
  • 覆盖索引
  • 本地索引
  • 三种索引区别和各自的应用场景
  1. Hbase整体读写流程
  • 集群中每个角色的具体功能
  • Master
  • RegionServer
  • Hbase读写数据中:元数据的内容和检索过程==【重点】==

知识点03:Phoenix二级索引设计

  • 目标
  • 基于Phoenix构建Hbase二级索引并维护二级索引
  • 分析
  • 为什么需要构建二级索引?
  • 因为Hbase使用Rowkey作为唯一索引,无法满足大部分的查询走索引,导致性能较差
  • 构建二级索引:通过走两次索引代替全表扫描
  • Phoenix如何实现二级索引?
  • Phoenix底层构建了大量的协处理器,来实现二级索引的构建
  • 实现
  • step1:根据数据存储需求,创建原始数据表,将数据写入原始数据表
rowkey:id   name    age
  • step2:根据数据查询需求,构建二级索引,Phoenix自动创建索引表
create index indexName on tbName(colName);
rowkey:name_id
  • step3:查询数据时,Phoenix根据过滤条件是否存在二级索引,优先判断走二级索引代替全表扫描
  • step4:原始数据表发生数据变化时,Phoenix会自动更新索引表的数据
  • 总结

知识点04:二级索引:全局索引设计

  • 目标
  • 了解二级索引中全局索引的设计思想
  • 分析
  • 什么是全局索引?
  • 当为某一列创建全局索引时,Phoenix自动创建一张索引表,将创建索引的这一列加上原表的rowkey作为新的rowkey
  • 实现
  • 原始数据表
rowkey:id   name    age
  • 需求:根据name进行数据查询
  • 创建全局索引
create index index01 on tbname(name);
  • 自动构建索引表
rowkey:name_id    col:占位值
  • 查询
  • 先查询索引表:通过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:id   name    age   addr    phone
  • 需求:根据name进行数据查询
  • 创建全局索引
create index index01 on tbname(name);
  • 自动构建索引表
rowkey:name_id    col:占位值
  • 如果需求发生改变,查询name和age,上面的全局索引会失效
  • 创建全局+覆盖:include(age)
create index index01 on tbname(name) include(age);
  • 自动构建索引表
rowkey:name_id    col: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:二级索引:本地索引实现

  • 目标
  • 基于Phoenix实现本地索引的测试
  • 分析
  • step1:先创建原始数据表
  • step2:基于查询条件创建本地索引
  • step3:实现索引查询
  • 实现
  • 关闭Hbase及Phoenix
  • 修改hbase-site.xml中Zookeeper的连接,所有Hbase节点及Phoenix的bin目录下
<property>
    <name>hbase.zookeeper.quorum</name>
    <value>node1,node2,node3:2181</value>
  </property>
  • 重启Hbase和Phoenix
  • 删除表
drop table if exists ORDER_DTL;
create table if not exists ORDER_DTL(
    "id" varchar primary key,
    C1."status" varchar,
    C1."money" float,
    C1."pay_way" integer,
    C1."user_id" varchar,
    C1."operation_time" varchar,
    C1."category" varchar
) 
CONPRESSION='GZ';
UPSERT INTO "ORDER_DTL" VALUES('02602f66-adc7-40d4-8485-76b5632b5b53','已提交',4070,1,'4944191','2020-04-25 12:09:16','手机;');
UPSERT INTO "ORDER_DTL" VALUES('0968a418-f2bc-49b4-b9a9-2157cf214cfd','已完成',4350,1,'1625615','2020-04-25 12:09:37','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('0e01edba-5e55-425e-837a-7efb91c56630','已提交',6370,3,'3919700','2020-04-25 12:09:39','男装;男鞋;');
UPSERT INTO "ORDER_DTL" VALUES('0f46d542-34cb-4ef4-b7fe-6dcfa5f14751','已付款',9380,1,'2993700','2020-04-25 12:09:46','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('1fb7c50f-9e26-4aa8-a140-a03d0de78729','已完成',6400,2,'5037058','2020-04-25 12:10:13','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('23275016-996b-420c-8edc-3e3b41de1aee','已付款',280,1,'3018827','2020-04-25 12:09:53','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('2375a7cf-c206-4ac0-8de4-863e7ffae27b','已完成',5600,1,'6489579','2020-04-25 12:08:55','食品;家用电器;');
UPSERT INTO "ORDER_DTL" VALUES('269fe10c-740b-4fdb-ad25-7939094073de','已提交',8340,2,'2948003','2020-04-25 12:09:26','男装;男鞋;');
UPSERT INTO "ORDER_DTL" VALUES('2849fa34-6513-44d6-8f66-97bccb3a31a1','已提交',7060,2,'2092774','2020-04-25 12:09:38','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('28b7e793-6d14-455b-91b3-0bd8b23b610c','已提交',640,3,'7152356','2020-04-25 12:09:49','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('2909b28a-5085-4f1d-b01e-a34fbaf6ce37','已提交',9390,3,'8237476','2020-04-25 12:10:08','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('2a01dfe5-f5dc-4140-b31b-a6ee27a6e51e','已提交',7490,2,'7813118','2020-04-25 12:09:05','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('2b86ab90-3180-4940-b624-c936a1e7568d','已付款',5360,2,'5301038','2020-04-25 12:08:50','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('2e19fbe8-7970-4d62-8e8f-d364afc2dd41','已付款',6490,0,'3141181','2020-04-25 12:09:22','食品;家用电器;');
UPSERT INTO "ORDER_DTL" VALUES('2fc28d36-dca0-49e8-bad0-42d0602bdb40','已付款',3820,1,'9054826','2020-04-25 12:10:04','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('31477850-8b15-4f1b-9ec3-939f7dc47241','已提交',4650,2,'5837271','2020-04-25 12:08:52','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('39319322-2d80-41e7-a862-8b8858e63316','已提交',5000,1,'5686435','2020-04-25 12:08:51','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('3d2254bd-c25a-404f-8e42-2faa4929a629','已完成',5000,1,'1274270','2020-04-25 12:08:43','男装;男鞋;');
UPSERT INTO "ORDER_DTL" VALUES('42f7fe21-55a3-416f-9535-baa222cc0098','已完成',3600,2,'2661641','2020-04-25 12:09:58','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('44231dbb-9e58-4f1a-8c83-be1aa814be83','已提交',3950,1,'3855371','2020-04-25 12:08:39','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('526e33d2-a095-4e19-b759-0017b13666ca','已完成',3280,0,'5553283','2020-04-25 12:09:01','食品;家用电器;');
UPSERT INTO "ORDER_DTL" VALUES('5a6932f4-b4a4-4a1a-b082-2475d13f9240','已提交',50,2,'1764961','2020-04-25 12:10:07','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('5fc0093c-59a3-417b-a9ff-104b9789b530','已提交',6310,2,'1292805','2020-04-25 12:09:36','男装;男鞋;');
UPSERT INTO "ORDER_DTL" VALUES('605c6dd8-123b-4088-a047-e9f377fcd866','已完成',8980,2,'6202324','2020-04-25 12:09:54','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('613cfd50-55c7-44d2-bb67-995f72c488ea','已完成',6830,3,'6977236','2020-04-25 12:10:06','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('62246ac1-3dcb-4f2c-8943-800c9216c29f','已提交',8610,1,'5264116','2020-04-25 12:09:14','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('625c7fef-de87-428a-b581-a63c71059b14','已提交',5970,0,'8051757','2020-04-25 12:09:07','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('6d43c490-58ab-4e23-b399-dda862e06481','已提交',4570,0,'5514248','2020-04-25 12:09:34','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('70fa0ae0-6c02-4cfa-91a9-6ad929fe6b1b','已付款',4100,1,'8598963','2020-04-25 12:09:08','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('7170ce71-1fc0-4b6e-a339-67f525536dcd','已完成',9740,1,'4816392','2020-04-25 12:09:51','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('71961b06-290b-457d-bbe0-86acb013b0e3','已完成',6550,3,'2393699','2020-04-25 12:08:49','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('72dc148e-ce64-432d-b99f-61c389cb82cd','已提交',4090,1,'2536942','2020-04-25 12:10:12','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('7c0c1668-b783-413f-afc4-678a5a6d1033','已完成',3850,3,'6803936','2020-04-25 12:09:20','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('7fa02f7a-10df-4247-9935-94c8b7d4dbc0','已提交',1060,0,'6119810','2020-04-25 12:09:21','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('820c5e83-f2e0-42d4-b5f0-83802c75addc','已付款',9270,2,'5818454','2020-04-25 12:10:09','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('83ed55ec-a439-44e0-8fe0-acb7703fb691','已完成',8380,2,'6804703','2020-04-25 12:09:52','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('85287268-f139-4d59-8087-23fa6454de9d','已取消',9750,1,'4382852','2020-04-25 12:10:00','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('8d32669e-327a-4802-89f4-2e91303aee59','已提交',9390,1,'4182962','2020-04-25 12:09:57','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('8dadc2e4-63f1-490f-9182-793be64fed76','已付款',9350,1,'5937549','2020-04-25 12:09:02','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('94ad8ee0-8898-442c-8cb1-083a4b609616','已提交',4370,0,'4666456','2020-04-25 12:09:13','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('994cbb44-f0ee-45ff-a4f4-76c87bc2b972','已付款',3190,3,'3200759','2020-04-25 12:09:25','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('9ff3032c-8679-4247-9e6f-4caf2dc93aff','已提交',850,0,'8835231','2020-04-25 12:09:40','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('9ff3032c-8679-4247-9e6f-4caf2dc93aff','已付款',850,0,'8835231','2020-04-25 12:09:45','食品;家用电器;');
UPSERT INTO "ORDER_DTL" VALUES('a467ba42-f91e-48a0-865e-1703aaa45e0e','已提交',8040,0,'8206022','2020-04-25 12:09:50','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('a5302f47-96d9-41b4-a14c-c7a508f59282','已付款',8570,2,'5319315','2020-04-25 12:08:44','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('a5b57bec-6235-45f4-bd7e-6deb5cd1e008','已提交',5700,3,'6486444','2020-04-25 12:09:27','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('ae5c3363-cf8f-48a9-9676-701a7b0a7ca5','已付款',7460,1,'2379296','2020-04-25 12:09:23','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('b1fb2399-7cf2-4af5-960a-a4d77f4803b8','已提交',2690,3,'6686018','2020-04-25 12:09:55','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('b21c7dbd-dabd-4610-94b9-d7039866a8eb','已提交',6310,2,'1552851','2020-04-25 12:09:15','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('b4bfd4b7-51f5-480e-9e23-8b1579e36248','已提交',4000,1,'3260372','2020-04-25 12:09:35','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('b63983cc-2b59-4992-84c6-9810526d0282','已提交',7370,3,'3107867','2020-04-25 12:08:45','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('bf60b752-1ccc-43bf-9bc3-b2aeccacc0ed','已提交',720,2,'5034117','2020-04-25 12:09:03','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('c808addc-8b8b-4d89-99b1-db2ed52e61b4','已提交',3630,1,'6435854','2020-04-25 12:09:10','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('cc9dbd20-cf9f-4097-ae8b-4e73db1e4ba1','已付款',5000,0,'2007322','2020-04-25 12:08:38','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('ccceaf57-a5ab-44df-834a-e7b32c63efc1','已提交',2660,2,'7928516','2020-04-25 12:09:42','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('d7be5c39-e07c-40e8-bf09-4922fbc6335c','已付款',8750,2,'1250995','2020-04-25 12:09:09','食品;家用电器;');
UPSERT INTO "ORDER_DTL" VALUES('dfe16df7-4a46-4b6f-9c6d-083ec215218e','已完成',410,0,'1923817','2020-04-25 12:09:56','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('e1241ad4-c9c1-4c17-93b9-ef2c26e7f2b2','已付款',6760,0,'2457464','2020-04-25 12:08:54','数码;女装;');
UPSERT INTO "ORDER_DTL" VALUES('e180a9f2-9f80-4b6d-99c8-452d6c037fc7','已完成',8120,2,'7645270','2020-04-25 12:09:32','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('e4418843-9ac0-47a7-bfd8-d61c4d296933','已付款',8170,2,'7695668','2020-04-25 12:09:11','家用电器;;电脑;');
UPSERT INTO "ORDER_DTL" VALUES('e8b3bb37-1019-4492-93c7-305177271a71','已完成',2560,2,'4405460','2020-04-25 12:10:05','男装;男鞋;');
UPSERT INTO "ORDER_DTL" VALUES('eb1a1a22-953a-42f1-b594-f5dfc8fb6262','已完成',2370,2,'8233485','2020-04-25 12:09:24','机票;文娱;');
UPSERT INTO "ORDER_DTL" VALUES('ecfd18f5-45f2-4dcd-9c47-f2ad9b216bd0','已付款',8070,3,'6387107','2020-04-25 12:09:04','酒店;旅游;');
UPSERT INTO "ORDER_DTL" VALUES('f1226752-7be3-4702-a496-3ddba56f66ec','已付款',4410,3,'1981968','2020-04-25 12:10:10','维修;手机;');
UPSERT INTO "ORDER_DTL" VALUES('f642b16b-eade-4169-9eeb-4d5f294ec594','已提交',4010,1,'6463215','2020-04-25 12:09:29','男鞋;汽车;');
UPSERT INTO "ORDER_DTL" VALUES('f8f3ca6f-2f5c-44fd-9755-1792de183845','已付款',5950,3,'4060214','2020-04-25 12:09:12','机票;文娱;');
  • 不创建索引查询
select "status", "money", "pay_way", "user_id" from ORDER_DTL WHERE "status" = '已提交';
explain select "status", "money", "pay_way", "user_id" from ORDER_DTL WHERE "status" = '已提交' AND "pay_way" = 1;
  • 创建本地索引
create local index LOCAL_IDX_ORDER_DTL on ORDER_DTL("id", "status", "money", "pay_way", "user_id") ;
  • 基于本地索引查询
select * from ORDER_DTL WHERE "status" = '已提交';
explain select * from ORDER_DTL WHERE "status" = '已提交' AND "pay_way" = 1;
  • 删除索引
drop index LOCAL_IDX_ORDER_DTL on ORDER_DTL;
  • 基于聊天案例,创建本地索引,构建二级索引查询
CREATE LOCAL INDEX LOCAL_IDX_MOMO_MSG ON MOMO_CHAT.MSG(substr("msg_time", 0, 10), "sender_account", "receiver_account");
explain
select 
  * 
from "MOMO_CHAT"."MSG" 
where 
  substr("msg_time",0,10) = '2021-03-22' 
  and "sender_account" = '17351912952' 
  and "receiver_account" = '17742251415';

         
  • 总结
  • 本地索引设计:将索引与数据存储在同一台机器,提高读写的性能,通过建列族来实现的
  • 本地索引不局限于是否对列构建索引,优先走本地索引实现数据查询

知识点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)]
  • 如果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表
  • 总结


相关实践学习
云数据库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
目录
相关文章
|
XML 存储 分布式计算
hbase构建二级索引解决方案
HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索。假设我们相对Hbase里面列族的列列进行一些组合查询,就只能全表扫描了。表如果较大的话,代价是不可接受的,所以要提出二级索引的方案。
788 0
hbase构建二级索引解决方案
|
4月前
|
SQL 分布式数据库 HIVE
Hbase二级索引_Hive on Hbase 及phoenix详解
Hbase二级索引_Hive on Hbase 及phoenix详解
44 0
|
8月前
|
SQL 分布式数据库 Apache
|
分布式数据库 索引 Hbase
《HBase应用与发展之HBase RowKey与索引设计》电子版地址
HBase应用与发展之HBase RowKey与索引设计
100 0
《HBase应用与发展之HBase RowKey与索引设计》电子版地址
|
分布式计算 Hadoop Linux
云计算集群搭建记录[Hadoop|Zookeeper|Hbase|Spark | Docker]更新索引 |动态更新
为了能够更好的查看所更新的文章,讲该博文设为索引 小约定 为了解决在编辑文件等操作的过程中的权限问题,博主一律默认采用root账户登录 对于初次安装的用户可以采用如下命令行:
116 0
云计算集群搭建记录[Hadoop|Zookeeper|Hbase|Spark | Docker]更新索引 |动态更新
|
SQL 搜索推荐 Java
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
410 0
「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践
|
SQL 存储 分布式计算
「从零单排HBase 11」HBase二级索引解决方案
「从零单排HBase 11」HBase二级索引解决方案
123 0
|
SQL 分布式计算 Java
spark-shell操作hudi并使用hbase作为索引
本文介绍spark-shell操作hudi并使用hbase作为索引
spark-shell操作hudi并使用hbase作为索引
|
机器学习/深度学习 SQL 分布式计算
云HBase Phoenix索引构建最佳实践
介绍三种的不同的索引构建方法及其适用场景
2590 0
|
SQL 消息中间件 自然语言处理
使用ElasticSearch赋能HBase二级索引 | 实践一年后总结
前言:还记得那是2018年的一个夏天,天气特别热,我一边擦汗一边听领导大刀阔斧的讲述自己未来的改革蓝图。会议开完了,核心思想就是:我们要搞一个数据大池子,要把公司能灌的数据都灌入这个大池子,然后让别人用 各种姿势 来捞这些数据。
1772 0