开发者学堂课程【HBase 入门与实战:基于 HBase 快速构架海量订单存储系统】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/808/detail/13896
基于 HBase 快速构架海量订单存储系统
内容介绍:
一、物流详情管理编码实战
二、交易订单管理系统
三、展示系统
一、物流详情管理编码实战
1、系统设计
(1)准备工作
购买 HBase 集群
·购买云 HBase 增强版服务
·用户密码在控制台->集群详情->账号管理页面
·链接串在数据库连接页面
配置集群
·开通公网服务获取连接配置
·将本机公网 IP 添加至白名单
配置开发环境
·下载并安装 Idea 开发环境
·在 Spring 模版生成器中生成项目模版,地址https://start.spring.iol
·将生成好的项目导入 Idea
首先要做一些准备的工作,比如买集群、配置账号、开通白名单、开通公网服务之类的操作,按照文档去做就可以,资料里面大家提供了一个已经写好的代码的工程,通过 ID 就可以打开直接跑,配上自己买的 HBase 集群就可以了,如果想要自己从头开始写也可以用里面 spring 的模板来生成好直接导入就可以。
(2)系统设计
从设计上来讲大概分几个层次,一个是前端,也就是通过浏览器操作的部分,有一个简单的界面,然后下来是一个 controller 负责与前端做交互的,就是前端比如插入一个订单的状态、查询一个订单这些操作都会直接落到 controller 的层次,然后 controller 会调用service 层的业务逻辑来处理具体订单的查询和写入。
下面会有一个基于这个Service 的一个封装,最下面的 HBase 数据库,通过event 的方式去管理任何订单的状态描述。
(3)Service 层
·调用 Util 方法,将 Order 和 Event 转换为 HBase 的 Put 和Scan
·再调用 HBaseTemplate 封装的接口执行
·对于 Scan,通过 RowMapper 解析将 Result 转换为 Event
·本例中的业务逻辑比较简单,实际开发中可在 Service 处理更复杂的逻辑
Service 层有三个接口正好每个接口对应前面的三个操作,协助操作是记录订单的状态变更,两个读操作读所有的时间,读最近的时间,这些操作都是把用户的请求转成对 HBase、API 调用,比如写的时候把 event 转成 HBase 的 Put 然后把查询的变成 Scan,这里面有很多具体实现的细节,比如 rock 是怎么拼的,大家可以仔细的去阅读一下代码,包括 stoprow 怎么设计的,包括开始的设计、Limit这些设计。最后结果是把 result 对象转回到业务对象,可以仔细看代码,这个里面做的比较简单,在实际的生产的时候 Service 实现的非常复杂。
1、总结
明确需求
·需要存储什么数据
·需要什么查询语句
设计表结构
·主键设计
·索引设计
MVC 实现
·基于 Model 实现控制器
·实现前端展示
进阶思考:物流订单的 ID 是全局唯一的吗?不同物流公司的单号会重复吗?
·设计原则:不强依赖弱假设,即系统不强依赖单号的唯一性
整个设计可以分三步走,第一步是看需要存什么样的数据,以及怎么对数据进行查询,有了这两个信息之后,就可以反推整个系统表的设计,可以得到一个主键的索引。但是这个场景还不涉及到索引的设计,下一个订单的场景需要涉及到索引,有了表设计以后可以对表设计作为一个实现可以用 spring mvc,也可以用其他的各种各样的方式,具体是取决于大家的业务情况。下面有一个进阶的思考,前面的设计隐含了一个假设的也是物流订单 ID 在范围内一定要全局唯一,如果有两个订单有相同的 ID,这个时候这两个订单会被当成一个订单来处理,问题在于物流订单的 ID 是否全局唯一,不同物流公司单号会重复吗,这个事情在做系统设计的时候可能不知道或者想要去知道这件事情成本会比较高。
国家对物流订单 ID 也没有一个比较明确的标准,各公司都可能会制定自己 ID 生成的规则,它其实是一个不确定性的假设,可能是唯一的也可能是因为鉴于物流相关的行业知识所限,可能不知道它真的可能到底是不是唯一的,这个时候在设计上要遵循一个原则,就是不要依赖不确定的假设或者不要依赖弱假设,在系统设计的时候不能可以认为物流订单不是全局唯一的。怎么做表设计来保证或者让系统能够不依赖订单 ID的唯一性这个问题给大家下课后去思考。
二、交易订单管理系统
1、需求定义
淘宝的交易订单管理系统,提供订单的存储、查询服务,数据具有体量大、增长快、查询复杂等特点
功能需求
·写入
·下单
·订单状态变更(付款、发货、交易完成、退款等等)
查询
·列 top N
·按状态查询 topN
·ad hoc
查询
这个系统跟前面物流订单系统不太一样,它的订单查询逻辑是复杂很多。比如这个是淘宝上的一个订单查询,成交时间的范围选择、卖家昵称的查询、交易状态、评价状态等等可以有这么多的机器,而且它写入的也会有一些比较复杂的特点,比如动态变化会比较复杂,它有各种各样的状态,这种状态可能会导致订单引向不同的处理流程,比如退款可能会导致订单进入一个非正常环节的状态。查询有 top N 的查询,各种各样的状态查询或者比较多的随机组合查询,而且它跟物流订单的一个共同特性数据量都很大,而且增长的非常快。
2、系统设计
(1)方案设计
主表:以订单 ID 为主键,hash 散列,冷热分离
索引:
买家订单:数据相对较小,可暴力扫描,也可构建少量的常用索引
卖家订单:数据量一般较大,通过 Lindorm Search 构建索引,支持多列随机组合查询和复杂分析
可以试一下订单 ID 为主键通过 Hash 做散列,然后通过冷热分离去解决产品成本的问题,但是对于按照 user_id 做的复杂查询往往通过索引来解决。对于买家来讲,买家订单不会特别的多,对于买的东西比较多的淘宝的用户,订单可能上千已经非常不错,一般可能就100不到,大部分时候这种场景数据量少,可以通过暴力扫描来解决,像有一些场景比如卖家的平台,但是卖家订单可能看不到,就是对于卖家视角来看它的订单非常多,比如有一些双11大促,618大促,某一些卖家可能一天的订单量可能就已经非常巨大,通过暴力扫描是解决不了的,这个时候可以通过 Lindorm Search 来构建一个全文索引,更好地支持多列随机组合的查询以及复杂的一些分析,想看一些某一类交易额的订单,对于服务商家来讲淘宝有一系列复杂的数据产品。
(1)更多企业级功能:Serverless
Serverless 简单就是按量付费,用多少付多少或者不买集群的这种模式,这样比较适合于业务不断发展或者刚开始规模很小但是随着业务的不断发展规模越来越大,看到传统的方式可能是先规划一个容量,比如买四台机器、三台机器,让业务员涨上去的时候就扩容,扩容也是这个图的直线。每次扩容的时候容量增加了很多,但是问题是容量增加的时候,业务体量并没有跟着涨得那么高,用业务峰值去做容量评估,这个时候有很多资源的浪费,用户为不必要的自己没用的东西付钱是我们不希望看到的,所以 service 的模式是用多少付多少,不用不付钱,而且整个系统的扩展性和稳定性跟买集群是一样的,这样就实现了最优的成本。
(3)Serverless 功能介绍
经济高效
·超低门槛
·存储计算独立计算
·按使用量计费
·多存储/可用性级别
简单易用
·全托管,无需数据库管理
·开源标准接口,应用0改造
·丰富生态和周边工具配套
按需弹性
·存储计算独立伸缩
·无需容量规划,自动伸缩
适用场景
√变化或不可预测的工作负载
√定时处理任务的场景
√新上线应用
√完全免运维的用户
比较适用场景变化不可预测的工作,同时还有一种定时任务的,比如不可能每周跑一个任务,跑任务的时候流量就很大,跑完了流量就下来了,这种比较适合所有人,它底下会自动根据业务的负载来选择合适的机器按需弹性。
而且对于开发阶段特别友好,可以不用去满足集群做开发测试,特别便宜而且特别有帮助,也有优惠活动可以关注产品的宣传。
计算:按请求次数计费,0请求=0费用
存储:按实际数据量计费
(4)下一代产品:云原生多模数据库 Lindorm
本身是一个多模数据库,提供了 HBase 的兼容以及各种各样的 Nosql 体系下面常见的绿色生态族比如 Phoenix、open TSDB 包括 Hadoop 本身的文件服务。
同时加入三种 solr 的语法,大家可以在一个数据产品里面完成多种业务。
三、展示系统
物流详情的系统,打开代码库可以进行编译,进入类通过 Idea 启动
package
com.zlibaba.
import.lindorm.hbaseeventsdemo;
Import
org.springframework.boot.
SpringApplication;
Import
org.springframework.boot.autoconfigure.SpringBootA
pplication;
@SpringBootApplication
public class HbaseEventsDemoApplication {
public static void main(String[] args){ SpringApplication.run
(HbaseEventsDemoApplication.class, args);}
}
表已经建好,相关的指导在 help 里面
default
2021-05-25 15:05:14.675 INFO 8767 ---[ main] o.s.b.w.embedded.tomcat.TomcatwebServer : Tomcat initialized with port(s):8080(http)
2021-05-25 15:05:14.099 INFO8767---[ main] o.apache.catalina.core.Standardservice :Starting service [Tomcat
2021-05-25 15:05:14.099 INFO 8767 =-- [ main] org.apache.catalina.core.StandardEngine :Starting Servlet engine: [Apache Tomcat/9.0.39]
2021-05-25 15:05:14.351 INFO 8767 --- [ main] o.a.c.c.c.[Tomcat].[localhost].[/] :Initializing Spring embedded WebApplicationContext
2021-05-25 15:05:14.351 INFO 8767 --- [ main] w.s.c.ServletWebServerApplicationContext:Root WebApplicationContext: initialization completed in
3069 ms
2021-05-25 15:05:15.209 INFO 8767 ---[ main1 o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-05-25 15:05:15.881 INFO 8767 --- [ main] o.s.b.w.embedded.tomcat.TomcatwebServer : Tomcat started on port(s): 8080 (http) with context path
2021-05-25 15:05:15.904 INFO 8767--- [ main] c.a.l.h.HbaseEventsDemoApplication :Started HbaseEventsDemoApplication in 6329seconds(JVM
running for 10.514)
准备云HBase
1.进入阿里云 lindorm 控制台,购买单机版 lindorm,等待开通
2.实例开通后,进入实例详情页,点击左侧 数据库链接 页面,开通公网服务。并点击页面下方的 Lindorm Shell 下载,并解压到本地
3.在使用 HBase Java API 访问 下,点击公网地址后面的一健生成配置项 ,复制 xmi 格式的配置
4.进入本地解压的 sholl(目录名是 alihb 开头的),编辑conf/hbase-site.xml ,全量替换上一步得到的配置
5.点击左侧访问控制,添加本机 IP 为白名单
6.进入 shell, bin/hbase shell
7.创律测试表 create 'events','f'
1.进入阿里云 lindorm 控制台1(https:///indorm.cons
1.实例开通后,进入实例详情页,点击左侧`数据库链接`页面,开通公网服务
1.在使用 HBase Java API 访问下,点击公网地址后面的`一键生成配置
1.进入本地解压的shell(目录名是 alihb 开头的),编辑 `conf/hbase-s
1.点击左侧访问控制,添加本机工 IP 为白名单
1.进入 shell,`bin/hbase shell`
1.创建测试表 `create 'events','fl'
开始测试
1.用 IDEA 启动 `HbaseEventsDemoApplication
1.打开浏览器,输入 localhost:8880,即可开始读写测试
浏览器来看整个系统的使用,比如现在要记录一个订单的状态,就在这里添加,比如 ts11,然后 detial 写 aaaa 提交。
查一下
再增添一个订单号提交
查 10,默认只是显示最后一个数据
查所有的数据写 true
可以查到所有数据,特别简单小的示例展示
背后数据的存储、 HBase 的处理可以在云原生的数据台上看。