分享

Redis+Nginx实现高并发缓存架构




问题导读:

1、怎样设计高并发缓存架构?
2、什么是Http缓存控制头?
3、怎样配置Nginx缓存?




1 缓存架构设计
一谈到缓存架构,很多人想到的是Redis,但其实整套体系的缓存架构并非只有Redis,而应该是多个层面多个软件结合形成一套非常良性的缓存体系。比如下面缓存架构设计就涉及到了多个层面的缓存软件。本文只提供思路不提供整体代码

1.1 缓存架构设计

6fb69b650797445ab2388ecd5385e019.png

架构图综合了多种缓存和多层面的缓存设计,从前端页面缓存到代理服务器lvs和nginx缓存,以及后端服务redis缓存,包括缓存数据同步等。
对上述架构,我们来个宏观解说:

  • HTML页面做缓存,浏览器端可以缓存HTML页面和其他静态资源,防止用户频繁刷新对后端造成巨大压力
  • Lvs实现记录不同协议以及不同用户请求链路缓存
  • Nginx这里会做HTML页面缓存配置以及Nginx自身缓存配置
  • 数据查找这里用Lua取代了其他语言查找,提高了处理的性能效率,并发处理能力将大大提升
  • 数据缓存采用了Redis集群+主从架构,并实现缓存读写分离操作
  • 集成Canal实现数据库数据增量实时同步Redis


2 Redis集群高级应用

这里安装6个redis,配置如下:

ed46b161e81147a5807725ceede4a570.png

3 Nginx缓存

为了提升网站的整体性能,我们一般会采用缓存,从宏观层面来说,会采用浏览器缓存和后端缓存,Nginx处于Web网站的服务最外层,而且支持浏览器缓存配置和后端数据缓存,用它来做部分数据缓存,效率更高。

Web缓存是可以自动保存常见文档副本的HTTP 设备。当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地设备而不是服务器中提取这个文 档。

3.1 OpenRestry安装

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、 Web 服务和动态网关。

OpenResty 通过lua脚本扩展 nginx 功能,可提供负载均衡、请求路由、安全认证、服务鉴权、流量控制与日志监控等服务。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样, Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

关于 OpenRestry 的学习,大家可以参考:http://openresty.org/cn/

安装依赖库

  1. yum install wget libtermcap-devel ncurses-devel libevent-devel readline-devel pcre-devel gcc
  2. openssl openssl-devel per
复制代码

下载安装包

wget https://openresty.org/download/openresty-1.11.2.5.tar.gz

解压安装

  1. tar -xf openresty-1.11.2.5.tar.gz
  2. cd openresty-1.11.2.5
  3. ./configure --prefix=/usr/local/openresty --with-luajit --without-http_redis2_module --with-
  4. http_stub_status_module --with-http_v2_module --with-http_gzip_static_module --with-
  5. http_sub_module --add-module=/usr/local/server/ngx_cache_purge-2.3/
  6. make && make install
复制代码

安装完成后,在 /usr/local/openrestry/nginx 目录下是安装好的nginx。

3.2 浏览器缓存

客户端侧缓存一般指的是浏览器缓存、app缓存等等,目的就是加速各种静态资源的访问,降低服务器压力。
我们通过配置Nginx设置网页缓存信息,从而降低用户对服务器频繁访问造成的巨大压力。我们先配置一个案例,再
基于案例去讲解Nginx缓存。

3.2.1 Nginx Web缓存配置

nginx 提供了 expires 、 etag 、 if-modified-since 指令来进行浏览器缓存控制。我们使用 expires 来配置Nginx对网页的缓存。

语法: expires [modified] time; 默认值: expires off;
上下文: http, server,
location, if in location

  • 上传html


将1.html上传到服务器的 /usr/local/server/html 目录下。

  • 配置nginx


修改 /usr/local/openrestry/nginx/conf/nginx.conf 文件,配置如下:

  1.     server {
  2.         listen 80;
  3.         server_name localhost;
  4.         location / {
  5.          #静态文件路径
  6.         root /usr/local/server/html;
  7.          #缓存10秒
  8.         expires 10s;
  9. }
  10.     }
复制代码

过期时间配置说明

  1. expires 30s; #30秒
  2. expires 30m; #30分钟
  3. expires 2h; #2个小时
  4. expires 30d; #30天
复制代码

第一次请求<http://192.168.211.141/1.html>

afc08729931342ac9ac68a7ef737050c.png

第二次请求 <http://192.168.211.141/1.html>

fa522ca82f4f466e81f034d3ad8ef84d.png

3.2.2 Http缓存控制头

14a458dcbd0a47e680fd54a29ef8bca6.png

参数说明:

HTTP 中最基本的缓存机制,涉及到的 HTTP 头字段,包括 Cache-Control, Last-Modified, If-Modified-Since, Etag,If-None-Match 等。

Last-Modified/If-Modified-Since

Etag是服务端的一个资源的标识,在 HTTP 响应头中将其传送到客户端。所谓的服务端资源可以是一个Web页面,也可以是JSON或XML等。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。比如,浏览器第一次请求一个资源的时候,服务端给予返回,并且返回了ETag: “50b1c1d4f775c61:df3” 这样的字样给浏览器,当浏览器再次请求这个资源的时候,浏览器会将If-None-Match: W/“50b1c1d4f775c61:df3” 传输给服务端,服务端拿到该ETAG,对比资源是否发生变化,如果资源未发生改变,则返回304HTTP状态码,不返回具体的资源。

Last-Modified :标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

If-Modified-Since :当资源过期时(使用Cache-Control标识的max-age),发现资源具有 Last-Modified 声明,则再次向web服务器请求时带上头。

If-Modified-Since ,表示请求时间。web服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源有被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应 HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的 cache。

Pragma行是为了兼容 HTTP1.0 ,作用与 Cache-Control: no-cache 是一样的

Etag/If-None-Match

Etag :web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),如果给定URL中的资源修改,则一定要生成新的Etag值。

If-None-Match :当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务
器请求时带上头 If-None-Match (Etag的值)。web服务器收到请求后发现有头 If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

Etag:

Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间,如果某些文件会被定期生成,当有时内容并没有任何变化,但 Last-Modified 却改变了,导致文件没法使用缓存有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。 Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag ,一致的情况下,才会继续比对 Last-Modified ,最后才决定是否返回304。

3.3 代理缓存

07fb62c0ce7b4040bdd7f966006a6489.png

用户如果请求获取的数据不是需要后端服务器处理返回,如果我们需要对数据做缓存来提高服务器的处理能力,我们
可以按照如下步骤实现:

  • 请求Nginx,Nginx将请求路由给后端服务
  • 后端服务查询Redis或者MySQL,再将返回结果给Nginx
  • Nginx将结果存入到Nginx缓存,并将结果返回给用户
  • 用户下次执行同样请求,直接在Nginx中获取缓存数据

3.3.1 proxy_cache

proxy_cache 是用于 proxy 模式(一般也可称为反代)的缓存功能,proxy_cache 在 Nginx 配置的 http 段、server
段(location 段)中分别写入不同的配置。http 段中的配置用于定义 proxy_cache 空间,server 段中的配置用于调
用 http 段中的定义,启用对 server 的缓存功能。

属性使用说明proxy_cache_path:

Example

proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2
keys_zone=openresty_cache:10m max_size=10g inactive=60m use_temp_path=off;

【作用】指定缓存存储的路径,缓存存储在/usr/local/openresty/nginx/cache目录

【levels=1:2】设置一个两级目录层次结构存储缓存,在单个目录中包含大量文件会降低文件访问速度,因此我们建议对大多数部署使用两级目录层次结构。如果 levels 未包含该参数,Nginx 会将所有文件放在同一目录中。

【keys_zone=openresty_cache:10m】设置共享内存区域,用于存储缓存键和元数据,例如使用计时器。拥有内存中的密钥副本,Nginx 可以快速确定请求是否是一个 HIT 或 MISS 不必转到磁盘,从而大大加快了检查速度。1 MB 区域可以存储大约 8,000 个密钥的数据,因此示例中配置的 10 MB 区域可以存储大约 80,000 个密钥的数据。

【max_size=10g】设置缓存大小的上限。它是可选的; 不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限制时,一个称为缓存管理器的进程将删除最近最少使用的缓存,将大小恢复到限制之下的文件。

【inactive=60m】指定项目在未被访问的情况下可以保留在缓存中的时间长度。在此示例中,缓存管理器进程会自动从缓存中删除 60 分钟未请求的文件,无论其是否已过期。默认值为 10 分钟(10m)。非活动内容与过期内容不同。Nginx 不会自动删除缓存 header 定义为已过期内容(例如 Cache-Control:max-age=120)。过期(陈旧)内容仅在指定时间内未
被访问时被删除。访问过期内容时,Nginx 会从原始服务器刷新它并重置 inactive 计时器。

【use_temp_path=off】表示NGINX会将临时文件保存在缓存数据的同一目录中。这是为了避免在更新缓存时,磁盘之间互相复制响应数据,我们一般关闭该功能。

proxy_cache:

设置是否开启对后端响应的缓存,如果开启的话,参数值就是zone的名称,比如:proxy_cache openresty_cache;

proxy_cache_valid:

针对不同的response code设定不同的缓存时间,如果不设置code,默认为200,301,302,也可以用any指定所有code
Example:
【proxy_cache_valid 200 304 10s;】所有200/304响应的数据都缓存10秒。
【proxy_cache_valid any 1m;】所有请求响应的值都缓存1分钟。

proxy_cache_min_uses:

指定在多少次请求之后才缓存响应内容,这里表示将缓存内容写入到磁盘。 Example: 【proxy_cache_min_uses 3;】同一个请求达到了3次,才将缓存写入磁盘。

proxy_cache_lock:

默认不开启,开启的话则每次只能有一个请求更新相同的缓存,其他请求要么等待缓存有数据要么限时等待锁释放;nginx1.1.12才开始有。

proxy_cache_key:

缓存文件的唯一key,可以根据它实现对缓存文件的清理操作

3.3.2 缓存操作

我们在 nginx.conf 中添加如下配置:

  1.         #缓存配置
  2.         proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2 keys_zone=openresty_cache:10m
  3.         max_size=10g inactive=60m use_temp_path=off;
  4.         server {
  5.         listen 80;
  6.         server_name localhost;
  7.         #html配置
  8.         location ~ \.html {
  9.         #静态文件路径
  10.         root /usr/local/server/html;
  11.         #缓存10秒
  12.         expires 10s;
  13.         }
  14.         #非html配置
  15.         location / {
  16.         #启用缓存openresty_cache
  17.         proxy_cache openresty_cache;
  18.         #针对指定请求缓存
  19.         #proxy_cache_methods GET;
  20.         #设置指定请求会缓存
  21.         proxy_cache_valid 200 304 10s;
  22.         #最少请求1次才会缓存
  23.         proxy_cache_min_uses 3;
  24.         #如果并发请求,只有第1个请求会去服务器获取数据
  25.         #proxy_cache_lock on;
  26.         #唯一的key
  27.         proxy_cache_key $host$uri$is_args$args;
  28.         proxy_pass http://myip:18081;
  29.       }
  30.   }
复制代码

此时 /usr/local/openresty/nginx/cache 目录下只有1个temp文件夹。

我们执行3次请求 <http://192.168.211.141/user/wangwu> ,可以发现此时多了一些其他目录,这些目录就是存
储每个请求对应的缓存。




最新经典文章,欢迎关注公众号



---------------------

作者:赵广陆
来源:csdn
原文:基于Redis和Nginx实现高并发缓存架构


已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条