Redis
Baisc
对数据的访问,保证了数据的安全。
MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据相关知识:
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(回收策略)。redis 提供 6 种数据淘汰策略: volatile-lru:从已设置过期时间的数据集(server.db [i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过期时间的数据集(server.db [i].expires)中挑选将要过期的数据淘汰 volatile-random:从已设置过期时间的数据集(server.db [i].expires)中任意选择数据淘汰 allkeys-lru:从数据集(server.db [i].dict)中挑选最近最少使用的数据淘汰 allkeys-random:从数据集(server.db [i].dict)中任意选择数据淘汰 no-enviction(驱逐):禁止驱逐数据
11.redis 是如何进行同步的,同步的方式,同步回滚怎么办,数据异常怎么办,同时会问 MYSQL 的同步方式和相关异常情况 redis 集群主从同步的简单原理Redis 的复制功能是基于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了 Redis 的复制功能,就一定会有内存快照发生。 当 Slave 启动并连接到 Master 之后,它将主动发送一个 SYNC 命令 (首先 Master 会启动一个后台进程,将数据快照保存到文件中 [rdb 文件] Master 会给 Slave 发送一个Ping 命令来判断 Slave 的存活状态 当存活时 Master 会将数据文件发送给 Slave 并将所有写命令发送到 Slave )。 Slave 首先会将数据文件保存到本地 之后再将 数据 加载到内存中。 当第一次链接 或者是 故障后 重新连接 都会先判断 Slave 的存活状态 在做全部数据的同步,之后只会同步 Master 的写操作 (将命令发送给 Slave) 问题:当 Master 同步数据时 若数据量较大 而 Master 本身只会启用一个后台进程 来对多个 Slave 进行同步 , 这样 Master 就会压力过大 , 而且 Slave 恢复的时间也会很慢! redis 主从复制的优点:(1)在一个Redis集群中,master负责写请求,slave负责读请求,这么做一方面通过将读请求分散到其他机器从而大大减少了master服务器的压力,另一方面slave专注于提供读服务从而提高了响应和读取速度。 (2) 在一个 Redis 集群中,如果 master 宕机,slave 可以介入并取代 master 的位置,因此对于整个 Redis 服务来说不至于提供不了服务,这样使得整个 Redis 服务足够安全。 (3) 水平增加 Slave 机器可以提高性能
缓存更新策略
延迟双删策略
延迟双删策略是一种用于解决缓存与数据库数据一致性问题的方法,特别适用于高并发场景下的缓存更新。
其核心思想是:在更新数据库时,先删除缓存,然后更新数据库,最后延迟一段时间后再删除一次缓存
在高并发场景下,传统的缓存更新策略(如先更新数据库再删除缓存,或先删除缓存再更新数据库)都存在数据不一致的问题
延迟双删策略通过以下步骤解决这些问题:
- 第一次删除缓存:确保缓存中不会存在旧数据。
- 更新数据库:执行数据库更新操作。
- 延迟一段时间后,再次删除缓存:防止并发请求在数据库更新后立即读取到旧缓存数据
import redis
import time
# 连接到 Redis
cache = redis.StrictRedis(host='localhost', port=6379, db=0)
# 模拟数据库更新操作
def update_database(product_id, new_inventory):
# 这里可以替换为实际的数据库更新逻辑
print(f"Updating database for product {product_id} with inventory {new_inventory}")
# 假设数据库更新成功
return True
# 延迟双删策略
def update_inventory(product_id, new_inventory):
# 第一次删除缓存
cache.delete(product_id)
print(f"First cache delete for product {product_id}")
# 更新数据库
if update_database(product_id, new_inventory):
print(f"Database updated for product {product_id}")
else:
print(f"Failed to update database for product {product_id}")
return
# 延迟一段时间(例如1秒)
time.sleep(1)
# 第二次删除缓存
cache.delete(product_id)
print(f"Second cache delete for product {product_id}")
# 测试代码
if __name__ == "__main__":
product_id = "12345"
new_inventory = 100
# 更新库存
update_inventory(product_id, new_inventory)
参考: