01.Redis 概述
Redis 概述
- Redis 概述
- 1. Redis 特性
- 2. Redis 常见应用场景
- 3. 缓存穿透,缓存击穿和缓存雪崩
- 4. Pipeline 流水线
Redis 概述
Redis (Remote Dictionary Server远程字典服务)是一个遵循BSD MIT开源协议的高性能的NoSQL。Redis 基于ANSI C语言语言编写的key-value数据库
Redis 官网地址: https://redis.io/
1. Redis 特性
- 速度快: 10W QPS,基于内存,C语言实现
- 单线程
- 持久化
- 支持多种数据结构
- 支持多种编程语言
- 功能丰富: 支持Lua脚本,发布订阅,事务,pipeline等功能
- 简单: 代码短小精悍(单机核心代码只有23000行左右),单线程开发容易,不依赖外部库,使用简单
- 主从复制
- 支持高可用和分布式
单线程
Redis 6.0版本前一直是单线程方式处理用户的请求
单线程为何如此快?
- 纯内存
- 非阻塞
- 避免线程切换和竞态消耗
- 基于Epoll实现IO多路复用
注意事项:
- 一次只运行一条命令
- 避免执行长(慢)命令:keys *, flushall, flushdb, slow lua script, mutil/exec, operate big value(collection)
- 其实不是单线程: 早期版本是单进程单线程,3.0 版本后实际还有其它的线程, 实现特定功能,如: fysnc file descriptor,close file descriptor
2. Redis 常见应用场景
- 缓存:缓存RDBMS中数据,比如网站的查询结果、商品信息、微博、新闻、消息
- Session 共享:实现Web集群中的多服务器间的session共享
- 计数器:商品访问排行榜、浏览数、粉丝数、关注、点赞、评论等和次数相关的数值统计场景
- 社交:朋友圈、共同好友、可能认识他们等
- 地理位置: 基于地理信息系统GIS(Geographic Information System)实现摇一摇、附近的人、外卖 等功能
- 消息队列:ELK等日志系统缓存、业务的订阅/发布系统
3. 缓存穿透,缓存击穿和缓存雪崩
-
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,比如: 发起为id为 “-1” 的数据或id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方法:
接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复 用同一个id暴力攻击
-
缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据,比如:热点数据的缓存时间到期后,这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决方法:
设置热点数据永远不过期。
-
缓存雪崩
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到 ,从而查数据库。
解决方法:
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中
设置热点数据永远不过期
4. Pipeline 流水线
Redis 客户端执行一条命令分4个过程:
发送命令--〉命令排队--〉命令执行--〉返回结果
这个过程称为Round trip time(简称RTT, 往返时间),mget,mset指令可以一次性的批量对多个数据的执行操作,所以有效节约了RTT
但大部分命令(如hgetall)不支持批量操作,需要消耗N次RTT ,利用 Pipeline 技术可以解决这一问题。使用Pipeline执行时速度比逐条执行要快,特别是客户端与服务端的网络延迟越 大,性能体能越明显。