太震撼了!权限缓存方案竟然还能这样设计?
在高并发的权限系统中,每次权限检查都直接查询数据库会导致严重的性能问题。缓存是解决这一问题的关键技术,通过将热点数据存储在内存中,可以大幅提升权限检查的响应速度。本章将深入探讨如何设计一个高性能、高可用的权限缓存方案。
1. 权限缓存架构设计
权限缓存系统需要考虑数据一致性、缓存命中率、失效策略等多个方面。一个典型的权限缓存架构如下:
#mermaid-svg-J5JazUc4bna02PZX{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-J5JazUc4bna02PZX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-J5JazUc4bna02PZX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-J5JazUc4bna02PZX .error-icon{fill:#552222;}#mermaid-svg-J5JazUc4bna02PZX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-J5JazUc4bna02PZX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-J5JazUc4bna02PZX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-J5JazUc4bna02PZX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-J5JazUc4bna02PZX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-J5JazUc4bna02PZX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-J5JazUc4bna02PZX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-J5JazUc4bna02PZX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-J5JazUc4bna02PZX .marker.cross{stroke:#333333;}#mermaid-svg-J5JazUc4bna02PZX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-J5JazUc4bna02PZX p{margin:0;}#mermaid-svg-J5JazUc4bna02PZX .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-J5JazUc4bna02PZX .cluster-label text{fill:#333;}#mermaid-svg-J5JazUc4bna02PZX .cluster-label span{color:#333;}#mermaid-svg-J5JazUc4bna02PZX .cluster-label span p{background-color:transparent;}#mermaid-svg-J5JazUc4bna02PZX .label text,#mermaid-svg-J5JazUc4bna02PZX span{fill:#333;color:#333;}#mermaid-svg-J5JazUc4bna02PZX .node rect,#mermaid-svg-J5JazUc4bna02PZX .node circle,#mermaid-svg-J5JazUc4bna02PZX .node ellipse,#mermaid-svg-J5JazUc4bna02PZX .node polygon,#mermaid-svg-J5JazUc4bna02PZX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-J5JazUc4bna02PZX .rough-node .label text,#mermaid-svg-J5JazUc4bna02PZX .node .label text,#mermaid-svg-J5JazUc4bna02PZX .image-shape .label,#mermaid-svg-J5JazUc4bna02PZX .icon-shape .label{text-anchor:middle;}#mermaid-svg-J5JazUc4bna02PZX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-J5JazUc4bna02PZX .rough-node .label,#mermaid-svg-J5JazUc4bna02PZX .node .label,#mermaid-svg-J5JazUc4bna02PZX .image-shape .label,#mermaid-svg-J5JazUc4bna02PZX .icon-shape .label{text-align:center;}#mermaid-svg-J5JazUc4bna02PZX .node.clickable{cursor:pointer;}#mermaid-svg-J5JazUc4bna02PZX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-J5JazUc4bna02PZX .arrowheadPath{fill:#333333;}#mermaid-svg-J5JazUc4bna02PZX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-J5JazUc4bna02PZX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-J5JazUc4bna02PZX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J5JazUc4bna02PZX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-J5JazUc4bna02PZX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J5JazUc4bna02PZX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-J5JazUc4bna02PZX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-J5JazUc4bna02PZX .cluster text{fill:#333;}#mermaid-svg-J5JazUc4bna02PZX .cluster span{color:#333;}#mermaid-svg-J5JazUc4bna02PZX 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-J5JazUc4bna02PZX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-J5JazUc4bna02PZX rect.text{fill:none;stroke-width:0;}#mermaid-svg-J5JazUc4bna02PZX .icon-shape,#mermaid-svg-J5JazUc4bna02PZX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-J5JazUc4bna02PZX .icon-shape p,#mermaid-svg-J5JazUc4bna02PZX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-J5JazUc4bna02PZX .icon-shape rect,#mermaid-svg-J5JazUc4bna02PZX .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-J5JazUc4bna02PZX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-J5JazUc4bna02PZX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-J5JazUc4bna02PZX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
应用服务
本地缓存
分布式缓存
数据库
缓存更新服务
权限变更事件
1.1 缓存层级设计
// CacheLayer 缓存层级
type CacheLayer int
const (
LayerLocal CacheLayer = iota // 本地缓存
LayerDistributed // 分布式缓存
LayerDatabase // 数据库
)
// PermissionCache 权限缓存接口
type PermissionCache interface {
Get(ctx context.Context, key string) (*PermissionData, error)
Set(ctx context.Context, key string, value *PermissionData, ttl time.Duration) error
Delete(ctx context.Context, key string) error
Clear(ctx context.Context) error
}
// PermissionData 权限数据
type PermissionData struct {
UserID string `json:\”user_id\”`
Permissions []string `json:\”permissions\”`
Roles []string `json:\”roles\”`
ExpiresAt time.Time `json:\”expires_at\”`
Metadata map[string]string `json:\”metadata\”`
}
1.2 多级缓存实现
// MultiLevelCache 多级缓存实现
type MultiLevelCache struct {
localCache *LocalCache
distributedCache DistributedCache
database Database
}
// LocalCache 本地缓存
type LocalCache struct {
cache *freecache.Cache
ttl time.Duration
}
// DistributedCache 分布式缓存接口
type DistributedCache interface {
Get(ctx context.Context, key string) ([]byte, error)
Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
Delete(ctx context.Context, key string) error
}
// Database 数据库接口
type Database interface {
GetUserPermissions(ctx context.Context, userID string) (*PermissionData, error)
}
// NewMultiLevelCache 创建多级缓存
func NewMultiLevelCache(localSize int, distCache DistributedCache, db Database) *MultiLevelCache {
return &MultiLevelCache{
localCache: &LocalCache{
cache: freecache



