Web开发基本准则-55实录-缓存策略(转)
原文地址:http://www.cnblogs.com/zhengyun_ustc/p/rule2.html
续上篇《Web开发基本准则-55实录-Web访问安全》。
Web开发基本准则-55实录-缓存策略
提纲:
- Web访问安全
- 缓存策略
- 存储介质连接池
- 业务降级
- 并发请求的处理
关键词:
- 目的
- 防止访问(短期内)必然不存在的数据导致请求穿透缓存直接打到 DB。
- 原因
- 可能是数据真的不存在,但也可能是第三方恶意构造大量不存在的 id 来冲击 DB。
- 多种手段结合
- 『存储EMPTY』思路:存储一个 EMPTY 对象到缓存对应键值,设置一个较短的过期时间。这样在缓存失效后,还能继续查询数据是否存在。
- 必须认真对待(不同业务不同端口的)缓存命中率(get_hits/cmd_get * 100)定期监控的结果,认真审视那些命中率低的缓存端口,找到命中率低的原因,提出优化方案。
- 『先行校验』思想:采用布隆过滤器算法,将所有可能存在的数据(如所有有效商品的id)哈希到一个足够大的 bitmap 里,那么一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。(出处)
- 系统预热数据的缓存过期时间过于整齐划一;
- 缓存系统宕机或重启;
- 访问高峰期间种下了一大批缓存,过期时间非常接近。
- 缓存过期时间散列开:在过期时间基础上增加一个随机值,如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访问安全基础点.尤其是一些从传统软件开发转入互联网开发的工程师,请仔细阅读,不要因为忽视 ...
- Firefox火狐浏览器web开发调试开启强制刷新缓存模式
Firefox火狐浏览器web开发调试开启强制刷新缓存模式 最近做项目的时候,在火狐浏览器发现缓存难清理,用Ctrl+F5 Ctrl+R 等在谷歌和IE浏览器的快捷键没用,搜索了一下,发现火狐清理缓存 ...
- Web开发中的图片管理:策略与实践
前言 在Web开发中,图像是无法忽视的重要组成部分.然而,随着图片数量的增加和高清图像的普及,图片管理变得越来越复杂.在这篇文章中,我们将详细探讨Web开发中的图片管理策略和实践,包括图片优化.存储. ...
- 微信web开发,页面未同步更新
参考学习:https://blog.csdn.net/Tony_Zzh/article/details/74349009 背景:微信web开发,通过微信跳转我们自己写的网页,某一天更新了网页的代码,并 ...
- (转载)Web 开发人员需知的 Web 缓存知识
什么是Web缓存,为什么要使用它? Web缓存游走于服务器和客户端之间.这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个:这个客户端也可能是1个或多个.Web缓存就在服务器- ...
- 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)...
在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价--流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...
- 面向Web开发人员和网站管理员的Web缓存指南
这是一篇知识性的文档,主要目的是为了让Web缓存相关概念更容易被开发者理解并应用于实际的应用环境中.为了简要起见,某些实现方面的细节被简化或省略了.如果你更关心细节实现则完全不必耐心看完本文,后面参考 ...
- Web 开发人员需知的 Web 缓存知识
原文出处: mnot 译文出处: 张鑫旭 最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转 ...
- Web开发人员需知的Web缓存知识
什么是Web缓存,为什么要使用它? 缓存的类型: 浏览器缓存: 代理服务器缓存: 网关缓存: Web缓存无害吗?为什么要鼓励缓存? Web缓存如何工作 如何控制缓存和不缓存: HTML Meta标签 ...
最新文章
- AndroidStudio git 提交代码,创建分支,合并分支,回滚版本,拉取代码
- 使用java连接JanusGraph进行操作,hbase报错信息为:Caused by: org.apache.hbase.thirdparty.io.netty.channel.AbstractCh
- [翻译]How JavaScript Timers Work
- hadoop之MapReduce自定义二次排序流程实例详解
- 用户画像,如何驱动产品链路优化?
- 使用HTML5、CSS3和jQuery增强网站用户体验
- Virtual Studio 2013 每次加载程序(dll)缓慢的问题
- 017 在SecureCRT中安装rz小工具
- git 创建webpack项目_使用webpack手动创建一个完整项目的全过程
- django 1.8 官方文档翻译: 9-1-1 国际化和本地化
- 华为笔试题 简答错误记录(字符串处理,好题!!!)
- Amanda之安装、部署、测试以及优缺点
- js简单实现div里面的内容向上平滑滚动。
- ZT:Linux上安装JDK,最准确
- 太阳粒子是什么东西_太阳粒子流是什么
- C++实现Rhino中画准均匀B样条曲线功能
- 【海康威视】WPF客户端二次开发:【5】Chrome浏览器调用客户端程序 链接参数处理 —— 前端encodeURIComponent编码,后端UrlDecode解码
- 08CMS之AJAX
- ProcessOn 在线作图,真香指南
- 前端h5 打开pdf文件
热门文章
- 台式机win10系统连不上网问题
- 理工大暑假计算机课程班,2019年申报北京理工大学在职研究生计算机专业课程班可以获得双证吗...
- Linux搭建部落冲突,Neovim+Coc.nvim配置 目前个人最舒服终端编辑环境(PythonC++)
- OSI七层协议模型和TCP/IP四层模型
- 脸部识别,简单图片识别
- js常用的循环,for of 和 for in等比较
- 咸鱼菌玩3D—123D 快捷键
- javax.servlet.ServletException: 实例化Servlet类[com.enjoy.book.action.UserServlet]异常
- CSS | 隐藏滚动条,但保持页面依旧能够滚动
- 2022年湖北省科技进步奖详细解答,该奖项申报条件以及奖励补贴具体情况解析