缓存命中率的介绍

命中:可以直接通过缓存获取到需要的数据。

不命中:无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作。原因可能是由于缓存中根本不存在,或者缓存已经过期。

通常来讲,缓存的命中率越高则表示使用缓存的收益越高,应用的性能越好(响应时间越短、吞吐量越高),抗并发的能力越强。

由此可见,在高并发的互联网系统中,缓存的命中率是至关重要的指标。

如何监控缓存的命中率

redis提供了INFO这个命令,能够随时监控服务器的状态,只用telnet到对应服务器的端口,执行命令即可:

telnet localhost 6379
info

在输出的信息里面有这几项和缓存的状态比较有关系:

keyspace_hits:14414110
keyspace_misses:3228654
used_memory:433264648
expired_keys:1333536
evicted_keys:1547380

通过计算hits和miss,我们可以得到缓存的命中率:14414110 / (14414110 + 3228654) = 81% ,一个缓存失效机制,和过期时间设计良好的系统,命中率可以做到95%以上

有个ruby gem叫redis-stat,它利用INFO命令展现出更直观的信息报表,推荐:
https://github.com/junegunn/redis-stat

同时,zabbix也提供了相关的插件对redis服务进行监控。

影响缓存命中率的几个因素

之前的章节中我们提到了缓存命中率的重要性,下面分析下影响缓存命中率的几个因素。

1.业务场景和业务需求

缓存适合“读多写少”的业务场景,反之,使用缓存的意义其实并不大,命中率会很低。

业务需求决定了对时效性的要求,直接影响到缓存的过期时间和更新策略。时效性要求越低,就越适合缓存。在相同key和相同请求数的情况下,缓存时间越长,命中率会越高。

互联网应用的大多数业务场景下都是很适合使用缓存的。

2.缓存的设计(粒度和策略)

通常情况下,缓存的粒度越小,命中率会越高。举个实际的例子说明:

当缓存单个对象的时候(例如:单个用户信息),只有当该对象对应的数据发生变化时,我们才需要更新缓存或者让移除缓存。而当缓存一个集合的时候(例如:所有用户数据),其中任何一个对象对应的数据发生变化时,都需要更新或移除缓存。

还有另一种情况,假设其他地方也需要获取该对象对应的数据时(比如其他地方也需要获取单个用户信息),如果缓存的是单个对象,则可以直接命中缓存,反之,则无法直接命中。这样更加灵活,缓存命中率会更高。

此外,缓存的更新/过期策略也直接影响到缓存的命中率。当数据发生变化时,直接更新缓存的值会比移除缓存(或者让缓存过期)的命中率更高,当然,系统复杂度也会更高。

3.缓存容量和基础设施

缓存的容量有限,则容易引起缓存失效和被淘汰(目前多数的缓存框架或中间件都采用了LRU算法)。同时,缓存的技术选型也是至关重要的,比如采用应用内置的本地缓存就比较容易出现单机瓶颈,而采用分布式缓存则毕竟容易扩展。所以需要做好系统容量规划,并考虑是否可扩展。此外,不同的缓存框架或中间件,其效率和稳定性也是存在差异的。

4.其他因素

当缓存节点发生故障时,需要避免缓存失效并最大程度降低影响,这种特殊情况也是架构师需要考虑的。业内比较典型的做法就是通过一致性Hash算法,或者通过节点冗余的方式。

有些朋友可能会有这样的理解误区:既然业务需求对数据时效性要求很高,而缓存时间又会影响到缓存命中率,那么系统就别使用缓存了。其实这忽略了一个重要因素--并发。通常来讲,在相同缓存时间和key的情况下,并发越高,缓存的收益会越高,即便缓存时间很短。

提高缓存命中率的方法

从架构师的角度,需要应用尽可能的通过缓存直接获取数据,并避免缓存失效。这也是比较考验架构师能力的,需要在业务需求,缓存粒度,缓存策略,技术选型等各个方面去通盘考虑并做权衡。尽可能的聚焦在高频访问且时效性要求不高的热点业务上(如字典数据、session、token),通过缓存预加载(预热)、增加存储容量、调整缓存粒度、更新缓存等手段来提高命中率。

对于时效性很高(或缓存空间有限),内容跨度很大(或访问很随机),并且访问量不高的应用来说缓存命中率可能长期很低,可能预热后的缓存还没来得被访问就已经过期了。

如何提高缓存命中率(Redis)的更多相关文章

  1. 关于如何提高缓存命中率(redis)

    一.缓存命中率的介绍 命中:可以直接通过缓存获取到需要的数据. 不命中:无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作.原因可能是由于缓存中根本不存在,或者缓存已经过期. 通常 ...

  2. [MySQL性能优化系列]提高缓存命中率

    1. 背景 通常情况下,能用一条sql语句完成的查询,我们尽量不用多次查询完成.因为,查询次数越多,通信开销越大.但是,分多次查询,有可能提高缓存命中率.到底使用一个复合查询还是多个独立查询,需要根据 ...

  3. 合理配置MySQL缓存 提高缓存命中率

    众所周知,系统读取数据时,从内存中读取要比从硬盘上速度要快好几百倍.故现在绝大部分应用系统,都会最大程度的使用缓存(内存中的一个存储区域),来提高系统的运行效率.MySQL数据库也不例外.在这里,笔者 ...

  4. MySQL缓存命中率概述及如何提高缓存命中率

    MySQL缓存命中率概述 工作原理: 查询缓存的工作原理,基本上可以概括为: 缓存SELECT操作或预处理查询(注释:5.1.17开始支持)的结果集和SQL语句: 新的SELECT语句或预处理查询语句 ...

  5. Memcache 提高缓存命中率

    最近手上某个项目跟新代码,新的代码里大量采用memcahce作为缓存.所以开始深入了解memcache的内存分配策略.以前就听说有个PHP写的memcache监控脚本,在网上搜索了一下,果断下载下来用 ...

  6. Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%。再往后,每提高0.1%,优化难度成指数级增长了。哪怕是千分之一,也直接影响用户体验,影响每天上万张机票的销售额。 在高并发场景下,提供了保证线程安全的对象、方法。比如经典的ConcurrentHashMap,它比起HashMap,有更小粒度的锁,并发读写性能更好。线程安全的StringBuilder取代S

    Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%.再往后,每提高0.1%,优化难度成指数级增长了.哪怕是千分之一,也直接影响用户体验,影响每天上万张机 ...

  7. 基于Spring Cache实现二级缓存(Caffeine+Redis)

    一.聊聊什么是硬编码使用缓存? 在学习Spring Cache之前,笔者经常会硬编码的方式使用缓存. 我们来举个实际中的例子,为了提升用户信息的查询效率,我们对用户信息使用了缓存,示例代码如下: @A ...

  8. 再谈缓存和Redis

    自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...

  9. 谈缓存和Redis

    自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...

随机推荐

  1. 02_创建Git仓库,克隆仓库,git add,git commit,git push,git pull,同行冲突,不同行冲突的结局方案,git mergetool的使用

    1 创建Git资源库,残酷目录信息 创建git资源库的命令: git init –bare 仓库名称 (其中-bare表示的意思是空的库的意思) 进入E:\software\repository\gi ...

  2. STL常用排序算法介绍

    merge()  以下是排序和通用算法:提供元素排序策略  merge: 合并两个有序序列,存放到另一个序列. #include <iostream> #include <cstdi ...

  3. Mac OS X 10.8.4下面XZ Utils(*.tar.xz)压缩解压缩命令工具的安装

    主要参考:http://bbs.chinaunix.net/thread-3610738-1-1.html 现在很多找到的软件都是tar.xz的格式的,xz 是一个使用 LZMA压缩算法的无损数据压缩 ...

  4. Linux文件系统的简单操作 - df, du, ln

    现在我们知道磁盘的整体数据是在 superblock 区块中,但是每个各别文件的容量则在 inode 当中记载的. 那在文字接口底下该如何叫出这几个数据呢?底下就让我们来谈一谈这两个命令: df:列出 ...

  5. 苹果新的编程语言 Swift 语言进阶(十五)--协议

    协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描述了一个实现可以 ...

  6. 第15章-输入/输出 --- File类

    (一) Java的IO通过java.io包下的类和接口来支持,在java.io包下主要包括输入.输出两种IO流. 每种输入.输出流又分为字节流和字符流两大类: (1)字节流以字节为单位来处理输入.输出 ...

  7. SDL相关资料

    SDL(Simple DirectMedia Layer)是一个自由的跨平台的多媒体开发包,适用于 游戏.游戏SDK.演示软件.模拟器.MPEG播放器和其他应用软件.目前支持windows,linux ...

  8. WebSocket 和 Golang 实现聊天功能

    http://www.open-open.com/lib/view/open1416379948711.html 这个示例应用程序展示了如何使用 WebSocket, Golang 和 jQuery  ...

  9. Future与Promise

    https://code.csdn.NET/DOC_Scala/chinese_scala_offical_document/file/Futures-and-Promises-cn.md#ancho ...

  10. python3学习笔记1---引用http://python3-cookbook.readthedocs.io/zh_CN/latest/

    2018-02-28数据结构和算法(1) 1.1解压序列赋值给多个变量: 任何的序列(或者是可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量. 唯一的前提就是变量的数量必须跟序列元素的数量是 ...