1. Redis 应用与缓存策略的高并发实战要点
1.1 数据结构与命中率优化
在高并发场景下,缓存命中率直接决定系统吞吐与响应时间。对常用对象,优先使用 Hash 或 Hash+String 的组合来降低内存碎片,并提升单条命中时的读取效率,这样可以减少网络往返与序列化成本。
为了提升内存利用率与访问效率,需对业务读写模板进行分析:热点对象宜采用 对象级别的哈希结构,非热点数据放在单独键上以避免大对象的反序列化成本。通过统计命中率与淘汰策略,逐步将内存热点数据提升至 高命中率区,同时降低冷数据的访问延时。
# 在 redis.conf 中设置内存与淘汰策略(示例)
maxmemory 4gb
maxmemory-policy allkeys-lru
为确保原子性与并发安全,可以借助简单的 Lua 脚本 实现复杂操作的原子执行,避免分布式锁带来的额外开销。下方示例展示一个原子检查-写入的逻辑片段,提升在高并发下的一致性与稳定性:

-- 原子性检查与写入示例
local exists = redis.call('EXISTS', KEYS[1])
if exists == 0 thenredis.call('SET', KEYS[1], ARGV[1])
end
return redis.call('GET', KEYS[1])
1.2 缓存穿透与击穿保护
面对大量请求穿透缓存直接访问数据库的情况,布隆过滤器是对抗缓存穿透的有效手段之一,通过在前端对不存在的数据进行快速命中率判断,可以显著降低对后端数据库的压力,并降低 击穿风险。
在 Redis 生态中,常与 RedisBloom 模块配合使用,利用 BloomFilter 判断是否可能存在某个 key,从而决定是否将请求发往后端。下面给出一个 Bloom 过滤器相关操作的示例(命令示意):
BF.MADD bloom_filter_user_id 12345
BF.MADD bloom_filter_user_id 67890
TTL bloom_filter_user_id 86400
若对尚未命中的数据执行并发请求,仍可通过 请求合并(coalescing) 机制在短时间窗内只让一个请求落地查询,其他请求获取同一结果,避免资源重复占用。下方为一个简单的 Lua 片段,展示锁定-查询的思路与释放:
-- 请求合并示例
local lock_key = KEYS[1]
local in_progress = redis.call('GET', lock_key)
if in_progress thenreturn in_progress
elseredis.call('SET', lock_key, '1', 'EX', 5)-- 这里执行数据库查询redis.call('DEL', lock_key)return 'done'
end
1.3 高并发下的分区与集群设计
为应对极端并发量,应采用 Redis 集群方案,将数据分布在多个节点上,通过 哈希槽 实现水平扩容与高可用。集群方式能显著提升并发写入能力,同时降低单点故障影响。
分区设计不仅在容量上带来优势,还要兼顾 写放大效应、数据局部性、以及对管线化操作的友好性。配合 Pipeline/Multi 操作可以减少网络往返次数,提高批量请求的吞吐。下列示例展示在集群模式下的基本查询路径,并强调对分区的尊重与利用:
# 使用集群客户端执行聚合查询(示例命令)
redis-cli -c -h node1 -p 7000 CLUSTER INFO
在分区场景中,设计 键命名约定 与数据分布策略至关重要,确保热数据落在相同哈希槽内以减少跨节点通信,提升延迟一致性。
2. MongoDB 缓存与查询优化的实战要点
2.1 索引设计与覆盖查询
对 MongoDB 的查询性能,索引设计是核心要素。合理的 覆盖索引 能让查询直接命中索引头部,避免回表操作,显著降低 I/O 成本与延迟。
在设计时需结合业务查询模式,优先创建对过滤条件和排序字段友好的复合索引,例如在经常按 userId 与创建时间筛选的场景中,优先构建复合索引以减少全表扫描风险。下方是一个典型的索引创建示例,强调字段顺序与方向的设计要点:
db.orders.createIndex({ "userId": 1, "createdAt": -1 }, { unique: false })
通过对查询计划的分析(explain)与持续的观测,持续迭代索引结构,确保热查询路径达到最优的 覆盖查询效果与最小的 I/O 开销。
2.2 TTL 与缓存失效策略
当 MongoDB 被用于缓存层或缓存元数据时,TTL(Time-To-Live)索引成为关键机制,确保历史数据在预期时间后自动从集合中清除,避免缓存失效导致的过期数据影响。
TTL 索引通常结合时间字段使用,如创建时间戳,配置失效时间以实现自动清除。该策略有助于维持热数据与冷数据的分离,降低存储与查询成本。示例创建TTL 索引如下:
db.sessions.createIndex({ "createdAt": 1 }, { expireAfterSeconds: 3600 })
在缓存失效时,后端可以触发重建或从权威源重新填充缓存,确保数据的一致性与可用性。
2.3 聚合管道与缓存友好性
对于需要聚合分析的场景,利用 MongoDB 的 聚合管道可以在数据库端完成复杂数据变换,减少客户端传输与多次请求开销。优化点包括尽量在前端阶段过滤数据,再将结果返回前端,提升缓存命中率与响应速度。
以下聚合管道示例演示对活跃用户的聚合统计,强调过滤、分组与排序的组合,以及对中间结果的缓存友好性:
db.userStats.aggregate([{ $match: { status: "active" } },{ $group: { _id: "$userId", count: { $sum: 1 } } },{ $sort: { count: -1 } },{ $limit: 100 }
])3. 双缓存架构与高并发调优要点
3.1 Cache-Aside 与写-through/写-behind 模式
在缓存设计中,Cache-Aside(旁路缓存)模式可实现数据从数据库向缓存的逐步导入,确保热数据在缓存命中时快速返回,冷数据在数据库更新后通过失效策略回填缓存。与此同时,写-through/写-behind 策略有助于降低写延迟与缓存一致性风险。
实现要点包括:在写操作时同时更新缓存与后端数据库,或在后台将更新延迟落地到缓存并与数据库保持一致性。下方给出一个简化的缓存-数据库协同的示例,展示缓存命中与写入过程的逻辑:
// Cache-Aside 示例伪代码
function getUser(id){let cache = redis.get('user:' + id)if (cache) return JSON.parse(cache)let user = db.users.findOne({ id: id })redis.set('user:' + id, JSON.stringify(user), 'EX', 3600)return user
}
3.2 监控、容量规划与性能基线
高并发环境下,持续监控是提升性能的关键。当系统运行稳定时,应关注 QPS、吞吐量、缓存命中率、延迟分布等指标,并以此做容量规划与参数调优。
为获得清晰的性能基线,需建立统一的监控口径,结合 应用端 SLA、数据库与缓存端的指标,确保在峰值时段系统仍具备可观的响应能力。以下是一个简化的监控脚本片段,用于记录常用指标并输出基线值:
# 简单性能基线记录(示意)
echo "QPS: 12000, 命中率: 92%, Redis 延迟: 1.2ms" >> /var/log/perf_baseline.log 

