缓存命中率

走进缓存的世界(一) - 开篇

孤街醉人 提交于 2020-03-26 11:55:29
系列文章 走进缓存的世界(一) - 开篇 走进缓存的世界(二) - 缓存设计 走进缓存的世界(三) - Memcache 概述 对于程序员来说多多少少都懂一点算法,算法是什么?算法是“时间”与“空间”的互换策略。 我们常常研究一个算法的时间复杂度和空间复杂度,如果我们有绝对足够的时间和空间,那么算法就不需要了,可惜这种条件是不存在的,只是在某些情况下我们会协调两者从而达到性能上的平衡。 缓存是一种“用空间换时间”的策略,通俗的讲,缓存就是把一些数据暂时存储起来,避免了某些重复的耗时操作,减少时间开销的一种方法。 商业世界中常说的一句话是“现金为王”。在技术世界里,与之相近的一个说法是“缓存为王”。 从底层到上层主要涉及:数据库模型设计,SQL优化,使用缓存等。从图中的优化模式来看,其中数据库模型设计的合理程度奠定了应用系统优化的基石,如果模型设计得不合理,随着业务发展,后续的优化将会变得很困难。另一方SQL优化也是数据库优化的一个重要方面,慢SQL和top SQL往往是系统性能杀手,它们是导致系统故障的重要潜在危险。 缓存在构建高性能服务器中有着举足轻重的作用,很多时候sql优化, 算法优化所带来的效果可能远远不如缓存带来的优化效果。但是缓存的使用并不是零成本的,任何缓存的增加,都会带来两大问题: 数据不一致 系统复杂度大幅度增加 如何解决呢?首先考虑去掉缓存。不要为了缓存而缓存

【 CDN 最佳实践】CDN 命中率优化思路

孤人 提交于 2020-03-14 11:15:29
摘要: CDN 在静态资源的加速场景中是将静态资源缓存在距离客户端较近的CDN 节点上,然后客户端访问该资源即可通过较短的链路直接从缓存中获取资源,而避免再通过较长的链路回源获取静态资源。因此 CDN的缓存命中率的高低直接影响客户体验,而保证较高的命中率也成为了站长的核心命题。 点此查看原文: https://yq.aliyun.com/articles/288084?spm=a2c41.11181499.0.0 CDN 在静态资源的加速场景中是将静态资源缓存在距离客户端较近的CDN 节点上,然后客户端访问该资源即可通过较短的链路直接从缓存中获取资源,而避免再通过较长的链路回源获取静态资源。因此 CDN的缓存命中率的高低直接影响客户体验,而保证较高的命中率也成为了站长的核心命题。在本文中我们就一起探讨 CDN 缓存命中率的概念、影响因素以及优化策略。 1、缓存命中率的概念 CDN 的缓存命中率包括两种:字节缓存命中率和请求缓存命中率。其中字节缓存命中率是指 CDN 缓存命中 Response 的字节数除以 CDN所有请求 Response 的字节数。而请求缓存命中率是指 CDN 缓存命中的请求的个数除以 CDN 所有的请求数。 从上面的描述中可以查看到字节缓存命中率可以表征回源流量的大小,回源流量越高那么源站的流出流量也就越大,这样对于源站的带宽资源以及其他的负载都会越大

LRU 缓存置换算法

流过昼夜 提交于 2020-03-06 18:18:12
1.LRU 1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。 1.2. 实现 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下: 1. 新数据插入到链表头部; 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部; 3. 当链表满的时候,将链表尾部的数据丢弃。 1.3. 分析 【命中率】 当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。 【复杂度】 实现简单。 【代价】 命中时需要遍历链表,找到命中的数据块索引,然后需要将数据移到头部。 2. LRU-K 2.1. 原理 LRU-K中的K代表最近使用的次数,因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。 2.2. 实现 相比LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才将数据放入缓存。当需要淘汰数据时,LRU-K会淘汰第K次访问时间距当前时间最大的数据。详细实现如下: 1. 数据第一次被访问,加入到访问历史列表; 2.

一文了解 Consistent Hash

ぐ巨炮叔叔 提交于 2019-12-17 19:07:23
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/LGLqEOlGExKob8xEXXWckQ 作者:钱幸川 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,本文描述的取模算法和一致性 Hash(Consistent Hash)是通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。 本文使用软件环境:Java 8 一、数据分布接口定义 概述 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,比如用户1的数据存储到数据库1、用户2的数据存储到数据库2...... 一般来说,有这么几种常用的方式: 有一个分布式环境中唯一的中心分发节点,每次在数据存储的时候,都会询问中心节点这个数据该去哪儿,这个分发节点明确告诉这个数据该去哪儿。 通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。本文描述的取模算法和一致性Hash,就是这样一种方式。 接口定义 /** * 数据分布hash算法接口定义 * @author xingchuan.qxc * */ public interface HashNodeService { /** * 集群增加一个数据存储节点 * @param node */ public void addNode(Node node)

spring boot+redis整合

泄露秘密 提交于 2019-12-15 08:21:37
Redis 概述 在我们日常的Java Web开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。 一般而言在使用 Redis 进行存储的时候,我们需要从以下几个方面来考虑: 业务数据常用吗?命中率如何? 如果命中率很低,就没有必要写入缓存; 该业务数据是读操作多,还是写操作多? 如果写操作多,频繁需要写入数据库,也没有必要使用缓存; 业务数据大小如何? 如果要存储几百兆字节的文件,会给缓存带来很大的压力,这样也没有必要; 在考虑了这些问题之后,如果觉得有必要使用缓存,那么就使用它!使用 Redis 作为缓存的读取逻辑如下图所示: 从上图我们可以知道以下两点: 当 第一次读取数据的时候 ,读取 Redis 的数据就会失败,此时就会触发程序读取数据库,把数据读取出来,并且写入 Redis 中; 当 第二次以及以后需要读取数据时 ,就会直接读取 Redis

缓存命中率

大憨熊 提交于 2019-12-14 09:49:30
B.miss rate 25% char* 每个结构体会做4次赋值操作,第一次赋值会miss,把整个结构体放到缓存中,后三次分量的赋值会hit. int*每个结构体只做一次赋值操作,指针运算+4跳到下一个结构体去赋值,每一次赋值都是cold miss. int*不会对每个分量都赋值,一次赋值把四个分量都赋值完毕了 C.miss rate 100% B的循环次数是C的四倍 A B C三个程序 C最高效 A 复杂度O(n^2) 来源: https://www.cnblogs.com/wwqdata/p/11949229.html

缓存解决方案

Deadly 提交于 2019-12-09 16:46:25
1. 常见概念 在合理应用缓存前,需要了解缓存领域里相关的几个常用术语:  1)缓存命中:表示数据能够从缓存中获取,不需要回源;  2)Cache miss:表示没有命中缓存,如果缓存内存中还有内存空间的话,会将数据加入到缓存中;  3)存储成本:当没有命中缓存时,回源获取后会将数据放置到存储中,整个将数据放置到存储空间所需要的时间以及空间称之为存储成本;  4)缓存失效:当源数据发生变更后,意味着缓存中的数据失效;  5)缓存污染:将不经常访问的数据放置到缓存存储空间中,以至于高频访问的数据无法放置到缓存中;  6)替代策略:当数据放置到缓存空间时,由于空间不足时,就需要从缓存空间中去除已有的数据,选择去除哪些数据就是由替代策略决定的。常见的替代策略有如下这些: Least-Recently-Used(LRU) Least-Frequently-Used(LFU) SIZE First in First Out(FIFO)   由于存储空间有限,替代策略要解决的核心问题是尽量保留高频访问的缓存数据,降低缓存污染以提升缓存命中率和整体的缓存效率,难点在于,需要基于数据历史访问情况,以一种合适的对未来访问情况的预估才能找到更佳的策略。 2. 访问缓存场景 分析   使用缓存通常的操作是,请求先访问缓存数据,如果缓存中不存在的话,就会回源到数据库中然后将数据写入到缓存中

一文了解 Consistent Hash

一世执手 提交于 2019-12-05 14:24:38
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/LGLqEOlGExKob8xEXXWckQ 作者:钱幸川 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,本文描述的取模算法和一致性 Hash(Consistent Hash)是通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。 本文使用软件环境:Java 8 一、数据分布接口定义 概述 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,比如用户1的数据存储到数据库1、用户2的数据存储到数据库2...... 一般来说,有这么几种常用的方式: 有一个分布式环境中唯一的中心分发节点,每次在数据存储的时候,都会询问中心节点这个数据该去哪儿,这个分发节点明确告诉这个数据该去哪儿。 通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。本文描述的取模算法和一致性Hash,就是这样一种方式。 接口定义 /** * 数据分布hash算法接口定义 * @author xingchuan.qxc * */ public interface HashNodeService { /** * 集群增加一个数据存储节点 * @param node */ public void addNode(Node node)

一文了解 Consistent Hash

ε祈祈猫儿з 提交于 2019-12-05 14:04:51
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/LGLqEOlGExKob8xEXXWckQ 作者:钱幸川 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,本文描述的取模算法和一致性 Hash(Consistent Hash)是通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。 本文使用软件环境:Java 8 一、数据分布接口定义 概述 在分布式环境下面,我们经常会通过一定的规则来进行数据分布的定义,比如用户1的数据存储到数据库1、用户2的数据存储到数据库2...... 一般来说,有这么几种常用的方式: 有一个分布式环境中唯一的中心分发节点,每次在数据存储的时候,都会询问中心节点这个数据该去哪儿,这个分发节点明确告诉这个数据该去哪儿。 通过一定规则产生一个key,对这个key进行一定规则的运算,得出这个数据该去哪儿。本文描述的取模算法和一致性Hash,就是这样一种方式。 接口定义 /** * 数据分布hash算法接口定义 * @author xingchuan.qxc * */ public interface HashNodeService { /** * 集群增加一个数据存储节点 * @param node */ public void addNode(Node node)

对缓存的思考——提高命中率

混江龙づ霸主 提交于 2019-12-01 03:36:07
开篇 编写高效的程序并不只在于算法的精巧,还应该考虑到计算机内部的组织结构,cpu微指令的执行,缓存的组织和工作原理等。 好的算法在实际中不见得有高效率,如果完全没有考虑缓存、微指令实现的话。 前两篇博文 局部性原理浅析 介绍了程序的局部性原理,如何写出局部性良好代码。 提高程序性能、何为缓存 讨论了存储器层次结构,计算机内部的存储结构、缓存的概念,简单的介绍了缓存的工作机制。 建议先阅读前两篇博文,虽然他们之间联系不大,在前面也有一些对本文的铺垫。而且,这是一个系列的文章。旨在优化程序性能。 这篇博文主要介绍的是缓存的组织、工作原理。拨开迷雾,让你更加清晰的认识缓存。 通用缓存结构 回顾 在 提高程序性能、何为缓存 中提到:早起的cpu存储层次只有三层,即cup的寄存器,DRAM主存和磁盘存储。因为寄存器和主存之间的访问时间开销差距很大,于是设计者在寄存器(一个时钟周期)和主存之间加入了L1缓存(2——4个时钟周期),后来由于L1缓存和主存之间的差距,又在主存和L1之间加入了L2缓存,当然后面还有L3缓存,,,等等。 在这里为了简单起见,假设CPU寄存器和主存之间只有一个L1缓存。 下图是高速缓存存储器的典型总线结构: 缓存结构 下图清晰的说明了通用缓存的组织结构: 可以看到,缓存内部是以组的形式组织的。图中的每一块代表一组,每组由一到多行组成(当然图中的是每组有多行)。