redis八股文


前言

redis八股文总结,后面有待补充


提示:以下是本篇文章正文内容,下面案例可供参考

1、什么是redis

redis是一种基于内存的数据库,对数据的读写操作都是在内存中完成的,因此读写速度非常快,常用于缓存、消息队列、分布式锁等场景
redis提供了多种数据类型来支持不同的业务场景,比如string(字符串)、hash(哈希)、List(列表)、set(集合)、Zset(有序集合)、Bitmaps(位图)、HyperLogLog(基数统计)、GEO(地理信息)、Stream(流),并且对数据类型的操作都是原子性的,因为redis执行命令是单线程,不存在并发竞争的问题

为什么用redis作为mysql的缓存
主要是因为redis具备高性能和高并发两种特性

  1. redis具备高性能
    用户第一次访问mysql中的某些数据,因为是从硬盘上读取的,所以过程会比较慢。将该用户访问的数据缓存在redis中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了,操作redis就是直接操作内存,不用访问硬盘,所以速度相当快。
    由于mysql数据改变后,需要同步改变redis缓存中的数据,不过这里会有redis和mysql双写一致性的问题。
  2. redis具备高并发
    单台设备的redis的QPS(每秒钟处理完请求的次数)是mysql的十倍,所以redis能够承受的请求是远远大于mysql的,因此可以考虑把数据库中的部分数据转移到缓存中去。

2、redis数据结构

2.1 五种类型是什么及使用场景

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

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

redis后续又支持四种数据类型:

  • BitMap:二值状态统计的场景,比如签到、判断用户登录状态、连续签到用户总数等。
  • HyperLogLog:海量数据基数统计的场景,比如百万级网页UV计数等。
  • GEO:存储地理位置信息的场景,比如滴滴叫车
  • Stream:消息队列,相比于基于List类型实现的消息队列,可以自动生成全局唯一消息ID,支持以消费组形式消费数据。

2.2 五种常见数据类型怎么实现

String类型内部实现

string类型底层数据结构使用简单动态字符串(SDS),SDS相比于C的原生字符串:

  • SDS不仅可以保存文本数据,还可以保存二进制数据(即能保存图片、音频、视频、压缩文件)
  • SDS获取字符串长度的时间复杂度是O(1),用len属性记录了字符串长度,复杂度为O(1)
  • Redis的SDS API 是安全的,拼接字符串不会造成缓冲区溢出。

String类型的使用场景

  • 常规计数,redis执行命令是单线程的,所以执行命令的过程是原子的。因此String类型适合用于计算访问次数、点赞、转发、库存数量等。
  • 分布式锁,setNx,如果key不存在才插入,即
    • 如果key不存在,则显示插入成功,可以用来表示加锁成功
    • 如果key存在,会显示插入失败,即可用来表示加锁失败
      一般而言,还会对分布式锁设置过期时间,防止某一线程崩溃,锁一直无法释放
  • 共享session信息
    在分布式系统中,借助redis对session信息进行统一的存储和管理,这样无论请求发送到哪台服务器,服务器都会去同一个redis获取相关的session信息,这就解决了分布式系统下session存储的问题。

List类型内部实现

双向链表或压缩列表实现,简单的字符串列表,按照插入顺序排序
元素较少,使用压缩列表(连锁更新情况保存前一个entry的长度,比较耗性能);元素较多使用双向链表;后期改为quickList,其实就是双向链表+压缩链表。
quickList
应用场景:消息队列
消息队列有三大需求:消息保序(list先进先出保证)、处理重复的消息(每个消息都会有个全局的id,消费者记录已处理过的消息id,来判断当前收到的消息有没有经过处理,如果处理过,消费者程序就不再进行处理)和保证消息可靠性(BRPOPLPUSH命令,让消费者程序从一个list读取消息,同时,redis将这个消息插入到另一个list(备份list)中留存
List作为消息队列,有缺陷:
list不支持多个消费者消费同一条消息,即不支持消费组的实现
Hash内部实现
压缩列表或者哈希表实现,redis7后压缩表列表舍弃,交由listpack数据结构实现(不存储上一个节点的长度,不出现连锁更新问题)。元素个数较少,使用压缩列表(listpack),较多使用哈希表
应用场景

  • 缓存对象
  • 购物车

set内部实现
哈希表或整数集合来实现
元素个数较少,使用整数集合;较多使用哈希表。
set集合的几个特性:无序、不可重复、支持并交差
应用场景

  • 点赞 (一篇文章有多少用户点赞,去重)
  • 共同关注
  • 抽奖活动(去重,保证一个用户不会中奖两次)

zset内部实现
小:压缩列表(listpack),多:跳表
有序集合
使用场景

  • 排行榜
  • 电话、姓名排序

Bitmap
位图,可以通过偏移量(offset)定位元素,即可以将最小的单位bit来进行0/1的设置,表示某个元素的值或者状态,特别适合一些数据量大且使用二值统计的场景,用String类型作为底层数据结构
应用场景

  • 签到统计
  • 判断用户登录状态
  • 连续签到用户总数

hyperLogLog
统计基数的数据集合类型,提供不精确的去重计数,用很小的内存空间,计算出很多元素的基数
使用场景
百万级网页UV计数

GEO
存储地理位置信息,并对存储的信息进行操作,使用数据类型为zset,sorted set
应用场景
滴滴叫车

Stream
消息队列,在list基础上增加了消费组的实现。

2.3 redis线程模型

2.3.1 redis是单线程嘛

redis单线程是指[接受客户端请求 -> 解析请求 -> 进行数据读写操作 -> 发送数据给客户端]这个过程是由一个线程来完成的
redis程序并不是单线程的,redis在启动的时候,会启动后台线程的。
redis会为很耗时的任务创建单独的线程来处理,如关闭文件、AOF刷盘、释放内存
注意redis的单线程只局限于网络IO和执行命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值