redis
文章平均质量分 95
持续输出 redis 系列文章,从应用实战到原理分析,再到底层源码解读,带你一步步吃透 redis。
另外,后期准备出 redis 面试专题解读,持续关注吧 ~
柏油
不负冬日春晓 不负青春韶华
展开
-
redis 副本机制 - 高可用的保障?
前面的系列文章我们聊了 redis 持久化机制,尽可能的保障少丢数据。那么,如何保障服务的高可用呢?相信你也想到了,`副本机制`。副本,也就是我们常说的主从模式,从节点通过全量或增量的方式从主节点同步数据。一般情况下,从节点可以作为只读节点对外提供服务,也可以仅作为主节点的备份节点;当主节点故障挂掉之后,提升从节点为主节点,并对外提供无间断服务。本文主要探讨,redis 副本数据同步的过程以及相关原理介绍,至于如何做到主节点故障后,从节点自动切换为主节点?我们将通过后面的文章在进行分析。...原创 2022-07-11 22:39:32 · 1018 阅读 · 0 评论 -
redis 持久化原理,原理 + 应用
前言本文参考源码版本为 redis6.2我们先来看看演进这个事儿。软件都是迭代中越做越复杂。redis 也是这样,刚开始做了一个简单功能,通过一定的数据结构组织数据,让你能够相当快的拿到这些数据;慢慢地,场景越来越多,想要的功能支持越来越强烈;好,redis 慢慢给你实现。以上,是功能上的迭代演进,性能上呢?首先,我要处理客户端的请求,按照服务端 socket 编程几个步子写,相当容易;写好之后,你说不行,QPS 至少 1W+;于是,继续.........原创 2022-06-30 22:46:03 · 1212 阅读 · 0 评论 -
redis 6.0之多线程,深入解读
前言一般来说,一个 redis 请求有两大模块,网络模块 + 命令处理模块。我们常说的 redis 单线程模型,其实主要就是值的一个正常请求涉及的网络模块和命令处理模块。当然,两者都有可能出现问题,我们分别来看看:当一个执行一个特别慢的命令时,比如删除一个百万级的字典,可能会造成暂时的卡.原创 2022-05-31 21:31:53 · 12688 阅读 · 13 评论 -
高性能网络编程之 Reactor 网络模型(彻底搞懂)
网络框架的设计离不开 I/O 线程模型,线程模型的优劣直接决定了系统的吞吐量、可扩展性、安全性等。目前主流的网络框架几乎都采用了 I/O 多路复用的方案。Reactor 模式作为其中的事件分发器,负责将读写事件分发给对应的读写事件处理者。大名鼎鼎的 Java 并发包作者 Doug Lea,在 Scalable I/O in Java 一文中阐述了服务端开发中 I/O 模型的演进过程。Netty 中三种 Reactor 线程模型也来源于这篇经典文章有助于分担 Reactor 线程的压力。原创 2022-04-26 23:38:14 · 6755 阅读 · 10 评论 -
I/O多路复用模型之 select、poll、epoll
Redis 作为一个 Client-Server 架构的数据库,其源码中少不了用来实现网络通信的部分。而你应该也清楚,通常系统实现网络通信的基本方法是使用 Socket 编程模型,**包括创建 Socket、监听端口、处理连接请求和读写请求**。但是,由于基本的 **Socket 编程模型一次只能处理一个客户端连接上的请求**,所以当要处理高并发请求时,一种方案就是使用多线程,让每个线程负责处理一个客户端的请求。而 Redis 负责客户端请求解析和处理的线程只有一个,那么如果直接采用基本 Socke原创 2022-04-20 23:29:24 · 4714 阅读 · 3 评论 -
Redis 核心原理串讲(下),架构演进之高扩展
本文围绕「架构主线」来透视 Redis「高可靠」的核心原理,在正文开始之前,我们先思考几个问题: - 数据要如何切分,在扩缩容过程迁移量最小? - 分片元数据如何维护?中心化 or 去中心化? - 如何平滑的从单机版升级到 cluster 集群版原创 2023-01-31 22:23:53 · 335 阅读 · 0 评论 -
Redis 核心原理串讲(中),架构演进之高可用
本文围绕「架构主线」来透视 Redis「高可靠」的核心原理,在正文开始之前,我们先思考几个问题:- Redis 数据丢失风险?- 持久化机制会拖慢 Redis 吗? - fork 子进程是否会阻塞主线程?不用 fork 操作行不行? - 有了持久化还需要副本机制? - 能不能自己写个 HA 来代替 Redis 哨兵?原创 2023-01-09 07:15:00 · 356 阅读 · 0 评论 -
Redis 核心原理串讲(上),从一条请求透视高性能的本质
本文围绕「请求主线」透视 Redis 高性能的核心原理,在正文开始之前我们先思考几个问题:- Redis 为什么节省内存又高效?- 同步/异步、阻塞/非阻塞有什么区别?- 删除一个百万级数据的 hash 字典会阻塞吗?- Redis6.0 的多线程需要考虑并发问题吗?原创 2022-12-26 22:39:35 · 392 阅读 · 0 评论 -
为什么要选择 Redis?
Redis(Remote Dictionary Server),即「远程字典服务」是一个使用 ANSI C 编写的、开源的、支持网络的、基于内存的、可选持久化的键值对存储系统。在 2013 年 5 月之前,Redis 的开发由 VMware 赞助,2013 年 5 月至 2015 年 6 月,由 Pivotal 赞助,从 2015 年 6 月起,Redis 的开发由 Redis Labs 赞助。根据数据库使用排行网站 db-engines.com 上的排名,Redis 是`目前最流行`的键值对存原创 2022-12-05 22:21:00 · 452 阅读 · 0 评论 -
Redis 源码该怎么读?(译文)
当你阅读 `README` 文档时,不管是通过 GitHub 页面上还是下载 Redis 分支源码等方式,离源码仅一步之遥,因此,我们在这里对 Redis 源码做粗略讲解,你会看到:翻译 2022-11-20 16:45:59 · 434 阅读 · 0 评论 -
Redis release cycle(译文)
Redis 新版本如何发布的?Redis 是系统软件,并且是处理用户数据的软件,也就是说,它处于软件栈关键的一环上。翻译 2022-11-09 08:12:27 · 297 阅读 · 0 评论 -
Redis数据结构为什么既省内存又高效?Redis 数据类型 + 数据结构超全指南
**Redis 数据结构为什么既高效又节省内存?**永恒的问题 ------ `空间`与`时间`的较量1)节省内存: - 一般通过特定的编码约定,将数据进行压缩,比如 ziplist、quicklist、listpack ..., - 还有,比如一些只包含数字的字符串可以通过 int 来存储(int 通常有 2字节、4字节、8字节) ,对应 redis 的 intset 结构 ... - 另外,把大家可能都有的部分抽取出来公用也是一种手段,比如 radix 前缀树、共享对象 ...原创 2022-10-24 07:42:39 · 634 阅读 · 0 评论 -
redis HyperLogLog,看这篇就够了
考虑这样一个场景,如何统计一个大型网站的去重日活、月活用户(UV)?你可以通过 set 集合、bitmap 这类常用工具,但有个最大的缺点是,如果数据量巨大,比如 1 亿,甚至 10 亿将耗费巨大内存消耗。有人研究出了这样一种算法叫 `HyperLogLog`,是一种概率性的统计算法,每个 `HyperLogLog` 对象最大占用空间为 `12KB`,相当节省内存。你应该也猜到了,这么小的内存消耗,是无法记录真实的明细数据,统计数值也不是完全精准,有一定的误差比例。原创 2022-10-18 11:30:00 · 5548 阅读 · 0 评论 -
redis 过期删除策略、惰性删除(lazy-free),深入剖析
如果一个键过期了,什么时候会被删除呢?又如何找出这些过期 key 并删除?会不会影响服务正常运行?redis 中有两种 key,一种带有 expire 过期时间,另一种则是不带过期时间,本文讨论的过期删除策略是针对带有 expire 过期时间的 key。为了方便找出带过期时间并且已经过期的 key,redis 用了额外的字典专门存储带 expire 过期时间的 key,这样一来,只需遍历该字典即可找出过期的 key。原创 2022-10-11 07:15:00 · 3025 阅读 · 2 评论 -
redis 通信协议(RESP),最简单的应用层协议,没有之一
所谓 `协议`,本质是一种约定,需要使用者双方来准守,常见于 `C/S 通信模式`中,比如在浏览器中最常用的 `HTTP` 应用层通信协议。通信两端需要某种约定,才能保持正常通信。一端通过约定的格式发送数据,另一端通过约定的格式解析数据,这种约定,取了一个好听的名字 ---- `协议`。典型的 HTTP 协议,最本质的原理也是如此。redis 作为一款高性能内存组件,要尽可能将精力花在数据的组织形式上,因此,没有采用开源的一些复杂协议,比如 HTTP,而是简单的自定义一套应用层通信协议。原创 2022-09-19 12:00:00 · 4966 阅读 · 0 评论 -
【Redis 实战】dump.rdb、appendonly.aof 文件路径
本文是实战性文章,带大家一起找找 `dump.rdb` 和 `apendonly.aof` 文件的路径。redis 服务在启动时有两种方式,既可以指定配置文件,也可以不指定配置文件。原创 2022-09-18 09:10:05 · 4366 阅读 · 0 评论 -
Redis 内存淘汰策略,从根儿上理解
Redis 基于内存设计,所有数据存放在内存,随着时间推移,内存占用也越来也高 ...由于内存容量这个物理限制,我们需要在内存使用量达到一定比例后,做一些内存清理工作,以保证有足够的空间来完成正常的处理。在 Redis 中,完成这个工作的就是本文的主角 ------- Redis 内存淘汰机制。 - 一定比例:在 redis 中就是 maxmemory 阈值 - 淘汰策略:在 redis 中目前有两种流行的算法:LRU 与 LFU 算法原创 2022-09-13 07:15:00 · 404 阅读 · 0 评论 -
redis 事务,深入解读
事务,古老而神秘的词汇,说起它,你应该能想起它的四大特性:原子性、隔离性、持久性和一致性。我们先往简单了想,事务解决了什么问题?确保一揽子修改操作的 `正确性` 和 `一致性`。事务需要做什么?本质是做了两件事,`控制并发` 和 `故障恢复`。redis 也提供了事务功能,不过,基于 redis 的一些特性,会在传统事务特性上做了一些宽松处理,也就是说,redis 的事务并非传统意义上的 “严格型事务”。我们先来回忆下,事务的的四大特性及其概念:`原子性`:一批操作要么一起成功,要么一起原创 2022-08-22 07:15:00 · 376 阅读 · 0 评论 -
redis 管道(pipeline),深入解读
管道,你肯定不陌生,你家里的自来水管、天然气管等,应用相当广泛。这些管道有啥特点?传输特定的物质、流式,.... 等等。我们知道,redis 是 C/S 模式,即客户端 + 服务端。当两端想要通信时,需要先建立特定的 TCP 握手连接,在进行通信时,采用 发送请求 -> 等待响应 这种`一问一答`模式。当然,这种一问一答模式在 redis 中应用非常广泛,可以说,绝大部分都是这种场景。但是,还是会存在一些特殊的场景,这个时候,我们可能更需要通过`批量`的方式来处理。比如,在一个接口或者某个操作中原创 2022-08-15 18:00:00 · 3603 阅读 · 2 评论 -
redis 发布订阅(PubSub),深入解读
发布订阅模式,本质来说,是将提供消息的人和需要消息的人,通过第三方组件联系起来,使得两类群体之间的消息能够及时触达。举例看看,在一些优化场景下,可能会使用 本地 + 远程 双缓存机制,远程缓存是一套共用的中间件,总共只有一套数据。而 本地缓存就不一样了,如果你部署的是多个实例,那就有多套本地数据,当数据更新了,如何触达这些本地缓存?这个时候,你就可以考虑使用发布订阅模式,消息提供者 - 更新数据的人,消息接收方 - 需要更新本地缓存的服务。我们以 redis 发布订阅的实现来看,其实是非常简单的原创 2022-08-04 07:53:20 · 7901 阅读 · 0 评论 -
分布式限流利器,小试牛刀
限流,是网站防止流量洪峰的必要手段,尤其是一些重要资源的处理,甚为重要。限流的核心目的自然是保障网站的正常运行,避免处理超过网站自身的流量,压死骆驼的最后一个稻草,你懂得。常见的限流算法有 `计数器`、`漏桶算法` 和 `令牌算法`。在之前的文章已经做过分析,有兴趣可以[详情查看](https://blog.csdn.net/ldw201510803006/article/details/83717870?spm=1001.2014.3001.5501)本文主要分析令牌桶算法,令牌桶有哪些特点?原创 2022-07-31 16:57:02 · 2437 阅读 · 0 评论 -
Redisson解决Redis分布式锁提前释放问题
项目场景:提示:这里简述项目相关背景:例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大)问题描述:提示:这里描述项目中遇到的问题:例如:数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据APP 中接收数据代码:@Override public void run() { bytes = mmInStream.read(buffer); mHandler.obtainMessage(READ_DATA, bytes,原创 2021-06-19 16:28:58 · 3589 阅读 · 3 评论 -
如何使用Redis实现分布式锁?
文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport warn...原创 2021-06-26 22:59:00 · 1497 阅读 · 1 评论 -
redis cluster 集群,终极方案?
前面系列文章,我们聊了 redis 主从模式、哨兵模式,这些都是单节点的高可用保障,受限于单机内存,另外,由于 redis 持久化的特性,单个 redis 实例的内存不宜过大。分布式存储的终极解决方案是什么?`加机器`。一台不够加两台、三台,直到足够撑起你的业务。因此,redis 也提出了集群版的解决方案。本质来说就是将数据尽可能`均分`到多个节点服务,这些节点可以同时对外提供服务,这样一来,集群模式既提高了整体存储容量,又提高了整体吞吐量。那这些数据如何进行切片分配呢?按关键字区间还是 关键字原创 2022-07-28 08:10:20 · 309 阅读 · 0 评论 -
redis 哨兵,高可用的执行者
哨兵是啥?站岗、放哨、巡逻之人,这种模式在生活中也十分常见,军队、安保、押运等等,都需要时刻注意周边异样,并及时作出响应。redis 哨兵也是如此。前面文章我们分析了 redis 副本机制,本质就是多个数据副本,为防止单副本故障而生。在 redis 服务遇到故障崩溃时,我们可以通过切换副本节点对外提供服务,你可以写一些脚本,做到一键切换,十分方便;前提是,需要人为判断是否需要故障切换,在工作时间遇到可能还能忍受,要是凌晨两三点呢?所以,我们可以选择更加智能一些,比如,你想继续写一个自动检测故障的原创 2022-07-20 22:39:01 · 1113 阅读 · 0 评论 -
Redis 6.0之前真的是单个线程吗?面试官:看来你只会背面试题
我们常说 redis 是`单线程模型`,一般是指正常的`请求处理` + `周期任务`。其中:- 处理请求包括:包括接收连接、IO监听/读/写以及命令执行。- 周期任务,如删除过期key、字典 rehash 等。其实,还有一些非常耗时的操作,redis 通过专用的线程来处理,这里的`专用线程`,便是我们这篇文章的主角,我们接着往下看~原创 2022-05-23 08:00:00 · 675 阅读 · 2 评论 -
Redis事件驱动框架(下),时间事件&文件事件详解
redis 服务器是典型的事件驱动程序,而事件又分为`文件事件`(socket 的可读/可写事件)与`时间事件`(定时任务)两大类。无论是文件事件还是时间事件都封装在结构体 `aeEventLoop`中。原创 2022-05-15 20:41:56 · 823 阅读 · 3 评论 -
一文搞懂,redis单线程执行全貌(深入拆解分析)
redis 6.0 版本之前,采用的是单线程模型,即:一个线程既要负责命令读写、解析,又要负责命令执行。但是,仍然能达到极高的并发能力,其终极法宝是`优秀的IO模型 + 纯内存操作 + 优秀的数据结构及算法的设计`。redis6.0 及之后的版本,引入了多线程模型,主要目的是`分担主线程的压力`,负责部分IO事件读写、解析的工作;但是,命令执行仍然都由主线程处理。原创 2022-05-04 16:28:54 · 3360 阅读 · 3 评论 -
redis scan 命令底层原理(为什么会重复扫描?)
`迭代器`——可在容器(容器可为字典、链表等数据结构)上遍访的接口,设计人员无须关心容器的内容,调用迭代器固定的接口就可遍历数据,在很多高级语言中都有实现。字典迭代器主要用于迭代字典这个数据结构中的数据,既然是迭代字典中的数据,必然会出现一个问题,迭代过程中,如果发生了`数据增删`,则可能导致字典触发 `rehash` 操作,或迭代开始时字典正在进行 rehash 操作,从而导致一条数据可能`多次遍历`到。原创 2022-04-12 09:54:01 · 2966 阅读 · 0 评论 -
redis 字典(dict)深入分析(抓住两个核心要点)
字典又称散列表,是用来存储键值(key-value)对的一种数据结构,在很多高级语言中都有实现,如 PHP 的数组。但是 C 语言没有这种数据结构,Redis 是 K-V 型数据库,整个数据库是用字典来存储的,对 Redis 数据库进行任何增、删、改、查操作,实际就是对字典中的数据进行增、删、改、查操作。原创 2022-04-06 08:23:26 · 2288 阅读 · 2 评论 -
redis之SDS字符串,到底高效在哪里?(全面分析)
Redis 只会使用 C 字符串作为字面量,在大多数情况下,Redis 使用SDS(`Simple Dynamic String,简单动态字符串`)作为字符串表示。SDS 的出现是为了解决 C 字符串在 Redis `三高` 场景下的不足,分别有 `安全性`、`效率`以及`功能`等方面。原创 2022-03-27 19:00:33 · 2339 阅读 · 0 评论 -
redis之intset整数集合,还是内存优化?
整数集合(intset)是一个`有序的`、`存储整型`数据的结构。我们知道 redis 是一个内存数据库,所以必须考虑如何能够高效地利用内存。当 redis 集合类型的元素都是整数并且都处在64位有符号整数范围之内时,使用该结构体存储。原创 2022-03-21 20:45:00 · 711 阅读 · 0 评论 -
redis zskiplist跳表,性能堪比红黑树?(深度分析)
`跳表`(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。跳跃表支持`平均O(logN)`、`最坏O(N)`复杂度的节点查找,还可以通过顺序性操作来批量处理节点。在大部分情况下,跳跃表的效率可以和`平衡树`相媲美,并且因为跳跃表的实现比平衡树要来得更为简单,所以有不少程序都使用跳跃表来代替平衡树。原创 2022-03-14 21:51:31 · 2682 阅读 · 0 评论 -
Stream:redis5.0 定制版消息队列底层实现(长文)
redis 从 5.0 版本开始支持提供 stream 数据类型,它可以用来保存消息数据,进而能帮助我们实现一个带有消息读写基本功能的消息队列,并用于日常的分布式程序通信当中。其中,为了节省内存空间,在 stream 数据类型的底层数据结构中,采用了 `radix tree` 和 `listpack` 两种数据结构来保存消息。listpack 是一个`紧凑型列表`,在保存数据时会非常节省内存;radix tree,这个数据结构的最大特点是适合保存具有`相同前缀`的数据,从而实现节省内存空间的目标,以及支原创 2022-02-28 23:42:50 · 1336 阅读 · 0 评论 -
redis消息队列,你还不敢用?
消息队列要能支持组件通信消息的快速读写,而 Redis 作为一款常用的缓存组件,本身支持数据的高速访问,正好可以满足消息队列的读写性能需求。不过,除了性能,消息队列还有其他的要求,所以,很多人都很关心一个问题:“Redis 适合做消息队列吗?”其实,这个问题的背后,隐含着两方面的核心问题:- 消息队列适用场景?有哪些设计要点?- Redis 如何实现消息队列的需求?原创 2022-02-19 18:32:42 · 1566 阅读 · 0 评论 -
深入分析redis之rax底层原理,前缀树?
Radix Tree 是属于 前缀树 的一种类型。前缀树也称为 Trie Tree,其特点是,保存在树上的每个 key 会被拆分成单字符,然后逐一保存在树上的节点中。前缀树的根节点不保存任何字符,而除了根节点以外的其他节点,每个节点只保存一个字符。当把从根节点到当前节点的路径上的字符拼接在一起时,就可以得到相应 key 的值了。不同的是,rax 在前缀树上做了一些优化原创 2022-01-16 12:15:45 · 2507 阅读 · 2 评论 -
深入分析redis之listpack,取代ziplist?
从 ziplist 到 quicklist,再到 listpack 结构;可以看到,初衷都是设计一款数据结构能够高效的使用内存。ziplist 设计出的紧凑型数据块可以有效利用内存,但在更新上,由于每一个 entry 都保留了前一个 entry 的 prevlen 长度,因此在插入或者更新时可能会出现连锁更新,这是一个影响效率的大问题。因此,接着又设计出 「链表 + ziplist」组成的 quicklist 结构来避免单个 ziplist 过大,可以有效降低连锁更新的影响面。原创 2022-01-11 22:18:18 · 5970 阅读 · 7 评论 -
深入分析redis之quicklist,不一样的ziplist使用方式?
基于ziplist存在的问题,要避免ziplist列表太大问题,因此将大ziplist分成一系列小的ziplist是一种思路。quicklist是由链表组成的结构,其中每个链表节点中都存在一个ziplist。是由ziplist改进而来,充分利用链表 + ziplist特性原创 2022-01-08 21:13:06 · 2405 阅读 · 0 评论 -
redis压缩列表ziplist,内存优化之路?
文章目录前言ziplist 中列表项结构解决问题应用场景存在问题总结前言ziplist 中列表项结构ziplist 列表项包括三部分内容,分别是前一项的长度(prevlen)、当前项长度信息的编码结果(encoding),以及当前项的实际数据(data)所谓的编码技术,就是指用不同数量的字节来表示保存的信息。在 ziplist 中,编码技术主要应用在列表项中的 prevlen 和 encoding 这两个元数据上。而当前项的实际数据 data,则正常用整数或是字符串来表示解决问题内存紧凑型列原创 2022-01-05 23:05:16 · 1838 阅读 · 0 评论