面试题答案
一键面试Redis缓存预热策略
- 数据分类与优先级确定
- 对于电商系统,商品信息缓存是基础且高频访问的数据,优先级较高。用户个性化推荐缓存虽与用户行为相关,但在系统启动初期,可适当降低优先级。
- 将缓存数据按业务重要性和访问频率分为不同级别,如商品基本信息、热门商品详情、用户个性化推荐等。
- 预热时间与方式
- 启动前预热:在系统启动脚本中,调用专门的预热程序。例如,使用Python脚本结合Redis客户端库(如
redis - py
),批量从数据库加载数据到Redis。
import redis import pymysql r = redis.Redis(host='localhost', port=6379, db = 0) conn = pymysql.connect(host='localhost', user='root', password='password', database='ecommerce') cursor = conn.cursor() cursor.execute('SELECT * FROM products') products = cursor.fetchall() for product in products: product_id = product[0] product_info = { 'name': product[1], 'price': product[2], # 其他商品信息 } r.hmset(f'product:{product_id}', product_info)
- 异步预热:系统启动后,利用异步任务队列(如Celery),在后台逐步加载优先级较低的数据,如用户个性化推荐缓存。
from celery import Celery app = Celery('tasks', broker='redis://localhost:6379/0') @app.task def preheat_user_recommendations(): # 从数据库或其他数据源获取用户个性化推荐数据 # 加载到Redis pass
- 启动前预热:在系统启动脚本中,调用专门的预热程序。例如,使用Python脚本结合Redis客户端库(如
- 缓存更新策略
- 读写时更新:当数据在数据库中发生变化时,同时更新Redis缓存。在电商系统中,商品价格更新时,立即更新Redis中对应的商品缓存。
- 定期刷新:对于一些变化不频繁但需要保持准确性的数据,如商品库存(库存变化相对商品浏览频率较低),可以设置定时任务,定期从数据库重新加载到Redis。
冷启动优化方案
- 分级缓存
- 一级缓存:使用内存型的Redis作为一级缓存,存储最常用、访问频率最高的数据。如热门商品的基本信息、购物车信息等。
- 二级缓存:采用分布式缓存(如Memcached)或磁盘型Redis作为二级缓存,存储访问频率稍低的数据。当一级缓存未命中时,快速从二级缓存获取数据,减少数据库访问压力。
- 缓存穿透处理
- 布隆过滤器:在系统启动时,构建布隆过滤器。例如,将所有商品ID预先添加到布隆过滤器中。当查询商品时,先通过布隆过滤器判断商品ID是否存在,若不存在则直接返回,避免无效的数据库查询。
- 空值缓存:当查询数据库未命中时,将空值缓存到Redis中,并设置较短的过期时间。这样后续相同的无效查询可直接从Redis获取空值,减少数据库压力。
- 缓存雪崩处理
- 随机过期时间:对于不同类型的缓存数据,设置随机的过期时间,避免大量缓存同时过期。例如,商品信息缓存的过期时间在1 - 2小时内随机设置。
- 互斥锁:在缓存过期后,当多个请求同时访问时,使用互斥锁(如Redis的SETNX命令)保证只有一个请求去加载数据到缓存,其他请求等待。待数据加载完成后,释放锁,其他请求可从缓存获取数据。
- 监控与动态调整
- 监控指标:设置监控系统(如Prometheus + Grafana),实时监控Redis的命中率、内存使用情况、请求响应时间等指标。
- 动态调整:根据监控数据,动态调整缓存策略。如命中率过低时,检查预热数据是否完整,或调整缓存过期时间;内存使用过高时,优化缓存数据结构或清理不必要的缓存。