redis 6.0新特性-客户端缓存学习总结

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: redis 6.0新特性-客户端缓存学习总结

redis 6.0的客户端缓存学习总结

官网原文: https://redis.io/docs/manual/client-side-caching/

客户端缓存是为了创建高性能的服务。有了客户端缓存,同样的key查询请求就可以在应用本地内存中获取到,无需网络请求。

+-------------+                                +----------+
|             |                                |          |
| Application |       ( No chat needed )       | Database |
|             |                                |          |
+-------------+                                +----------+
| Local cache |
|             |
| user:1234 = |
| username    |
| Alice       |
+-------------+

而在客户端缓存上,计算机科学面临两个难题:

  1. 如何使过时信息无效,避免其向用户呈现
  2. 通过PUB/SUB的形式向客户端发送过期信息,有很大的带宽压力,即使那个客户端可能没有缓存该key。

所以redis6直接对其进行支持,提供了更可靠、更高效的实现。

redis的客户端缓存主要有两种模式:

  1. redis服务端记录客户端缓存的key(默认)
  2. redis客户端向服务端提供会缓存的key的前缀(广播模式)

服务端记录客户端缓存key的模式(默认)

  • 服务端记录每个客户端缓存的key,在一个名为Invalidation Table的全局表里。
  • 当客户端断开连接的时候,该客户端缓存的key会渐进式的进行垃圾回收。
    (若因网络情况发生这种情况的redis客户端,也应该清理自己的本地缓存,因为它很可能会有过期)
  • 服务端不会为每个database提供一个缓存key的命名空间,因此,如果客户端在database 2 修改了key,
    则该key在database 3 中没有被修改,也会被发送过期信息到客户端。这样的设计是为了减少内存开销,以及实现复杂度。
    但是在我看来,我们应用系统往往都是在database 0 上进行读写的。

在这种模式下,如果使用RESP2 协议(兼容老版本),则使用PUB/SUB命令进行实现。并且通过两个连接来维护。

一个连接进行正常的命令操作,一个连接专门用来接收无效信息(invalidation messages)。

但是如果使用RESP3 协议,无效信息将会使用push命令进行发送,无论是一个还是两个连接。

参数

  • OPTIN
    CLIENT TRACKING on REDIRECT 1234 OPTIN

这个参数在开启TRACKING后,使得redis服务端不会记录redis客户端缓存了哪个key,除非客户端通知服务端进行缓存

CLIENT CACHING YES
+OK
GET foo
"bar"

CACHING 命令只会将紧跟其后的命令进行缓存,使用MULTI 命令会将一整个交易的key进行缓存,例如lua脚本的。

服务端广播模式

  • 客户端开启客户端缓存时携带BCAST参数,并使用一个或多个PREFIX 参数声明需要缓存的key的前缀。
    并且前缀之间不可冲突。
  • 服务端此时不再需要维护Invalidation Table,而是维护一张与每个客户端关联的Prefixes Table表。
  • 所有符合前缀的key被修改后,都会通知对应的客户端进行无效。
  • 这种模式服务端CPU的消耗和客户端注册的key的前缀数量成正比。
    如果是少量的,基本无影响。但是如果数量众多,就会十分影响CPU性能。
  • 这种模式下,服务端可以优化,将过期指令合并成单个回复。

参数

  • NOLOOP
    这个参数对两种模式都生效。
    默认情况下,服务端会将key失效信息发送给所有客户端,包括对这个key进行修改的客户端。
    但是对于那些实现先进的客户端,它们已经将自身的本地缓存做了修改,无需接收自己发起的修改的过期信息。
    使用这个参数,就可以来避免自己刚写的本地缓存被服务端通知清除。

避免紊乱情况

针对通过两个连接进行实现的客户端缓存,应当要通过占位符来避免因为两个连接接收服务端返回的响应顺序不一致而导致的问题。单连接的顺序有保证,不会有此问题。

例如下面这种情况,对旧版本请求的key的响应将出现问题,并缓存到了本地:

[D] client -> server: GET foo
[I] server -> client: Invalidate foo (somebody else touched it)
[D] server -> client: "bar" (the reply of "GET foo")

那么通过一个占位符,来使得旧版本的请求即使返回,也不会被缓存。

Client cache: set the local copy of "foo" to "caching-in-progress"
[D] client-> server: GET foo.
[I] server -> client: Invalidate foo (somebody else touched it)
Client cache: delete "foo" from the local cache.
[D] server -> client: "bar" (the reply of "GET foo")
Client cache: don't set "bar" since the entry for "foo" is missing.

连接断开的情况

  1. 本地缓存必须被清除
  2. 不管是使用RESP2还是RESP3,都需要定期通过PING命令进行心跳检查,保持通道正常。

所以在连接通道断开,且未被检测出来的时间段内,本地缓存可能存在过期情况!

什么应该被缓存

  1. 不应该缓存那些会被连续性更新的key
  2. 不应该缓存那些请求次数稀少的key
  3. 应该缓存那些频繁被请求并且更新频率可接受的key

然而,简单的客户端实现往往只是随机的清除key,或使用LRU进行清除。

其他几个对客户端库的提示

  1. 处理TTL(过期时间)
    在本地缓存页实现TTL,如果你想支持这个特性
  2. 设置最大过期时间
    即使没有过期时间,但也建议本地有最大过期时间。防止产生bug或者连接问题而导致本地副本一直保留该数据。
  3. 限制本地缓存的内存用量
    限制本地内存用量,并且在添加新的缓存key时,淘汰旧的缓存

学习总结

  1. redis的客户端缓存有两种模式,默认模式会占用redis服务端的内存资源,广播模式会占用redis服务端的CPU资源。
  2. 默认模式需要注意缓存的key的数量不能太大。
  3. 广播模式需要注意缓存的key的前缀数量不能太大。(具体性能转折点在哪里需要自行测试)
  4. 客户端缓存在网络问题导致连接通道断开且未被检测出来的时间段内,应用可能读到过期数据,实时性要求特别高的业务需要注意避免使用或者有兜底方案。
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1天前
|
缓存 NoSQL 安全
Redis经典问题:缓存击穿
本文探讨了高并发系统中Redis缓存击穿的问题及其解决方案。缓存击穿指大量请求同一未缓存数据,导致数据库压力过大。为解决此问题,可以采取以下策略:1) 热点数据永不过期,启动时加载并定期异步刷新;2) 写操作加互斥锁,保证并发安全并设置查询失败返回默认值;3) 预期热点数据直接加缓存,系统启动时加载并设定合理过期时间;4) 手动操作热点数据上下线,通过界面控制缓存刷新。这些方法能有效增强系统稳定性和响应速度。
25 0
|
2天前
|
缓存 NoSQL 应用服务中间件
Redis多级缓存
Redis多级缓存
8 0
|
2天前
|
缓存 NoSQL 关系型数据库
Redis 缓存 一致性
Redis 缓存 一致性
6 0
|
2天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
57 3
|
3天前
|
JSON NoSQL Java
深入浅出Redis(十三):SpringBoot整合Redis客户端
深入浅出Redis(十三):SpringBoot整合Redis客户端
|
3天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
3天前
|
消息中间件 缓存 NoSQL
Redis经典问题:缓存雪崩
本文介绍了Redis缓存雪崩问题及其解决方案。缓存雪崩是指大量缓存同一时间失效,导致请求涌入数据库,可能造成系统崩溃。解决方法包括:1) 使用Redis主从复制和哨兵机制提高高可用性;2) 结合本地ehcache缓存和Hystrix限流降级策略;3) 设置随机过期时间避免同一时刻大量缓存失效;4) 使用缓存标记策略,在标记失效时更新数据缓存;5) 实施多级缓存策略,如一级缓存失效时由二级缓存更新;6) 通过第三方插件如RocketMQ自动更新缓存。这些策略有助于保障系统的稳定运行。
108 1
|
6天前
|
存储 消息中间件 缓存
Redis缓存技术详解
【5月更文挑战第6天】Redis是一款高性能内存数据结构存储系统,常用于缓存、消息队列、分布式锁等场景。其特点包括速度快(全内存存储)、丰富数据类型、持久化、发布/订阅、主从复制和分布式锁。优化策略包括选择合适数据类型、设置过期时间、使用Pipeline、开启持久化、监控调优及使用集群。通过这些手段,Redis能为系统提供高效稳定的服务。
|
12天前
|
存储 缓存 NoSQL
【Go语言专栏】Go语言中的Redis操作与缓存应用
【4月更文挑战第30天】本文探讨了在Go语言中使用Redis进行操作和缓存应用的方法。文章介绍了Redis作为高性能键值存储系统,用于提升应用性能。推荐使用`go-redis/redis`库,示例代码展示了连接、设置、获取和删除键值对的基本操作。文章还详细阐述了缓存应用的步骤及常见缓存策略,包括缓存穿透、缓存击穿和缓存雪崩的解决方案。利用Redis和合适策略可有效优化应用性能。
|
15天前
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
41 1