Redis学习-Redis的九种数据结构

String (字符串)

虽然redis是用C语言编写,但是redis中的string是redis自己实现的字符串结构,叫Simple Dynamic String简称(SDS),因为redis做为中间件会接受不同语言编写的程序传过来的字符串,它们都可能和C语言中的字符串结构不一样,例如C语言中以’\0’表是字符串的结尾,当传过来的二进制数据转换成C语言中的字符串中间有’\0’那么C语言就会认为这个字符串已经结束了,则后面的数据就丢失了。redis中的string包含四部分:一个char类型的数组buff、一个len记录已经使用的长度、一个flags标识当前string的头信息以及一个alloc记录给当前string分配的大小。当客户端通过append或者setbit命令对string进行操作时,如果增加的字符串长度小于等于alloc-len则还是在当前string内存空间中直接添加即可,如果超出了string中剩余空间,则会重新分配一块内存,大小为新的字符串的长度*2(如果字符串的大小超过1mb则之后的扩容不会翻倍扩容而是每次增加1mb)。string最大的大小为512MB

使用场景

  • 计数器:Redis的原子递增操作可以用来实现Web应用中的各种计数功能,如页面访问计数、点赞数、评论数等。
  • 分布式锁:在需要保证操作原子性的场景下,比如防止多个用户同时修改同一资源,可以使用Redis的String类型实现分布式锁。
  • 会话共享:在多实例部署的Web应用中,可以使用Redis来存储用户的会话信息,实现会话共享,避免因会话问题导致的登录失效。
  • 限流:通过设置特定的key来限制用户在一定时间内的请求次数,如短信验证码的发送频率控制,防止滥用。
  • 全局序列号生成:在分布式系统中,可以使用Redis生成全局唯一的序列号,适用于订单号、票据号等。
  • 消息队列:虽然不是String类型的直接应用,但可以通过List或Pub/Sub功能来实现消息队列,处理异步任务或事件通知。
  • 存储JSON对象:将序列化后的JSON对象存储在Redis的String类型中,用于快速读取和修改,如用户配置、系统状态等,(如果对象中的某些字段经常修改时,建议用hash存储)。
  • Webhook触发器:存储Webhook URL,当特定事件发生时,通过调用这些URL来触发外部服务。
  • 分布式系统间的通信:在微服务架构中,Redis可以作为不同服务间的通信桥梁,传递轻量级的消息或数据。
  • 缓存静态资源:将不经常变动的静态资源如图片、CSS和JavaScript文件缓存到Redis中,以减少数据库和文件系统的压力。
  • 用户个性化设置:存储用户的个性化设置,如主题偏好、界面布局等,以便快速加载用户定制的界面。

常用命令

set key value//存储字符串键值对
mset key value [key value....]//批量存储字符串键值对
setnx  key value//存入一个不存在的字符串键值对
get key//通过key获取value
mget key [key....]//批量获取value
del key [key....]//删除键值对
expire key seconds//设置过期时间
setex key seconds value//存储键值对并设置过期时间(秒)
psetex key milliseconds value//存储键值对并设置过期时间(毫秒)
append key value//key存在则追加字符串,不存在则设置
incr key//将key对应的数字值加一
decr key//将key对应的数字值减一
incrby key increment//将key对应的数字值加increment 
decrby key increment//将key对应的数字值减increment 

hash(散列)

redis的K-V键值对用的结构是dict,hash用的也是这个结构,类似于java中的hashtalbe,先有一个数组假设长度是4,当hset key field value时,将field通过hash算法如CRD16(field)计算得到一个0-65535之间的一个整数,再和数组长度取模得到这个field在数组中的位置,如果这个位置已经有了数据则将当前的value加入对应的链表中(当前的value为首节点)。
hash表中有一个重要的参数叫负载因子(负载因子 = used / size ; used 是哈希数组存储的元素个数,size 是哈希数组的长度)。当负载因子过大或过小,hash表会进行扩展或缩容,这两种都是通过渐进式rehash的方式完成的。
渐进式rehash:当哈希表中的元素过多时,如果一次性rehash到新的hashtable里,庞大的计算量,可能导致redis服务在一段时间不可用。为了避免rehash对服务器带来的影响,redis分多次、慢慢的将原本的哈希表中的键值对rehash到新的哈希表,这就是渐进式rehash
注:使用hash结构时,应避免单个hash结构过大,否则使用hgetall的操作时可能会导致线程阻塞,而且field是无法单独设置过期时间的

使用场景

类似于电商购物车这样的需要对对象中某一属性频繁修改的数据。

常用命令

HSET key field value//存储一个哈希表key的键值
HSETNX key field value//存储一个不存在的哈希表key的键值
HMSET key field value [field value ...]//在一个哈希表key中存储多个键值对
HGET key field//获取哈希表key对应的field键值
HMGET key field [field ...]//批量获取哈希表key中多个field键值
HDEL key field [field ...]//删除哈希表key中的field键值
HLEN key//返回哈希表key中field的数量
HGETALL ey//返回哈希表key中所有的键值
HINCRBY key field increment//为哈希表key中field键的值加上增量increment

list(列表)

一个有序的链表结构,使用quicklist和ziplist实现。
当List满足以下两个条件时,使用Ziplist编码:

  • 列表中的元素数量小于或等于list-max-ziplist-entries配置(默认512个)。
  • 列表中每个元素的长度小于或等于list-max-ziplist-value配置(默认64字节)

在这里插入图片描述
ZipList虽然节省内存,但申请内存必须是连续空间,如果内存占用较多,申请内存效率很低。所以我们必须限制ZipList的长度和entry大小。当list中的元素大小超过list-max-ziplist-value或者元素个数超过list-max-ziplist-entries,就会使用quciklist编码,将一个list拆分成多个小的ziplist,ziplist作为quicklist的节点,由quicklist来控制多个ziplist之间的联系。
配置参数:

  • list-max-ziplist-size:控制着每个ziplist的最大长度,超过这个长度时,Redis会创建新的ziplist。
  • list-compress-depth:控制着压缩的层数,即在进行列表操作时,Redis会从外到内压缩多少层ziplist。

quickList结构如下:

  • head:quickListNode头节点
  • tail:quickListNode尾节点
  • count:所有的ziplist中的entry总数量
  • len:ziplist节点数量
  • fill:ziplist中entry的上限,默认为-2
  • compress:首尾节点不压缩的个数,若设置为1,则首尾节点各有一节点不压缩,中间节点压缩,中间节点压缩为0x4…等乱码,读的时候需要解压缩;写的时候需要重新压缩;设置为0,则代表所有节点不压缩

quickListNode结构如下:

  • prev: 前一个节点指针
  • next:后一个节点指针
  • zl: 当前节点ziplist指针
    具体结构如图
    在这里插入图片描述

使用场景

  1. Stack(栈) = LPUSH + LPOP
  2. Queue(队列)= LPUSH + RPOP
  3. Blocking MQ(阻塞队列)= LPUSH + BRPOP

常用命令

LPUSH key value [value ...]//将一个或多个值value插入到key列表的表头(最左边)
RPUSH key value [value ...]//将一个或多个值value插入到key列表的表尾(最右边)
LPOP key//移除并返回key列表的头元素
RPOP key//移除并返回key列表的尾元素
LRANGE key  start stop//返回列表key中指定区间内的元素,区间以偏移量start和stop指定
BLPOP key [key ...] timeout//从key列表表头弹出一个元素,若列表中没有元素,阻塞等待					timeout秒,如果timeout=0,一直阻塞等待
BRPOP key [key ...] timeout//从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待					timeout秒,如果timeout=0,一直阻塞等待

set (无序集合)

set是一个无序的、自动去重的集合数据类型,它的基本数据结构就是value为null的dict,当set中存储的元素都是整型,且set中元素的个数没有超过set-max-intset-entries(默认512,intset能存储的最大元素个数)的大小,则set集合编码为intset结构。

使用场景

  1. 抽奖
  2. 微信朋友圈点赞用户列表
  3. 微博我关注的人、共同关注、朋友推荐

常用命令

SADD key member [member ...]//往集合key中存入元素,元素存在则忽略,若key不存在则新建
SREM key member [member ...]//从集合key中删除元素
SMEMBERS key//获取集合key中所有元素 点赞用户列表
SCARD key//获取集合key的元素个数 点赞数量
SISMEMBER key member//判断member元素是否存在于集合key中 是否点赞
SRANDMEMBER key [count]//从集合key中选出count个元素,元素不从key中删除 单次抽奖
SPOP key [count]//从集合key中选出count个元素,元素从key中删除 一等奖 二等奖 三等奖 且不能重复获奖的情况
SINTER key [key ...]//交集运算 共同关注
SINTERSTORE destination key [key ..]//将交集结果存入新集合destination中
SUNION key [key ..]//并集运算
SUNIONSTORE destination key [key ...]//将并集结果存入新集合destination中
SDIFF key [key ...]//差集运算 朋友推荐 
SDIFFSTORE destination  key [key ...]//将差集结果存入新集合destination中

Sort set (有序集合)

sortset是一个有序且去重的集合,当数据量较小时使用ziplist结构编码,当到达一定数量时使用dict+skiplist的结构去实现。
ziplist结构编码使用条件

  • 元素数量小于zset_max_ziplist_entries,默认值128
  • 每个元素都小于zset_max_ziplist_value,默认值64byte

ZipList本身没有排序功能,而且没有键值对的概念,因此存储sortset时score和element是紧挨在一起的两个entry,element在前,score在后,Score越小越接近队首,score越大越接近队尾,按照score值升序排列。
skiplist基于score进行排序,每个节点存有索引数组,所以有多个索引层级,优先从最高的层级查询,依次往下级索引查询,每个节点都有指针(每个指针的跨度可能不同)指向上一个和下一个节点,所以skiplist还是一个双向链表,具体结构如图:

  • 逻辑图:
    在这里插入图片描述
  • 实际结构:
    在这里插入图片描述

使用场景

  1. 排行榜,例如微博热搜top10

常用命令

ZADD key score member [[score member]]//往有序集合key中加入带分值元素
ZREM key member [member …]//从有序集合key中删除元素
ZSCORE key member//返回有序集合key中元素member的分值
ZINCRBY key increment member//为有序集合key中元素member的分值加上increment 
ZCARD key//返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES]//正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]//倒序获取有序集合key从start下标到stop下标的元素
ZUNIONSTORE destkey numkeys key [key ...]//并集计算
ZINTERSTORE destkey numkeys key [key …]//交集计算

bitmap(位图)

基于string类型实现,相当于是对一个二进制的字符串进行操作,每个位都表示一个数据,0和1表示不同的两种状态。

使用场景

  1. 布隆过滤器:将数据经过哈希算法和取模,最终数据可以落在bitmap的某一个位上,将这个位设为1,查询时如果存在,可能因为哈希冲突的问题不能确认当前记录是否存在,但是如果获取不到则一定不存在,可用于缓存穿透问题中对大部分系统内没有的数据进行过滤
  2. 用户登录:一个string最大长度是512MB,则一个bitmap最大可以记录一天内51210241024*8 = 4294967296个用户的登录情况

常用命令

setbit key offset value//对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。当 key 不存在时,自动生成一个新的字符串值。未设置的位置以 0 填充。
getbit key offset //对 key 所储存的字符串值,获取指定偏移量上的位(bit)。当 offset 比字符串值的长度大,或者 key 不存在时,返回 0
bitop operation destkey key [key ...]//对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种
bitop and destkey key [key ...]//获取指定的天数都有登录的用户
bitop or destkey key [key ...]//指定天数中登录过的用户
bitcount key [start] [end]//计算给定字符串中,被设置为 1 的比特位的数量。

HyperLogLog(超日志)

HyperLogLog(HLL)是一种概率数据结构,用于估计集合中唯一元素的数量,而不需要存储这些元素本身。

使用场景

  1. 可用于统计大数据量且不重复的数据,例如一个页面的用户访问量,用户需要去重的情况

常用命令

PFADD key elemet [elemet...]# 添加元素到HyperLogLog
PFCOUNT key#获取HyperLogLog的基数估计值
PFMERGE destkey key[key...]# 合并多个HyperLogLog

Geospatial(地理空间)

地图经纬度信息,基于Sort set实现,存入时会将经纬度通过GeoHash算法转换为整数作为score存入sort set

使用场景

  1. 计算两点之间的距离
  2. 附件的人

常用命令

GEOADD key longitude latitude member [longitude latitude member ...]//将一个或多个指定的地理位置(经度和纬度)添加到给定的键(key)中。
GEOPOS key member [member ...]//返回一个或多个在键(key)中已存储的地理位置的坐标(经度和纬度)。
GEODIST key member1 member2 [m|km|mi|ft]//计算两个地理位置之间的距离。
GEORADIUS key longitude latitude radius m|km|mi|ft [WITHCOORD] [WITHDIST]//返回给定中心坐标和半径内的所有地理位置。
GEORADIUSBYMEMBER key member radius m|km|mi|ft [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]//返回与给定位置名称为中心的指定半径内的所有地理位置。
GEOHASH key member [member ...]//返回一个或多个位置对象的Geohash表示。

Stream (流)

  1. redis最早可以使用list来实现消息队列,但是list只能由一个消费者消费,不能广播。
  2. 之后redis引入了发布/订阅模式,l引入一个概念叫channel,生产者通过publish接口投递消息时会指定channel,消费者通过subscribe接口订阅它关心的channel,调用subscribe后这条连接会进入一个特殊的状态,通常不能在发送其他请求,当有消息投递到这个channel时Redis服务端会立刻通过该连接将消息推送到消费者。这里一个channel可以被多个应用订阅,消息会同时投递到每个订阅者,做到了消息的广播。另一方面,消费者也可以订阅一批channel。这解决了List结构单播的局限,允许一个消息被多个客户端接收。但是pub/sub模式中,是不管消费者是否接受到消息的,发完广播消息就删掉了,所以容易出现消息丢失的问题。
  3. redis在5.0之后引入了stream,提供了消息持久化,消费者群组,消费者待确认消息列表以及消费者确认消息的功能

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

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

相关文章

Mysql The last packet sent successfully to the server was 0 milliseconds ago.

项目启动后,报错,但是我的navicat 数据库连接工具是连接上的,没有问题的,但是程序就是连接不上。端口放开了,防火墙也放开了 先说问题:是网络问题, 如何解决:因为我的机子上又跑了…

vue-textarea光标位置插入指定元素

vue-textarea光标位置插入指定元素 需求 点击插入关键字的时候把内容插入到光标所在的位置 效果图 实现 html <div class"temlate-container"><div class"template-content"><el-inputref"modelContent"v-model"mould.m…

HarmonyOS NEXT 使用XComponent + Vsync 实现自定义动画

介绍 XComponent 提供了应用在 native 侧调用 OpenGLES 图形接口的能力&#xff0c;本文主要介绍如何配合 Vsync 事件&#xff0c;完成自定义动画。在这种实现方式下&#xff0c;自定义动画的绘制不在 UI 主线程中完成&#xff0c;即使主线程卡顿&#xff0c;动画效果也不会受…

Android 获取手机整体流量使用情况以及某个应用的流量的统计

源代码下载地址&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/b6ab9000c0bd

java高校办公室行政事务管理系统设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于mvc的高校办公室行政…

嵌入式Linux开发实操(十七):Linux Media Infrastructure userspace API

视频和无线电流媒体设备使用的Linux内核到用户空间API,包括摄像机、模拟和数字电视接收卡、AM/FM接收卡、软件定义无线电(SDR)、流捕获和输出设备、编解码器设备和遥控器。典型的媒体设备硬件如下: 媒体基础设施API就是用于控制此类设备的,分五个部分。 第一部分V4L2 API…

【编程Tool】VS code安装与使用配置保姆级教程

目录 1.软件介绍 2.软件下载&#xff1a; 3.安装 3.1. 双击可执行文件 3.2. 同意协议 3.3. 选择安装路径&#xff0c;默认在C盘 3.4. 点击下一步 3.5. 可选择所有附加任务 3.6. 点击安装 3.7. 等待安装 3.8. 点击完成 3.9. 安装成功 4.下载MinGW64 4.1. MinGW-64下载地址 &…

labview中循环停止事件的深入研究

1.错误用法 第一次值事件运行的时候空白按钮给的F值&#xff0c;第二次值事件运行的时候空白按钮给的T值&#xff0c;这时循环才真正结束。 2.正确用法之一 赋值和值改变事件从同时进行变成按顺序执行。 3.正确用法之二 值事件发生以后超时事件将T值赋值给结束条件&#xff…

堆的概念、堆的向下调整算法、堆的向上调整算法、堆的基本功能实现

目录 堆的介绍 堆的概念 堆的性质 堆的结构 堆的向下调整算法 基本思想&#xff08;以建小堆为例&#xff09; 代码 堆的向上调整算法 基本思想&#xff08;以建小堆为例&#xff09; 代码 堆功能的实现 堆的初始化 HeapInit 销毁堆 HeapDestroy 打印堆 HeapPrint …

【ZYNQ】Zynq 芯片介绍

Zynq 是 Xilinx 公司提出的全可编程 SoC 架构&#xff0c;集成了单核或多核 ARM 处理器与 Xilinx 16nm 或 28nm 可编程逻辑&#xff0c;包括 Zynq 7000 Soc&#xff0c;Zynq UltraScale MPSoC 和 Zync UltraScale RFSoC 等系列。本文主要介绍 Xilinx Zynq 7000 系列芯片架构、功…

[阅读笔记20][BTX]Branch-Train-MiX: Mixing Expert LLMs into a Mixture-of-Experts LLM

这篇论文是meta在24年3月发表的&#xff0c;它提出的BTX结构融合了BTM和MoE的优点&#xff0c;既能保证各专家模型训练时的高度并行&#xff0c;又是一个统一的单个模型&#xff0c;可以进一步微调。 这篇论文研究了以高效方法训练LLM使其获得各领域专家的能力&#xff0c;例如…

欧科云链:香港虚拟资产OTC合规在即,技术监管成市场规范关键

4月12日香港OTC发牌制度公众咨询结束后&#xff0c;欧科云链研究院在星岛日报发表专栏文章&#xff0c;分享对香港OTC市场的调研情况&#xff0c;并提出“技术监管是香港OTC及Web3生态走向规范的关键”。欧科云链研究院认为&#xff0c;随着OTC监管及虚拟资产现货ETF等事件向前…