一、Redis 与关系型数据库(MySQL)
Redis 与 MySQL 等关系型数据库结合使用时,通常用于加速查询、缓存热点数据,或作为消息队列来分担主库压力。
1. 数据查询加速
场景分析
关系型数据库擅长复杂查询,但某些频繁访问的热点数据可能导致性能瓶颈。这时,Redis 可作为查询缓存,减少数据库的直接访问。
实现思路
- 查询数据时,优先检查 Redis 缓存;
- 如果缓存中存在,直接返回;
- 如果缓存中不存在,则查询 MySQL,同时将结果写入 Redis。
代码示例
import redis
import pymysql
# 配置 Redis 和 MySQL
redis_client = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)
db = pymysql.connect(host='localhost', user='root', password='password', database='test_db')
def get_user_info(user_id):
# 尝试从 Redis 获取
cache_key = f"user:{user_id}"
cached_data = redis_client.get(cache_key)
if cached_data:
print("Cache hit")
return cached_data
print("Cache miss")
# 缓存未命中,从 MySQL 查询
cursor = db.cursor()
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
user_info = cursor.fetchone()
if user_info:
# 将结果存入 Redis
redis_client.set(cache_key, str(user_info), ex=3600) # 缓存 1 小时
return user_info
# 示例调用
print(get_user_info(1))
2. 延时双删策略
为确保数据一致性,可采用“延时双删”策略:
- 删除缓存:在更新数据库前删除缓存数据。
- 更新数据库:对数据库执行更新操作。
- 延迟一段时间后再次删除缓存:确保延迟期间产生的读请求不影响更新后的数据一致性。
代码示例:
import time
def update_user_info(user_id, new_info):
# 删除缓存
cache_key = f"user:{user_id}"
redis_client.delete(cache_key)
# 更新数据库
cursor = db.cursor()
cursor.execute("UPDATE users SET info = %s WHERE id = %s", (new_info, user_id))
db.commit()
# 延迟再次删除缓存
time.sleep(1)
redis_client.delete(cache_key)
# 示例调用
update_user_info(1, "Updated info")
二、Redis 与 NoSQL 数据库(MongoDB)
Redis 与 MongoDB 结合使用时,Redis 通常用于缓存实时数据或加速读写,而 MongoDB 负责存储结构化或半结构化的历史数据。
1. 高频读写场景
场景分析
MongoDB 适合存储大规模数据,但实时性要求较高的场景可以结合 Redis 使用。比如,Redis 存储最近 100 条数据,MongoDB 保存全部历史数据。
实现方案
- 将实时数据写入 Redis,同时写入 MongoDB。
- 当 Redis 数据超出限制时,按规则将数据清理,而 MongoDB 始终保留完整数据。
代码示例
from pymongo import MongoClient
# 配置 MongoDB
mongo_client = MongoClient("mongodb://localhost:27017/")
db = mongo_client.test_db
collection = db.logs
def log_event(event_id, event_data):
# 写入 Redis
redis_client.lpush("recent_logs", f"{event_id}:{event_data}")
redis_client.ltrim("recent_logs", 0, 99) # 保留最近 100 条
# 写入 MongoDB
collection.insert_one({"event_id": event_id, "data": event_data})
def get_recent_logs():
return redis_client.lrange("recent_logs", 0, -1)
# 示例调用
log_event(1, "User logged in")
print(get_recent_logs())
三、Redis 与 Elasticsearch
Redis 与 Elasticsearch (ES) 结合时,Redis 通常用于实时查询缓存,而 Elasticsearch 负责全文检索和分析。
1. 搜索结果缓存
场景分析
Elasticsearch 提供强大的搜索功能,但复杂查询可能耗时较长。通过 Redis 缓存搜索结果,可显著提升系统响应速度。
实现思路
- 搜索请求先检查 Redis;
- 如果命中缓存,直接返回;
- 如果未命中缓存,查询 Elasticsearch,并将结果写入 Redis。
代码示例
from elasticsearch import Elasticsearch
# 配置 Elasticsearch
es = Elasticsearch(["http://localhost:9200"])
def search_query(index, query):
cache_key = f"search:{query}"
cached_result = redis_client.get(cache_key)
if cached_result:
print("Cache hit")
return cached_result
print("Cache miss")
# 查询 Elasticsearch
result = es.search(index=index, body={"query": {"match": {"content": query}}})
redis_client.set(cache_key, str(result), ex=300) # 缓存 5 分钟
return result
# 示例调用
print(search_query("articles", "Redis"))
四、混合架构设计中的实际应用
1. 数据分层存储
通过结合 Redis、MySQL、MongoDB、Elasticsearch 的特点,可实现分层存储架构:
- Redis:缓存高频数据或实时性要求高的数据。
- MySQL:存储关系型核心数据。
- MongoDB:存储非结构化或半结构化数据。
- Elasticsearch:提供全文搜索与分析能力。
示例架构图:
[Client Requests]
|
[API Layer]
|
-------------------------------------
| | | |
[Redis] [MySQL] [MongoDB] [Elasticsearch]
2. 分布式事务与最终一致性
在多数据库结合的场景中,事务性操作可能涉及 Redis 和其他数据库。可使用消息队列(如 Kafka 或 Redis Stream)实现最终一致性:
- 将 Redis 操作与数据库操作解耦。
- 使用队列记录需要异步处理的操作。
- 异步消费者定期检查并补偿未完成的操作。
五、总结
Redis 作为内存数据库,在与 MySQL、MongoDB、Elasticsearch 等结合时,充分发挥了其速度快、数据结构丰富的优势。通过合理设计数据流与分层存储架构,可以显著提升系统性能与扩展性。
Redis 的使用场景丰富且灵活,是现代复杂系统架构中的重要组成部分。下一篇文章将讨论 Redis 安全性与数据备份策略,敬请期待!