上一篇
想象一下,你正在运营一个日活百万的电商平台,每当用户浏览商品详情页时,系统需要实时推荐"相似商品"和"你可能也喜欢"的列表,这些推荐数据都存储在Redis中,但问题来了:如何在不影响性能的前提下,持续从Redis获取最新数据,同时确保核心推荐词(比如用户最近浏览的3个商品ID)始终保留在内存中?
这就是我们今天要聊的Redis数据循环技术——一种既能保持核心数据常驻内存,又能高效循环获取周边数据的实用方案。
中心词(比如用户最近浏览记录)是我们必须长期保留的关键数据,在Redis中,我们可以采用两种方式:
# 方案1:使用永不过期的String类型 redis_client.set(f"user:{user_id}:core_keywords", json.dumps(core_data)) # 方案2:使用足够长的过期时间(比如7天) redis_client.setex(f"user:{user_id}:core_keywords", 604800, json.dumps(core_data))
对于需要循环获取的周边数据(比如推荐商品列表),我们有几种典型模式:
def get_rotated_data(user_id): data_key = f"user:{user_id}:recommendations" # 从列表左侧弹出第一个元素 item = redis_client.lpop(data_key) if item: # 将弹出的元素放回列表右侧 redis_client.rpush(data_key, item) return json.loads(item) return None
def get_rotated_by_index(user_id): data_key = f"user:{user_id}:recommendations" index_key = f"user:{user_id}:recommend_index" # 获取当前索引 current_index = redis_client.get(index_key) or 0 # 获取列表长度 list_length = redis_client.llen(data_key) if list_length == 0: return None # 获取索引位置的数据 item = redis_client.lindex(data_key, current_index) # 更新索引(循环) new_index = (int(current_index) + 1) % list_length redis_client.set(index_key, new_index) return json.loads(item) if item else None
def get_data_with_pipeline(user_id): pipe = redis_client.pipeline() pipe.get(f"user:{user_id}:core_keywords") pipe.lpop(f"user:{user_id}:recommendations") core_data, rotated_item = pipe.execute() if rotated_item: redis_client.rpush(f"user:{user_id}:recommendations", rotated_item) return { "core": json.loads(core_data), "rotated": json.loads(rotated_item) if rotated_item else None }
当数据量很大时,可以考虑:
# 使用zset存储可循环数据 redis_client.zadd("recommendations", {"item1": 1, "item2": 2, "item3": 3}) # 循环获取时 def get_rotated_from_zset(): # 获取并增加分数实现轮询 pipe = redis_client.pipeline() pipe.zrange("recommendations", 0, 0) # 获取分数最低的 pipe.zincrby("recommendations", 1, "item1") # 增加分数使其"沉底" item, _ = pipe.execute() return item[0] if item else None
在实际生产环境中,别忘了处理这些边界情况:
def safe_get_data(user_id): try: # 使用watch确保原子性 with redis_client.pipeline() as pipe: while True: try: pipe.watch(f"user:{user_id}:recommend_index") current_index = pipe.get(f"user:{user_id}:recommend_index") or 0 pipe.multi() pipe.lindex(f"user:{user_id}:recommendations", current_index) new_index = (int(current_index) + 1) % pipe.llen(f"user:{user_id}:recommendations") pipe.set(f"user:{user_id}:recommend_index", new_index) item, _ = pipe.execute() return json.loads(item) if item else None except WatchError: continue except RedisError as e: log_error(f"Redis操作失败: {e}") return get_local_cache(user_id) # 降级方案
Redis数据循环技术在实际系统中非常实用,特别是在需要:
关键点在于:
按照2025年最新的Redis最佳实践,这种模式在推荐系统、消息轮播、负载均衡等场景下依然保持着极高的性价比。
本文由 佛三诗 于2025-08-09发表在【云服务器提供商】,文中图片由(佛三诗)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://up.7tqx.com/wenda/575984.html
发表评论