本文作者:IMWeb daihuimi 原文出处:IMWeb社区 未经同意,禁止转载 学习整理了web缓存的一些策略,如有不正确的地方,欢迎指正。 在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头有: Web缓存的作用 减少网络带宽消耗 降低服务器压力 减少网络延迟,加快页面打开速度 HTTP缓存机制 缓存行为主要由缓存策略决定,而缓存策略由内容拥有者设置 这些策略主要通过特定的HTTP头部来清晰地表达。 CDN缓存策略 CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的Cache-control: max-age的字段来设置CDN边缘节点数据缓存时间。 前端工程与性能优化 参考: Web开发基本准则-55实录-缓存策略 【Web缓存机制系列】2 – Web浏览器的缓存机制 HTTP协议详解 CDN缓存那些事 浅谈HTTP缓存机制
本文作者:IMWeb daihuimi 原文出处:IMWeb社区 未经同意,禁止转载 学习整理了web缓存的一些策略,如有不正确的地方,欢迎指正。 ? Web缓存的作用 减少网络带宽消耗 降低服务器压力 减少网络延迟,加快页面打开速度 HTTP缓存机制 缓存行为主要由缓存策略决定,而缓存策略由内容拥有者设置。 这些策略主要通过特定的HTTP头部来清晰地表达。 CDN缓存策略 CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的Cache-control: max-age的字段来设置CDN边缘节点数据缓存时间。 前端工程与性能优化 参考: Web开发基本准则-55实录-缓存策略 【Web缓存机制系列】2 – Web浏览器的缓存机制 HTTP协议详解 CDN缓存那些事 浅谈HTTP缓存机制
策略 Cache-Aside 可能是最常用的缓存策略。 使用 Cache Aside 策略的系统可以在一定程度上抵抗缓存故障。如果缓存服务发生故障,系统仍然可以通过直接访问数据库进行操作。 然而,这种策略并不能保证数据存储和缓存之间的一致性,需要配合使用其它策略来更新或使缓存无效。另外,首次请求数据时,总是会导致缓存未命中,这种情况下需要额外的时间来将数据加载到缓存中。 Read-Through 策略 在上面的 Cache-Aside 策略中,应用程序需要与缓存和数据源“打交道”,而在 Read-Through 策略下,应用程序无需管理数据源和缓存,只需要将数据源的同步委托给缓存提供程序 Write-Through 策略 Write-Through 策略下,当发生数据更新(Write)时,缓存提供程序 Cache Provider 负责更新底层数据源和缓存。
viewholder的快速重用 mChangedScrap ArrayList<ViewHolder> mCachedViews ArrayList<ViewHolder> 移除屏幕外的viewholder缓存集合 ,移动到recyclerpool,并将移出屏幕外的viewholder,加入到cachedview集合里面 mViewCacheExtension ViewCacheExtension 用户自己实现的缓存类 缓存viewholder的对象,当mCachedViews长度大于2,就会把mCachedViews超出的内容放到mRecyclerPool,然后给viewholder复用。
而解决上述问题需要一个优秀的缓存策略。除此之外,web缓存的优点还有很多,例如:减轻服务器压力 ,加快了客户端加载速度,节省网络带宽等。 web缓存按缓存位置,缓存机制可大致分为三类。 当然这需要一系列策略进行约定。 2.1 强缓存策略 所谓强缓存策略即在静态资源有效期内,使用该资源时直接使用本地资源,不请求服务器。 ()) // HTTP1.1 强缓存 cache-control字段 cache-control 优先级更高 res.setHeader('Cache-Control', 'max-age=10') 下面进行实例验证 // 协商缓存 // 方式一 last-modified & if-Modified-Since 通过协商修改时间为基础的策略 // 首先需要禁用强缓存 res.setHeader res.statusCode = 304; res.end(); return; } Etag协商缓验证.jpg Etag协商缓命中.jpg 可以看到由于该策略是通过判断内容来决定是否需要更新
首先,SDWebImage 的图片缓存采用的是 Memory(内存) 和 Disk(硬盘) 双重 Cache 机制,SDImageCache 中有一个叫做 memCache 的属性,它是一个 NSCache 对象,用于实现我们对图片的 `Memory Cache,其实就是接受系统的内存警告通知,然后清除掉自身的图片缓存。 Disk Cache,也就是文件缓存,SDWebImage` 会将图片存放到 NSCachesDirectory 目录中,然后为每一个缓存文件生成一个 md5 文件名, 存放到文件中。 Disk(硬盘)缓存清理策略:SDWebImage 会在每次 APP 结束的时候执行清理任务。 清理缓存的规则分两步进行。 第一步先清除掉过期的缓存文件。 如果清除掉过期的缓存之后,空间还不够。 那么就继续按文件时间从早到晚排序,先清除最早的缓存文件,直到剩余空间达到要求。
缓存介绍 这里是列表文本在高并发多用户的系统中常常会使用缓存来提升读写性能 这里是列表文本常见的如memcached, redis, 内存缓存等 现象 这里是列表文本某产品上线后不久 0x00000007384b16c8, 0x0000000723221798, 0x00000007232299c0, 0x000000072efb1228, 0x00000007005b70c0, 0x00000007005aff10 0x00000007232425a0, 0x0000000723242648, 0x0000000732c31da0, 0x0000000731a4fd78, 0x0000000731a4fe20, 0x0000000738139a10 0x00000007231b0c98, 0x00000007fc8bdea8, 0x00000007318a5808, 0x000000073189e0c8, 0x0000000731870018, 0x0000000723279d10 com.xxxx.xxxx.web.controller.login.LoginController.login(LoginController.java:119) 分析 仔细分析对应代码逻辑,可发现有如下的缓存策略
Redis 缓存淘汰策略 如何估算缓存容量大小 「二八定律」:百分之八十的访问会落到百分之二十的热点数据上 内存容量建议设置在总数据量的 15%~30% Redis 设置最大缓存容量: config set maxmemory 4gb Redis 缓存淘汰策略 8 中淘汰策略: 1 种不进行淘汰策略: noeviction 7 种进行淘汰策略,按照是否设置过期时间,进行数据集淘汰进行分类 有设置过期时间 一般不使用这个配置策略。 配置项 maxmemory-samples 用于配置候选集 N 的数据个数: config set maxmemory-samples 100 Redis 缓存淘汰策略最佳实践 数据访问频率差异大(冷热数据区分明显 )优先使用 allkeys-lru 策略 数据访问频率差异不大时(无明显冷热数据区分)推荐使用 allkeys-random 策略 业务有置顶需求(置顶新闻、视频)使用 volatile-lru 策略,
元数据缓存 JuiceFS 支持在内核和客户端内存(即 JuiceFS 进程)中缓存元数据以提升元数据的访问性能。 数据缓存 JuiceFS 对数据也提供多种缓存机制来提高性能,包括内核中的页缓存和客户端所在节点的本地缓存。 内核数据缓存 注意:此特性需要使用 0.15.0 及以上版本的 JuiceFS。 客户端读缓存 JuiceFS 客户端会根据读取模式自动预读数据放入缓存,从而提高顺序读的性能。默认情况下,会在读取数据时并发预读 1 个 block 缓存在本地。 为防止缓存盘被写满,当缓存目录所在文件系统空间不足时,客户端会尽量减少缓存用量。 通过上述介绍,我们对 JuiceFS 的缓存机制的原理有了进一步了解。 JuiceFS 本身作为底层文件系统,提供了包括元数据缓存、数据读写缓存等多种缓存机制,最大限度的保证了数据的一致性。希望大家通过本文的了解能更好的应用 JuiceFS。
Redis是一个流行的内存缓存系统,由于内存有限,缓存系统必须遵循一些淘汰策略来删除一些不再需要的键,以便为新键腾出空间。 在Redis中,缓存淘汰策略是由maxmemory和maxmemory-policy两个配置参数控制的。本文将详细介绍Redis的缓存淘汰策略,并给出一些示例。 缓存淘汰策略当Redis的内存达到maxmemory配置的值时,Redis会尝试删除一些键,以便为新键腾出空间。 示例以下是一些Redis缓存淘汰策略的示例:noeviction策略示例maxmemory 10mbmaxmemory-policy noeviction在此示例中,当Redis的内存使用达到10MB时 volatile-lru策略示例maxmemory 10mbmaxmemory-policy volatile-lru在此示例中,当Redis的内存使用达到10MB时,Redis将从过期的键中使用LRU
问题:项目中,Redis用了缓存热点数据,持久化数据在MySQL DB中;那么Redis缓存数据什么时候更新呢? 方法A: 步骤:1. 删除缓存,2.更新DB , 3.下一次读操作没有命中缓存时,更新缓存; 存在的问题:如果另外一个读任务发生在"更新DB"之前,那么缓存就"更新DB"之前的“脏数据”; 方法B: 删除缓存; 3. 下一次读操作没有命中缓存时,更新缓存; 存在的问题:如果在步骤1“更新DB”之前,有一个并发读任务没有命中缓存,从DB读取到“老数据”,在步骤2之后才把“老数据”更新到缓存,那么缓存中就是 “脏数据”; 思考:方法C采取的策略,在实际场景中发送的概率比前两种方法小很多;但是怎么完全杜绝这种问题呢?
Redis有哪些淘汰策略 Redis共提供了8中缓存淘汰策略,其中volatile-lfu和allkeys-lfu是Redis 4.0版本新增的。 Redis 用作缓存时,实际的数据集通常都是大于缓存容量的,总会有新的数据要写入缓存,这个策略本身不淘汰数据,也就不会腾出新的缓存空间,我们不把它用在 Redis 缓存中。 allkeys-random 策略,从所有键值对中随机选择并删除数据。 allkeys-lru 策略,使用 LRU 算法在所有数据中进行筛选。 allkeys-lfu 策略,使用 LFU 算法在所有数据中进行筛选。 通常情况下推荐优先使用 allkeys-lru 策略。 这样,可以充分利用 LRU 这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果你的业务数据中有明显的冷热数据区分,我建议你使用 allkeys-lru 策略。
所以设计一个简单的缓存更新策略就很必要了。 以资源为出发点 以上面的例子为示例: 以uid(用户)为资源的考量对象。引入版本的概念。 在缓存的对象中,加入version的概念。 cache:{ 'data': xxx, 'version': timestamp } 取缓存时,同时取ut:1的值。 如果cache['version']小于 ut:1,说明缓存落后于数据库。此时,刷新缓存。并更新cache['version']为最新timestamp。 完成上面操作后,实作中,把所有和user task表相关的缓存都绑定到ut:{uid}这个key上。只要在更新表时更新这个key。就能引发所有的缓存惰性更新。 wraps(f) async def run(request, *args, **kwargs): key = prefix # 绑定的过期策略键
Glide的缓存策略 前言 众所周知,图片加载框架的基本模式就是三层缓存。内存、文件和网络。 但Glide在缓存策略上,花费了很多心思,从而使得其在加载图片过程中,对内存的使用量非常小。 本文将分享Glide在缓存策略上使用的技巧。 在加载图片之后,内存缓存填满,我们可以将Bitmap从内存缓存中移出。但是,Bitmap还是存在于Java堆中,此时我们将失去对这个Bitmap的任何控制。 内存缓存的策略 既然要区分Bitmap是否正在显示。Glide的策略是从源头上,区分正在显示和没有显示的Bitmap。Glide将内存分为两块儿:ActiveCache和MemoryCache。 综上,生命周期的监听、BitmapPool的复用、可见/不可见资源的分开缓存。是Glide缓存策略的精妙之处。 如有问题,欢迎指正。
-----------------------------------概述---------------------------------------- Memcached是一套高性能分布式内存对象缓存服务器 客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期 ----------------------------------------缓存策略 比如将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了;按照预先规定的大小,将分配的内存分割成特定长度的内存块chunk,再把尺寸相同的内存块分层组chunk集合,这些内存不会释放 96Byte 2.page对应实际的物理空间,1个page为1M 3.同样大小的chunk集合又称为slab 客户端选择slab机制: 下面说明memcached如何针对客户端发送的数据选择slab并缓存到 存取操作均通过key进行,例如可以把后端数据库中的select操作提取出来,然后对相应的SQL进行hash计算得出key,然后以这个key在memcached中查找数据,如果数据不存在,说明其尚未被写入缓存中
【持久化存储模块/策略】,使我们可以更加精准地控制缓存,即使是在 http 缓存过期之后也可以使用。 [a88b975cb6391c0a807450163e401e5c.png] 过期策略 在LocalStorage中存在一组key: _gzh_cache_webuy.qq.com/static/js 技术实现 * 支持缓存的文件类型:js|css * 根据文件MD5摘要或版本号比对缓存变化,若无变化,直接使用缓存的内容,若有变化,请求服务器,然后替换旧缓存内容 */ var PREFIX = || 缓存过期,从服务器请求 if (! (); } }; // 启动时,清除太久未访问的缓存文件,释放空间 cache.clear();
上一篇文章我写了koa-static的源码解析[1],其中用到了HTTP的缓存策略,给返回的静态文件设置了一些缓存的头,比如Cache-Control之类的。 于是我就跟朋友讨论了一下HTTP的缓存策略: 朋友说:“HTTP里面控制缓存的头(header)太多了,啥Cache-Control,ETag,Last-Modified,一大堆,乱七八糟的,而且之间逻辑关系不强 HTTP缓存策略只是为了解决客户端和服务端信息不对称的问题而存在的,客户端为了加快速度会缓存部分资源,但是下次请求时,客户端不知道这个资源有没有更新,服务端也不知道客户端缓存的是哪个版本,不知道该不该再返回资源 ,其实就是一个信息同步问题,HTTP缓存策略就是来解决这个问题的。 集,具体返回什么值要看服务器的计算策略。
场景描述 比如一条数据同时存在数据库、缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题。 (1)先更新数据库,后更新缓存 ? 这样会造成数据不一致。 A 先把数据库更新为 123,由于网络问题,更新缓存的动作慢了。 这时,B 去更新数据库了,改为了 456,紧接着把缓存也更新为 456。 现在 A 更新缓存的请求到了,把缓存更新为了 123。 Cache Aside 策略 其实,在更新数据时,我们可以不更新缓存,而是删除缓存中的数据,在读取数据时,发现缓存中没有,再从数据库中读取数据,更新到缓存中。 这就是 Cache Aside 策略(旁路缓存策略)。 读策略步骤 ? 写策略步骤 ? 写时可以不可以先删除缓存?不行! 例如这个场景: ? A 先删了缓存,还没等数据库更新完成呢,就被 B 把缓存更新为了旧值。 注意 Cache Aside 策略也是不保证数据一致性的,它的作用是大大减少不一致性。
目前常用的一种缓存算法是lru(least recently used),它的核心思想是当缓存满了,会优先淘汰近期最少使用的缓存对象。 当缓存空间不足时,可以remove头部结点释放缓存空间。 disklrucache顾名思义,实现存储设备缓存,即磁盘缓存,它通过将缓存对象写入文件系统从而实现缓存效果。 ps: 如果缓存的图片经常被使用,可以考虑使用contentprovider。 disklrucache的数据缓存与获取缓存: 数据缓存操作是借助disklrucache.editor类完成的,editor表示一个缓存对象的编辑对象。 缓存策略对比与总结 lrucache是android中已经封装好的类,disklrucache需要导入相应的包才可以使用。
今天着重探讨的是关于回源服务器缓存的配置以及合理的缓存策略。 通过给回源服务器配置缓存的案例,详细讲解一整套缓存配置机制,并且可沿用到其他任何缓存配置场景中。 所以为了优化这些问题,需要给源站做一层缓存。缓存策略采用nginx自带的proxy_cache模块。 proxy_cache原理: proxy_cache模块的工作原理如图所示: ? proxy_cache_valid 200 206 304 301 302 10d; 对httpcode为200…的缓存10天 proxy_cache_key $uri 定义缓存唯一key,通过唯一 如何让源站支持断点续传,以及断点续传的缓存策略 如果请求端 range 请求(分片下载)一个大资源,同样的uri,如何区别请求? 总结: 整个一套完备的缓存策略就介绍到此,这套方案中不仅实现了基本的缓存配置,还解决了实际场景应用中会遇到的,磁盘扩展,缓存清理,断点续传,缓存过期时间,缓存命中提示等问题,只要将这套方案灵活运用,不管是再复杂的场景