后端架构学习(2)- redis

本贴最后更新于 1406 天前,其中的信息可能已经物是人非

后端架构学习(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. 架构

v2 架构.png

在 V1 架构的基础上增加了 SpringBoot 与 redis 的交互

2.1 秒杀实现

V1 架构秒杀实现的流程:秒杀页面=> 秒杀接口=> 后端 <=>MySQL

  1. 用户进入秒杀页面
  2. 前端调用秒杀接口
  3. 后端通过 ORM 框架生成 SQL 语句交给 MySQL 并等待数据返回
  4. MySQL 解析语句,定位数据位置,最差情况需要读磁盘
  5. 数据返回给后端,返回给接口,前端展示页面

V2 架构秒杀实现的流程:在第 5 步,数据返回给后端以后,写入 redis,并设置过期时间为 1 天,以后每次查询如果 redis 有数据则直接拿 redis 数据

V1 架构与 V2 架构比较:

  1. V1 架构每次需要去数据库进行查询;虽然 MySQL 可能会缓存查询,预读数据页,但最差还是可能存在磁盘 IO,预估 20ms 左右
  2. 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. 总结

  1. 可以缓存访问频繁的数据,提高并发量。
  2. 解决问题需要找到问题的关键,并且使用合适的组件来充分发挥其优势。
  3. 多学习,很多问题可以采用相似的方案解决;比如很多地方都用到了缓存,浏览器、数据库、DNS、CPU 等
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3165 引用 • 8206 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    139 引用 • 441 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 210 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...