后端架构学习(2)- redis
之前主要记录了 docker 部署一个最简单的后端,本次加入 redis。
架构会随着场景的变更而变换;因此,这里假设一个很简单的场景:
- 实现商品秒杀
- 商品信息存储在数据库中
- 功能为每天拿前一天销量 TOP100 商品作为秒杀商品
V2 架构
1. 技术栈
1.1 简介
-
SpringBoot
-
MySQL
-
docker
-
redis
在 V1 架构的基础上加入了 redis,redis 是一个基于内存的高性能 key*-*value 数据库。
1.2 使用
在使用上:类比 redis 为 Java 的 Map,redis 有以下几种数据类型作为 value
- String: 字符串 ~ Map<String,String>
- Hash: 散列 ~ Map<String,Object>
- List: 列表 ~ Map<String,ArrayList>
- Set: 集合 ~ Map<String,HashSet>
- Sorted Set: 有序集合 ~ Map<String,TreeSet>
String
> set name ccran
OK
> get name
ccran
> set age 18 EX 5
OK
> get age
18
> keys *
name
> get age
null
set 命令格式:set key value
EX 设置过期时间,5S 后该 key-value 失效
keys * 可以获取所有的 key 值
Hash
> hmset person name "ccran" age 18
OK
> hgetall person
name
ccran
age
18
hmset 格式: HMSET key field value [field value ...]
hgetall 获取 key 对应 value 对象的所有字段和值
List
> lpush skill redis
1
> lpush skill mysql
2
> lrange skill 0 5
mysql
redis
> rpush skill java
3
> lrange skill 0 -1
mysql
redis
java
lpush 列表头添加对象,rpush 列表尾添加对象
lrange 取列表范围元素,命令格式为 lrange key start stop,包含 start 以及 stop
Set
> sadd num 1
1
> sadd num 2
1
> sadd num 2
0
> smembers num
1
2
集合里面没有重复元素
Sorted Set
> zadd company 1 google
1
> zadd company 2 apple
1
> zadd company 2 apple
0
> zadd company 1 apple
0
> zrange company 0 -1 withscores
apple
1
google
1
zadd 命令格式:ZADD key score member [[score member] [score member] ...]
根据 score 排序,value 不能重复,但是 score 可以重复
最后贴出 Redis 命令参考: http://doc.redisfans.com/
2. 架构
在 V1 架构的基础上增加了 SpringBoot 与 redis 的交互
2.1 秒杀实现
V1 架构秒杀实现的流程:秒杀页面=> 秒杀接口=> 后端 <=>MySQL
- 用户进入秒杀页面
- 前端调用秒杀接口
- 后端通过 ORM 框架生成 SQL 语句交给 MySQL 并等待数据返回
- MySQL 解析语句,定位数据位置,最差情况需要读磁盘
- 数据返回给后端,返回给接口,前端展示页面
V2 架构秒杀实现的流程:在第 5 步,数据返回给后端以后,写入 redis,并设置过期时间为 1 天,以后每次查询如果 redis 有数据则直接拿 redis 数据。
V1 架构与 V2 架构比较:
- V1 架构每次需要去数据库进行查询;虽然 MySQL 可能会缓存查询,预读数据页,但最差还是可能存在磁盘 IO,预估 20ms 左右
- V2 架构只有第一次需要去数据库进行查询;后续所有访问全部到 redis,由于是在内存中,预估 2ms 左右
V1 架构如果能支持 2000 并发的话,V2 架构则能支持 20000 并发了。😄
2.2 redis vs map
为什么不用 java map 呢?(个人理解)
- map 会占据堆内存;增大垃圾回收压力,增大整个后端压力
- 如果开多个后端实例,会造成数据冗余;
- 不便于后期分布式拓展;
- redis 功能更丰富;如过期,否则我们只能手动管理
- 数据与业务解耦;可能有其他后端业务需要,类比于使用 MySQL 存储数据,而不是后端自身组织数据
- ...
3. 部署
首先拉取镜像
docker pull redis:5.0
然后运行镜像,生成容器
docker run -p 6379:6379 -d --name redis redis:5.0
4. 总结
- 可以缓存访问频繁的数据,提高并发量。
- 解决问题需要找到问题的关键,并且使用合适的组件来充分发挥其优势。
- 多学习,很多问题可以采用相似的方案解决;比如很多地方都用到了缓存,浏览器、数据库、DNS、CPU 等
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于