https://www.cnblogs.com/remcarpediem/p/12872053.html
带你100% 地了解 Redis 6.0 的客户端缓存 近日 Redis 6.0.0 GA 版本发布,这是 Redis 历史上最大的一次版本更新,包括了客户端缓存 (Client side caching)、ACL、Threaded I/O 和 Redis Cluster Proxy 等诸多更新。
我们今天就依次聊一下客户端缓存的必要性、具体使用、原理分析和实现。
为什么需要客户端缓存? 我们都知道,使用 Redis 进行数据的缓存的主要目的是减少对 MySQL 等数据库的访问,提供更快的访问速度,毕竟 《Redis in Action》中提到的, Redis 的性能大致是普通关系型数据库的 10 ~ 100 倍。
所以,如下图所示,Redis 用来存储热点数据,Redis 未命中,再去访问数据库,这样可以应付大多数情况下的性能要求。
但是,Redis 也有其性能上限,并且访问 Redis 必然有一定的网络 I/O 以及序列化反序列化损耗。所以,往往会引入进程缓存,将最热的数据存储在本地,进一步加快访问速度。
如上图所示,Guava Cache 等进程缓存作为一级缓存,Redis 作为二级缓存:
先去 Guava Cache 中查询数据,如果命中则直接返回。 Guava Cache 中未命中,则再去 Redis 中查询,如果命中则返回数据,并在 Guava Cache 中设置此数据。 Redis 也未命中的话,只有去 MySQL 中查询,然后依次将数据设置到 Redis 和 Guava Cache 中。 只使用 Redis 分布式缓存时,遇到数据更新时,应用程序更新完 MySQL 中的数据,可以直接将 Redis 中对应缓存失效掉,保持数据的一致性。
时间:
|
阅读:
112 字 ~1分钟
原文地址:https://www.51cto.com/article/707706.html
简介 客户端缓存是Redis6众多新特性中比较实用的一项新功能,我们看看官方文档,了解一下它的作用:
客户端缓存是一种用于创建高性能服务的技术,它可以利用应用服务器上的可用内存(这些服务器通常是一些不同于数据库服务器的节点),在这些应用服务端来直接存储数据库中的一些信息。
与访问数据库等网络服务相比,访问本地内存所需要的时间消耗要少得多,因此这个模式可以大大缩短应用程序获取数据的延迟,同时也能减轻数据库的负载压力。
看到这,我心想这不是和其他本地缓存Guava、Caffeine啥的一样吗,换汤不换药,都是使用的应用服务的内存罢了。要说有什么好处,可能就是我在项目中能少引入一个中间件了。
不过,我这点浅薄的猜想,在看完客户端缓存的具体应用模式后,彻底被颠覆了。
两种模式 在了解了客户端缓存的基本功能后,我们来看看它的两种基本应用模式。Redis的客户端缓存支持被称为tracking,个人感觉翻译为对key的追踪就很好理解,它具有两种模式:
默认模式,服务端会记录某个客户端具体访问过哪一些key,当这些key对应的值发生变化时,会发送失效消息给这些客户端。这个模式会在服务端消耗一些内存,但是发送失效消息的范围,被限制在了客户端存储了的key的集合范围内 广播模式,服务端不会再记录某个客户端访问了哪些key,因此这个模式不消耗服务端的内存。取而代之的是,客户端需要订阅key的特定前缀,每当符合这个前缀的key对应的值发生改变时,客户端都会收到通知消息 看到这里,它和我们之前使用的两级缓存之间差异,是不是已经初露端倪了呢?如果还不熟悉两级缓存的架构,那么可以先来看看下面的这张图:
这种架构在理论上看起来不错,但是实际使用起来需要注意的点不少,尤其是在分布式模式下,需要保证各个主机下的一级缓存的一致性问题,回想一下我们原先的解决方案,可以使用redis本身的发布/订阅功能来实现:
而客户端缓存的出现,大大简化了这一过程。我们以默认模式为例,看一下使用了客户端缓存后的操作过程:
相比原先的发布/订阅模式,我们可以看到明显的优势,使用客户端缓存功能后,我们只需要单纯的修改redis中的数据就可以了,手动处理发布/订阅消息的这一过程可以完全被省略。
优势 到这里,在了解了客户端缓存的基本功能与两种模式后,我们来对比一下,和传统的只使用redis做远程缓存、以及使用整合后的两级缓存相比较,客户端缓存具有什么样的优势。
当应用的服务端存在缓存时,会直接读取本地缓存,能够减少网络访问上造成的延迟,从而加快访问速度 同时也能减少访问redis服务端的次数,降低redis的负载压力 在分布式环境下,不再需要通过发布订阅来通知其他主机更新本地缓存,来保证数据的一致性。使用客户端缓存后,它所具有的原生的消息通知功能,能很好地支持作废本地缓存,保证之后访问时能取到更新后的新数据 误区 在开始演示客户端缓存的使用之前,我们先来纠正一个误区。
虽然这个新特性被称为客户端缓存,但是redis本身不提供在应用服务端缓存数据的功能,这个功能要由访问redis的客户端自己去实现。
说白了,也就是redis服务端只负责通知你,你缓存在应用服务本地的这个key已经作废了,至于你本地如何缓存的这些数据,redis并不关心,也不负责。
功能演示 下面将通过一些实例来进行演示,本文代码的运行前提条件是你已经装好了Redis6.x版本,linux环境下可以直接从官网下载后编译安装,windows环境下的安装可以参考 手摸手教你在Windows环境下运行Redis6.x 这篇文章。
概念上的东西我们也大体了解了,下面我们分别来看一下客户端缓存具体实现的三种模式(至于为什么多了一种,后面再来细说)。在正式开始前,强烈建议大家先花个十几分钟了解一下 Redis6底层的通信协议RESP3,否则在看到具体的通信内容时可能会存在一些疑问。
首先做一下准备工作,通过telnet连接redis服务,并切换到resp3协议模式:
telnet 127.0.0.1 6379 hello 3 1、默认模式 在使用客户端连接到redis服务后,需要先通过指令开启tracking模式的功能,因为在客户端连接后这个选项是默认关闭的,会无法收到失效类型的push消息:
#开启 client tracking on #关闭 client tracking off 当开启tracking后的默认模式下,redis服务端会记录每个客户端请求过的key,当key对应的值发生变化时,会发送失效信息给客户端。简单总结一下,也就是说这个模式能够生效的必要前提条件有两个:
开启tracking 客户端访问过某个key 下面我们还是在telnet中来模拟一下这个过程,分别启动两个redis客户端,在client1中先执行get命令后,再在client2对相同的key执行set操作修改它的值,之后就会在client1中收到push类型的消息。
push类型的消息我们在RESP3中介绍过了,这里简单再唠叨两句:
>2 $10 invalidate *1 $4 user 起始的第一字节>表示该消息为push类型,后面消息体中包含了两部分内容,第一部分表示收到的消息类型为invalidate,也就是作废类型的信息,第二部分则是需要作废的key是user。
时间:
|
阅读:
3353 字 ~16分钟
原文地址:https://redis.io/docs/manual/client-side-caching/
Client-side caching in Redis Redis客户端侧缓存
Server-assisted, client-side caching in Redis > Redis服务端支持的客户端侧缓存
Client-side caching is a technique used to create high performance services. It exploits the memory available on application servers, servers that are usually distinct computers compared to the database nodes, to store some subset of the database information directly in the application side. > 客户端侧缓存是用来创建高性能服务的技术。应用服务器通常与Redis数据库服务器在不同的服务器机器上,客户端缓存可以利用应用服务器的可用内存来数据库信息的子集直接存储到客户端侧。
Normally when data is required, the application servers ask the database about such information, like in the following diagram:
时间:
|
阅读:
432 字 ~3分钟
Introduction to the Redis 6 release Redis 6 improves Redis in a number of key areas and is one of the largest Redis releases in the history of the project, so here we’ll list only the biggest features in this release:
The modules system now has a number of new APIs that allow module authors to make things otherwise not possible in the past. It is possible to store arbitrary module private data in RDB files, to hook on different server events, capture and rewrite commands executions, block clients on keys, and so forth.
时间:
|
阅读:
1803 字 ~9分钟
Introduction to the Redis 6.2 release This release is the first significant Redis release managed by the core team under the new project governance model.
Redis 6.2 includes many new commands and improvements, but no big features. It mainly makes Redis more complete and addresses issues that have been requested by many users frequently or for a long time. > Redis 6.2包含很多新命令和提升,但是没有大的特性功能。完善Redis功能,并且解决用户常提到的和已经存在很长时间的问题。
Many of these changes were not eligible for 6.
时间:
|
阅读:
4773 字 ~23分钟
Redis 6.0 release notes Upgrade urgency levels:
LOW: No need to upgrade unless there are new features you want to use. MODERATE: Program an upgrade of the server, but it’s not urgent. HIGH: There is a critical bug that may affect a subset of users. Upgrade! CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. SECURITY: There are security fixes in the release.
升级紧要级别 LOW : 不需要升级,除非你想要使用新的功能。 MODERATE : 程序升级,但不是紧迫。 HIGH : 有一个严重的bug,可能会影响一些用户。升级! CRITICAL : 有一个严重的bug,影响大多数用户。立即升级! SECURITY : 在此版本中有安全修复。
时间:
|
阅读:
182 字 ~1分钟
Redis6生产配置
daemonize yes pidfile "xxx/redis.pid" tcp-backlog 511 timeout 0 tcp-keepalive 60 logfile "xxx/redis.log" loglevel notice databases 16 dir "xxx/data" stop-writes-on-bgsave-error yes repl-timeout 120 repl-ping-replica-period 10 repl-disable-tcp-nodelay no repl-backlog-size 64mb repl-backlog-ttl 7200 replica-serve-stale-data yes replica-read-only no replica-priority 100 lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 1000 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 set-max-intset-entries 512 zset-max-ziplist-entries 512 zset-max-ziplist-value 64 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 2gb 1gb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 port 13980 maxmemory 1gb maxmemory-policy allkeys-lru appendonly no appendfsync everysec appendfilename "appendonly.
时间:
|
阅读:
1071 字 ~6分钟
https://blog.csdn.net/ldw201510803006/article/details/122420585
前言 从 ziplist 到 quicklist,再到 listpack 结构;可以看到,初衷都是设计一款数据结构能够高效的使用内存。
ziplist 设计出的紧凑型数据块可以有效利用内存,但在更新上,由于每一个 entry 都保留了前一个 entry 的 prevlen 长度,因此在插入或者更新时可能会出现连锁更新,这是一个影响效率的大问题。
因此,接着又设计出 「链表 + ziplist」组成的 quicklist 结构来避免单个 ziplist 过大,可以有效降低连锁更新的影响面。
但 quicklist 本质上不能完全避免连锁更新问题,因此,又设计出与 ziplist 完全不同的内存紧凑型结构 listpack,继续往下看~
一、listpack是什么? listpack 也叫紧凑列表,它的特点就是用一块连续的内存空间来紧凑地保存数据,同时为了节省内存空间,listpack 列表项使用了多种编码方式,来表示不同长度的数据,这些数据包括整数和字符串。
Redis源码对于listpack的解释为 A lists of strings serialization format,一个字符串列表的序列化格式,也就是将一个字符串列表进行序列化存储。Redis listpack可用于存储字符串或者整型
二、原理分析 1. 结构 listpack结构: <tot-bytes> <num-elements> <element-1> ... <element-N> <listpack-end-byte> listpack由4部分组成:total Bytes、Num Elem、Entry以及End
Total Bytes为整个listpack的空间大小,占用4个字节,每个listpack最多占用4294967295Bytes。 Num Elem为listpack中的元素个数,即Entry的个数,占用2个字节,值得注意的是,这并不意味着listpack最多只能存放65535个Entry,当Entry个数大于等于65535时,Num Elem被设置为65535,此时如果需要获取元素个数,需要遍历整个listpack。 Entry为每个具体的元素。 End为listpack结束标志,占用1个字节,内容为0xFF。 entry结构: Entry为listpack中的具体元素,其内容可以为字符串或者整型,每个Entry由3部分组成:
<encoding-type><element-data><element-tot-len> | | +--------------------------------------------+ (This is an element) 从组成上可以看出,和 ziplist 列表项类似,listpack 列表项也包含了元数据信息和数据本身。