万隆的笔记 万隆的笔记
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
  • Redis

  • 集群架构

    • Redis主从模式
    • Redis Sentinel 集群部署
    • Redis集群分区
    • 缓存架构设计
      • 多级缓存
      • 缓存大小设置
      • Redis的设计要点
      • 分布式的session分离
      • Redis开发手册
    • 分布式缓存问题
    • Redis分布式锁
  • Redis
  • 集群架构
2022-04-01
目录

缓存架构设计

# 缓存架构设计

# 多级缓存

缓存的设计要分多个层次,在不同的层次上选择不同的缓存,包括JVM缓存、文件缓存和Redis缓存。

# JVM缓存

JVM缓存就是本地缓存,设计在应用服务器中。通常可以采用Ehcache和Guava Cache,在互联网应用中,由于要处理高并发,通常选择Guava Cache。

适用本地(JVM)缓存的场景:

  • 对性能有非常高的要求。
  • 不经常变化
  • 占用内存不大
  • 有访问整个集合的需求
  • 数据允许不实时一致

# 文件缓存

这里的文件缓存是指基于http协议的文件缓存,一般放在Nginx中。

因为静态文件(比如css,js, 图片)中,很多都是不经常更新的。Nginx使用proxy_cache将用户的请求缓存到本地一个目录。下一个相同请求可以直接调取缓存文件,就不用去请求服务器了。

Nginx缓存配置 (opens new window)

server {
  listen 80 default_server;   server_name localhost; 
  root /usr/local/blog/; 
  location / { 
     proxy_pass http://localhost:8080; 
  }
  # 要缓存文件的后缀
  location ~ .*\.(gif|jpg|png|css|js)(.*) { 
    proxy_pass http://localhost:8080; 
    proxy_redirect off; 
    proxy_set_header Host $host; 
    proxy_cache one; # 使用名称为one的缓存
    proxy_cache_valid 200 302 24h; # 响应状态码为200、302时,24小时有效;
    proxy_cache_valid 301 30d;  # 响应状态码为301时,15天有效;
    proxy_cache_valid any 5m; # 任何其他状态吗,5分钟有效;
    expires 30d; # 过期时间30天
  } 
}

# Redis缓存

分布式缓存,采用主从+哨兵或RedisCluster的方式缓存数据库的数据(还可以作为Mybatis的二级缓存使用)。

在实际开发中Redis如果作为数据库使用,数据要完整。

# 缓存大小设置

Guava Cache的缓存设置方式:

CacheBuilder.newBuilder().maximumSize(num) // 超过num会按照LRU算法来移除缓存

Nginx的缓存设置方式:

http { 
  ... 
  proxy_cache_path /lib/nginx/cache  levels=1:2 keys_zone=one:10m inactive=60m loader_threshold=300 loader_files=200 max_size=200m; 
  server { 
    proxy_cache one; 
    location / { 
      proxy_pass http://localhost:8080; 
    }
  }
}

Redis缓存设置:

# 最大缓存量 一般为内存的3/4
maxmemory=num  
# 内存回收策略,所有key回收最近最少使用
maxmemory-policy allkeys-lru

关于回收策略,详见回收策略与缓存过期

# Redis的设计要点

  • key数量:官方说Redis一个单例能处理2.5亿个key。一个key或是value大小最大是512M。

  • 读写峰值:Redis采用的是基于内存的采用的是单进程单线程模型的 K-V 数据库,由C语言编写,官方提供的数据是 可以达到**110000+**的QPS(每秒内查询次数)以及80000的写。

  • 命中率:可以直接通过缓存获取到需要的数据称为命中,而无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作就是没有命中缓存。原因可能是由于缓存中根本不存在,或者缓存已经过期。通常来讲,缓存的命中率越高则表示使用缓存的收益越高,应用的性能越好(响应时间越短、吞吐量越高),抗并发的能力越强。由此可见,在高并发的互联网系统中,缓存的命中率是至关重要的指标。通过info命令可以监控服务器状态:

    #缓存命中 
    keyspace_hits:300
    #缓存未命中 
    keyspace_misses:2
    

    选择一个适合的缓存失效机制和过期时间设计良好的系统,命中率可以做到95%以上。 影响缓存命中率的因素:

    • 缓存的数量越少命中率越高,比如缓存单个对象的命中率要高于缓存集合
    • 过期时间越长命中率越高
    • 缓存越大缓存的对象越多,则命中的越多
  • 过期策略:详见回收策略与缓存过期

  • 性能监控指标:利用info命令就可以了解Redis的状态了,主要监控指标有:

    connected_clients:68 # 连接的客户端数量 
    used_memory_rss_human:847.62M # 系统给redis分配的内存 
    used_memory_peak_human:794.42M # 内存使用的峰值大小 
    total_connections_received:619104 # 服务器已接受的连接请求数量 
    instantaneous_ops_per_sec:1159 # 服务器每秒钟执行的命令数量 qps 
    instantaneous_input_kbps:55.85 # redis网络入口kps
    instantaneous_output_kbps:3553.89 # redis网络出口kps 
    rejected_connections:0 # 因为最大客户端数量限制而被拒绝的连接请求数量 
    expired_keys:0 # 因为过期而被自动删除的数据库键数量 
    evicted_keys:0 # 因为最大内存容量限制而被驱逐(evict)的键数量 
    keyspace_hits:0 # 查找数据库键成功的次数 
    keyspace_misses:0 # 查找数据库键失败的次数
    

    Redis监控平台:grafana、prometheus以及redis_exporter。

  • 缓存预热:缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询实现被预热的缓存数据。 加载缓存思路:

    • 数据量不大,可以在项目启动的时候自动进行加载
    • 利用定时任务刷新缓存,将数据库的数据刷新到缓存中

# 分布式的session分离

传统的session是由tomcat自己进行维护和管理,但是对于集群或分布式环境,不同的tomcat管理各自的session,很难进行session共享,通过传统的模式进行session共享,会造成session对象在各个tomcat之间,通过网络和Io进行复制,极大的影响了系统的性能。 可以将登录成功后的Session信息,存放在Redis中,这样多个服务器(Tomcat)可以共享Session信息。

利用spring-session-data-redis(SpringSession),可以实现基于redis来实现的session分离。

# Redis开发手册

  • 阿里云Redis开发规范 (opens new window)
上次更新: 5/30/2023, 11:42:20 PM
分布式缓存问题

分布式缓存问题→

最近更新
01
2025
01-15
02
Elasticsearch面试题
07-17
03
Elasticsearch进阶
07-16
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式