资讯专栏INFORMATION COLUMN

ngx_srcache + lua异步更新缓存----提升10倍的响应速度

gaomysion / 270人阅读

摘要:异步更新缓存一直使用作为反向代理服务器,一来基于事件驱动,速度快。同时,本身还能提供快速的读写速度。都是由于自动删除过期缓存,导致的缓存缺失。在结束请求的同时,使用一个异步任务去更新缓存,考虑到并发情况,这里也需要使用一个共享内存锁。

nginx_lua异步更新缓存 NGINX

一直使用nginx作为反向代理服务器,一来nginx基于事件驱动,速度快。而来nginx的反向代理模块能很好的支持页面缓存负载均衡

页面缓存

nginx有proxy_cache这个内置的缓存功能,是基于文件的。如果把缓存路径设置到RAMDISK上面,可以达到和内存缓存差不多的缓存读写速度。这样做虽然解决了文件读写慢的问题,但是如果分布式部署的时候,这个缓存不能跨机器共享。

srcache-nginx-module

章大神写的这个模块支持和另一个模块配合将页面缓存写入redis集群。就很好的解决了

缓存不能跨机器共享的问题

也使得缓存大小不受单机资源限制

同时,redis本身还能提供快速的读写速度

问题

看上面列的几点,似乎已经很完美了。
但是在实际使用的时候还是发现有需要改善的地方:

缓存不存在的时候:
第一个请求查询redis失败,到后端,最后还要存储redis。比没有缓存的情况还多出两次redis访问,一次读一次写。而且当并发访问的时候还可能请求都会进入后端服务器,后端不够健壮的时候会导致“雪崩效应”。(如果使用默认的proxy_cache模块还能通过proxy_cache_use_stale命令避免,但是srcache模块没有实现类似功能)

缓存失效的时候
通常我们为页面设置缓存时间,缓存失效的时候,需要重新更新缓存。这个时候也会出现第一种情况类似的问题。

以上两种情况,第一种出现较少,第二种情况出现较多。都是由于redis自动删除过期缓存,导致的缓存缺失。

解决办法

由于nginx不知道redis里面数据的缓存时间,所以会频繁的导致缓存缺失的情况出现。
既然知道原因了,那么咱们就来针对性的解决一下这个问题。让nginx能够知道甚至参与到缓存时间的管理里面,就能有效的避免被动的缓存缺失问题,能有意识的主动更新缓存

ngx_lua

这里需要提到一个nginx的第三方模块就是把lua集成到nginx里面扩展了nginx配置文件语法,支持在配置文件里面直接使用lua语言编写逻辑。

lua-resty-cache

我将自己在项目中使用的一个仓库开源到github上面了。

能让nginx主动的检测缓存的过期时间

在快过期的时候,直接返回旧的缓存数据

使用异步任务更新缓存

以上的第二第三两点,就能在缓存快过期的时候,主动的异步更新缓存,让终端用户感知不到更新缓存的过程。
项目中实测,使用这个缓存机制之后,用户感知到的平均响应速度提升了10倍(nginx access log分析结果),而这都是在原有系统性能不变的情况下实现的!是不是有点不可思议。

原理

下面就来说一说提升速度的原理:

如果缓存缺失,直接跳过srcache_fetch步骤,将请求发到后端server。同时申请一个共享内存锁,并发而来的相同的请求不用发送到后端,而是等待这个请求返回。

更新缓存的时候,在过期时间expire基础上加上一个stale time。那么在到了过期时间的时候,redis还不会立即删掉这个数据。

如果检测到数据过期,但是redis还能拿到这个“过期”数据,则立即返回过期数据给终端用户。

在结束请求的同时,使用一个异步任务去更新缓存,考虑到并发情况,这里也需要使用一个共享内存锁。

这样,即使在缓存过期的时候,用户也很少会遇到只能从后端server拿数据的情况。所以能节省相当的时间,在速度上有这么大的提升。

后记

这个库运行了有好几个月了,非常的稳定。当然这得益于nginx的稳定。
但是也不得不说,使用这个库之后,后端server能够收到的请求,已经绝大部分都是由那个异步的任务发出的。用户基本都能在缓存里面直接拿到数据。所以,后端server的性能,没有提升,但是给用户的感觉却是快了很多!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61766.html

相关文章

  • ngx_srcache + lua异步更新缓存----提升10倍的响应速度

    摘要:异步更新缓存一直使用作为反向代理服务器,一来基于事件驱动,速度快。同时,本身还能提供快速的读写速度。都是由于自动删除过期缓存,导致的缓存缺失。在结束请求的同时,使用一个异步任务去更新缓存,考虑到并发情况,这里也需要使用一个共享内存锁。 nginx_lua异步更新缓存 NGINX 一直使用nginx作为反向代理服务器,一来nginx基于事件驱动,速度快。而来nginx的反向代理模块能很好...

    baishancloud 评论0 收藏0
  • UPYUN Open Talk :同盾,从零打造千万级实时风控云服务

    摘要:同盾技术总监张新波在第二期移动时代互联网金融的架构趋势中阐述了同盾是如何从零开始打造千万级实时风控云服务,具体介绍了同盾系统平台构建过程中主要需要解决的三大难题,以及解决这些问题的具体时实践过程。 同盾科技,是由阿里、Paypal 反欺诈专家创建的,国内第一家风险控制与反欺诈云服务提供商,其涉及领域包括电商、B2B、互联网金融、游戏等。同盾技术总监张新波在 UPYUN Open ...

    malakashi 评论0 收藏0
  • 写文件操作探微

    摘要:写缓存与写磁盘先看下写文件操作的流程结构图磁盘缓存是物理内存的一部分,专门供操作系统用作读写磁盘的缓冲之用。这印证了前面的说法,字符串在文件关闭前只在磁盘缓存里,还未真正写到磁盘上,所以读进程无法读出。 多进程读写同一个文件的问题 不考虑文件内容的错乱,多进程是可以同时读写一个文件的。当一个进程在写,读的进程能否读到最新的内容,取决于最新的内容是否真正写到了磁盘上。 写缓存与写磁盘 先...

    plus2047 评论0 收藏0
  • 写文件操作探微

    摘要:写缓存与写磁盘先看下写文件操作的流程结构图磁盘缓存是物理内存的一部分,专门供操作系统用作读写磁盘的缓冲之用。这印证了前面的说法,字符串在文件关闭前只在磁盘缓存里,还未真正写到磁盘上,所以读进程无法读出。 多进程读写同一个文件的问题 不考虑文件内容的错乱,多进程是可以同时读写一个文件的。当一个进程在写,读的进程能否读到最新的内容,取决于最新的内容是否真正写到了磁盘上。 写缓存与写磁盘 先...

    cppowboy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<