Web开发基本准则-55实录-缓存策略
续上篇《Web开发基本准则-55实录-Web访问安全》。
Web开发基本准则-55实录-缓存策略
提纲:
- Web访问安全
- 缓存策略
- 存储介质连接池
- 业务降级
- 并发请求的处理
关键词:
- 目的
- 防止访问(短期内)必然不存在的数据导致请求穿透缓存直接打到 DB。
- 原因
- 可能是数据真的不存在,但也可能是第三方恶意构造大量不存在的 id 来冲击 DB。
- 多种手段结合
- 系统预热数据的缓存过期时间过于整齐划一;
- 缓存系统宕机或重启;
- 访问高峰期间种下了一大批缓存,过期时间非常接近。
- 缓存过期时间散列开:在过期时间基础上增加一个随机值,如1秒~120秒随机,将大家的过期时间尽量打散。
- 防范缓存节点暂不可用的缓存双写策略:
- memcache双写:向 memcahce 的 Master Ring 和 Backup Ring 双写,如下图1所示:
图1 memcache 双写 原图出自点评技术PPT- Redis备份写:向 memcache 写入的同时,写一份到备份缓存 Redis 里,键值的缓存过期时间非常大,如原键值在 memcache 过期时间5分钟,在 Redis 里则8小时过期。当 memcache 集群节点暂不可用时,Web工程就切换读取备用缓存 Redis。这种思路是保证基本可用性,所以必要时刻可以给用户返回脏数据。
- 对于不同的业务场景,缓存的使用策略也不同:
- 当系统面临缓存异常的危险时,有些系统可以采用备份方案继续支撑服务。有些系统则会优雅降级,将某些依赖缓存的功能直接去除,保证主服务的正确性。所以这两种策略的选择需要根据实际的业务场景考虑并实施。(出处)
- 手段:
- 由远及近分层建立缓存,越靠近前端,缓存片段越大(或存储粒度越大)。
- 上一层的缓存失效,可以靠下一级的缓存迅速重建。
- 目的:
- 避免系统产生抖动。
- 减少缓存雪崩,防止 DB 连接数暴涨、响应变慢,连累前端应用连接数持续高涨、最后宕机。


|
分布式缓存的另一个应用场景是缓存计数器。 对于多服务器的系统,分布式缓存提供了统一的存储和原子操作,便于集群环境下的使用。库存计数器是分布式缓存的一个典型应用场景, 对于集群中的每一台机器,库存都应该是一个统一的值,因此使用本地缓存记录库存,数据肯定是不准确的(下面会陈述例外情况)。因此,统一的存储空间是必要 的条件。 由于库存数据被多台机器共享,因此,必须使用锁机制控制多个请求的并行并发问题。基于这样的机制就可以实行库存技术器的作用,防止货物超卖。最近的积分商城超值兑换就是使用的这种机制。 这种机制下,需要注意操作的逻辑顺序,错误的顺序会导致意想不到的结果。积分兑换的业务流程为,用户看到要抢兑的商品,如果库存大于0,则用户可以点击抢兑操作,这时用户会获得兑换该商品的权限,从而优惠购买,这时库存商品应该减一。 如果完全按照这个业务流程,我们会完成下面这三步操作:
乍一看这样的逻辑是很正常的,但是考虑一下异常情况,就会发现它防不住超卖。如果库存只有一件,那么多个用户并发验证库存时,都大于0。这样并发的多个用户都会获得优惠资格,产生了超卖。 正确的逻辑为:
这样的方法,无法保证缓存中的值一定大于等于0,因为并发的发生会把缓存减为负数,但是,真正能够优惠购买的用户一定是小于等于库存数的。因为,每次原子减操作后,只有返回的库存值大于等于零的用户才能够获得购买资格。无论并发量有多大,原子操作都会成功的防止超卖的发生。 |
|
对于上述的逻辑,可以应对绝大多数的情况。
但是随着量的增加,这种方式也有风险。当用户量极大、货物的库存极少时,就变成了秒杀。这个时候,大量的用户涌入分布式缓存减库存,对分布式缓存有极大冲击,一旦分布式缓存挂掉,秒杀活动也就宣告失败。使用分布式缓存,目的是为了让用户准确的看到剩余库存数 目,秒杀活动非常快,用户还没有看清楚库存,活动就结束了。其实用户只关心有没有秒到商品,并不关心库存的剩余数量,因此,库存减得准不准确并不是主要矛盾,这时就可以放弃分布式缓存的设计,转而使用本地缓存存储库存数,这也就是本地缓存使用的第二个场景。
比如,一共有10件商品,2台机器,可以设置每台机器的本地内存中库存等于10,那么对于外网的千万个用户,就可以有20个人抢到商品,剩下的人都 被挡在库存之外。当这20个人抢到后,就可以实现另一个处理逻辑,从20个人中选出10个真正中标的人,获得10个商品的购买权限。这个选择的逻辑非常灵活,可随意定制。但是从20选10的操作,无论如何也比从千千万万个人中选10要好的多,这样可以确保秒杀的安全完成。
如果秒杀的人继续增多,那么也可以通过客户端(即javascript)设置格挡率的方法,使少量的用户可以发出请求到服务器,绝大多数的用户都被挡在浏览器上。(注:一些技术人士在2013年吐槽小米网站抢购小米手机时,浏览器模拟排队等待其实没有发出任何网络请求,这就是客户端格挡率生效的结果。)
|
延伸阅读:
赠图几枚:



Web开发基本准则-55实录-缓存策略的更多相关文章
- Web开发基本准则-55实录-Web访问安全
Web开发工程师请阅读下面的前端开发准则,这是第一部分,强调了过去几年里我们注意到的Web工程师务须处理的Web访问安全基础点.尤其是一些从传统软件开发转入互联网开发的工程师,请仔细阅读,不要因为忽视 ...
- web开发方面会遇到哪些缓存?分别如何优化
Web缓存定义: Web缓存游走于服务器和客户端之间,这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个. Web缓存就在服务器-客户端之间搞监控,监控请求,并且把请求输出的内 ...
- Web开发须知的浏览器内幕 缓存与存储篇(2)
本文禁止转载,由UC浏览器内部出品. 3. HTTP Cache 综述 HTTP Cache是完全按照IETF规范实现的,最新的RFC规范地址是 https://tools.ietf.org/html ...
- Web开发须知的浏览器内幕 缓存与存储篇(1)
本文禁止转载,由UC浏览器内部出品. 0.前言 大纲 浏览器缓存和存储相关的功能分为四类: 加载流程 Memory Cache Application Cache(简称AppCache) HTTP C ...
- Web开发人员需知的Web缓存知识
最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...
- Web缓存基础:术语、HTTP报头和缓存策略
简介 对于您的站点的访问者来说,智能化的内容缓存是提高用户体验最有效的方式之一.缓存,或者对之前的请求的临时存储,是HTTP协议实现中最核心的内容分发策略之一.分发路径中的组件均可以缓存内容来加速后续 ...
- Web 开发人员需知的 Web 缓存知识
今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~~ 什么是Web缓存,为什么要使用它? Web ...
- 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)
在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...
- J2EE开发中常用的缓存策略
一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...
随机推荐
- Mysql 命令大全
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root - ...
- 教你一招:解决windows xp系统开机出现“disk checking has been canceled”
问题重现: 问题分析: 系统的注册表被修改了. 问题解决: 1.(临时解决)开机时,按ESC或ENTER键取消. 2.(彻底解决)修改注册表文件. Win + R 打开运行 Regedit ,进入注册 ...
- JavaScript数组的方法
push() :将参数加载到数组的最后,返回数组的长度 pop() :删除数组的最后一个元素,返回删除的值 shift() :删除数组的第一个元素,返回删除的值 unshift ...
- Zabbix监控php-fpm status
开启php-fpm status php-fpm.conf pm.status_path = /statusx45 nginx.conf location ~ /(statusx45)$ { incl ...
- POJ 3349 Snowflake Snow Snowflakes(简单哈希)
Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 39324 Accep ...
- jQuery 复习
jQuery 复习 基础知识 1, window.onload $(function(){}); $(document).ready(function(){}); 只执行函数体重的最后一个方法,事 ...
- Java中vector的使用详解
Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(vector)以实现类似动态数组的功能.在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提 ...
- 图解JVM的类加载机制(详细版)
注:本文为作者整理和原创,如有转载,请注明出处. 上一篇博文,把JAVA中的Class文件格式用图形的方式画了一下,逻辑感觉清晰多了,同时,也为以后查阅的方便. Class文件只是一种静态格式的二进制 ...
- Java数据结构——字典树TRIE
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 它的优点是:利用字符串的公共 ...
- 什么?你还不会写JQuery 插件
前言 如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquery 及ui 内置web项目里了.至于使用jquery好处这里就不再赘述了,用过的都知道.今天我们来讨论 ...