前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis面试知识点-精简版

Redis面试知识点-精简版

作者头像
炳臣
发布2020-05-18 17:25:07
5320
发布2020-05-18 17:25:07
举报
文章被收录于专栏:一块自留地一块自留地

一、redis数据结构

redis的所有数据结构都以唯一的key作为名称,然后通过key获取对应的value数据,不同类型的数据结构的差异就在于value的结构不一样。

  • Sting
  • list
  • hash
  • set
  • zset
1.1、string
1.1.1、结构

字符串String是redis中最简单的数据结构,也是我们最常用的。它的内部结构就是一个字符数组,底层是由SDS,即"simple dynamic string"来实现的,SDS结构入下:

代码语言:javascript
复制
stryct SDS<T>{
    T capacity;     //数组容量
    T len;          //数组长度
    byte flags; 
    byte[] cotent; //数组内容
}

也可以通过下图来更好理解:

1.1.2、特点

SDS是动态字符串,内部实现类似与ArrayLisk,采用预分配空间的方式来减少内存的频繁分配,所以一般字符容量capacity要高于实际字符长度len。 当字符串长度小于1MB,扩容是加倍现有空间, 当字符串长度大于1MB,扩容时一次只会多扩1MB, 字符串长度最大为512MB。

1.2、list

redis的list结构是个链表,相当于LinkedList,但是底层其实是由ziplist+quicklist实现的。 ziplist在元素个数较少时使用,采用压缩列表,是一块连续的内存空间,元素之间紧挨着存储,没有任何冗余空间,不像SDS。 由于ziplist是没有冗余空间的,所以每次新增元素都需要扩容,如果ziplist占据内存太大,重新分配内存和拷贝内存就会有很大消耗,所以它不适合存储大型字符串,数量也不宜过多。

quicklist在元素个数较多时使用,它就是把ziplist当作元素,多个ziplist之间使用双向指针串起来。

代码语言:javascript
复制
struct quicklistNode{
    prev;
    next;
    ziplist*zl;     //指向压缩列表
    int32 size;     //ziplist的字节总数
    int16 count;    //ziplist中的元素数量
    ...
}
1.3、hash

redis的hash字典相当于hashMap,都是数组+链表结构,不同的是,redis的字典只能是字符串,并且rehash方式不一样。

java的HashMap在字典很大的时候,是个很耗时的操作,因为需要一次性全部rehash。 redis为了追求高性能,采用渐进式rehash。它会保留新旧2个hash结构,查询时会同时查询2个hash,然后在定时任务中循序渐进的将旧的hash迁移到新的hash中。

1.4、set

redis的set类似于java的hashtable

1.5、zset

zset类似于SortedSet和HashMap的结合体,技能保证元素唯一,又可以排序。 它的内部实现是跳表。

二、redis事务

不支持回滚

三、redis单线程

  • 优点: 快、避免创建销毁线程的消耗、避免CPU上下午切换、避免资源竞争(加锁、死锁)
  • 缺点: 执行lua有死循环风险,整个redis服务端都会被阻塞,busy redis
  • 解决: 设置lua超时时间,script kill、shutdown nosave 钩子函数

单线程不会浪费CPU吗?官网说:cpu不是redis的瓶颈,内存和网络才是,单核已经够用了

四、redis为什么快?

  • 读取内存
  • KY数据结构,数据复杂度是O1
  • 单线程
  • 异步非阻塞IO

redis慢的原因?

  • 检查RDB配置,是否每隔900s同步一次。
  • 改为凌晨1点同步,因为RDB是全量的,磁盘IO操作

建议:

  • 主节点:AOF,不影响使用
  • 从节点:RDB

五、过期策略

redis会把设置过期时间的key单独放到一个字典中去处理,它的过期策略有如下三种:

  • 定时扫描 redis默认每秒进行10次过期扫描,但不是扫面全部,而是采用一种简单的贪心策略: 从过期字典中随机选出20个key; 删除这20中过期的key; 如果过期的key超过1/4,就重复步骤; 同时为了避免循环过度,算法增加了扫面时间限制,默认不会超过25ms。
  • 懒惰过期 只在用到这个key的时候,进行判断,然后删除 优点:不占用cpu 缺点:占用内存
  • 定期过期: 达到最大内存阈值的时候,扫描一定数量进行删除
  • 从节点过期策略 从节点不会进行过期扫描,当主节点删除过期key时,会同步del指令到aof文件,同步给所有从节点。

六、内存淘汰策略

  • volatile-LRU :只对设置了过期时间的key进行LRU淘汰
  • allkeys-LRU: 对所有key进行LRU
  • volatile-LFU: 访问频率少的淘汰掉
  • allkeys-LFU:
  • volatile-random:随机
  • allkeys-random:
  • volatile-ttl:把最近要过期的key淘汰掉

LRU原理推荐阅读这篇文章:LRU原理

七、持久化机制

redis的持久化机制有2种:

  • RDB
  • AOF
7.1 RDB
7.1.1、什么是RDB

RDB 是redis默认的持久化方案。 它指的是只要满足一定条件,redis会把内存中的所有数据生成快照文件dump.rdb,保存在磁盘上。

7.1.2、RDB的触发机制:
  • 满足配置条件时 redis有以下几个默认配置:
代码语言:javascript
复制
    save (seconds) (changes)    
    save 900 1     #900秒内如果超过1个key被修改,则发起快照保存
    save 300 10    #300秒内容如超过10个key被修改,则发起快照保存
代码语言:javascript
复制
    这几个规则是叠加相互作用的。  
  • 停机的时候 shutdown
  • flushall
  • 手动触发 save命令,但是会阻塞 bgsave命令会异步执行 fork一个子进程进行持久化,主进程继续接收客户端请求 但是bgsave执行之后的数据不会被保存
7.2 AOF
7.2.1、什么是AOF

AOF就是将redis执行过的命令保存到appendonly.aof文件中,后续恢复的时候执行AOF中的命令。

7.2.2、触发机制
代码语言:javascript
复制
appendonly yes              //启用aof持久化方式
# appendfsync always      //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec     //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,默认是这个
# appendfsync no    //完全依赖os,性能最好,持久化没保证
7.2.3、重写机制

AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。

redis会fork一个子进程,从redis数据中重建一个AOF临时文件,最后用临时文件替换旧文件。

触发机制: 达到上次重写的100% 超过AOF指定大小

重写AOF时有新的命令进来了怎么办? 有一个AOF重写缓存,主进程把新进来的命令写到缓存中,当子进程重新完毕,最后把缓存并入AOF中。

7.3 AOF于RDB比较

RDB: 恢复速度快 会造成数据丢失 如果bgsave时数据量庞大,会影响性能,造成卡顿

AOF: 数据完整性更好 但是文件会比较大

AOF和RDB是可以一起配合使用的

面试: 如果同一时间有大量的key过期,会有什么后果?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年05月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、redis数据结构
    • 1.1、string
      • 1.1.1、结构
      • 1.1.2、特点
    • 1.2、list
      • 1.3、hash
        • 1.4、set
          • 1.5、zset
          • 二、redis事务
          • 三、redis单线程
          • 四、redis为什么快?
          • 五、过期策略
          • 六、内存淘汰策略
          • 七、持久化机制
            • 7.1 RDB
              • 7.1.1、什么是RDB
              • 7.1.2、RDB的触发机制:
            • 7.2 AOF
              • 7.2.1、什么是AOF
              • 7.2.2、触发机制
              • 7.2.3、重写机制
            • 7.3 AOF于RDB比较
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档