redis双写一致性旁路缓存
时间: 2025-04-16 17:43:34 浏览: 26
### Redis 双写一致性旁路缓存实现方案
#### 1. 缓存读取逻辑
当应用程序尝试获取某个键的数据时,会首先访问缓存。如果缓存命中,则直接返回缓存中的数据[^4]。
```python
def get_data_from_cache(key):
data = redis.get(key)
if data is not None:
return data
# Cache miss, read from database and populate cache
data = db.query(key)
# Check deleteKey to avoid dirty reads during replication delay
if check_delete_key(key):
data = master_db.query(key) # Force read from master
else:
data = slave_db.query(key) # Normal read from slave
redis.setex(key, ttl, data) # Populate the cache with fresh data
return data
```
#### 2. 数据更新逻辑
对于数据更新操作,在修改数据库之前先清除对应的缓存条目,并设置一个`deleteKey`标志位用于处理主从延迟期间可能发生的脏读问题[^3]。
```python
def update_data_in_database(key, value):
set_delete_key(key) # Set a flag indicating this key was deleted recently
try:
result = db.update(key, value)
clear_delete_key_after_delay(key) # Clear after estimated replication lag time
return result
finally:
redis.delete(key) # Invalidate stale cached entry immediately
```
#### 3. 处理主从复制延迟
为了避免因MySQL主从同步延迟而导致的脏读现象,可以在删除缓存的同时创建一条带有过期时间(`TTL`)等于预计最大主从延迟周期的特殊标记记录(deleteKey)[^3]。
```python
import threading
def set_delete_key(key):
"""Set a temporary marker that indicates recent deletion."""
redis.set(f'delete:{key}', 'true', ex=replication_lag_time)
def check_delete_key(key):
"""Check whether there's an active delete mark for given key."""
return bool(redis.exists(f'delete:{key}'))
def clear_delete_key_after_delay(key):
timer = threading.Timer(replication_lag_time, lambda: redis.delete(f'delete:{key}'))
timer.start()
```
通过上述措施可以有效解决Redis作为旁路缓存时可能出现的一致性问题,既保持了良好的性能又确保了数据准确性。
阅读全文
相关推荐


















