面试题答案
一键面试实现思路
- 连接Redis:使用
redis
库连接到Redis服务器。 - 设置缓存:使用
setex
方法,它可以在设置键值对的同时设置过期时间(以秒为单位)。 - 获取缓存:先尝试从缓存获取数据,如果获取到则直接返回;如果未获取到(即缓存过期或不存在),则从数据源(如数据库等)获取,然后重新设置到缓存中。
核心代码片段
import redis
class CacheSystem:
def __init__(self, host='localhost', port=6379, db=0):
self.redis_client = redis.StrictRedis(host=host, port=port, db=db)
def set_cache(self, key, value, expiration_time):
self.redis_client.setex(key, expiration_time, value)
def get_cache(self, key):
value = self.redis_client.get(key)
if value is not None:
return value.decode('utf-8') if isinstance(value, bytes) else value
# 如果缓存未命中,从其他数据源获取数据并更新缓存(这里省略从其他数据源获取数据的逻辑)
# new_value = get_from_other_source()
# self.set_cache(key, new_value, expiration_time)
# return new_value
return None
大量数据同时过期可能带来的问题及解决方案
问题:
- 缓存雪崩:大量缓存同时过期,使得大量请求直接落到后端数据源,可能导致数据源压力过大甚至崩溃。
解决方案:
- 分散过期时间:在设置过期时间时,加上一个随机值,让过期时间分散开,避免集中过期。例如,原本设置过期时间为600秒,可以设置为600 + random.randint(0, 100) 秒。
- 使用二级缓存:在应用层增加一个本地缓存(如
functools.lru_cache
)作为二级缓存。当一级缓存(Redis)失效时,先从二级缓存获取数据,减轻后端数据源压力。 - 缓存永不过期:对于一些不经常变化的数据,可以设置缓存永不过期,然后定期在后台更新缓存数据。这样即使缓存没有过期,也能保证数据的实时性。