在哪个网站做外贸生意好,网站程序预装,深圳市浩天建设网站,软件设计师含金量说起缓存相关技术#xff0c;老多了#xff0c; memcache、redis、squid、varnish、web cache、 CDN等等。缓存技术五花八门#xff0c;但这些技术间有什么共性的地方#xff0c;又有什么不同的地方呢#xff1f;答案肯定是有的#xff0c;这次为大家分享及整理一下缓存方…说起缓存相关技术老多了 memcache、redis、squid、varnish、web cache、 CDN等等。缓存技术五花八门但这些技术间有什么共性的地方又有什么不同的地方呢答案肯定是有的这次为大家分享及整理一下缓存方面的技术主要分为三个系列展开
缓存随谈系列之一数据库缓存
缓存随谈系列之二静态缓存
缓存随谈系列之三动态缓存 一、什么是数据库缓存
我们知道常见的数据库比如oracle、mysql等数据都是存放在磁盘中。虽然在数据库层也做了对应的缓存但这种数据库层次的缓存一般针对的是查询内容而且粒度也太小一般只有表中数据没有变更的时候数据库对应的cache才发挥了作用。但这并不能减少业务系统对数据库产生的增、删、查、改的庞大IO压力。所以数据库缓存技术在此诞生实现热点数据的高速缓存提高应用的响应速度极大缓解后端数据库的压力。
以下为memcache数据库缓存为例以图说明一下什么是数据库缓存
022f6d6489e6facab3ee148f0150bdc7aa5bfe32
二、数据库缓存的技术特点
性能优越
数据库缓存的第一个技术特点就是提高性能所以数据库缓存的数据基本上都是存储在内存中相比io读写的速度数据访问快速返回。而且在mysql 5.6的版本开始已经把memcache这种跟数据库缓存直接挂钩的中间件直接集成进去了已经等不及我们自己去单独部署对应数据库缓存的中间件了。
应用场景
针对数据库的增、删、查、改数据库缓存技术应用场景绝大部分针对的是“查”的场景。比如一篇经常访问的帖子/文章/新闻、热门商品的描述信息、好友评论/留言等。因为在常见的应用中数据库层次的压力有80%的是查询20%的才是数据的变更操作。所以绝大部分的应用场景的还是“查”缓存。当然“增、删、改”的场景也是有的。比如一篇文章访问的次数不可能每访问一次我们就去数据库里面加一次吧这种时候我们一般“增”场景的缓存就必不可少。否则一篇文章被访问了十万次代码层次不会还去做十万次的数据库操作吧。
数据一致性
在很多应用场景中当一个数据发生变更的时候很多人在考虑怎么样确保缓存数据和数据库中数据保存一致性确保从缓存读取的数据是最新的。甚至有人在对应数据变更的时候先更新数据库然后再去更新缓存。我觉得这个考虑不太现实一方面这会导致代码层次逻辑变得复杂另外一方面也真想不明白还要缓存干什么了。在绝大多数的应用中缓存中的数据和数据库中的数据是不一致的。即我们牺牲了实时性换回了访问速度。比如一篇经常访问的帖子可能这篇帖子已经在数据库层次进行了变更。而我们每次访问的时候读取的都是缓存中的数据帖子。既然是缓存那么必然是对实时性可以有一定的容忍度的数据容忍度的时间可以是5分钟也可以是5小时取决于业务场景的要求。相反一定要求是实时性的数据库就不应该从缓存里读取比如库存再比如价格。
高可用
自从有了缓存代码每天快乐的去缓存中愉快的玩耍。为什么说高可用呢我们知道缓存为数据库抵挡了很多压力同时也为应用提供了良好的访问速度。但同时有没有想过缓存的感受如果当数据库缓存“罢工”了这会出现什么后果特别在一些高并发的应用中数据库层肯定是“消化不良“最终导致应用全面崩溃。所以缓存的高可用显得非常重要。 三、数据库缓存常见开源技术
要说用于数据库缓存场景的开源技术那必然是memcache和redis这两个中间件。
74ba1c9a1c6cd0a7d59872b5b8e77f366ff6ce50
因为都是专注于内存缓存领域memcache和redis向来都有争议。比如性能到底是memcache性能好还是redis性能更好等。同样都是内存缓存技术它们都有自己的技术特性。没有更好的技术只有更合适的技术。个人总结一下有持久化需求或者对数据结构和处理有高级要求的应用选择redis。其他简单的key/value存储选择memcache。所以根据自身业务特性数据库缓存来选择适合自己的技术。
暂不说用不用数据库缓存见过有人把session存储在数据库中的也见过把视频/文件转化成二进制存储在数据库的这种行为无疑是逆天的。合理应用数据库缓存技术且行且珍惜切勿走向误区。
静态缓存
上次写了一篇数据库缓存由于快餐式的风格遭到了广大读友的吐槽。上篇风格有点 “ 虚 ”我本身是一个技术控偏向经验/干货的分享本文主要描述静态缓存方面的一些心得及分享。作为系列二有所不足之处依旧希望大家踊跃“ 亮砖 ”。
说起静态缓存技术CDN是经典代表之作。静态缓存技术面非常广涉及的开源技术包含apache、Lighttpd、nginx、varnish、squid等。
静态缓存一般指 web 类应用中将图片、js、css、视频、html等静态文件/资源通过磁盘/内存等缓存方式提高资源响应方式减少服务器压力/资源开销的一门缓存技术。
本文主要通过浏览器缓存、磁盘缓存、内存缓存、nginx的内存缓存、CDN五个方面围绕静态缓存而展开。
一、浏览器缓存
浏览器缓存也称为客户端缓存是静态缓存中最常见最直接的表现形式很多时候都往往被人忽略掉。
案例1
我们经常在nginx的配置文件中看到以下缓存配置 案例2
在经常写 jsp 的时候html 标签中关于 http 头信息也可以注意到“ expires ”的字样 对于案例1和案例2中nginx设置的expires优先级大于代码中设置的expires优先级expires是给一个资源设定一个过期时间也就是说无需去服务端验证直接通过浏览器自身确认是否过期即可所以不会产生额外的流量。此种方法非常适合不经常变动的资源。如果文件变动较频繁就不要使用 expires 来缓存。
比如对于常见类web网站来说css 样式和 js 脚本基本已经定型所以最适合的方法是 expires 来缓存一些内容到访问者浏览器。 案例3
通过 chrome 访问服务器端的一张图片用F12键打开开发者前端调试工具 第一次访问响应200状态当第二次及后续访问的时候变成304状态客户端已经开始获取浏览器缓存内容而不需要去服务器端获取对应的请求内容即 nginx 中 expires 参数设置已经生效。等待客户端缓存时间过期后会再次请求服务器端内容来更新本地缓存。 介绍到这里突然想起一个有意思的需求。比如访问一张静态文件不想客户端缓存需要每次都去服务器端取数据。我们可以用“ last-modified ”参数来实现即“ last-modified ”是根据文件更新时间来确定是否再次发送加载。
Nginx核心配置如下 我们更改掉服务器传回客户端的“ last-modified ”文件修改时间参数的值这样导致客户端本地保存的文件时间每次跟服务器端传回来的时间不一致所以每次客户端“ 误认为 ”服务器端有静态文件更新每次都会去服务器端取“ 所谓的最新数据 ”。这样我们可以看到不管在浏览器访问多少次返回的 http 状态都是200再也找不到304状态了。
误区在 nginx 中设置 expires并不是指把静态内容缓存在 nginx 中而是设置客户端浏览器缓存的时间这是很多人的误区所在。 二、磁盘缓存
除了存储在客户端的静态缓存浏览器静态技术外在服务器端的静态缓存技术主要分为磁盘缓存和内存缓存两大类。单纯围绕 nginx 的 squid、varnish 等一类中间件处理静态数据的性能十分优秀。核心是 nginx 基于 epoll 网络模型而相比 apache 基于 select 网络模型。所以 apache 的优势在于密计算型稳定性好。而 nginx 偏向静态处理反向代理高并发。比如 apachephp 的稳定性比 nginxphp 要好而性能是明显 nginx 要优秀许多。
以上仅单纯是对磁盘中静态数据处理的能力所谓磁盘缓存指另外的一种缓存静态文件的技术。以 nginx 配置为例 可以看出 nginx 主要通过 proxy_cache 来实现 web cache熟悉 nginx 的同学不难看出以上配置在 location 这里不仅可以实现静态文件的缓存还可以实现动态文件的缓存这里放在下章节详细介绍。我们编写个 test.html测试文件然后并访问。test.html 源码如下 我们发现服务器的 cache 目录里面多了两个缓存文件 有意思的这两个文件里面的内容分别为通过 less 命令查看 b0ad5d3e7f099bfff9e4fc6a159d868c 53edc39ed253e14415a29412cfc01faf
所以不难看出nginx 把 html 内容和图片二进制全部缓存到本地磁盘上了。下次用户再次来访问 test.html 的时候nginx 直接将缓存在本地磁盘的文件返回给用户。特别是后端如若是部署的 tomcat、iis 等nginx 强大的静态缓存能力有效减少了服务器压力。 三、内存缓存
紧接上面描述的磁盘缓存内存缓存顾名思义就是把静态文件缓存在服务器端的内存中。所以这种缓存如若命中缓存的话取内存中的缓存数据返回比取磁盘中的缓存数据返回性能要高很多。以 varnish 为例varnish 核心配置如下
启动命令 参数简介 default.vcl核心配置如下 Varnish对.gif、.jpg、.jpeg、.png等结尾的 URL 缓存时间设置1小时。varnish设置完毕后我们用命令行方式通过查看网页头来查看命中情况 最后我们可以通过 varnishadm 命令来清理缓存也可以通过 varnishstat 命令来查看 varnish 系统缓存状态。 四、Nginx 的内存缓存
以上主要以 Varnish 为例介绍了内存缓存静态资源的方法。其实 nginx 也有内存缓存相比 squid、varnish 而言nginx 的内存缓存需要通过编码实现。如下配置 memcached_pass 指定服务器地址使用变量 $memcache_key 为 key 查询值去 memcache 查询对应 value 值。
如我们访问http://***.***.***.***/image/test.jpg ,则 nginx 去 memcache 中查询key 为“ test.jpg ”的 value 值并返回。如果没有相应的值则返回 error_page 404。介绍到这里关键在于存储在 memcache 中的静态文件需要通过代码写入 memcache 中。怎么样通过 php/java 等代码把静态资源的数据写入 memcache 中关于这块的示例就不再过多介绍了。
Nginx的内存缓存因为需要通过编码实现所以灵活性特别高。这块可以结合自身业务系统的特点让静态缓存的灵活性和效率都能得到保障。可能唯一的缺陷就是通过编码实现的方式给我们维护管理带来了负担。在之前我曾参与的一个电商系统就是把客户的订单照片通过 php 代码写入 memcache客户访问取图的时候从 memcache 中获取速度效率特别高。Nginx 作为一款在七层无所不能且轻量级高性能的中间件能够直接去 memcache 中取数据来实现静态缓存的效果这块相应的功能是其他软件无法相媲美的。 五、CDN
说起 CDN大家都不陌生它是静态缓存加速最典型的代表。CDN技术并不是一门新的技术它是基于传统 nginx、squid、varnish 等 web 缓存技术结合 DNS 智能解析的静态缓存加速技术。值得注意的是他对动态链接访问并没有加速效果。架构原理图如下 所以CDN的静态缓存技术核心主要在于两点
节点缓存对需要加速的网站应用相应的静态资源通过内存缓存磁盘缓存的方式缓存在服务器端。
精准调度对访问的用户 ip 进行智能解析调度实现就近缓存节点访问。比如以上图例中北京用户访问 www.a.com。通过 dns 解析的时候分析用户 ip发现是北京用户。则 dns 返回对应北京缓存节点的 ip 地址给到用户则用户 www.a.com 默认访问北京服务器上面的缓存数据实现就近访问的策略大大提升了访问速度。