文档目录
分布式缓存配置

简介

本指南面向在 DouPHP 中落地“分布式缓存”的工程师与运维人员,目标是给出可操作的集群部署方案、数据一致性策略、穿透与雪崩防护、以及监控扩容等运维方法。文档基于仓库内已有的缓存适配器与配置构建器(支持 Memcached/Memcache),并结合框架内的会话与清理能力,形成一套从代码到运维的完整实践。

项目结构

DouPHP 当前未内置统一的“应用级缓存服务”,但提供了两类与缓存相关的实现:

  • 插件 SDK 中的缓存抽象层:通过配置构建器组织多节点、主从角色,并通过连接管理器选择适配器(Memcached/Memcache)。
  • 框架会话与缓存清理:提供 Session 门面与实现,以及后台缓存目录清理服务,便于配合外部缓存进行一致性管理。
graph TB
A["业务模块"] --> B["缓存句柄<br/>LtCacheHandle"]
B --> C["连接管理器<br/>LtCacheConnectionManager"]
C --> D["配置构建器<br/>LtCacheConfigBuilder"]
C --> E["适配器<br/>Memcached / Memcache"]
A --> F["会话门面/实现<br/>Session Facade/Infra"]
A --> G["缓存清理服务<br/>CacheClearService"]

图示来源

  • CacheHandle.php(alipayf2f):1-53
  • CacheConfigBuilder.php(alipayf2f):1-42
  • CacheAdapterMemcached.php(alipayf2f):1-36
  • CacheAdapterMemcache.php(alipayf2f):1-34
  • Session.php(门面):1-61
  • Session.php(实现):1-321
  • CacheClearService.php:1-46

核心组件

  • 缓存配置构建器:支持按 group/node/role 组织节点,并允许为 slave 继承 master 默认配置,便于主从与多实例编排。
  • 缓存句柄:封装 add/get/update/del 等操作,内部通过连接管理器获取适配器与连接资源。
  • 缓存适配器:对 Memcached/Memcache 的统一封装,键名以表名前缀隔离,避免跨模块冲突。
  • 会话门面/实现:提供安全的命名空间读写、一次性消息、计数器等能力,可作为本地快速缓存或分布式扩展的参考。
  • 缓存清理服务:用于清理本地缓存目录,配合外部缓存失效策略使用。

架构总览

下图展示了请求如何经由缓存句柄访问后端缓存集群,并在需要时回源数据库;同时展示会话与清理服务在整体流程中的位置。

sequenceDiagram
participant App as "业务代码"
participant Handle as "缓存句柄"
participant ConnMgr as "连接管理器"
participant Adapter as "缓存适配器"
participant Cache as "Memcached/Memcache 集群"
participant DB as "数据库"
App->>Handle : get(key, table)
Handle->>ConnMgr : getConnection(group,node,role)
ConnMgr-->>Handle : adapter + connection
Handle->>Adapter : get(realKey)
alt 命中
Adapter-->>Handle : value
Handle-->>App : value
else 未命中
Adapter-->>Handle : null
Handle-->>App : null
App->>DB : 查询数据
DB-->>App : data
App->>Handle : set(key, data, ttl)
Handle->>Adapter : set(realKey, data, ttl)
Adapter-->>Cache : 写入
Cache-->>Adapter : ok
Adapter-->>Handle : ok
Handle-->>App : data
end

图示来源

  • CacheHandle.php(alipayf2f):1-53
  • CacheAdapterMemcached.php(alipayf2f):1-36
  • CacheAdapterMemcache.php(alipayf2f):1-34

详细组件分析

组件A:缓存配置与节点编排(主从/多实例)

  • 角色与分组:通过 group/node/role 三元组组织节点,支持 master 与 slave 角色,slave 可继承 master 默认配置,简化多副本配置。
  • 适配器选择:根据配置中的 adapter 字段选择具体实现(如 memcached/memcache)。
  • 键隔离:适配器统一以“表名-键”形式生成真实键,避免不同模块间键冲突。
classDiagram
class LtCacheConfigBuilder {
-servers
-defaultConfig
+addSingleHost(hostConfig)
+addHost(groupId, nodeId, role, hostConfig)
+getServers()
}
class LtCacheHandle {
+init()
+add(key,value,ttl,table)
+get(key,table)
+update(key,value,ttl,table)
+del(key,table)
-initConnection()
}
class LtCacheAdapterMemcached {
+connect(hostConf)
+add(key,value,ttl,table,conn)
+get(key,table,conn)
+update(key,value,ttl,table,conn)
+del(key,table,conn)
-getRealKey(table,key)
}
class LtCacheAdapterMemcache {
+connect(hostConf)
+add(key,value,ttl,table,conn)
+get(key,table,conn)
+update(key,value,ttl,table,conn)
+del(key,table,conn)
-getRealKey(table,key)
}
LtCacheHandle --> LtCacheConfigBuilder : "读取配置"
LtCacheHandle --> LtCacheAdapterMemcached : "使用"
LtCacheHandle --> LtCacheAdapterMemcache : "使用"

图示来源

  • CacheConfigBuilder.php(alipayf2f):1-42
  • CacheHandle.php(alipayf2f):1-53
  • CacheAdapterMemcached.php(alipayf2f):1-36
  • CacheAdapterMemcache.php(alipayf2f):1-34

组件B:会话与本地缓存能力

  • 会话门面/实现:提供安全的命名空间读写、一次性消息、计数器等能力,适合短生命周期、进程内或会话级缓存场景。
  • 与分布式缓存的关系:可将热点读路径接入分布式缓存,写路径通过会话或消息队列触发异步刷新,降低耦合。
flowchart TD
Start(["进入请求"]) --> CheckSession["检查会话命名空间"]
CheckSession --> ReadLocal["读取本地会话值"]
ReadLocal --> Hit{"命中?"}
Hit -- 是 --> ReturnLocal["返回本地值"]
Hit -- 否 --> ReadDist["读取分布式缓存"]
ReadDist --> DistHit{"命中?"}
DistHit -- 是 --> WriteLocal["写入本地会话(可选)"] --> ReturnDist["返回分布式值"]
DistHit -- 否 --> BackToDB["回源数据库"] --> SetDist["写入分布式缓存"] --> ReturnDB["返回DB结果"]

图示来源

  • Session.php(门面):1-61
  • Session.php(实现):1-321

组件C:缓存清理与一致性辅助

  • 清理服务:提供删除缓存目录的能力,可用于模板编译缓存、静态资源缓存等本地缓存的清理。
  • 与外部缓存联动:建议在数据更新后,先写分布式缓存,再调用清理服务清理本地缓存,保证一致性。

依赖关系分析

  • 配置构建器负责组装节点拓扑(group/node/role),连接管理器据此选择适配器与连接。
  • 适配器对底层 Memcached/Memcache 进行统一封装,键名带前缀隔离。
  • 业务侧通过缓存句柄访问缓存,屏蔽底层差异。
graph LR
Builder["配置构建器"] --> Handle["缓存句柄"]
Handle --> AdapterM["Memcached 适配器"]
Handle --> AdapterC["Memcache 适配器"]
AdapterM --> Cluster["缓存集群"]
AdapterC --> Cluster

图示来源

  • CacheConfigBuilder.php(alipayf2f):1-42
  • CacheHandle.php(alipayf2f):1-53
  • CacheAdapterMemcached.php(alipayf2f):1-36
  • CacheAdapterMemcache.php(alipayf2f):1-34

性能考虑

  • 连接复用:适配器通过连接对象复用连接,减少握手开销。
  • 键设计:统一“表名-键”前缀,避免冲突且利于分片与统计。
  • TTL 控制:合理设置过期时间,结合随机抖动避免集中过期。
  • 读写分离:读路径优先走缓存,写路径采用“先更新缓存,再清理本地缓存”的策略,降低一致性成本。
  • 容量规划:依据热点键数量与平均大小估算内存占用,预留 20%-30% 余量。

故障排查指南

  • 连接失败:检查适配器配置的 host/port 是否正确,确认 Memcached/Memcache 服务可达。
  • 键冲突:确认各模块使用不同的表名前缀,避免 key 碰撞。
  • 缓存未命中:检查 TTL 是否过短、是否存在批量过期;核对业务逻辑是否在写路径正确写入缓存。
  • 本地缓存不一致:在数据变更后,调用缓存清理服务清理本地缓存目录,确保与分布式缓存一致。

结论

DouPHP 通过插件 SDK 提供的缓存抽象层,已具备对接 Memcached/Memcache 集群的基础能力。结合会话与清理服务,可在应用层实现高可用、可扩展的缓存体系。建议在生产环境优先采用 Memcached 作为分布式缓存后端,配合合理的 TTL、键设计与清理策略,获得稳定高效的缓存体验。

附录:部署与运维清单

  • 集群部署方案

    • 节点配置:通过配置构建器添加多个 host,区分 group/node/role;master 作为主写节点,slave 作为只读或冗余副本。
    • 负载均衡:利用底层客户端的分片/轮询机制,将键均匀分布到多个节点。
    • 故障转移:当某节点不可用时,由客户端自动切换到其他可用节点;必要时在主从之间切换角色。
  • 数据一致性保证

    • 主从同步:由缓存集群自身保障副本间的数据复制;应用侧通过写主读从或全主模式控制一致性级别。
    • 冲突检测:缓存层通常无复杂冲突处理,建议在业务层做幂等写入与版本号控制。
    • 数据复制:依赖底层 Memcached/Memcache 集群的复制能力;若需强一致,可在写路径增加校验与重试。
  • 缓存穿透防护

    • 空值缓存:对不存在的数据写入短 TTL 的空值,防止重复回源。
    • 布隆过滤器:在缓存前置一层布隆过滤器,拦截明显不存在的键。
    • 请求限流:在网关或中间件层对高频 key 进行限流,保护后端。
  • 缓存雪崩防护

    • 随机过期时间:TTL 加上随机抖动,避免同一时刻大量键过期。
    • 熔断机制:当缓存命中率骤降或错误率升高时,快速降级至直连数据库或返回兜底数据。
    • 降级策略:在极端情况下,关闭非关键缓存,优先保障核心链路。
  • 分布式环境下的缓存管理

    • 集群监控:监控内存使用、命中率、连接数、错误率等指标。
    • 容量规划:根据 QPS、键大小、TTL 估算内存需求,定期评估并扩容。
    • 扩容缩容:在线增减节点,借助客户端分片算法平滑迁移;缩容前做好数据预热与下线策略。
  • 具体部署配置与运维管理

    • 安装与启动:部署 Memcached/Memcache 服务,开放必要端口,配置最大内存与连接数。
    • 应用配置:在配置构建器中添加节点信息,选择合适的适配器,设置合理的 TTL 与键前缀。
    • 运维操作:使用缓存清理服务清理本地缓存;定期巡检集群健康状态与慢查询;制定回滚与应急预案。
添加日期:2026-10-05