Redis概述与数据类型

深入复习Redis 常见面试题

Redis概述与数据类型

Redis介绍

  • Redis 是一个开源的 key-value 存储系统。

  • 和 Memcached 类似,它支持存储的 value 类型相对更多,包括 string (字符串)、list (链表)、set (集合)、zset (sorted set –有序集合) 和 hash(哈希类型)。

  • 这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。

  • 在此基础上,Redis 支持各种不同方式的排序。

  • 与 memcached 一样,为了保证效率,数据都是缓存在内存中。

  • 区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。

  • 并且在此基础上实现了 master-slave (主从) 同步。

应用场景

  • 配合关系型数据库做高速缓存

  • 分布式架构,做 session 共享。

请添加图片描述

  • 多样的数据结构存储持久化数据

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkqaJUCz-1686636730393)(null)]

Redis为什么那么快?

  • Redis是基于内存操作,需要的时候需要我们手动持久化到硬盘中

  • Redis高效数据结构,对数据的操作也比较简单

  • Redis是单线程模型,从而避开了多线程中上下文频繁切换的操作

  • 使用多路I/O复用模型,非阻塞I/O

想要详细了解I/O多路复用可看I/O 多路复用:select/poll/epoll

  • 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

为什么用 Redis 作为 MySQL 的缓存?

主要是因为 Redis 具备「高性能」和「高并发」两种特性

  1. Redis 具备高性能
    假如用户第一次访问 MySQL 中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据缓存在 Redis 中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了,操作 Redis 缓存就是直接操作内存,所以速度相当快。

img

  1. Redis 具备高并发
    单台设备的 Redis 的 QPS(Query Per Second,每秒钟处理完请求的次数) 是 MySQL 的 10 倍,Redis 单机的 QPS 能轻松破 10w,而 MySQL 单机的 QPS 很难破 1w。
    所以,直接访问 Redis 能够承受的请求是远远大于直接访问 MySQL 的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

Redis数据结构

Redis 数据类型以及使用场景分别是什么?

Redis 提供了丰富的数据类型,常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)。
在这里插入图片描述
Redis 五种数据类型的应用场景:

  1. String 类型的应用场景:缓存对象、常规计数、分布式锁、共享 session 信息等。
  2. List 类型的应用场景:消息队列(但是有两个问题:1. 生产者需要自行实现全局唯一 ID;2. 不能以消费组形式消费数据)等。
  3. Hash 类型:缓存对象、购物车等。
  4. Set 类型:聚合计算(并集、交集、差集)场景,比如点赞、共同关注、抽奖活动等。
  5. Zset 类型:排序场景,比如排行榜、电话和姓名排序等。

Redis 后续版本又支持四种数据类型,它们的应用场景如下:

  1. BitMap(2.2 版新增):二值状态统计的场景,比如签到、判断用户登陆状态、连续签到用户总数等;
  2. HyperLogLog(2.8 版新增):海量数据基数统计的场景,比如百万级网页 UV 计数等;
  3. GEO(3.2 版新增):存储地理位置信息的场景,比如滴滴叫车;
  4. Stream(5.0 版新增):消息队列,相比于基于 List 类型实现的消息队列,有这两个特有的特性:自动生成全局唯一消息ID,支持以消费组形式消费数据。

五种常见的 Redis 数据类型底层实现

  1. String 类型内部实现

String 类型的底层的数据结构实现主要是 SDS(简单动态字符串)。 SDS 和我们认识的 C 字符串不太一样,之所以没有使用 C 语言的字符串表示,因为 SDS 相比于 C 的原生字符串:
SDS 不仅可以保存文本数据,还可以保存二进制数据。因为 SDS 使用 len 属性的值而不是空字符来判断字符串是否结束,并且 SDS 的所有 API 都会以处理二进制的方式来处理 SDS 存放在 buf[] 数组里的数据。所以 SDS 不光能存放文本数据,而且能保存图片、音频、视频、压缩文件这样的二进制数据。
SDS 获取字符串长度的时间复杂度是 O(1)。因为 C 语言的字符串并不记录自身长度,所以获取长度的复杂度为 O(n);而 SDS 结构里用 len 属性记录了字符串长度,所以复杂度为 O(1)。
Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出。因为 SDS 在拼接字符串之前会检查 SDS 空间是否满足要求,如果空间不够会自动扩容,所以不会导致缓冲区溢出的问题。

  1. List 类型内部实现

List 类型的底层数据结构是由双向链表或压缩列表实现的:
如果列表的元素个数小于 512 个(默认值,可由 list-max-ziplist-entries 配置),列表每个元素的值都小于 64 字节(默认值,可由 list-max-ziplist-value 配置),Redis 会使用压缩列表作为 List 类型的底层数据结构;
如果列表的元素不满足上面的条件,Redis 会使用双向链表作为 List 类型的底层数据结构;
但是在 Redis 3.2 版本之后,List 数据类型底层数据结构就只由 quicklist 实现了,替代了双向链表和压缩列表。

  1. Hash 类型内部实现

Hash 类型的底层数据结构是由压缩列表或哈希表实现的:
如果哈希类型元素个数小于 512 个(默认值,可由 hash-max-ziplist-entries 配置),所有值小于 64 字节(默认值,可由 hash-max-ziplist-value 配置)的话,Redis 会使用压缩列表作为 Hash 类型的底层数据结构;
如果哈希类型元素不满足上面条件,Redis 会使用哈希表作为 Hash 类型的底层数据结构。
在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

  1. Set 类型内部实现

Set 类型的底层数据结构是由哈希表或整数集合实现的:
如果集合中的元素都是整数且元素个数小于 512 (默认值,set-maxintset-entries配置)个,Redis 会使用整数集合作为 Set 类型的底层数据结构;
如果集合中的元素不满足上面条件,则 Redis 使用哈希表作为 Set 类型的底层数据结构。

  1. ZSet 类型内部实现

Zset 类型的底层数据结构是由压缩列表或跳表实现的:
如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构;
如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构;
在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值