Redis的五种常用数据类型详解及相关面试问题

news2024/11/14 5:53:01

目录

Redis的五种常用数据类型详解

简述

Redis五种基本数据类型

String字符串

常用命令

应用场景

Hash散列表

常用命令

使用场景

List链表

常用命令

应用场景

Set( 集合)

常用命令

应用场景

SortedSet( 有序集合) zset

常用命令介绍

应用场景

面试题常问的数据类型

简述

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings),散列(hashes), 列表(lists),集合(sets),有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询 。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

Redis的英文官网

Redis的中文官网

Redis的中文命令手册

本文主要介绍Redis五种常用的数据类型、三种特殊的数据类型的使用、应用场景。

Redis五种基本数据类型

String字符串

Redis 字符串是字节序列。Redis 字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你可以存储任何东西,512 M为上限,主要的还是操作键值对。 String的数据结构是简单的Key-Value模型,Value可以是字符串,也可以是数字。

常用命令
  • 添加元素(SET命令)

格式:

set key value [expiration EX seconds|PX milliseconds] [NX|XX]

ex:秒级过期时间,nx:键不存在时才能设置成功,xx键存在时才能设置成功

(1)普通添加: set key value

(2)设置过期时间 setex: setex key seconds value

上图中:设置一个键为key1,值为hello,并且30秒后过期。 使用 ttl命令 可以查看该键还有多少时间过期。

(3)不存在设置 setnx(set if not exist) setnx key value 如果key不存在,则创建一个key,如果key存在,则创建失败并返回0。

上图中,执行第一条命令时,由于key2不存在,所以就创建一个key2,执行第二句命令时,由于key2前面已经创建了,已经存在了,所以就创建失败,并且返回0。

setnx在分布式锁中经常使用到


  • 获取值 (GET命令)

127.0.0.1:6379> set name oldou

OK

127.0.0.1:6379> get name   #获取name中的值

"oldou"


  • mset/mget命令 同时设置/获取一个或者多个键值对,主要就是批量设置和获取键值对。


  • msetnx key1 value1 key2 value2… 同时设置多个值,如果其中有一个存在,那么就都创建失败。 要么一起成功,要么一起失败,这是一个 原子性操作

  • incr命令 让当前键值以 1 的数量递增,并返回递增后的值。相当于Java中的自增,每次使用改命令都能让变量自增1。

  • 应用场景:(一般可用于设置浏览量、阅读量)


  • incrby命令 可以指定参数一次增加的数值,并返回递增后的值,(原来的num是2,加10之后变为12)


  • decr命令 可以指定参数一次递减的数值,并返回递减后的值,每次使用该命令都自减1,相当于Java中的自减。


  • decrby 可以指定参数一次递减的数值,并返回递减后的值


  • append命令 向键值的末尾追加 value。如果键不存在则将该键的值设置为 value。 返回值是追加后字符串的总长度。


  • strlen命令 :获取字符串长度


  • **getrange命令:**截去指定索引的字符串


  • setrange命令 :从指定索引开始替换字符串

  • 以上表示从索引为0开始的元素替换为QQQQQ


  • del命令 : 根据key删除一个或者多个元素


  • 设置对象 set user:1 {name:zhangsan,age:3}

  • 设置一个user:1对象,值为json字符串来保存一个对象。

  • 这是一个巧妙的设计: user:{id}:{field} 如此设置在Redis中是完全OK的。


  • getset命令 :先get然后再set 如果设置的键不存在值,则设置值,并且返回nil 如果设置的键存在值,则返回该值,并设置新的值

应用场景
  • 计数器—点赞,视频播放量,每播放一次就+1

  • 统计多单位的数量

  • 粉丝数

  • 对象缓存存储

Hash散列表

Redis 的哈希是键值对的集合。

Redis 的哈希值是字符串字段和字符串值之间的映射,因此它们被用来表示对象,还有用户信息之类的,经常变动的信息。

Hash更适合用于对象的存储,String更适合字符串存储。


常用命令
  • (1) hset命令 :存储一个哈希键值对的集合 格式为:hset key field value -----表示的是在key的field下设置一个为“value”的值。

  • (2) hget命令 :获取一个哈希键的值    格式为:hget key field

  • (3) hmset : 存储一个或多个哈希是键值对的集合

  • 格式为:hmset key field1 value1 …fieldN keyN

  • (4) hmget : 获取多个指定的键的值       

  • 格式为:hmget key field1 … fieldN


  • (5) hexists : 判断哈希表中的字段名是否存在 如果存在返回 1 否则返回 0

  • 格式为:hexists key field

  • (6) hdel : 删除一个或多个字段

  • 格式为:hdel key field

  • (7) hgetall : 获取一个哈希是键值对的集合

  • 格式为:hgetall key

  • (8) hvals : 只返回字段值

  • 格式为:hvals key

  • (9) hkeys : 只返回字段名

  • 格式为:hkeys key

  • (10) hlen : 返回 key 的 hash 的元素个数

  • 格式为:hlen key

  • 这里是因为user下有两个属性 username和userage


  • (11) hincrby key field value : 指定增量value

  • (12) hsetnx key field value : 如果该键不存在就创建,如果该键存在就创建失败。

使用场景

主要用于存储部分变更数据,比如存储用户信息等等

List链表

Redis 的链表是简单的字符串列表,排序插入顺序。您可以添加元素到 Redis 的列表的头部或尾部 Lpush:表示的是向链表的左添加,也就是向链表的头添加; Rpush:表示的是向链表的右添加,也就是向链表的尾添加;

常用命令
  • (1) lpush key value : 向链表左侧添加—头插法

  • (2) rpush key value : 向链表右侧添加–尾插法

  • (3) lpop key : 从左边移出一个元素,就是从最左边的那个节点剔除掉。

  • (4) rpop key : 从右边移出一个元素,就是从最右边的那个节点剔除掉。

  • (5) lrange key start end lrange : 命令将返回索引从 start 到 stop 之间的所有元素。Redis 的列表起始索引为 0。

  • 如果是要获取全部的元素: lrange key 0 -1

  • (6) llen key : 返回链表中元素的个数 相当于关系型数据库中 select count(*)

  • (7) lindex key indexnumber :lindex 命令用来返回指定索引的元素,索引从 0 开始,如果是负数表示从右边开始计算的索引,最右边元素的索引是-1。如果要将列表类型当做数组来用,lindex 命令是必不可少的。

  • (8) lset key indexnumber value : 是另一个通过索引操作列表的命令,它会将索引为 index的元素赋值为 value,原来的值会被覆盖。如果该列表不存在就会报错。所以使用这个命令之前先使用exists判断一下。

  • (9) lrem key count value : 移除key链表中count个元素的value值,精确匹配,如果链表中可以有多个重复的值,这里的count指的是可以删除多个相同key的值。

  • (10) ltrim list startIndex endIndex :通过下标截取指定的长度,这个时候list已经改变了,只剩下截断的元素。

  • (11) rpoplpush source destination :移除当前的source链表中的最后一个元素,并且将该元素移动到destination链表当中。

  • (12) linsert key BEFORE|AFTER pivot value :在key列表的pivot元素的前/后面插入元素value。

  • 小结:

  • 实际上list是一个链表,before node after,left ,right都可以插入值;

  • 如果key不存在,就创建新的链表;

  • 如果key存在就创建新的值;

  • 如果移除了所有的值,空链表,也就代表不存在;

  • 在两边插入或者改动值,效率最高,中间元素相对来说效率会低一点。

应用场景
  • 消息队列:利用List的PUSH操作,将任务存在List中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作List中某一段的api,你可以直接查询,删除List中某一段的元素。

  • 消息排队,消息队列(Lpush、Rpop)、栈(Lpush、Lpop)

  • 使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。

Set( 集合)

Redis 的集合是字符串的无序集合。

在Set集合当中,是不允许有重复的。

set是通过hash table实现的,可以进行添加、删除和查找。对集合我们可以取并集,交集,差集.

常用命令
  • (1) sadd key value :添加一个 string 元素到,key 对应的 set 集合中, 成功返回 1,如果元素已经在集合中返回 0

  • (2) scard key : 返回 set 的元素个数,如果 set 是空或者 key 不存在返回 0

  • (3) smembers key : 返回 key 对应 set 的所有元素,结果是无序的

  • (4) sismember key value : 判断 value 是否在 set 中,存在返回 1,0 表示不存在或者 key 不存在

  • (5) srem key value : 从 key 对应 set 中移除给定元素,成功返回 1,如果 value 在集合中不存在或者 key 不存在返回 0

  • (6) srandmember key nums : 从key集合中随机抽取nums个元素。

  • (7) spop key :随机删除一些key集合中的元素。

  • (8) smove source destination member :将原集合source中的member元素移动到destination集合中。


  • (9) sdiff key1 key2 :取出key1中与key2集合的不同元素,差集

  • (10) sinter key1 key2 :取key1与key2两个集合中相同的元素,交集

  • (11) sunion key1 key2 :将key1与key2两个集合中的元素合在一起,并集

应用场景
  • 微博、用户将所有关注的人都放入到一个set集合当中,将它的粉丝也放在一个集合中。

  • 共同关注、共同爱好、二度好友、QQ的好友推荐(六度分割理论)

SortedSet( 有序集合) zset

Redis 的有序集合类似于 Redis 的集合,字符串不重复的集合。

常用命令介绍
  • (1) zadd key score value : 将一个或多个 value 及其 socre 加入到 set 中

  • (2) zrange key start end :0 和-1 表示从索引为 0 的元素到最后一个元素(同 LRANGE 命令相似)

  • (3) zrange key 0 -1 withscores 也可以连同 score 一块输出,使用 WITHSCORES 参数

  • (4) zremrangebyscore key start end :可用于范围删除操作

  • (5) zrangebyscore key min max : 升序排序操作,将key按最小值到最大值进行输出。 zrevrange salary 0 -1 :这个是倒序全部输出

  • 以上是从小到大排序,也就是升序排序。

  • (6) zrevrangebyscore key max min :倒序排序操作,将key按照从大到小排序输出

  • (6) zrem key value : 删除指定的元素

  • (7) zcard key :获取有序集合中的个数

  • (8) zcount key min max : 获取指定区间的成员数量

应用场景
  • 存储班级成绩表、工资表排序

面试题常问的数据类型

1、Redis 的数据类型有哪些?
  • Redis支持五种数据类型:String(字符串)、hash(哈希)、list(列表)、set(集合)以及zsetsorted set(有序集合)。

  • 我们实际项目中比较常用的是String和hash,如果你是Redis的中高级用户,还需要加上以下几种数据类型,分别是:HyperLogLog、Geo、Pub/Sub。

  • 如果你玩过Redis Module,像BloomFilter、RedisSearch、Redis-ML,,等等,是加分项。

2、一个字符串类型的值能存储最大容量是多少?

一个字符串类型的值能存储的最大容量为512M。

3、Redis key 的过期时间和永久有效分别怎么设置?
  • 使用expire命令对key的过期时间进行设置;

  • 使用persist命令对key永久有效进行设置;

4、一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set他们最多能存放多少元素?

理论上Redis可以处理多达232个keys,并且在实际中进行了测试,每个实例至少存放了2亿5千万的keys。

任何list、set和sorted set都可以放232个元素,换句话说,Redis的存储极限是系统中的可用内存值。

5、Redis 最适合的场景?
  • (1)会话缓存(最常用的一种使用 Redis 的情景是会话缓存(session cache)。用 Redis 缓存会话比其他存储(如 Memcached)的优势在于:Redis 提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗? 幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用 Redis 来缓存会话的文档。甚至广为人知的商业平台Magento 也提供 Redis 的插件。

  • (2)全页缓存(FPC) 除基本的会话 token 之外,Redis 还提供很简便的 FPC 平台。回到一致性问题,即使重启了 Redis 实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似 PHP 本地 FPC。 再次以 Magento 为例,Magento提供一个插件来使用 Redis 作为全页缓存后端。 此外,对 WordPress 的用户来说,Pantheon 有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

  • (3)队列 Reids 在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得 Redis能作为一个很好的消息队列平台来使用。Redis 作为队列使用的操作,就类似于本地程序语言(如 Python)对 list 的 push/pop 操作。 如果你快速的在 Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用 Redis 创建非常好的后端工具,以满足各种队列需求。例如,Celery 有一个后台就是使用 Redis 作为 broker,你可以从这里去查看。

  • (4)排行榜/计数器 Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis 只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的 10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可: 当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis 来存储数据的,你可以在这里看到。

  • (5)发布/订阅 最后(但肯定不是最不重要的)是 Redis 的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用 Redis 的发布/订阅功能来建立聊天系统!)

6、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?

使用keys指令可以扫出指定模式的key列表。

7、如果这个Redis正在给线上的业务提供服务,那使用keys指令会有什么问题? 这个时候就要回答:Redis是单线程的,keys指令会导致线程阻塞一段时间,线上服务会停顿,知道指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取指令模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
8、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

如果大量的key过期时间设置过于集中,那么到过期的那个时间点,Redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一点。

9、使用过 Redis 做异步队列么,你是怎么用的?

一般使用list结构作为队列,rpush生产消息,lpop消费消息。 当lpop没有消息的时候,要适当sleep一会儿再重试。

追问:可不可以不使用sleep呢?

list还有个指令叫blpop,在没有消息的时候,它会阻塞住,直到消息到来。

再追问:能不能生产一次,消费多次呢?

使用pub/sub主题订阅者模式,可以使用1:N的消息队列。

再问:pub/sub有什么缺点?

在消费者下线的情况下,生产的消息会丢失,解决这样的问题得使用专业的消息队列,如RabbitMQ等。

Redis如何实现延时队列呢?

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

10、使用过 Redis 分布式锁么,它是什么回事?

先拿setnx来争抢锁,抢到之后再用expire给锁加一个过期时间防止锁忘记了释放。

问:如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?

这个时候确实锁会永远得不到释放了,但是set指令有个非常复杂的参数是可以同时把setnx和expire合成一条指令来用的。

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

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

相关文章

【MySQL】打开科技创新的第一生产力

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-EtRkflNU19AGWAkT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

景联文科技大模型数据集更新!教育题库新增高质量数学题、逻辑推理题及英文题

苏格拉底曾以“点燃火焰”的理念来诠释教育。随着大语言模型在教育中的不断应用,教育与AI的深度融合,让我们看到了“点燃火焰”的理念的更多可能性。 大语言模型可以通过与学生的互动,为他们提供个性化的学习体验,更好地满足学习需…

Maven简述

Maven是用于管理和构建Java项目的工具,提供了一套标准化的项目结构,提供了一套标准化的构建流程,提供了一套依赖管理机制,通过Maven使得所有IDE构建的项目结构完全一样,让项目可以通用。 项目名称下分为src 和 pom.xm…

差分进化算法求解基于移动边缘计算 (MEC) 的无线区块链网络的联合挖矿决策和资源分配(提供MATLAB代码)

一、优化模型介绍 在所研究的区块链网络中,优化的变量为:挖矿决策(即 m)和资源分配(即 p 和 f),目标函数是使所有矿工的总利润最大化。问题可以表述为: max ⁡ m , p , f F miner …

Linux系统SSH远程管理服务

目录 一、SSH服务介绍 1、SSH协议是什么? 2、SSH的优点 3、SSH的客户端与服务端 4、SSH的原理 4.1 公钥首次连接原理 4.2 ssh加密通讯原理 4.2.1 对称加密 4.2.2 非对称加密 4.2 ssh远程登录 二、服务端配置 1、常见配置项 1.1 修改默认端口 1.2 禁止…

Transformer and Pretrain Language Models3-1

content transformer attention mechanism transformer structure​​​​​​​ pretrained language models language modeling pre-trained langue models(PLMs) fine-tuning approaches PLMs after BERT applications of masked LM frontiers of PLMs …

【Godot4自学手册】第四节动画状态机-AnimationTree

各位同学大家好!今天继续学习Godot4,本节将要学习AnimationTree,来实现控制主人公的动画。 一、AnimationPlay节点介绍 Godot引擎通过AnimationPlay节点实现了最灵活的动画系统,它几乎可以给godot中的任意节点的任意属性添加动画…

携程基于Jira Cloud的敏捷项目管理实践

好的工具可以满足团队在各个成长阶段的管理诉求 实践一:对齐目标/团队OKR/多团队协作战略项目 实践二:以产品为中心的协作框架 实践三:交付团队管理 实践四:和海外子公司对齐,协作

数灵通丨可以实现抖音引流微信小程序了

抖音作为一款火爆的短视频社交平台,吸引了数亿用户的关注和喜爱。除了观看和制作视频外,抖音还提供了跳转到小程序的功能,让用户可以享受更多功能和乐趣。那么,如何在抖音中跳转到小程序呢?以下是详细解答:…

Android 基础技术——View 的宽高

笔者希望做一个系列,整理 Android 基础技术,本章是关于 View 的宽高 Activity Resume 的时候设置或者获取view的宽高是否有效? 回答:不确定。 首次 onResume 无效,二次 onResume 就有效了。 回顾「Android 基础技术——addView 流…

[Python] glob内置模块介绍和使用场景(案例)

Unix glob是一种用于匹配文件路径的模式,它可以帮助我们快速地找到符合特定规则的文件。在本文中,我们将介绍glob的基本概念、使用方法以及一些实际应用案例。 glob介绍 Glob(Global Match)是Unix和类Unix系统中的一种文件名扩展功能,它可以…

eNSP学习——理解交换机Hybird接口的应用

目录 原理概述 实验内容 实验目的 实验步骤 实验拓扑 实验编址 实验步骤 基本配置(此处仅以PC1为例) 实现组内通信、组间间隔 实现网络管理员对所有网络的访问 原理概述 Hybrid接口既可以连接普通终端的接入链路又可以连接交换机间的干道…

嵌入式面试提问

嵌入式面试问题 1.讲一下STM32的时钟系统 现总结下:首先是时钟源输入时钟信号到单片机,然后单片机对输入的时钟信号进行倍频和分频处理,再将处理后的时钟信号输出至系统,外设或外部接口。   先看这张图,最外面的线上…

[docker] Docker资源管理

一、docker资源控制 Docker通过Cgroup 来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。Caroup 是ControlGroups的缩写,是Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如…

[linux] 域名解析失败案例定位 [Errno -2] Name or service not known

首先发现代码里这段运行报错: socket.gethostbyname_ex(host_name) Traceback (most recent call last): File “”, line 1, in socket.gaierror: [Errno -2] Name or service not known import socket host_name socket.gethostname() print(socket.gethostby…

CSS3基础知识总结

目录 一、CSS3 边框 1.border-radius:圆角边框 2.box-shadow:添加阴影 3.border-image:图片边框 二、CSS3 渐变 1.线性渐变(Linear Gradients) a.由上到下(默认) b.从左到右 c.对角 d.使用角度 2.径向渐变(…

js计算皮尔逊相关系数

代码如下; let XGX {correlationCoefficient(pA, pB) {let covXY -pA * pBlet varX pA * (1-pA) let varY (1-pB)* pBlet res covXY / (Math.sqrt(varX*varY, 2))return res},correlation(x,y){x[0.3,50.2,99.5,199.3,299,398];y[0.1,50,99.9,200,300,400];// 计算均值con…

深入理解HarmonyOS UIAbility:生命周期、WindowStage与启动模式探析

UIAbility组件概述 UIAbility组件是HarmonyOS中一种包含UI界面的应用组件,主要用于与用户进行交互。每个UIAbility组件实例对应最近任务列表中的一个任务,可以包含多个页面来实现不同功能模块。 声明配置 为了使用UIAbility,首先需要在mod…

Nginx 配置解析:从基础到高级应用指南

Nginx 配置解析:从基础到高级应用指南 Nginx 配置解析:从基础到高级应用指南1. 安装和基本配置安装 Nginx基本配置 2. 虚拟主机配置3. 反向代理配置4. 负载均衡配置5. SSL 配置6. 高级配置选项结语 Nginx 配置解析:从基础到高级应用指南 Ngi…

Scapy编程指南(基础概念)

Scapy编程指南(基础概念) Scapy是什么 Scapy是Python中一个非常强大的库,它专门用于处理、发送和捕获网络协议中的数据包,它允许开发人员通过Python代码构建、解析和发送自定义网络协议的数据包。Scapy提供了一种直观、灵活的方…