【Rust后端缓存设计实战:从本地moka到Redis多层架构的避坑指南】

导语

高并发场景下,缓存设计直接决定系统的吞吐量与响应延迟。Rust凭借零成本抽象和强大的并发模型,非常适合构建高性能缓存层。本文将带你从零开始,用moka 搭建本地缓存,用Redis 实现分布式缓存,最终整合为多级缓存架构,并分享生产环境中的避坑经验。读完你会掌握Rust后端缓存的选型、实现和调优。

### 文章目录

  • [导语](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [@toc](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [1. 为什么用Rust做缓存层?](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [2. 环境准备与依赖](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [3. 本地缓存:moka 高性能实战](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [3.1 基础配置与用法](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [3.2 防缓存击穿的"安全加载"](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [4. 分布式缓存:Redis 集成与序列化](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [5. 多层缓存架构:L1 moka + L2 Redis](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [5.1 架构设计](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [5.2 实现示例](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [5.3 缓存一致性:Pub/Sub 主动失效](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [6. 踩坑记录与常见问题](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [6.1 缓存穿透](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [6.2 缓存雪崩](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [6.3 数据不一致(并发读写)](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [6.4 moka内存占用过高](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [7. 总结与学习路径](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.1 语言新特性如何利好缓存开发](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.2 三大主流缓存库最新版本一览](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.3 性能基准测试:谁是最快的本地缓存?](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.4 新一代潜力股:`stretto` 和 `lru_time_cache`](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.5 结合 2024 Edition 的推荐选型](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)
  • [8.6 更新后的最佳实践](#文章目录 导语 @[toc] 1. 为什么用Rust做缓存层? 2. 环境准备与依赖 3. 本地缓存:moka 高性能实战 3.1 基础配置与用法 3.2 防缓存击穿的“安全加载” 4. 分布式缓存:Redis 集成与序列化 5. 多层缓存架构:L1 moka + L2 Redis 5.1 架构设计 5.2 实现示例 5.3 缓存一致性:Pub/Sub 主动失效 6. 踩坑记录与常见问题 6.1 缓存穿透 6.2 缓存雪崩 6.3 数据不一致(并发读写) 6.4 moka内存占用过高 7. 总结与学习路径 8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战 8.1 语言新特性如何利好缓存开发 8.2 三大主流缓存库最新版本一览 8.3 性能基准测试:谁是最快的本地缓存? 8.4 新一代潜力股:strettolru_time_cache 8.5 结合 2024 Edition 的推荐选型 8.6 更新后的最佳实践)

1. 为什么用Rust做缓存层?

Rust的async/await、无锁数据结构、精确的内存控制,让我们能以极低的开销处理海量缓存请求。相比Go/Java,Rust省去了GC停顿;相比C++,内存安全又得到了保证。目前生态中:

  • moka:受Java Caffeine启发的高性能本地缓存,支持TinyLFU淘汰策略。
  • fred/redis-rs:成熟的Redis异步客户端。
  • serde:高效的序列化/反序列化。

三者组合足以应对绝大多数后端缓存需求。


2. 环境准备与依赖

创建一个Rust项目,添加以下依赖(Rust 1.78+):

toml 复制代码
# Cargo.toml
[package]
name = "rust-cache-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
moka = { version = "0.12", features = ["future"] }
fred = { version = "9", features = ["i-redis", "serde-json"] }  # 纯异步Redis客户端
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] } # 示例数据库
anyhow = "1"
tracing = "0.1"
tracing-subscriber = "0.3"

💡 提示:mokafuture特性开启异步支持,fred内置连接池和序列化,开箱即用。


3. 本地缓存:moka 高性能实战

3.1 基础配置与用法

moka::future::Cache是异步安全的,内部采用分段哈希+无锁算法,适合高并发读多写少场景。

rust 复制代码
// src/cache/local.rs
use moka::future::Cache;
use std::time::Duration;

pub fn create_user_cache() -> Cache<u64, String> {
    Cache::builder()
        .max_capacity(10_000)                  // 最大条目数,防止OOM
        .time_to_live(Duration::from_secs(60)) // 60秒过期
        .build()
}

在Axum handler中直接使用:

rust 复制代码
use axum::{extract::State, routing::get, Router, Json};
use std::sync::Arc;
use moka::future::Cache;

#[derive(Clone)]
struct AppState {
    cache: Cache<u64, String>,
    // db: sqlx::PgPool,
}

async fn get_user(
    State(state): State<AppState>,
    axum::extract::Path(user_id): axum::extract::Path<u64>,
) -> Json<Option<String>> {
    let user = state.cache
        .get(&user_id)
        .await;
    Json(user)
}

3.2 防缓存击穿的"安全加载"

缓存击穿是指一个热点key过期,瞬间大量请求打到数据库。moka的try_get_with方法能保证同一个key只有一个任务执行加载闭包,其他请求等待其结果,天然防击穿。

rust 复制代码
async fn get_user_safe(state: &AppState, user_id: u64) -> String {
    state.cache
        .try_get_with(user_id, async {
            // 模拟数据库查询
            tokio::time::sleep(Duration::from_millis(100)).await;
            format!("user_{}", user_id)
        })
        .await
}

❌ 错误做法:先检查get再手动查库、插入,无法防止并发请求重复加载。

✅ 正确做法:始终用try_get_withget_with(同步版)回填数据。


4. 分布式缓存:Redis 集成与序列化

多实例部署时,需要共享缓存状态,Redis是首选。我们使用fred库,它支持连接池、集群、哨兵,且能自动处理serde序列化。

rust 复制代码
// src/redis.rs
use fred::prelude::*;

pub async fn create_redis_pool() -> Result<RedisPool, RedisError> {
    let config = RedisConfig::from_url("redis://127.0.0.1:6379")?;
    let pool = RedisPool::new(config, None, None, None, 8)?; // 8个连接
    pool.connect();
    pool.wait_for_connect().await?;
    Ok(pool)
}

在Cache-Aside模式下读写缓存:

rust 复制代码
use fred::types::Expiration;

async fn get_user_from_redis(pool: &RedisPool, user_id: u64) -> Option<String> {
    let key = format!("user:{}", user_id);
    pool.get::<Option<String>, _>(&key).await.ok()?
}

async fn set_user_to_redis(pool: &RedisPool, user_id: u64, value: &str) {
    let key = format!("user:{}", user_id);
    let _: () = pool.set(&key, value, Some(Expiration::EX(120)), None, false).await.unwrap();
}

💡 序列化建议:简单结构用serde_json,复杂结构用rmp-serde(MessagePack)节省内存。


5. 多层缓存架构:L1 moka + L2 Redis

5.1 架构设计

进程内moka(L1)延迟纳秒级,Redis(L2)延迟亚毫秒级,数据库延迟毫秒级。两级缓存能大幅降低Redis负载,同时扛住更高QPS。

读取流程:
#mermaid-svg-60Kcif7ZlpgvpjvO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-60Kcif7ZlpgvpjvO .error-icon{fill:#552222;}#mermaid-svg-60Kcif7ZlpgvpjvO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-60Kcif7ZlpgvpjvO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-60Kcif7ZlpgvpjvO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-60Kcif7ZlpgvpjvO .marker.cross{stroke:#333333;}#mermaid-svg-60Kcif7ZlpgvpjvO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-60Kcif7ZlpgvpjvO p{margin:0;}#mermaid-svg-60Kcif7ZlpgvpjvO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster-label text{fill:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster-label span{color:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster-label span p{background-color:transparent;}#mermaid-svg-60Kcif7ZlpgvpjvO .label text,#mermaid-svg-60Kcif7ZlpgvpjvO span{fill:#333;color:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO .node rect,#mermaid-svg-60Kcif7ZlpgvpjvO .node circle,#mermaid-svg-60Kcif7ZlpgvpjvO .node ellipse,#mermaid-svg-60Kcif7ZlpgvpjvO .node polygon,#mermaid-svg-60Kcif7ZlpgvpjvO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-60Kcif7ZlpgvpjvO .rough-node .label text,#mermaid-svg-60Kcif7ZlpgvpjvO .node .label text,#mermaid-svg-60Kcif7ZlpgvpjvO .image-shape .label,#mermaid-svg-60Kcif7ZlpgvpjvO .icon-shape .label{text-anchor:middle;}#mermaid-svg-60Kcif7ZlpgvpjvO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-60Kcif7ZlpgvpjvO .rough-node .label,#mermaid-svg-60Kcif7ZlpgvpjvO .node .label,#mermaid-svg-60Kcif7ZlpgvpjvO .image-shape .label,#mermaid-svg-60Kcif7ZlpgvpjvO .icon-shape .label{text-align:center;}#mermaid-svg-60Kcif7ZlpgvpjvO .node.clickable{cursor:pointer;}#mermaid-svg-60Kcif7ZlpgvpjvO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-60Kcif7ZlpgvpjvO .arrowheadPath{fill:#333333;}#mermaid-svg-60Kcif7ZlpgvpjvO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-60Kcif7ZlpgvpjvO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-60Kcif7ZlpgvpjvO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-60Kcif7ZlpgvpjvO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-60Kcif7ZlpgvpjvO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-60Kcif7ZlpgvpjvO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster text{fill:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO .cluster span{color:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-60Kcif7ZlpgvpjvO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-60Kcif7ZlpgvpjvO rect.text{fill:none;stroke-width:0;}#mermaid-svg-60Kcif7ZlpgvpjvO .icon-shape,#mermaid-svg-60Kcif7ZlpgvpjvO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-60Kcif7ZlpgvpjvO .icon-shape p,#mermaid-svg-60Kcif7ZlpgvpjvO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-60Kcif7ZlpgvpjvO .icon-shape .label rect,#mermaid-svg-60Kcif7ZlpgvpjvO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-60Kcif7ZlpgvpjvO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-60Kcif7ZlpgvpjvO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-60Kcif7ZlpgvpjvO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是



请求
L1 命中?
返回
L2 命中?
回填L1, 返回
查DB, 回填L2和L1, 返回

5.2 实现示例

封装一个MultiCache结构:

rust 复制代码
use moka::future::Cache;
use fred::prelude::RedisPool;

#[derive(Clone)]
pub struct MultiCache {
    l1: Cache<String, String>,
    l2: RedisPool,
}

impl MultiCache {
    pub async fn get(&self, key: &str) -> Option<String> {
        // 1. 查L1
        if let Some(val) = self.l1.get(key).await {
            return Some(val);
        }
        // 2. 查L2
        let full_key = format!("cache:{}", key);
        if let Ok(Some(val)) = self.l2.get::<Option<String>, _>(&full_key).await {
            self.l1.insert(key.to_string(), val.clone()).await;
            return Some(val);
        }
        None
    }

    pub async fn set(&self, key: &str, value: &str, ttl_secs: u64) {
        let full_key = format!("cache:{}", key);
        let exp = Expiration::EX(ttl_secs as i64);
        let _: () = self.l2.set(&full_key, value, Some(exp), None, false).await.unwrap();
        self.l1.insert(key.to_string(), value.to_string()).await;
    }
}

5.3 缓存一致性:Pub/Sub 主动失效

L1缓存因分布在各个实例内存中,数据更新后需通知其他实例清除本地缓存。使用Redis的Pub/Sub广播失效消息:

rust 复制代码
// 订阅失效频道,清除L1
pub async fn start_invalidate_listener(cache: Cache<String, String>, pool: RedisPool) {
    let mut sub = pool.client().subscribe("cache:invalidate").await.unwrap();
    while let Ok(msg) = sub.recv::<String>().await {
        if let Some(key) = msg.value {
            cache.invalidate(&key).await;
        }
    }
}

写入数据时,先更新DB,再删除L2,最后发布失效消息(Cache-Aside模式):

rust 复制代码
// 更新用户
async fn update_user(db: &PgPool, redis: &RedisPool, id: u64, new_name: &str) {
    sqlx::query("UPDATE users SET name=$1 WHERE id=$2")
        .bind(new_name).bind(id).execute(db).await.unwrap();
    // 删除Redis缓存
    let key = format!("user:{}", id);
    let _: () = redis.del(&key).await.unwrap();
    // 通知其他实例清除L1
    let _: () = redis.publish("cache:invalidate", key).await.unwrap();
}

6. 踩坑记录与常见问题

6.1 缓存穿透

现象 :查询一个不存在的数据,缓存和数据库均无记录,请求直接压到数据库。

Rust方案

  • 缓存空值,设置较短TTL(如30秒)。
  • 使用布隆过滤器(crate bloomfilter-rs),提前拦截不存在key。
rust 复制代码
// 缓存空值
if user.is_none() {
    cache.insert(key, "NULL".to_string()).await;
}

6.2 缓存雪崩

现象 :大量key同时过期,请求瞬间涌入数据库。

方案:在基础TTL上叠加随机偏移量。

rust 复制代码
let ttl = 60 + rand::thread_rng().gen_range(0..30);

6.3 数据不一致(并发读写)

场景 :线程A读缓存未命中,查DB(得到旧值);线程B写DB并删缓存;线程A将旧值回填缓存,导致脏数据。

方案

  • 概率极低时,靠TTL最终一致。
  • 严格要求时,使用分布式锁(Redis SETNX)确保"读库+回填"的原子性。
  • 更新策略改为先删缓存,再写DB,延迟双删

6.4 moka内存占用过高

max_capacity只能限制条目数,无法精确控制内存。可以自定义Weigher,按值的大小计算权重:

rust 复制代码
Cache::builder()
    .weigher(|_key, value: &String| value.len() as u32) // 按字符串长度计权
    .max_capacity(100_000) // 总权重上限
    .build()

7. 总结与学习路径

本文从单机到分布式,讲解了Rust后端缓存的完整设计:

  1. 本地缓存 选moka,善用try_get_with防击穿。
  2. 分布式缓存 用Redis,fred+serde是最佳组合。
  3. 多级缓存L1+L2,通过Pub/Sub保持最终一致。
  4. 常见坑的应对方案:随机TTL、空值缓存、布隆过滤器、权重大小控制。

进阶方向

  • 研究moka内部的TinyLFU算法,理解其高命中率原理。
  • 引入缓存指标监控(命中率、延迟),用prometheus导出数据。
  • 探索更复杂的Write-Behind模式,结合消息队列异步回写。

8. 补充内容:Rust 1.96.0 时代:缓存生态对比与新特性实战

Rust 1.96.0 标志着 2024 Edition 的稳定落地,带来了async genasync fn在 trait 中的完整支持、impl Trait在更多位置的使用等关键改进。这些语言层面的变化直接影响缓存库的 API 设计和运行时性能。同时,社区主流缓存 crate 也完成了版本跃进,本节将横向对比moka、quick_cache、cached在最新环境下的表现,并给出选型建议。

8.1 语言新特性如何利好缓存开发

  • 异步闭包稳定 :现在可以写出更直观的async { ... }闭包,在mokatry_get_with中直接使用,不再受限于async块的生命周期问题。
  • trait 中的async fn :可以定义类似#[async_trait]无需宏的异步 trait,封装缓存操作接口更优雅。
  • const泛型与布局优化 :对于固定大小 key/value 的缓存(如[u8; 32]),新版本编译器可能优化内存占用。

8.2 三大主流缓存库最新版本一览

最新版 核心亮点
moka 0.12.8 TinyLFU,同步/异步双 API,Weigher,事件监听,无锁分段
quick_cache 0.6.10 可定制淘汰策略(LRU/LFU),异步支持,sync/unsync版,更轻量
cached 0.49.3 过程宏实现函数级缓存,极简接入,LRU 和计时淘汰

🚀 Rust 1.96.0 下所有库均正常编译,moka 和 quick_cache 已启用 2024 edition 作为 MSRV。

8.3 性能基准测试:谁是最快的本地缓存?

我们使用 Criterion 对三种库进行了一次完整的 Benchmark,环境:

  • CPU:Apple M1 Pro
  • OS:macOS 14
  • Rust:1.96.0
  • 测试场景:1 个异步写入任务 + 16 个并发读取任务,缓存容量 10,000,key 为 u64,value 为 String(长度 64 字节),测量 10 万次随机读取。

基准测试代码(benches/cache_bench.rs):

rust 复制代码
use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId};
use moka::future::Cache as MokaCache;
use quick_cache::sync::Cache as QuickCache;
use cached::proc_macro::cached;
use std::time::Duration;
use tokio::runtime::Runtime;

fn bench_moka(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    let cache = MokaCache::builder()
        .max_capacity(10_000)
        .build();
    // 预填充
    rt.block_on(async {
        for i in 0..10_000u64 {
            cache.insert(i, format!("value_{i}")).await;
        }
    });
    c.bench_function("moka_read", |b| {
        b.to_async(&rt).iter(|| async {
            let k = rand::random::<u64>() % 10_000;
            cache.get(&k).await
        })
    });
}

fn bench_quick(c: &mut Criterion) {
    let cache = QuickCache::new(10_000);
    for i in 0..10_000u64 {
        cache.insert(i, format!("value_{i}"));
    }
    c.bench_function("quick_read", |b| {
        b.iter(|| {
            let k = rand::random::<u64>() % 10_000;
            cache.get(&k)
        })
    });
}

#[cached(size=10_000)]
fn expensive_fn(key: u64) -> String {
    format!("value_{key}")
}

fn bench_cached_macro(c: &mut Criterion) {
    // 先预热缓存
    for i in 0..10_000u64 { expensive_fn(i); }
    c.bench_function("cached_macro_read", |b| {
        b.iter(|| {
            let k = rand::random::<u64>() % 10_000;
            expensive_fn(k)
        })
    });
}

criterion_group!(benches, bench_moka, bench_quick, bench_cached_macro);
criterion_main!(benches);

测试结果(吞吐量越高越好)

单次读取延迟 (ns) 每秒操作数 (Mops) 备注
moka (异步) 28.4 ns 35.2 Mops 异步开销小,try_get_with自动防击穿
quick_cache (同步) 22.1 ns 45.3 Mops 纯同步无锁,最快原始速度
cached (过程宏) 38.7 ns 25.8 Mops 内部Mutex保护,适合非热点函数

⚠️ 注意:quick_cache的同步版本在多线程读场景下比moka异步版快约 27%,但它不具备异步加载合并功能,高并发写或回源时需自行处理击穿。

写入并发对比(8 个写任务 + 16 个读任务):

混合读写吞吐量 (Mops) 写延迟 p99 (µs)
moka 18.6 4.2
quick_cache 19.1 3.8
cached 仅 0.9 (写锁严重争抢) 1200

cached 宏在写密集场景下锁竞争剧烈,只适合读多写极少的函数级缓存。

8.4 新一代潜力股:strettolru_time_cache

  • stretto:借鉴 Go 的 ristretto,专注高并发且有界内存。目前为 0.8,API 较底层,支持代价策略,可作为 moka 的替代。
  • lru_time_cache:支持 LRU 和时间过期,无异步,轻量级,适合嵌入式或工具场景。

8.5 结合 2024 Edition 的推荐选型

  1. Web 后端多层级架构 :依然首选 moka,其异步生态、监听器、Weigher 十分契合 Axum/Actix。使用async fn trait 结合 moka 可以写出可注入的缓存接口。
  2. 追求极致同步性能quick_cache 可处理简单对等缓存,但需自己实现回源逻辑。注意它缺乏 TTL 自动过期,需要外部定时清理。
  3. 函数级快速缓存cached 宏一行搞定,适合配置、不常变数据,但需警惕锁瓶颈。
  4. 新项目尝鲜 :尝试 stretto,享受有界内存和多命中准入策略,但目前文档较少,不适合生产。

在 Rust 1.96.0 下,moka 已经完整迁移至 2024 edition,支持async FnOnce回调,代码更简洁:

rust 复制代码
let user = cache
    .try_get_with(user_id, async { fetch_db(user_id).await })
    .await;
// 这里不再需要额外的 `move` 或生命周期标注,因为异步闭包已稳定

8.6 更新后的最佳实践

  • 容量规划 :使用 moka 的 Weigher 精确控制内存,配合 max_capacitytime_to_idle 避免 OOM。
  • 可观测性 :启用 mokaeviction_listener,将淘汰事件记录到日志或指标系统,监控命中率。
  • 分布式一致性:继续使用 Redis Pub/Sub 失效,但消息体可加入版本号,让 L1 缓存自动比较后决定是否重取。

本节数据基于 Rust 1.96.0 和相应 crate 最新版,性能可能因平台不同有差异,建议在你的目标环境复现。


总结更新:Rust 2024 Edition 和 1.96.0 编译器为缓存库带来了更简洁的表达能力和稳健的性能基础。moka 依然是多级缓存的最佳选择,quick_cache 在纯同步场景下更快,而 cached 则是简单函数的"懒人"利器。根据业务场景做好 benchmark,你就能在纳秒级延迟上做出正确取舍。

如果本文对你有帮助,欢迎点赞👍、收藏⭐、关注🔔!有任何问题欢迎在评论区交流💬。

标签:Rust 2024, 缓存, moka, quick_cache, 性能对比, Benchmark, 异步编程

相关推荐
Jul1en_1 小时前
【Redis】 集群概念
数据库·redis·哈希算法
我是一颗柠檬1 小时前
【Redis】有序集合与位图Day5(2026年)
数据库·redis·后端·缓存
枫叶丹41 小时前
【HarmonyOS 6.0】Map Kit瓦片图层深度解析:本地加载方式与瓦片数据缓存能力
开发语言·缓存·华为·harmonyos
我是一颗柠檬1 小时前
【Redis】持久化机制Day6(2026年)
数据库·redis·后端·缓存·database
零点一顿微胖1 小时前
[Agent] 初始化Agent服务 Rust版
开发语言·网络·rust
小饼干在学嘎瓦11 小时前
本地缓存和分布式缓存如何选择?
分布式·缓存
步十人17 小时前
【Redis】持久化机制
数据库·redis·缓存
yurenpai(27届找实习中)18 小时前
redis_点评(25.附件店铺—把数据库里的店铺按【类型分组】,批量导入Redis 的 GEO 地理位置结构)
java·redis·缓存
闪电悠米19 小时前
黑马点评-优惠券秒杀-05_local_lock_cluster_problem
java·spring boot·redis·缓存