数据库-Redis

1.Redis

1.1 为什么要用Redis,特点是什么

  • what:基于键值对的数据库,
  • why:
    速度快[基于内存、单线程]、简单稳定、功能丰富【键过期、发布订阅、事务、流水线】、持久化、主从复制、高可用和分布式转移、客户端语言多【lua】

单线程:无锁,避免了多线程获取释放锁开销,免去可能的死锁所造成的性能问题;节省线程切换的cpu消耗

  • how:
    基本通讯模型:
    客户端发送消息----消息放入队列----执行命令----返回结果给客户端

1.2 Redis支持的数据类型,使用场景以及底层数据结构

  • String : 计数器,定时器 简单动态字符串,最大长度512M
  • Hash : 存储对象,用作缓存 哈希、压缩列表
  • List : 队列 双向链表、压缩列表
  • Set : 朋友圈 哈希表、整数数组
  • ZSet : 排行榜 跳表、压缩列表

1.3 Redis中String 的底层结构

SDS: [LEN长度,ALLOC剩余空间,char[]数据,flag数据类型大小] 简单动态字符串类型
好处:

  • 获取长度简单
  • 二进制安全 【字符以\0结尾】
  • 动态扩容,避免频繁的内存分配【alloc扩容时】
  • 防止内存溢出
  • 兼容c语言

1.3.1 Redis中的bitmap

  • what:位图,一个bit表示一个状态,只有两种状态【0/1】
  • why:占用内存空间低;排序、查找、去重效率高
    缺点:结果本身不能重复且只有0/1;数据量小时浪费空间
    适用场景:统计在线人数、签到统计
  • how :
  setbit  key offset value; //offset为偏移量  value取值0/1
  getbit  key offset //获取值
  bitcount key [start,end]//获取区间内值为1的个数
  BITOP AND destkey key [key …] //对一个或多个 key 求逻辑并,并将结果保存到 destkey 。
  BITOP OR destkey key [key …] //对一个或多个 key 求逻辑或,并将结果保存到  destkey 。
  BITOP XOR destkey key [key …] //对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。
  BITOP NOT destkey key//对给定 key 求逻辑非,并将结果保存到 destkey 。

1.4 Redis中ZSet 的底层结构

  • 压缩列表:【列表长度、尾步偏移量、列表个数---数据---列表结束标志】
    有序集合元素个数<128或者长度<64字节时采用列表
  • 跳表:增加了多级索引,通过多级索引的位置跳转,实现快速查找元素
    时间复杂度O(log)
    不采用树形结构的原因:范围查找效率更高;跳表实现更加简单易懂。

1.5 Redis支持的数据类型持久化【基于fork-join进行】

  • RDB:某一时刻点的数据生成快照存储在磁盘介质上;
    手动触发: save阻塞线程;bgSave使用fork子线程完成持久化,阻塞时间短
    自动触发:未开启aof时,自动执行bgSave
    优点:恢复数据快;全量复制用于灾备;
    缺点:无法做到实时持久化,每次都要创建子线程,频繁操作成本高;各版本文件不兼容

  • AOF:记录所有写操作,数据完整度更高。
    所有写入命令append追加到aof_buff中--缓冲区同步sync到硬盘--定期rewrite-- 重启时load
    三种同步机制appendSync:
    always:即时同步,性能差,不推荐
    everysec:每秒强制写入,性能和持久化都做了折中,推荐
    no:完全依赖os,性能最好
    重启时两文件同时存在,如何加载:优先aof

1.6 缓存雪崩、缓存穿透、缓存击穿以及对应解决方案

  • 缓存雪崩:大量key失效;错峰失效、二级缓存、访问限流
  • 缓存穿透:大量访问不存在的key;缓存预知空值、布隆过滤器【说不存在比不存在,但说存在不一定为真】
  • 缓存击穿:热key失效

1.7主从复制和哨兵

  • 主从集群: master节点负责数据读写,slave节点负责数据读取,master同步数据到slave;
    实现读写分离,提升查询效率;但不提供容错和恢复功能
  • 哨兵:主节点出现问题时,哨兵选举出新的主节点;在线扩容的问题依然未得到解决

1.8 集群

  • cluster:通过slot槽[16383]实现数据分片,根据key计算数据放哪个节点,每个Master节点实现主从复制;若出现故障,从从节点中选出一个主节点。
    • 优点 实现了扩容和故障转移的能力;
    • 缺点:客户端实现复杂;slave只是个冷备节点,不提供分担读写的能力;批量操作指令存在限制

1.8.1两种集群方式的区别【哨兵集群、cluster】

一个侧重高可用,一个侧重扩展性

  • 读写访问:哨兵集群基于主从复制,可实现读写分离,分担读操作访问压力;cluster的slave只实现了冷备功能,只有master宕机后才工作
  • 扩容:主从无法在线扩容,受制于单个服务器配置限制;cluster基于slot槽的数据分片实现,支持在线扩容
  • 架构:哨兵是一主多从,cluster是多主多从

1.9如何保证缓存与数据库的数据一致性

  • 延迟双删:先删除缓存,更新数据库,停顿几秒后再次删除缓存。
  • 队列异步: 消息放入队列,消费者异步删除redis。可达到解耦

1.10Redis分布式锁和看门狗机制

  • setnx加锁,设置过期时间
  • 看门狗:watch-dog 每隔10s看下,如果还持有锁,则延长生存时间
  • 防死锁,高性能,可重入锁

1.11 Redis的淘汰策略

当Redis内存超过MaxMemory限定时,触发主动清理策略

  • 算法:
    LRU:最近使用;底层哈希表+双向链表
    LFU:频率最高使用,底层为两个链表
    random:随机
    ttl:快要过期的先淘汰

  • keys: volatile allkeys
    redis淘汰策略

1.12 RedissionRedLock

  • 解决问题:主节点挂掉,从节点升级成为主节点时,分布式锁失效。
  • 步骤:记录当前时间;设置锁有效时间;去各个master节点获取锁,半数获取到的话计算获取时间是否超过锁有效时间;超时则返回失败,解锁。

1.13Redis删除策略

  • 惰性/被动删除:访问key时删除;遗留问题:冷数据一直不会删除占用内存
  • 定时/主动删除:每隔10s去轮询取得一定量key,删除其中过期的
    定时不生效时注意修改的时候是否未标注过期时间

1.14 你的项目出现过oOM嘛?怎么解决的?

OOM原因:maxMemory设置不合理,且未设置合适的maxMemory-policy
解决方案:

  • 调整maxMemory:分配大一些
  • 设置maxMemory-policy:默认为lru算法
  • 增加物理机内存,或者分布式存储

1.15 redis的pipeline

好处:减少网络传输开销

1.16 拓展

工业级分桶算法实现分位数
P99算法=100个数字从小到大排列后第99位的值=数组99%<该值=位置取整后的值+(取整后一位值-取整值)*(位置取证后一位-位置取整)

  • 数据集群会丢数据吗?怎么防止丢数据?
  • redis性能怎么样?你们的数据量多少【qps:】,key【几十个字节,小于1kb】 value【几kb吧】值大概又是多少?
  • 出现过什么问题?又是如何解决的?
  • 一个redis的写入大概多久10ms;key集中过期会怎么样【过期的时间会出现访问延迟】?
  • 内存优化

1.17 书籍推荐

《Redis设计与实现》《Reids深度历险:核心原理和应用实践》《Redis开发与运维》

1.18 附录

可搭配食用文章:面试 Redis 没底?这 40 道面试题让你不再慌(附答案)

红锁.png

Redis延迟问题全面排障指南

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容