Redis之数据类型

Redis常见数据类型与应用场景

Type1:String

内部实现

  • 也是key-value的形式。value 也可以是整数 不一定非得是String 最多容纳512mb

  • 底层数据结构是int 和 SDS(简单动态字符串) SDS和C的不一样,区别在于

    • 不仅能保存文本数据 还能保存二进制数据 根据长度len来判断是否结束而不是空值 存放在buf[]中
    • 本身就保存len 所以获取长度为O(1)(SDS包含free剩余空间 len内容长度 buf存放内容)
    • 安全、拼接不会溢出 因为空间不够会自动扩容,不是死的
  • 字符串对象内部编码int raw embstr

    • int 整数值保存在ptr属性里
    • embstr 长度小于32字节时 一次分配连续内存保存redisObject 和SDS(只读的,但能提升性能 修改时变成raw)
    • raw 长度大于32bit时用 两次内存分配分别存放redisObject 和SDS
      在这里插入图片描述

应用场景

  • 缓存对象
    • user:1:name---->xiaolin user:1:age---->18 user:2:name---->xiaomei user:2:age---->20
    • SET user:1 ‘{“name”:“xiaolin”, “age”:18}’ (json)
  • 常规计数:redis处理命令是单线程、原子性的 计数不会混乱 适合:计算访问次数、点赞、转发、库存数量
  • 分布式锁:利用”不存在才插入的特性“来实现分布式锁 key存在则加锁失败 并且可以设置过期时间 来释放锁(解锁:先判断是否是加了锁的 再解锁 这个需要保证原子性)
  • 共享session信息 :session常用来表示登录状态 当服务器分布式时,别的服务器不知道登录信息,就需要重新登录 ,这里可以用redis缓存来解决
    *在这里插入图片描述

Type2:List

内部实现

  • list按照插入顺序排序 包括头插和尾插 先进先出
  • 数据结构是quicklist 快速链表 快速链表是压缩链表和双向链表的集合体,将链表按段切分,每一段使用压缩链表ziplist来存储 ,多个段之间用双向指针串接起来。压缩链表是多个结点凑成一段,次序为 内存大小、 到尾部距离、结点数、各个结点、尾端
    在这里插入图片描述
    在这里插入图片描述

应用场景

  • 消息队列:处理消息要满足三个需求
    • 01、消息保序: 先发的消息先收到 因为list本身就是先入先出 刚好符合 LPUSH+RPOP(或者反过来) 生产者将消息插入到队列的头部 消费者依次读取消息
    • 注:有个潜在的性能风险点 :生产者发消息时不会告诉消费者,消费者想及时处理消息就要不停的RPOP,有消息则得到消息,没有则得到空 。消费者的CPU一直在读消息 ,带来性能损失。
    • 解决办法:redis提供了BRPOP命令,即阻塞式读取,客户端没有消息时,自动阻塞,有消息才开始读取数据。节省性能开销。
      在这里插入图片描述
      BPORP
  • 02、处理重复的消息:消费者要记录消息id,对于重复的消息不会再处理。但是List并不会自动为消息生成id号。我们要自行为消息生成一个全局唯一id。因此push的消息是加了id的
  • 03、保证消息的可靠性:消费者读取消息后list不会保留这个消息了,如果消费者处理消息时宕机,那么就读不到这个消息了。redis的list提供了BRPOPLPUSH命令,消费者读完消息后,这个消息放到另一个list中作为备份
  • 缺点:不支持多个消费者读取同一个消息。这个功能需要将消费者组成消费组,但是list不支持这个功能。需要靠后面的Stream

Type3:Hash

内部实现

  • 键值对集合 (key-value)其中value={(field1,value1),(field2,value2)…(field1,value2)}
  • 底层结构为压缩列表和哈希表 redis7.0之后用listpack实现
    在这里插入图片描述

应用场景

  • 缓存对象:key field value 和对象的 对象id 属性 值这种天然相似,所以可以用来存储对象
  • 本来string + json也可以存储对象 一般对象用它存储,那些属性值频繁改变的用hash存储
  • 购物车:用户id(key) 商品id(field) 商品数量(value)
    在这里插入图片描述

Type4:Set

内部实现

  • set是无序唯一的键值集合。存储顺序与插入顺序无关;放进去多个一样的值只会保存其中一个。
  • 有集合的特性,除了支持集合内的增删改查,还支持多个set集合之间的交集、并集、差集。
  • k1----> it、music、sport、…
  • set 和 list 的区别
    • list按照插入的先后顺序排序
    • list可以存储重复元素
  • 内部实现:元素为int且<512个 用整数集合存 ,其余情况用哈希表

应用场景

  • 应用场景取决于其特性:无序、唯一、支持并交差操作
  • 注:潜在风险是 求差集、交集、并集的计算复杂度很高,数据量较大的时候进行这些计算,会产生Redis实例阻塞
  • 场景1:点赞 保证一个用户只能点一个赞(唯一性)eg: article1---->uid:1; article1---->uid:2;article1---->uid:3 重复点赞不会增加赞数
  • 场景2:共同关注(交集) 用交集来计算可以关注的共同好友、公众号
  • 场景3:抽奖 去重功能保证一个人不会中奖两次 存 lucky—>a,b,c,d,e,… 抽奖lucky 2得到 c,e

Type5:Zset

内部实现

  • Zset是有序集合类型,相比set多了个score用于排序 key---->score+内容
  • 元素数小于128且单个小于64用 用压缩列表实现
  • 其余用跳表实现
  • zset不支持差集运算 其他和set运算差不多
    在这里插入图片描述

应用场景

  • 排行榜:用score排序
  • 电话、姓名排序 这里要求score一样 按照内容排序(A-Z)

Type6:BitMap

内部实现

  • 这是位图,是一串连续的二进制数组01 可以通过偏移量(offset)来定位元素 、
  • 非常节省空间,特别适合于非常大数据量且用二进制值统计的场景
  • 底层数据结构是String 但每个位置存放01可以看成bit数组

应用场景

  • 签到统计 用01标记是否签到 101101010111111.。。一年也才365bit
  • 判断用户登录状态
  • 连续签到用户总数 周一 110 周二 111 周三 111 。。。周日101 这些一起与运算 得到 100说明就一个人连续七天打卡了、

Type6:HyperLogLog

介绍

  • 是一种用于{统计基数}的数据集合类型 基数统计就是统计一共集合中不重复元素个数
  • 它是基于概率完成的,不是非常准确的 误差率是0.81%
  • 简单来说功能就是提供不精确的去重计数
  • 优点:在输入元素数量级特别大的时候,计算所需内存空间总是固定的,而且很小 12kb空间就能计算2^64个元素的基数

应用场景

*统计百万级网页UV计数(独立访客数量) 比如统计直播间访问人数 100万 但可能真实结果是101万 不精确但是内存小


Type7:GEO

内部实现

  • 用sorted set集合类型
  • 存储地理空间位置的经纬度
  • 使用GeoHash编码的方法实现了经纬度到SortedSet元素权重分数的转化 按照权重可以查询地理位置的附近范围地址

应用场景

  • 滴滴叫车 根据用户自己的经纬度信息查找周围五公里内的车辆信息

Type8:Stream

介绍

  • 这时专门为消息队列设计的数据类型,弥补list的不足
  • List的不足:不能持久化 无法可靠的保存消息 不能重复消费消息 需要自行实现全局唯一id
应用场景

消息队列

  • 生产者通过XADD插入一条消息 而且可以同时生成唯一id (由插入数据时以毫秒为单位计算的时间+该毫秒内消息的次序)
  • 还可以实现阻塞读 设定阻塞时间 没有消息到来 阻塞一段时间再返回
  • XGROUP创建消费组 一堆消息来了 消费组1 2 3 都能读取这些消息 组内分工每个处理一部分消息 从而分担消息 实现负载的均衡(消息队列中的消息一旦被组内某个读取,就不能被组内其余读取)
  • 会使用内部队列留存消费者读取过的消息 直到用XACK通知stream消息已经处理完成(消费者重启后也可以去看看已读取为确认的消息)
    在这里插入图片描述
  • 总结:消息保序、阻塞读取、重复消息处理、消息可靠性、支持消费组读取数据。

Redis Stream会出现消息丢失吗

在这里插入图片描述
三大块:消息生产者、队列中间件、消费者 保证闭环就是保证这三个消息不丢失
在这里插入图片描述

Redis Stream会消息可堆积吗

Stream提供了可以指定队列最大长度的功能 长度超过上限后,删除旧消息 所以还是会有丢失风险的

场景

  • 业务场景简单,对数据丢失不敏感,消息积压概率较低的情况下,完全可以用redis
  • 如果不能接受上述,还是用专业的消息中间件吧
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值