
Redis 核心原理与实战
本专栏里面的所有知识点都是,理论 + 实战的方式,例如主从同步、哨兵、Redis 集群等功能都是先讲它们的搭建、再讲它们的运行原理、再结合 Java 代码完成相关的操作,以这个的方式,力求把每一个知识点都讲透,让用户知其然并知其所以然的同时,还能把每个知识点通过实战的方式串联起来,让读者融会贯通
sufu1065
这个作者很懒,什么都没留下…
展开
-
Redis 是如何执行的?
在以往的面试中,当问到一些面试者:Redis 是如何执行的?收到的答案往往是:客户端发命令给服务器端,服务端收到执行之后再返回给客户端。然而对于执行细节却「避而不谈」 ,当继续追问服务器端是如何执行的?能回答上来的人更是寥寥无几,这未免让人有些遗憾,一个我们每天都在用的技术,知道原理的人却寥若晨星。对于任何一门技术,如果你只停留在「会用」的阶段,那就很难有所成就,甚至还有被裁员和找不到工作的风险...原创 2020-10-28 16:09:46 · 614 阅读 · 0 评论 -
Redis 快速搭建与使用
Redis 是由 C 语言开发的开源内存数据存储器,经常被用作数据库、缓存以及消息队列等。Redis 因为其强大的功能和简洁的设计,深受广大开发者和公司的喜爱,几乎占领了内存数据库市场的所有份额。1 Redis 特性Redis 有很多优秀的特性,这也是它最受欢迎的原因。1)多种数据类型支持Redis 支持多种数据类型,例如字符串、散列、列表、集合、有序集合、HyperLogLog、流、地...原创 2020-10-28 16:09:46 · 331 阅读 · 0 评论 -
字符串使用与内部实现原理
Redis 发展到现在已经有 9 种数据类型了,其中最基础、最常用的数据类型有 5 种,它们分别是:字符串类型、列表类型、哈希表类型、集合类型、有序集合类型,而在这 5 种数据类型中最常用的是字符串类型,所以本文我们先从字符串的使用开始说起。字符串类型的全称是 Simple Dynamic Strings 简称 SDS,中文意思是:简单动态字符串。它是以键值对 key-value 的形式进行存储...原创 2020-10-28 16:09:46 · 585 阅读 · 0 评论 -
字典使用与内部实现原理
字典类型 (Hash) 又被成为散列类型或者是哈希表类型,它是将一个键值 (key) 和一个特殊的“哈希表”关联起来,这个“哈希表”表包含两列数据:字段和值。例如我们使用字典类型来存储一篇文章的详情信息,存储结构如下图所示:同理我们也可以使用字典类型来存储用户信息,并且使用字典类型来存储此类信息,是不需要手动序列化和反序列化数据的,所以使用起来更加的方便和高效。1.基础使用首先我们使用命令...原创 2020-10-28 16:09:47 · 615 阅读 · 0 评论 -
列表使用与内部实现原理
列表类型 (List) 是一个使用链表结构存储的有序结构,它的元素插入会按照先后顺序存储到链表结构中,因此它的元素操作 (插入\删除) 时间复杂度为 O(1),所以相对来说速度还是比较快的,但它的查询时间复杂度为 O(n),因此查询可能会比较慢。1 基础使用列表类型的使用相对来说比较简单,对它的操作就相当操作一个没有任何 key 值的 value 集合,如下图所示:1)给列表添加一个或多个...原创 2020-10-28 16:09:47 · 331 阅读 · 0 评论 -
集合使用与内部实现原理
集合类型 (Set) 是一个无序并唯一的键值集合。之所以说集合类型是一个无序集合,是因为它的存储顺序不会按照插入的先后顺序进行存储,如下代码所示:127.0.0.1:6379> sadd myset v2 v1 v3 #插入数据 v2、v1、v3 (integer) 3127.0.0.1:6379> smembers myset #查询数据1) "v1"2) "v3"3)...原创 2020-10-28 16:09:48 · 334 阅读 · 0 评论 -
有序集合使用与内部实现原理
有序集合类型 (Sorted Set) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。有序集合的存储元素值也是不能重复的,但分值是可以重复的。当我们把学生的成绩存储在有序集合中时,它的存储结构如下图所示:下面我们先从有序集合的使用开始说起。1 基础使用1)添加一个或多个元素语法:...原创 2020-10-28 16:09:48 · 673 阅读 · 0 评论 -
Redis 持久化——RDB
Redis 的读写都是在内存中,所以它的性能较高,但在内存中的数据会随着服务器的重启而丢失,为了保证数据不丢失,我们需要将内存中的数据存储到磁盘,以便 Redis 重启时能够从磁盘中恢复原有的数据,而整个过程就叫做 Redis 持久化。Redis 持久化也是 Redis 和 Memcached 的主要区别之一,因为 Memcached 不具备持久化功能。1 持久化的几种方式Redi...原创 2020-10-28 16:09:49 · 318 阅读 · 0 评论 -
Redis 持久化——AOF
使用 RDB 持久化有一个风险,它可能会造成最新数据丢失的风险。因为 RDB 的持久化有一定的时间间隔,在这个时间段内如果 Redis 服务意外终止的话,就会造成最新的数据全部丢失。可能会操作 Redis 服务意外终止的条件:安装 Redis 的机器停止运行,蓝屏或者系统崩溃;安装 Redis 的机器出现电源故障,例如突然断电;使用 kill -9 Redis_PID 等。那么如何解...原创 2020-10-28 16:09:49 · 228 阅读 · 0 评论 -
Redis 持久化——混合持久化
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时使用 RDB 和 AOF 各种的优点,Redis 4.0 之后新增了混合持久化的方式。在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。...原创 2020-10-28 16:09:50 · 1296 阅读 · 0 评论 -
Redis 事务深入解析
作为关系型数据库中一项非常重要的基础功能——事务,在 Redis 中是如何处理并使用的?前言事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命令后,才会继续处理此客户端的其他命令。事务也是其他关系型数据库所必备的基础功能,以支付的场景为例,正常情况下只有正常消费完成之后,才会减去账户余额。但如果没有事务的保障,可能会发生消费失败了,但...原创 2020-10-28 16:09:50 · 211 阅读 · 0 评论 -
Redis 键值过期操作
过期设置Redis 中设置过期时间主要通过以下四种方式:expire key seconds:设置 key 在 n 秒后过期;pexpire key milliseconds:设置 key 在 n 毫秒后过期;expireat key timestamp:设置 key 在某个时间戳(精确到秒)之后过期;pexpireat key millisecondsTimestamp:设置 key...原创 2020-10-28 16:09:51 · 662 阅读 · 0 评论 -
Redis 过期策略与源码分析
在 Redis 中我们可以给一些元素设置过期时间,那当它过期之后 Redis 是如何处理这些过期键呢?过期键执行流程Redis 之所以能知道那些键值过期,是因为在 Redis 中维护了一个字典,存储了所有设置了过期时间的键值,我们称之为过期字典。过期键判断流程如下图所示:过期键源码分析过期键存储在 redisDb 结构中,源代码在 src/server.h 文件中:/* Redis ...原创 2020-10-28 16:09:51 · 258 阅读 · 0 评论 -
Redis 管道技术——Pipeline
管道技术(Pipeline)是客户端提供的一种批处理技术,用于一次处理多个 Redis 命令,从而提高整个交互的性能。通常情况下 Redis 是单行执行的,客户端先向服务器发送请求,服务端接收并处理请求后再把结果返回给客户端,这种处理模式在非频繁请求时不会有任何问题。但如果出现集中大批量的请求时,因为每个请求都要经历先请求再响应的过程,这就会造成网络资源浪费,此时就需要管道技术来把所有的命令整...原创 2020-10-28 16:09:51 · 771 阅读 · 0 评论 -
查询附近的人——GEO
受过高等教育的我们都知道,我们所处的任何位置都可以用经度和纬度来标识,经度的范围 -180 到 180,纬度的范围为 -90 到 90。纬度以赤道为界,赤道以南为负数,赤道以北为正数;经度以本初子午线(英国格林尼治天文台)为界,东边为正数,西边为负数。Redis 在 3.2 版本中增加了 GEO 类型用于存储和查询地理位置,关于 GEO 的命令不多,主要包含以下 6 个:geoadd:添加地...原创 2020-10-28 16:09:52 · 395 阅读 · 0 评论 -
优秀的基数统计算法——HyperLogLog
为什么要使用 HyperLogLog?在我们实际开发的过程中,可能会遇到这样一个问题,当我们需要统计一个大型网站的独立访问次数时,该用什么的类型来统计?如果我们使用 Redis 中的集合来统计,当它每天有数千万级别的访问时,将会是一个巨大的问题。因为这些访问量不能被清空,我们运营人员可能会随时查看这些信息,那么随着时间的推移,这些统计数据所占用的空间会越来越大,逐渐超出我们能承载最大空间。例...原创 2020-10-28 16:09:52 · 506 阅读 · 0 评论 -
游标迭代器(过滤器)——Scan
一个问题引发的「血案」曾经发生过这样一件事,我们的 Redis 服务器存储了海量的数据,其中登录用户信息是以 user_token_id 的形式存储的。运营人员想要当前所有的用户登录信息,然后悲剧就发生了:因为我们的工程师使用了 keys user_token_* 来查询对应的用户,结果导致 Redis 假死不可用,以至于影响到线上的其他业务接连发生问题,然后就收到了一堆的系统预警短信。并且这个...原创 2020-10-28 16:09:53 · 448 阅读 · 0 评论 -
内存淘汰机制与算法
在本文开始之前,我们先要明白:在 Redis 中,过期策略和内存淘汰策略两个完全不同的概念,但很多人会把两者搞混。首先,Redis 过期策略指的是 Redis 使用那种策略,来删除已经过期的键值对;而 Redis 内存淘汰机制指的是,当 Redis 运行内存已经超过 Redis 设置的最大内存之后,将采用什么策略来删除符合条件的键值对,以此来保障 Redis 高效的运行。过期策略前面的文章,我...原创 2020-10-28 16:09:53 · 663 阅读 · 0 评论 -
消息队列——发布订阅模式
在 Redis 中提供了专门的类型:Publisher(发布者)和 Subscriber(订阅者)来实现消息队列。在文章开始之前,先来介绍消息队列中有几个基础概念,以便大家更好的理解本文的内容。首先,发布消息的叫做发布方或发布者,也就是消息的生产者,而接收消息的叫做消息的订阅方或订阅者,也就是消费者,用来处理生产者发布的消息。除了发布和和订阅者,在消息队列中还有一个重要的概念:channe...原创 2020-10-28 16:09:54 · 1643 阅读 · 0 评论 -
消息队列的其他实现方式
在 Redis 5.0 之前消息队列的实现方式有很多种,比较常见的除了我们上文介绍的发布订阅模式,还有两种:List 和 ZSet 的实现方式。List 和 ZSet 的方式解决了发布订阅模式不能持久化的问题,但这两种方式也有自己的缺点,接下来我们一起来了解一下,先从 List 实现消息队列的方式...原创 2020-10-28 16:09:54 · 376 阅读 · 0 评论 -
消息队列终极解决方案——Stream(上)
在 Redis 5.0 Stream 没出来之前,消息队列的实现方式都有着各自的缺陷,例如:发布订阅模式 PubSub,不能持久化也就无法可靠的保存消息,并且对于离线重连的客户端不能读取历史消息的缺陷;列表实现消息队列的方式不能重复消费,一个消息消费完就会被删除;有序集合消息队列的实现方式不能存储相同 value 的消息,并且不能阻塞读取消...原创 2020-10-28 16:09:55 · 434 阅读 · 0 评论 -
消息队列终极解决方案——Stream(下)
在开始使用消息分组之前,我们必须手动创建分组才行,以下是几个和 Stream 分组有关的命令,我们先来学习一下它的使用。消息分组命令创建消费者群组127.0.0.1:6379> xgroup create mq group1 0-0 OK相关语法: xgroup create stream-key group-key ID其中:mq 为&n...原创 2020-10-28 16:09:55 · 242 阅读 · 0 评论 -
实战:分布式锁详解与代码
什么是锁?锁是一种常用的并发控制机制,用于保证一项资源在任何时候只能被一个线程使用,如果其他线程也要使用同样的资源,必须排队等待上一个线程使用完。锁的示意图,如下所示:什么是分布式锁?上面说的锁指的是程序级别的锁,例如 Java 语言中的 synchronized 和 ReentrantLock 在单应用中使用不会有任何问题,但如果放到分布式环境下...原创 2020-10-28 16:09:55 · 282 阅读 · 0 评论 -
实战:布隆过滤器安装与使用及原理分析
我们前面有讲到过 HyperLogLog 可以用来做基数统计,但它没提供判断一个值是否存在的查询方法,那我们如何才能查询一个值是否存在于海量数据之中呢?如果使用传统的方式,例如 SQL 中的传统查询,因为数据量太多,查询效率又低有占用系统的资源,因此我们需要一个优秀的算法和功能来实现这个需求,这是我们今天要讲的——布隆过滤器。开启布隆过滤器在 ...原创 2020-10-28 16:09:57 · 437 阅读 · 0 评论 -
完整案例:实现延迟队列的两种方法
延迟队列是指把当前要做的事情,往后推迟一段时间再做。延迟队列在实际工作中和面试中都比较常见,它的实现方式有很多种,然而每种实现方式也都有它的优缺点,接下来我们来看。延迟队列的使用场景延迟队列的常见使用场景有以下几种:超过 30 分钟未支付的订单,将会被取消外卖商家超过 5 分钟未接单的订单,将会被取消在平台注册但 30 天内未登录的用户,发短信提醒等类似的应用...原创 2020-10-28 16:09:57 · 2069 阅读 · 0 评论 -
实战:定时任务案例
我在开发的时候曾经遇到了这样一个问题,产品要求给每个在线预约看病的患者,距离预约时间的前一天发送一条提醒推送,以防止患者错过看病的时间。这个时候就要求我们给每个人设置一个定时任务,用前面文章说的延迟队列也可以实现,但延迟队列的实现方式需要开启一个无限循环任务,那有没有其他的实现方式呢?答案是肯定的,接下来我们就用 Keyspace Notifications(键空间通知)来实现定时任务,定时任务...原创 2020-10-28 16:09:58 · 604 阅读 · 0 评论 -
实战:RediSearch 高性能的全文搜索引擎
RediSearch 是一个高性能的全文搜索引擎,它可以作为一个 Redis Module(扩展模块)运行在 Redis 服务器上。RediSearch 主要特性如下:基于文档的多个字段全文索引高性能增量索引文档排序(由用户在索引时手动提供)在子查询之间使用 AND 或 NOT 操作符的复杂布尔查询可选的查询子句基于前缀的搜索支持字段权重设置自动完成建议(带有模糊前缀建议)精...原创 2020-10-28 16:09:58 · 3792 阅读 · 0 评论 -
实战:Redis 性能测试
为什么需要性能测试?性能测试的使用场景有很多,例如以下几个:技术选型,比如测试 Memcached 和 Redis;对比单机 Redis 和集群 Redis 的吞吐量;评估不同类型的存储性能,例如集合和有序集合;对比开启持久化和关闭持久化的吞吐量;对比调优和未调优的吞吐量;对比不同 Redis 版本的吞吐量,作为是否升级的一个参考标准。等等,诸如此类的情况,我们都需要进行性能测...原创 2020-10-28 16:09:59 · 512 阅读 · 0 评论 -
实战:Redis 慢查询
Redis 慢查询作用和 MySQL 慢查询作用类似,都是为我们查询出不合理的执行命令,然后让开发人员和运维人员一起来规避这些耗时的命令,从而让服务器更加高效和健康的运行。对于单线程的 Redis 来说,不合理的使用更是致命的,因此掌握 Redis 慢查询技能对我们来说非常的关键。如何进行慢查询?在开始之前,我们先要了解一下 Redis 中和慢查询相关的配置项,Redis 慢查询重要的配置项有...原创 2020-10-28 16:09:59 · 265 阅读 · 0 评论 -
实战:Redis 性能优化方案
Redis 是基于单线程模型实现的,也就是 Redis 是使用一个线程来处理所有的客户端请求的,尽管 Redis 使用了非阻塞式 IO,并且对各种命令都做了优化(大部分命令操作时间复杂度都是 O(1)),但由于 Redis 是单线程执行的特点,因此它对性能的要求更加苛刻,本文我们将通过一些优化手段,让 Redis 更加高效的运行。本文我们将使用以下手段,来提升 Redis 的运行速度:缩短键...原创 2020-10-28 16:09:59 · 1633 阅读 · 0 评论 -
实战:Redis 主从同步
主从同步(主从复制)是 Redis 高可用服务的基石,也是多机运行中最基础的一个。我们把主要存储数据的节点叫做主节点 (master),把其他通过复制主节点数据的副本节点叫做从节点 (slave),如下图所示:在 Redis 中一个主节点可以拥有多个从节点,一个从节点也可以是其他服务器的主节点,如下图所示:主从同步的优点主从同步具有以下三个优点:性能方面:有了主从同步之后,可以把查询...原创 2020-10-28 16:10:00 · 285 阅读 · 0 评论 -
实战:Redis哨兵模式(上)
上一篇我们讲了主从复制模式,它是属于 Redis 多机运行的基础,但这种模式本身存在一个致命的问题,当主节点奔溃之后,需要人工干预才能恢复 Redis 的正常使用。例如,我们有 3 台服务器做了主从复制,一个主服务器 A 和两个从服务器 B、C,当 A 发生故障之后,需要人工把 B 服务器设置为主服务器,同时再去 C 服务器设置成从服务器并且从主服务器 B 同步数据,如果是发生在晚上或者从服务器...原创 2020-10-28 16:10:00 · 218 阅读 · 0 评论 -
实战:Redis 哨兵模式(下)
上一篇我们介绍了 Redis Sentinel 的搭建和运行原理,本文我们重点来看下 Sentinel 的命令操作和代码实战。Sentinel 命令操作要使用 Sentinel 实现要连接到 Sentinel 服务器,和连接 Redis 服务相同,我们可以使用 redis-cli 来连接 Sentinel,如下命令所示:[@iZ2ze0nc5n41zomzyqtksmZ:~]$ redis-...原创 2020-10-28 16:10:01 · 302 阅读 · 0 评论 -
实战:Redis 集群模式(上)
Redis Cluster 是 Redis 3.0 版本推出的 Redis 集群方案,它将数据分布在不同的服务区上,以此来降低系统对单主节点的依赖,并且可以大大的提高 Redis 服务的读写性能。Redis 将所有的数据分为 16384 个 slots(槽),每个节点负责其中的一部分槽位,当有 Redis 客户端连接集群时,会得到一份集群的槽位配置信息,这样它就可以直接把请求命令发送给对应的节点...原创 2020-10-28 16:10:01 · 208 阅读 · 0 评论 -
实战:Redis 集群模式(下)
上篇文章我们讲了 Redis 集群的搭建与节点的动态添加和删除,我们这里再来简单的复习一下,其中 30001~30006 是我们最初搭建的集群,而 30007 和 30008 是后面动态添加的主从节点,我们使用 --cluster info 命令来看一下主节点和槽位的分配情况,执行代码如下:$ redis-cli --cluster info 127.0.0.1:30001127.0.0.1:...原创 2020-10-28 16:10:02 · 240 阅读 · 0 评论 -
案例:Redis 问题汇总和相关解决方案
本文收集了一些 Redis 使用中经常遇到的一些问题,和与之相对应的解决方案,这些内容不但会出现在实际工作中,也是面试的高频问题,接下来一起来看。缓存雪崩缓存雪崩是指在短时间内,有大量缓存同时过期,导致大量的请求直接查询数据库,从而对数据库造成了巨大的压力,严重情况下可能会导致数据库宕机的情况叫做缓存雪崩。我们先来看下正常情况下和缓存雪崩时程序的执行流程图,正常情况下系统的执行流程如下图所示...原创 2020-10-28 16:10:02 · 231 阅读 · 0 评论 -
技能学习指南
经过前面文章的学习,我相信一定有一半的人看懂了,而另一半人一定是似懂非懂或者是完全不懂,如果你属于前者,那恭喜你,但如果没看懂,也没关系,本文来给你具体的解决方案。我们来仔细回忆两件事,第一件是大学考级学的那些英语,我每个单词每个语句当时都背的滚瓜烂熟,那时候你也以为这些东西你都会了吧?但你现在还能记起多少呢?我们再来回忆一下,我们小的时候学习骑自行车的本领,即使相隔很多年,但依旧没能忘记,这...原创 2020-10-28 16:10:03 · 266 阅读 · 0 评论 -
加餐:Redis 的可视化管理工具
因为 Redis 官方只提供了命令行版的 Redis 客户端 redis-cli,以至于我们在使用的时候会比较麻烦,通常要输入一堆命令,而且命令行版的客户端看起来也不够直观,基于以上两个原因我们需要找一个可视化的 Redis 客户端,下面是我这些年使用过的一些 Redis 可视化客户端,分享给大家。RedisClient是否收费:免费。项目介绍:Java 编写的 Redis 连接客户端,功能...原创 2020-10-28 16:10:03 · 262 阅读 · 0 评论 -
附录:更多字符串操作命令
键值对过期操作a.添加键值对并设置过期时间语法:set key value [expiration EX seconds|PX milliseconds] [NX|XX]示例:127.0.0.1:6379> set k1 val1 ex 1000OK设置键值对 k1=val1,过期时间为 1000 秒。查询键的过期时间可以使用 ttl key,如下代码所示:127.0.0....原创 2020-10-28 16:10:04 · 240 阅读 · 0 评论 -
附录:更多字典操作命令
插入一个或多个元素语法:hmset key field value [field value …]示例:127.0.0.1:6379> hmset myhash k1 val1 k2 val2OK127.0.0.1:6379> hmget myhash k1 k21) "val1"2) "val2"查询一个或多个元素语法:hmget key field [field...原创 2020-10-28 16:10:04 · 192 阅读 · 0 评论