Redis 数据类型有哪些?

详细可以查看:数据类型及其应用场景

基本数据类型

  1. String:最常用的一种数据类型,String类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。一般用于 缓存和计数器

  2. Hash:Hash 是一个键值对集合。存储商品的各个属性

  3. Set:无序去重的集合。Set 提供了交集、并集等方法,对于实现共同好友、共同关注等功能特别方便。

  4. List:有序可重复的集合,底层是依赖双向链表实现的。用于消息队列

  5. SortedSet:有序Set。内部维护了一个score的参数来实现。适用于排行榜和带权重的消息队列等场景。

特殊的数据类型

  1. Bitmap:位图,可以认为是一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在 Bitmap 中叫做偏移量。Bitmap的长度与集合中元素个数无关,而是与基数的上限有关。

  2. Hyperloglog。HyperLogLog 是用来做基数统计的算法,其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。典型的使用场景是统计独立访客。

  3. Geospatial :主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如定位、附近的人等。

  4. Stream :一种日志数据结构,适合于存储时间序列数据或消息流。支持高效的消息生产和消费模式,具有持久性和序列化特性。

SortedSet和List异同点?

相同点

  1. 都是有序的;

  2. 都可以获得某个范围内的元素。

不同点:

  1. 列表基于链表实现,获取两端元素速度快,访问中间元素速度慢;

  2. 有序集合基于散列表和跳跃表实现,访问中间元素时间复杂度是OlogN;

  3. 列表不能简单的调整某个元素的位置,有序列表可以(更改元素的分数);

  4. 有序集合更耗内存。

Redis 怎么实现消息队列?

BLPOP queue 0  //0表示不限制等待时间

BLPOP和LPOP命令相似,唯一的区别就是当列表没有元素时BLPOP命令会一直阻塞连接,直到有新元素加入。

redis可以通过pub/sub主题订阅模式实现一个生产者,多个消费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。

PUBLISH channel1 hi
SUBSCRIBE channel1
UNSUBSCRIBE channel1 //退订通过SUBSCRIBE命令订阅的频道。

PSUBSCRIBE channel?* 按照规则订阅。PUNSUBSCRIBE channel?* 退订通过PSUBSCRIBE命令按照某种规则订阅的频道。其中订阅规则要进行严格的字符串匹配,PUNSUBSCRIBE *无法退订channel?*规则。

如何在 Redis 中实现队列和栈数据结构?

可以通过 List 类型 来实现 队列 和 栈

实现队列(FIFO):队列是一种 先进先出(FIFO)的数据结构。在Redis中,可以使用 PUSH 和 RPOP命令组合来实现队列。LPUSH 向列表的左侧推入元素,而 RPOP从列表的右侧弹出元素,这样可以保证最先进入的元素最先被弹出

实现栈(LIFO):栈是一种 后进先出(LIFO)的数据结构。在Redis 中,可以使用 LPUSH和 LPoP命令组合来实现栈。LPUSH 向列表的左侧推入元素,而 LPoP从列表的左侧弹出元素,这样可以保证最后进入的元素最先被弹出。

Redis 怎么实现延时队列

使用sortedset,拿时间戳作为score,消息内容作为key,调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

如何使用 Redis 快速实现排行榜?

使用 Redis 实现排行榜的方式主要利用 Sorted Set(有序集合),它可以高效地存储、更新、以及获取排名数据。实现排行榜的主要步骤:

  1. 使用 Sorted Set 存储分数和成员:使用 Redis 的 ADD命令,将用户和对应的分数添加到有序集合中。例如:add leaderboard 1000 user1,将用户 user1 的分数设置为 1000。

  2. 获取排名:使用 ZRANK命令获取某个用户的排名。例如:zrank leaderboard user1,返回用户user1 的排名(从0开始)。

  3. 获取前 N 名:使用 ZREVRANGE 命令获取分数最高的前N名。例如:REVRANGE leaderboard 0 9 WITHSCORES ,获取排行榜前 10 名用户及其分数。

  4. 更新分数:如果用户的分数需要更新,可以使用 ZINCRBY 命令对其分数进行加减操作。例如:ZINCRBY leaderboard 500 user1,将用户 user1 的分数增加 500。

如何使用 Redis 快速实现布隆过滤器?

可以通过使用 位图(Bitmap)或使用 Redis 模块 RedisBloom。

  • 使用位图实现布隆过滤器:使用 Redis 的位图结构 SETBIT 和 GETBIT 操作来实现布隆过滤器。位图本质上是一个比特数组,用于标识元素是否存在对于给定的数据,通过多个 哈希函数 计算位置索引,将位图中的相应位置设置为 1,表示该元素可能存在。

  • 使用 RedisBloom 模块:Redis 提供了一个官方模块 RedisBloom,封装了哈希函数、位图大小等操作,可以直接用于创建和管理布隆过滤器。使用 BF.ADD 来向布隆过滤器添加元素,使用 BF.EXISTS 来检查某个元素是否可能存在,

如何使用 Redis 统计大量用户唯一访问量(UV)?

Redis 中 HyperLogLog 结构,可以快速实现网页UV、PV 等统计场景。它是一种基数估算算法的概率性数据结构,可以用极少的内存统计海量用户唯一访问量的近似值。

Set 也可以实现,用于精确统计唯一用户访问量,但是但当用户数非常大时,内存开销较高。

Redis 中的 Geo 数据结构是什么?

Redis中的 Geo(Geoloaton的简写形式,代表地理坐标) 数据结构主要用于地理位置信息的存储,通过这个结构,可以方便地进行地理位置的存储、检索、以及计算地理距离等课作,GeO 数据结内存层使用了 Sorted set, 并结合了Geohash 编码算法来对地理位置进行处理。

Redis String 类型的底层实现是什么?(SDS)

Redis 中的 Sting 类型底层实现主要基于 SDS(Simple Dynamic string 简单动态字符串)结构,并结合 int、embstr、raw 等不同的编码方式进行优化存储。

Redis 中的 Ziplist 和 Quicklist 数据结构的特点是什么?

Ziplist:

  • 简单、紧凑、连续存储,适用于小数据量场景,但对大量数据或频繁的修改操作不太友好。

  • 适合小数据量场景,例如短列表、小哈希表等,因为它的内存紧凑,可以大幅减少内存使用

Quicklist:

  • 通过将链表和 Ziplist 结合,既实现了链表的灵活操作,又能节省内存,在 Redis 3.2 之后成为 List 的默认实现。

  • Quicklist是为了替代纯而设计的,适用于需要频繁对列表进行插入、删除、查找等提作的场景,并目数据量可能较大,它在存储多个元素时,既保留了链表的灵活性,又具备压缩列表的内存优势

Redis Zset 的实现原理是什么?

Redis 中的Zset(有序集合,Sorted set)是一种由 跳表 (Skip List)和哈希表 (Hash Table)组成的数据结构,Zset 结合了集合 (Set)的特性和排序功能,能够存储具有唯一性的成员,并根据成员的分数 (score) 进行排序

ZSet 的实现由两个核心数据结构组成:

  1. 跳表(Skip List):用于存储数据的排序和快速查找。

  2. 哈希表(Hash Table):用于存储成员与其分数的映射,提供快速查找

当 Zset 元素数量较少时,Redis 会使用压缩列表(Zip List)来节省内存

  • 即元素个数≤ zset-max-ziplist-entries(默认 128)

  • 元素成员名和分值的长度 ≤ zset-max-ziplist-value(默认 64 字节)

如果任何一个条件不满足,Zset 将使用 跳表 +哈希表 作为底层实现,

Redis 的有序集合底层为什么要用跳表,而不用平衡树、红黑树或者 B+树?

这道面试题很多大厂比较喜欢问,难度还是有点大的。

  • 平衡树 vs 跳表:平衡树的插入、删除和查询的时间复杂度和跳表一样都是 O(log n)。对于范围查询来说,平衡树也可以通过中序遍历的方式达到和跳表一样的效果。但是它的每一次插入或者删除操作都需要保证整颗树左右节点的绝对平衡,只要不平衡就要通过旋转操作来保持平衡,这个过程是比较耗时的。跳表诞生的初衷就是为了克服平衡树的一些缺点。跳表使用概率平衡而不是严格强制的平衡,因此,跳表中的插入和删除算法比平衡树的等效算法简单得多,速度也快得多。

  • 红黑树 vs 跳表:相比较于红黑树来说,跳表的实现也更简单一些,不需要通过旋转和染色(红黑变换)来保证黑平衡。并且,按照区间来查找数据这个操作,红黑树的效率没有跳表高。

  • B+树 vs 跳表:B+树更适合作为数据库和文件系统中常用的索引结构之一,它的核心思想是通过尽可能少的 IO 定位到尽可能多的索引来获得查询数据。对于 Redis 这种内存数据库来说,它对这些并不感冒,因为 Redis 作为内存数据库它不可能存储大量的数据,所以对于索引不需要通过 B+树这种方式进行维护,只需按照概率进行随机维护即可,节约内存。而且使用跳表实现 zset 时相较前者来说更简单一些,在进行插入时只需通过索引将数据插入到链表中合适的位置再随机维护一定高度的索引即可,也不需要像 B+树那样插入时发现失衡时还需要对节点分裂与合并。

Redis 中跳表的实现原理是什么?

跳表主要是通过多层链表来实现,底层链表保存所有元素,而每一层链表都是下一层的子集。

插入时,首先从最高层开始查找插入位置,然后随机决定新节点的层数,最后在相应的层中插入节点并更新指针

删除时,同样从最高层开始查找要删除的节点,并在各层中更新指针,以保持跳表的结构。

查找时,从最高层开始,逐层向下,直到找到目标元素或确定元素不存在。查找效率高,时间复杂度为 O(logn)

Redis中的跳表是两步两步跳的吗?

如果采用新增节点或者删除节点时,来调整跳表节点以维持比例2:1的方法的话,显然是会带来额外开销的。

跳表在创建节点时候,会生成范围为[0-1]的一个随机数,如果这个随机数小于 0.25(相当于概率 25%),那么层数就增加 1 层,然后继续生成下一个随机数,直到随机数的结果大于 0.25 结束,最终确定该节点的层数。因为随机数取值在[0,0.25)范围内概率不会超过25%,所以这也说明了增加一层的概率不会超过25%。这样的话,当插入一个新结点时,只需修改前后结点的指针,而其它结点的层数就不需要随之改变了,这样就降低插入操作的复杂度。

// #define ZSKIPLIST_P 0.25
int zslRandomLevel(void) {static const int threshold = ZSKIPLIST_P*RAND_MAX;int level = 1; //初始化为一级索引while (random() < threshold)level += 1;//随机数小于 0.25就增加一层//如果level 没有超过最大层数就返回,否则就返回最大层数return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

Redis遇到哈希冲突怎么办?

当有两个或以上数量的键被分配到了哈希表数组的同一个索引上面时, 我们称这些键发生了冲突(collision)。

而redis是先通过拉链法解决,再通过rehash来解决hash冲突问题的,即再hash法,只不过redis的hash使渐进式hash

rehash原理?

渐进式 rehash 步骤如下:

  1. 先给哈希表 2分配空间;

  2. 在 rehash 进行期间,每次哈希表元素进行新增、删除、查找或者更新操作时,Redis 除了会执行对应的操作之外,还会顺序将哈希表 1中索引位置上的所有 key-value 迁移到哈希表 2上;

  3. 随着处理客户端发起的哈希表操作请求数量越多,最终在某个时间点会把哈希表 1的所有 key-value 迁移到哈希表 2,从而完成 rehash 操作。

这样就把一次性大量数据迁移工作的开销,分摊到了多次处理请求的过程中,避免了一次性 rehash 的耗时操作。

在进行渐进式 rehash 的过程中,会有两个哈希表,所以在渐进式 rehash 进行期间,哈希表元素的删除、查找、更新等操作都会在这两个哈希表进行。比如,在渐进式 rehash 进行期间,查找一个 key 的值的话,先会在哈希表 1里面进行查找,如果没找到,就会继续到哈希表 2 里面进行找到。新增一个 key-value 时,会被保存到哈希表 2里面,而哈希表 1则不再进行任何添加操作,这样保证了哈希表 1的 key-value 数量只会减少,随着 rehash 操作的完成,最终哈希表 1就会变成空表。

rehash的触发条件?

负载因子 = 哈希表已保存节点数量/哈希表大小

触发 rehash 操作的条件,主要有两个:

  • 当负载因子大于等于 1 ,并且 Redis 没有在执行 bgsave 命令或者 bgrewiteaof 命令,也就是没有执行 RDB 快照或没有进行 AOF 重写的时候,就会进行 rehash 操作。

  • 当负载因子大于等于 5 时,此时说明哈希冲突非常严重了,不管有没有有在执行 RDB 快照或 AOF 重写,都会强制进行 rehash 操作

一个REDIS实例最多能存放多少KEYS

redis 的每个实例最多可以存放约 2^32 - 1 个keys,即大约 42 亿个keys。这是由 Redis 内部使用的哈希表实现决定的,它使用 32 位有符号整数作为索引。Redis 使用的哈希函数和负载因子等因素也会影响实际可存放键的数量。

需要注意的是,尽管 Redis 允许存储数量庞大的键,但在实践中,存储过多的键可能会导致性能下降和内存消耗增加。因此,在设计应用程序时,需要根据实际需求和硬件资源来合理规划键的数量,避免过度使用 Redis 实例造成负担。如果需要存储更多的键值对,可以考虑使用 Redis 集群或分片技术,以扩展整体存储容量。

文章转载自:Seven

原文链接:用过redis哪些数据类型?Redis String 类型的底层实现是什么? - 程序员Seven - 博客园

体验地址:JNPF快速开发平台

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大视协作码垛机:颠覆传统制造,开启智能工厂新纪元

在东三省某食品厂的深夜生产线上&#xff0c;码垛作业正有序进行&#xff0c;却不见人影——这不是魔法&#xff0c;而是大视协作码垛机器人带来的现实变革。在工业4.0浪潮席卷全球的今天&#xff0c;智能制造已成为企业生存与发展的必由之路。智能码垛环节作为产线的关键步骤&…

c# 保姆级分析继承详见问题 父类有一个列表对象,子类继承这个列表对象并对其进行修改后,将子类对象赋值给父类对象,父类对象是否能包含子类新增的内容?

文章目录 深入解析:父类与子类列表继承关系的终极指南 一、问题背景:从实际开发困惑说起 二、基础知识回顾:必备概念理解 2.1 继承的本质 2.2 引用类型 vs 值类型 2.3 多态的实现方式 三、核心问题分析:列表继承场景 3.1 基础代码示例 3.2 关键问题分解 3.3 结论验证 四、深…

tensorflow-gpu 2.7下的tensorboard与profiler插件版本问题

可行版本&#xff1a; python3.9.23cuda12.0tensorflow-gpu2.7.0tensorboard2.20.0 tensorboard-plugin-profile 2.4.0 问题描述&#xff1a; 1. 安装tensorboard后运行tensorboard --logdirlogs在网页中打开&#xff0c;发现profile模块无法显示&#xff0c;报错如下&#x…

数据结构青铜到王者第一话---数据结构基本常识(1)

目录 一、集合框架 1、什么是集合框架 2、集合框架的重要性 2.1开发中的使用 2.2笔试及面试题 3、背后涉及的数据结构以及算法 3.1什么是数据结构 3.2容器背后对应的数据结构 3.3相关java知识 3.4什么是算法 3.5如何学好数据结构以及算法 二、时间和空间复杂度 1、…

【Verilog】延时和时序检查

Verilog中延时和时序检查1. 延时模型1.1 分布延迟1.2 集总延迟1.3 路径延迟2. specify 语法2.1 指定路径延时基本路径延时边沿敏感路径延时状态依赖路径延时2.2 时序检查$setup, $hold, $setuphold$recovery, $removal, $recrem$width, $periodnotifier1. 延时模型 真实的逻辑元…

DigitalOcean Gradient AI平台现已支持OpenAI gpt-oss

OpenAI 的首批开源 GPT 模型&#xff08;200 亿和 1200 亿参数&#xff09;现已登陆 Gradient AI 平台。此次发布让开发者在构建 AI 应用时拥有更高的灵活度和更多选择&#xff0c;无论是快速原型还是大规模生产级智能体&#xff0c;都能轻松上手。新特性开源 GPT 模型&#xf…

藏在 K8s 幕后的记忆中枢(etcd)

目录1&#xff09;etcd 基本架构2&#xff09;etcd 的读写流程总览a&#xff09;一个读流程b&#xff09;一个写流程3&#xff09;k8s存储数据过程源码解读4&#xff09;watch 机制Informer 机制etcd watch机制etcd的watchableStore源码解读5&#xff09; k8s大规模集群时会存在…

腾讯云EdgeOne安全防护:快速上手,全面抵御Web攻击

为什么需要专业的安全防护&#xff1f; 在当今数字化时代&#xff0c;网站面临的安全威胁日益增多。据统计&#xff0c;2023年全球Web应用程序攻击超7千亿次&#xff0c;持续快速增长。 其中最常见的包括&#xff1a; DDoS攻击&#xff1a;通过海量请求使服务器瘫痪Web应用攻…

SpringBoot中的条件注解

文章目录前言什么是条件注解核心原理常用条件注解详解1. ConditionalOnClass和ConditionalOnMissingClass2. ConditionalOnBean和ConditionalOnMissingBean3. ConditionalOnProperty应用场景&#xff1a;多数据源配置在SpringBoot自动配置中的核心作用自动配置的工作原理经典自…

LightGBM时序预测详解:从原理到 PSO 参数优化

前言 在时间序列预测领域&#xff0c;集成学习方法一直占据重要地位。此前我们介绍了基于传统集成思想的时序预测方法&#xff08;查看前文&#xff09;&#xff0c;而梯度提升树&#xff08;GBDT&#xff09;作为集成学习的佼佼者&#xff0c;在时序预测中表现尤为突出。本文…

django生成迁移文件,执行生成到数据库

当报错时 重新拉取git&#xff0c;重新生成迁移文件&#xff0c;重新执行 1、生成迁移文件 python manage.py makemigrations 子应用2、执行建表、建字段、修改字段 python manage.py migrate 子应用3、当手动已经在数据库创建字段时&#xff0c; 用 --fake 标记迁移为 “已应用…

2025软件供应链安全技术路线未来趋势预测

软件供应链安全已从一个技术圈的议题演变为全球企业的治理焦点。近几年&#xff0c;APT渗透、恶意包植入、开发者误操作等不同类型的供应链安全事件频发&#xff0c;使得“安全的代码来源”和“可信的交付链路”成为企业数字化转型的生命线。2025年的软件供应链安全&#xff0c…

用户登录Token缓存Redis实践:提升SpringBoot应用性能

前言在现代Web应用中&#xff0c;用户认证和授权是至关重要的功能。传统的基于数据库的Token存储方式虽然简单易用&#xff0c;但在高并发场景下容易成为性能瓶颈。本文将介绍如何将SpringBoot项目中的用户Token从数据库存储迁移到Redis缓存&#xff0c;显著提升系统性能。一、…

深度解析Structured Outputs:让AI输出严格遵循JSON Schema的结构化响应

深度解析Structured Outputs&#xff1a;让AI输出严格遵循JSON Schema的结构化响应 引言 在现代应用开发中&#xff0c;JSON 是最流行的数据交换格式之一。为了提升 API 接口的健壮性和数据一致性&#xff0c;结构化输出&#xff08;Structured Outputs&#xff09;成为了大模…

关于 微服务中服务注册与发现 的详细说明,涵盖主流框架/解决方案的对比、核心功能、配置示例及总结表格

以下是关于 微服务中服务注册与发现 的详细说明&#xff0c;涵盖主流框架/解决方案的对比、核心功能、配置示例及总结表格&#xff1a;1. 服务注册与发现的核心概念 服务注册与发现是微服务架构的基础能力&#xff0c;主要解决以下问题&#xff1a; 服务注册&#xff1a;服务实…

08高级语言逻辑结构到汇编语言之逻辑结构转换 continue break 完结汇编按逻辑结构

目录 &#x1f4da; 1. continue 语句的原理与实现 &#x1f6e0; 1.1 continue 语句的基本概念 ⚙️ 1.2 底层原理 &#x1f4d6; 1.3 案例分析&#xff1a;跳过偶数&#xff0c;累加奇数 &#x1f680; 2. break 语句的原理与实现 &#x1f6e0; 2.1 break 语句的基本概…

AI出题人给出的Java后端面经(二十二)(日更)

链接双端链表 前一篇&#xff1a;AI出题人给出的Java后端面经&#xff08;二十一&#xff09;&#xff08;日更&#xff09; 后一篇&#xff1a;null 目录 &#x1f535; 一、Java基础&#xff08;集合/流式/OOP&#xff09; 答案&#xff1a; 题目1&#xff1a;集合遍历性…

AI赋能体育训练突破:AI动作捕捉矫正精准、战术分析系统提效率,运动员破瓶颈新路径

传统体育训练长期受限于 “动作矫正依赖教练主观判断”“战术分析滞后于赛场变化”“运动员体能分配凭经验摸索” 的难题&#xff0c;而 AI 技术的深度介入&#xff0c;正让体育训练从 “经验驱动” 转向 “数据驱动”&#xff0c;既能实时捕捉动作偏差&#xff0c;又能动态优化…

【python实用小脚本-194】Python PNR一键查票:输入号码秒出座位状态——再也不用刷12306

Python PNR一键查票&#xff1a;输入号码秒出座位状态——再也不用刷12306 PNR查询, 实时座位, 离线脚本, 零广告, 瑞士军刀 故事开场&#xff1a;一把瑞士军刀救了赶火车的你 周五傍晚&#xff0c;你拎着行李冲向站台&#xff0c;手机信号一格&#xff0c;12306 死活刷不出座位…

【python】python进阶——推导式

目录 一、推导式介绍 二、推导式的用法 2.1 列表推导式 2.2 字典推导式 2.3 集合推导式 2.4 生成器表达式 三、推导式的嵌套和复杂用法 3.1 嵌套推导式 3.2 多重条件推导式 四、推导式对比传统循环 4.1 性能比较 4.2 可读性比较 五、常见应用场景 5.1 数据清…