图解Redis 01 | 初识Redis

什么是 Redis?

Redis 是一种基于内存的数据库,所有的数据读写操作都在内存中完成,因此读写速度非常快。它被广泛应用于缓存、消息队列、分布式锁等场景。

Redis 提供了多种数据类型来支持不同的业务需求,如 String、Hash、List、Set、Zset、Bitmaps、HyperLogLog、GEO、Stream 等。Redis 对这些数据类型的操作都是原子的——因为Redis是单线程架构,一条命令的执行是由单个线程完成,不会出现并发竞争的问题。

除了基本的数据存储功能,Redis 还支持事务、持久化、Lua 脚本、多种集群方案(包括主从复制模式、哨兵模式和分片集群模式)、发布/订阅模式、内存驱逐机制以及过期删除机制等一些高级特性,进一步增强了其功能和应用场景的多样性。

Redis 和 Memcached 有什么区别?

很多人常建议用Redis做缓存,但是Memcached同样是基于内存的非关系型数据库,为什么Redis的使用场景更多呢?

要回答这个问题,我们需要搞清楚Redis和Memcached的区别。Redis与Memcached主要有以下区别:

1. 支持的数据类型
  • Redis不仅仅支持简单的String键值对存储,还提供了Hash、List、Set、Zset等多种复杂的数据结构,可以满足更复杂的数据存储场景需求。
  • Memcached主要是简单的键值对存储。
2. 持久化
  • Redis支持数据持久化,可以将数据保存到磁盘,从而保证数据在Redis发生故障后能够恢复。
  • Memcached通常不具备数据持久化功能,数据只存在于内存中。服务器重启后数据会丢失。
3. 内存管理
  • Redis具有更加灵活的内存管理策略和机制,可以配置和优化内存使用方式,以适应不同的应用场景,这一点在后面会详细的介绍。
  • Memcached在内存管理方面比较简单。
4. 性能特点:
  • 在一些特定场景下,Memcached可能在简单的键值对操作中展现出极高的性能。
  • Redis在综合性能、功能多样性方面具有优势。
5. 应用场景
  • Memcached比较适合缓存比较简单的数据。
  • Redis可以应用在更广泛的场景,比如缓存,消息队列,分布式锁等等。

可以看出,当只需快速缓存简单的键值对时,Memcached 可能是更好的选择;而在需要处理复杂数据结构且存在持久化需求的情况下,Redis 则更为合适。在实际应用中,应该根据具体的需求和场景来选择合适的缓存方案。

Redis 支持的数据类型

Redis 提供了丰富多样的数据类型,其中常见的五种类型包括:String、Hash、List、Set 和 Zset。注意这里说的数据类型指的是value的类型,因为key的类型永远只有String这一种类型。

在后续版本中,Redis 还新增了四种数据类型:BitMap(2.2 版本)、HyperLogLog(2.8 版本)、GEO(3.2 版本)以及 Stream(5.0 版本)。

各种数据类型的应用场景

  • String:一般用于计数或缓存简单的键值对数据,例如用户信息、配置参数等。
  • Hash:用于存储对象信息,如一个用户的详细属性,常用于实现购物车等场景。
  • List:适用于消息队列、排行榜等。
  • Set:用于处理聚合计算(如并、交、差运算)的场景,比如点赞、共同关注、抽奖活动等。
  • Zset:适合实现带权重的排行榜或按时间排序的事件。
  • Bitmaps:用于处理二进制状态统计的场景,比如签到、判断用户登录状态、统计连续签到的用户总数等。
  • HyperLogLog:适合海量数据基数统计的场景,例如对百万级网页的 UV(独立访问用户数)进行计数。
  • GEO:用于基于位置的服务,如查找附近的商家、网约车等。
  • Stream:用于实现高级消息队列。

关于各个数据类型的指令使用方式和应用场景,会在后续的文章中一一介绍

Redis 五种常见数据类型是如何实现的?

下面是一张 Redis 数据类型与底层数据结构的对应关系图,其中左边展示的是 Redis 3.0 版本的数据类型实现,现在看来已经有些过时;右边则是 Redis 7.0 版本的数据类型实现。

下面对这些底层数据结构做一个简单的介绍,让我们有一个大致的映像,后面会写一篇文章详细剖析这些数据结构。

1. String类型内部实现

在 Redis 中,String 类型的底层数据结构主要是 SDS(Simple Dynamic String)。

SDS 与我们熟知的 C 语言字符串有所不同。相比于 C语言 原生的字符串,Redis 选择 SDS 作为实现方式有其特定原因:

  • SDS 不仅可以保存文本数据,还可以保存二进制数据。这是因为 SDS 使用 len 属性来判断字符串的结束位置,而不是依靠空字符 (‘\0’) 标记结束。同时,SDS 的所有 API 都会将 buf[] 数组中的数据作为二进制来处理。因此,SDS 不仅可以存储文本,还能存储图片、音频、视频、压缩文件等二进制数据。

  • SDS获取字符串长度的时间复杂度为O(1)。由于C语言的字符串没有记录自身的长度,所以获取长度的复杂度为O(n);而SDS结构体中的len属性记录了字符串长度,所以复杂度为O(1)。

  • Redis 的 SDS API 是安全的,拼接字符串不会导致缓冲区溢出。因为 SDS 会在拼接字符串前检查空间是否足够,如果空间不足,会自动扩展,避免缓冲区溢出的问题。

2. List类型的内部实现

List 类型的底层数据结构通过双向链表或者 ziplist实现:

  • 当列表中的元素数量小于 512 个 (默认值,可通过 list-max-ziplist-entries 配置),且每个元素的长度小于 64 字节 (默认值,可通过 list-max-ziplist-value 配置)时,Redis 会使用 ziplist 作为 List 类型的底层数据结构。

  • 如果列表中的元素不满足这些条件,Redis 则会使用双向链表 作为 List 类型的底层数据结构。

然而,从 Redis 3.2 版本开始,List 类型的底层数据结构改为仅由 quicklist 实现,取代了早期的双向链表和 ziplist。

3. Hash类型的内部实现

Hash 类型的底层数据结构通过ziplist 或者 hash table实现:

  • 当 Hash 类型的元素数量少于 512 个(默认值,可通过 hash-max-ziplist-entries 配置),且所有元素的值小于 64 字节(默认值,可通过 hash-max-ziplist-value 配置)时,Redis 会使用 ziplist 作为 Hash 类型的底层数据结构。

  • 如果 Hash 类型的元素不满足这些条件,Redis 则会使用hash table作为底层数据结构。

从 Redis 7.0 开始,ziplist 数据结构已被废弃,取而代之的是 listpack 数据结构。

4. Set 类型的内部实现

Set 类型的底层数据结构可以通过hash table整数集合实现:

  • 当集合中的所有元素都是整数且元素数量少于 512 个(默认值,可通过 set-maxintset-entries 配置)时,Redis 会使用整数集合作为 Set 类型的底层数据结构。

  • 如果集合中的元素不满足这些条件,Redis 则会使用哈希表作为 Set 类型的底层数据结构。

5. ZSet类型内部实现

ZSet 类型的底层数据结构可以通过 ziplist 或 skiplist 实现:

  • 当有序集合中的元素数量少于 128 个且每个元素的值小于 64 字节时,Redis 会使用 ziplist 作为 ZSet 类型的底层数据结构。
  • 如果有序集合的元素不满足这些条件,Redis 则会使用 skiplist 作为 ZSet 类型的底层数据结构。

从 Redis 7.0 开始,ziplist 数据结构已被废弃,取而代之的是 listpack 数据结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142624.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

环形数组与单向链表的队列实现(Queue)

什么是队列 队列是一种重要的线性数据结构,具有先进先出(FIFO)的特性。元素的插入操作称为入队,删除操作称为出队。队列在许多计算机科学应用中非常常见,如任务调度和数据缓冲等。 在实现队列时,可…

路由策略PBR

文章目录 策略路由PBR概述本地流量接口策略 策略路由 策略路由和路由策略的区别: 策略路由可以不按照路由表进行转发路由策略主要控制路由信息的引入、发布和接受等,主要靠 RIB和FIB PBR概述 比路由策略耗资源,直接跳过路由表,数…

Pytorch详解-模型模块(RNN,CNN,FNN,LSTM,GRU,TCN,Transformer)

Pytorch详解-模型模块 Module & parameterModule初认识forward函数 ParameterPytorch中的权重、参数和超参数 Module容器-ContainersSequentialModuleListModuleDictParameterList & ParameterDict 常用网络层LSTM输入和输出 GRUConvolutional Layers卷积层的基本概念常…

IP协议及相关特性

IP协议负责地址管理和路由选择。它的组成为: 接下来我们将对其中较重要的部分进行介绍。 4位版本:这里的四位版本只有两个取值 分别为IPv4和IPv6,这两个额分别为不同的IP协议,但是现在主流的还是IPv4但是近年来IPv6在中国的普及率…

linux系统如何通过进程PID号找到对应的程序在系统中的路径

linux系统如何通过进程PID号找到对应的程序在系统中的路径 首先我们用ps -aux​命令找到对应进程的PID号,比如我这里要得就是xmrig这个进程的PID号 ​​ 通过lsof命令查看对应进程的关联的文件,并找到可执行文件的路径 lsof -p 22785 | grep txt​​ 或…

棉花叶片病害检测数据集

【棉花叶片病害检测数据集】nc: 5 names: [blight, curl, healthy, wilt, wilt_png] 名称:【枯萎病, 卷叶病, 健康,萎蔫病,‘萎蔫病图像’】共3474张,8:1:1比例划分,(train;2888张,val&#xff…

MVCC机制解析:提升数据库并发性能的关键

MVCC机制解析:提升数据库并发性能的关键 MVCC(Multi-Version Concurrency Control) 多版本并发控制 。 MVCC只在事务隔离级别为读已提交(Read Committed)和可重复读(Repeated Read)下生效。 MVCC是做什么用的 MVCC是为了处理 可重复读 和…

C++ 带约束的Ceres形状拟合

C 带约束的Ceres形状拟合 一、Ceres Solver1.定义问题2. 添加残差AddResidualBlockAutoDiffCostFunction 3. 配置求解器4. 求解5. 检查结果 二、基于Ceres的最佳拟合残差结构体拟合主函数 三、带约束的Ceres拟合残差设计拟合区间限定 四、拟合结果bestminmax 五、完整代码 对Ce…

无法将ggplot图保存为PDF文件怎么办

即serif代表Times New Roman字体,sans代表Arial字体,mono代表Courier New字体。这种映射关系在基础绘图系统和ggplot2系统中均可使用。 既然字体找不到,那么就导入我们电脑的字体咯: # 这个代码只需运行一次 extrafont::font_im…

使用GitHub Actions实现前后端CI/CD到云服务器

一、静态站点部署(前端) 如果你要部署到github pages或者你不用SSR(服务端渲染),那就构建(SSG)静态站点 配置 nextjs配置SSG(静态站点)next.config.mjs,其…

跨域训练评估BEVal:自动驾驶 BEV 的跨数据集评估框架

跨域训练评估BEVal:自动驾驶 BEV 的跨数据集评估框架 Abstract 当前在自动驾驶中的鸟瞰图语义分割研究主要集中在使用单个数据集(通常是nuScenes数据集)优化神经网络模型。这种做法导致了高度专业化的模型,可能在面对不同环境或…

孙溟㠭浅析中国碑帖〈曹全碑〉

孙溟㠭浅析中国碑帖《曹全碑》 《曹全碑》 《曹全碑》亦称《郃阳令曹全碑》,东汉时期的碑刻。属于隶书体,东汉中平二年(公元158年)立碑。 《曹全碑》 于明代万历初年在陕西郃阳县莘里村被发现,碑文记载了东汉末年曹全…

2025秋招LLM大模型多模态面试题(七)- 思维链CoT

1.思维链(cot) 论文名称:Chain-of-Thought Prompting Elicits Reasoningin Large Language Models论文连接:Chain-of-Thought Prompting Elicits Reasoningin Large Language Models1.什么是思维链提示? 思维链(CoT)提示过程是一种最近开发的提示方法,它鼓励大语言模型解…

GUI编程14:Icon(图标)、ImageIcon(图像图标)标签

视频链接:16、Icon、ImageIcon标签_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p16&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.在Label上添加Icon package com.yundait.lesson04;import javax.swing.*; import java.awt.*;public cl…

C++数据结构-树的深度优先搜索及树形模拟法运用(进阶篇)

1. DFS简介 深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件&am…

Vue2电商平台项目 (三) Search模块、面包屑(页面自己跳自己)、排序、分页器!

文章目录 一、Search模块1、Search模块的api2、Vuex保存数据3、组件获取vuex数据并渲染(1)、分析请求数据的数据结构(2)、getters简化数据、渲染页面 4、Search模块根据不同的参数获取数据(1)、 派发actions的操作封装为函数(2)、设置带给服务器的参数(3)、Object.assign整理参…

comfyui中报错 Cmd(‘git‘) failed due to: exit code(128) 如何解决

🎈背景 comfyui今天在安装插件的过程中,发现有个插件第一次安装失败后,再次安装就开始报错了,提示: ComfyUI-Inpaint-CropAndStitch install failed: Bad Request 截图如下: 看下后台的报错: …

输入一个整数表示输出函数,也表示组成正方形边的*的数量

//输入一个整数表示输出函数&#xff0c;也表示组成正方形边的*的数量 //空心正方形 #include<stdio.h> int main() {int c 5;int i 0;int a[5][5] { 0 };int j 0;for (i 0; i < c; i){for (j 0; j < c; j){if (i 0)a[i][j] *;else if (j 0)a[i][j] *;el…

python的数据类型详解

python基础 认识python基本类型python的注释风格有三种&#xff08;也可以说是两种&#xff09;python的对齐方式python的多行语句折断字符串类型的“计算”列表的常见用法元组的常见用法集合set的常见用法字典的常见用法bytes类型python的输入输出python中的引用 认识python基…

优化最长上升子序列

前言&#xff1a;平时我们做的题目都是用动态规划做的&#xff0c;但是有没有能够优化一下呢&#xff1f; 有一个结论&#xff0c;长度为 i 的一个序列&#xff0c;最后一个元素一定是构成长度为 i 的序列中最小的 我们可以用二分来优化 题目地址 #include<bits/stdc.h>…