资讯动态

Redis应用

发布时间:2026/8/20 15:14:20 来源:尧图企业网站定制
一、缓存1.1 介绍缓存就是把常用的数据放到访问速度快的地方。这里的访问速度快是相对的CPU寄存器 内存 磁盘 网络。对于网络来说磁盘就是缓存但对于磁盘来说内存就是缓存。Redis 一般用于 MySQL 缓存但是内存的容量毕竟小于磁盘如果都放到内存中那不就满了吗其实在实际的业务中是符合二八定律的就是 20% 的热点数据可以满足 80% 的场景。注意缓存一般解决的都是读操作对于写操作只能去 MySQL 中写。1.2 更新策略它可以细分为定期生成、实时生成。定期生成这个比较简单就是每个一段时间统计出现频率高的数据然后把数据更新到 Redis 中即可。实时生成当 Redis 命中数据则直接返回没有命中则从 MySQL 中查找然后添加到 Redis 中然后返回。但是如果一直这样用不了多久 Redis 就会把内存打满所以就引入了内存淘汰机制具体如下FIFO淘汰最先来的数据LRU淘汰最长时间没有使用的数据LFU淘汰使用次数最少的数据Random随机淘汰在 Redis 中是可以配置Redis 中默认的淘汰策略是当内存不足以容纳新写入数据时新写入操作会报错。1.3 缓存预热当刚启动 Redis 时由于 Redis 中并没有数据所以如果有请求来会访问到 MySQL。如果数据量大会导致 MySQL 扛不住严重甚至直接宕机。解决方法也简单就是可以在离线的状态下先把一批热点数据导入到 Redis 中。当然热点数据也不一定要非常精准只要能阻止大部分请求访问 MySQL 即可随着时间的推移热点数据会调整。1.4 缓存穿透当数据既不在 Redis 也不在 MySQL 时就会缓存穿透。一次倒也什么大问题如果有大量的类似这种数据请求时会增加 MySQL 压力严重甚至直接宕机。出现这种情况一般是1. 业务上面没有对 key 做出检查2. 不小心误删了数据3. 黑客攻击。解决方法1. 在查询前对 key 做出检查2. 可以在 Redis 中插入该 key 把 value 设为非法值3.使用布隆过滤器来判断 key 是否存在。1.5 缓存雪崩短时间内大量的 key 过期导致访问 MySQL 的请求变多严重甚至直接宕机。出现这种情况一般是1. Redis 挂了2. 短时间大量 key 过期。解决方法1. 部署高可用的 Redis 集群, 并且完善监控报警体系。1.6 缓存击穿它是缓存雪崩的特殊情况它是热点数据过期导致访问 MySQL 的请求变多严重甚至直接宕机。解决方法1. 基于统计的方式发现热点 key并设置永不过期。2. 限制同一时间访问数据库的并发数。二、分布式锁2.1 介绍锁相信大家都不陌生不过之前都是在一台主机上。其实分布式锁很好理解就是在一台主机创建锁然后其他主机要修改数据库数据时从那台主机申请到锁然后修改。大家可能会想事务不是也能做到吗事务确实可以但是如果数据量太大 MySQL 扛不住并且存储数据也不一定使用的一定是数据库。大概过程就是一台主机先在另一个主机上创建一个 key这个 key 就是锁创建成功就代表加锁成功失败则代表加锁失败。用 setnx 命令实现使用完后把 key 删除即可。这个流程虽然听着很简单但要考虑的东西很多。2.2 引入过期时间如果一个主机加锁成功假如这个主机断电了或者挂了那么锁就不能被释放这就会导致其他机器无法申请到锁。为了解决这种情况就要在申请锁的时候加入过期时间时间一到则自动被释放。注意引入过期时间最好使用set ex nx不要用 setnx、expire。虽然说第二种也是可以实现但是可能会出现一台机器刚 setnx 成功之后突然挂了或者 setnx 成功 expire 失败。2.3 引入检验 id当 A 主机申请锁成功了但是 B 主机把 A 主机申请的锁给删了。这种情况一般是误操作。为了解决这种情况可以把申请 key 的 value 设置为主机 id当要删除时先判断 id 是否相同相同则在删除。2.4 引入 lua因为上面引入 id 后需要先 get 获取 value 值然后 del这是两个命令在 Redis 中虽然命令是原子的单命令之间并不是。这就可能导致当 A 线程 get 之后准备del时锁过期了然后 B 线程申请成功了锁之后 A 线程把执行 del 将 B 线程刚申请的锁给删了。这时相信大家一定会想到 Redis 事务让 get、del 操作一起执行。这当然可以但是 Redis 的事务并不保证一定执行成功所以更好的方法是引入 lua 脚本在 Redis 执行 lua 脚本的过程是原子的所以一般是让它来代替事务。这个 lua 脚本是在 Redis 中客户端可以直接调用它。2.5 引入看门狗有一种情况是申请锁的时间不够用如果依然选择到时间释放就会出现问题。所以就在那台机器的后台起一个线程这个线程被称为看门狗线程它用于向 Redis 发送延长多少时间。就算机器挂了也没事儿因为没有人给它续约时间到了也就释放了。2.6 引入 Redlock 算法还有一种情况是 Redis 挂了。大概情况是 A 主机刚加好锁然后 Redis 挂了大家可能会想不是有哨兵吗它挂了还有其他 Redis 存在。确实是但是因为数据同步是需要时间的所以就有一种情况是没来得及同步就挂了这样 A 主机以为加上锁了但是其实没加上。为了解决这个方法 Redis 作者提出了 Redlock 算法本质上就是冗余。大概是加锁不是只给一个 Redis 发请求而是给多个 Redis 都发请求注意这里的 Redis 都是主节点就是给多个主节点同时发请求。加锁是设置时间如果超出时间则认为加锁失败去尝试下一个节点。只要加锁成功的数量大于一半则认为加锁成功这样即使某个主节点挂了也不影响。2.7 总结上面设计了这么多本质上都是对节点突然挂了的措施因为是分布式我们需认为每个节点都不可靠。对于之前学习的加锁没这么复杂是因为是在不行就进程挂了锁直接释放了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价