Redis知识点

redis是什么

redis是有C语言编写的高性能非关系型键值对数据库;
官方的说法是读可达到100000次/s,写可达810000次/s,
采用IO多路复用模型处理处理网络请求,
单进程执行命令保证了原子性。

优点

  1. 读写性能优秀,开源nosql数据库中性能最好
  2. 支持丰富的数据类型:string、hash、list、set、zset
  3. 好用的增强功能:bitmap作为布隆过滤器,HyperLogLog估算集合的基数
  4. 提供数据持久化:RDB、AOF
  5. 自带cluster和主从复制

缺点

  • 数据库容量受物理内容限制,无法作为海量数据的高性能读写
  • 不具备自动容错和恢复的功能,主从机宕机都会导致请求失败
  • 哨兵的监控和数据同步过程中可能发生(脑裂)问题,主机假死,从升主的过程中,有数据继续写入原主机,导致数据不一致
  • 难以在线扩容
  • 持久化策略仍然可能有数据丢失
  • 内存溢出的部分淘汰策略也可能导致数据丢失

redis为什么快

  • 完全基于内存
  • 精巧的底层数据结构简单动态字符串、hash表、双向链表、数组、跳表、压缩链表,基本操作都是O(1),集合的全量查询和集合操作也只是O(n)的时间复杂度
  • 采用单线程执行command,避免了不必要的上线文切换和竞争问题
  • 使用多路IO复用模型,提高吞吐量
  • RESP协议,简化回复数据解析过程
  • 6.0以后采用多进程处理网络IO进一步提高吞吐量(请求获取后寄存到队列中,执行命令还是单线程)

有哪些数据类型

数据类型 底层数据结构 应用场景
string 简单动态字符串 简单的热点数据
hash hash-map,压缩链表 对象
list 双向链表,压缩链表 队列
set 数组,压缩链表 集合
zset 跳表,hash-map 有序集合,排行榜,热门数据分页

持久化

提供两种持久化方式RDB和AOF

RDB:默认的持久化方式,快照保存,间隔m秒内有n个数据发生变化,触发一次bgsave

优点:

  • 容灾性好,全量备份,只有一个dump.rdb文件,rdb文件紧凑
  • 性能好,bgsave命令fork子进程进行持久化,主进程不需要进行任何磁盘IO
  • 相对数据集大时,比AOF的恢复效率高

缺点:

  • 数据安全性低,间隔一段时间的持久化策略,间隔时间中的数据可能会丢失,子进程备份数据期间主进程发生的修改不会反应给子进程,数据会丢失
  • fork子进程需要增加内容开销,如果内存不足,可能会使用虚拟内存,导致redis阻塞

AOF:Append Only File,redis执行的命令记录到单独的日志文件中;

三种触发机制:

命令 always everysec no
优点 不丢数据 fork子进程进行备份,性能好 不备份
缺点 同步进行,主进程参与磁盘IO 可能会丢失1s的数据 --

优点:

  • 更好的保护数据,一般采用everysec策略,只会丢失1s的数据
  • 没有磁盘寻址的的开销,写入性能高
  • AOF文件可读性强,适合做灾难性误删除的紧急修复(抢在bgrewriteaof之前)。

缺点:

  • 相对RDB,AOF文件更大

过期删除策略

  1. 定时删除,一般不采用,对cpu不友好
  2. 惰性删除,get这个key时检查是否过期,如果过期则删除,对cpu友好,浪费内存
  3. 定期删除,隔一段时间随机检测一些key,如果过期则删除,对内存好友,检查频率不宜过高,否则会对CPU造成压力

一般采用 惰性删除+定期删除

内存满后的淘汰策略

基于lru算法的

  • allkeys-lru
  • volatitle-lru

基于lfu算法的

  • allkeys-lfu
  • volatitle-lfu

随机删除

  • allkeys-random
  • volatitle-random

即将过期的

  • volatitle-ttl

不淘汰,直接报错的

  • noeviction

redis线程模型

redis基于reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的由4个部分组成:多个server socket、IO多路复用程序,文件事件分派器、事件处理器。因为文件事件分派队列的消费是单线程、同步、阻塞的,redis才被称为单线程模型。

  • IO多路复用程序同时监听多个socket,并根据套接字目前执行的任务为套接字关联不同的时间处理器。实现了高性能的网络通信模型
  • 当被监听的套接字准备好执行应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相应的文件事件就会产生,这是文件事件处理器,就会调用套接字之前关联好的事件处理器来处理这些时间。

事务

配合piple使用,既可以保证原子性,也可以减少开销;
==redis的事务只保证一致性和隔离性==。

watch 监控key
multi 开启事务
exec 执行事务
discard 放弃事务
//如果监控的key发生改变,事务执行失败

redis集群的方案

  1. 推特开源的twemproxy,是一个代理服务,使用方式简单与使用普通的redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以代理的方式接收请求并使用一致性hash算法,将请求转发给具体的redis实例,再讲结果返回给twemproxy,是对就项目扩展的首选。

问题:twemproxy自身单端口实例的的压力,使用一致性hash后,redis节点数改变计算值改变,数据无法自动转移到新的节点。

  1. 豌豆荚开源的codis,目前用的最多的集群方案,基本上跟twemproxy的效果一致,弥补了twemproxy对redis节点数改变的情况下,旧节点数据无法自动转移到新节点的问题。
  2. redis3.0以后自带的cluster。利用hash slot的概念,以及自身支持主从。请求发送给任意节点,接收到请求的节点会查询节点,客户端再redirect到正确的节点上执行。
  3. 业务代码实现,多个无关的redis实例,对数据进行hash分配到对应的redis实例。

优点:简单灵活,易于线性扩展

缺点: 不支持动态增删节点,服务端redis的实例群拓扑结构变化时,每个客户端都需要更新调整。连接不能共享,当应用规模增大时,资源浪费制约优化。

分布式寻址算法:

  1. hash算法,一般采用取模的方式进行分片
  2. 一致性hash
  3. hash slot 哈希槽

主从复制

再从节点配置 slaveof masterip masterport

过程:

  1. 从节点发主节点发送sync请求
  2. 主节点快照生成rdb文件,在次期间缓存新的命令
  3. 快照完成后,主节点将rdb文件和所有缓存的写命令发送给从节点
  4. 从节点保存rdb文件,载入数据,之后执行缓存中的命令
  5. 之后,主节点没当接收到写命令都会讲命令发送给从节点

缺点:复制和同步都需要主节点处理,会造成master节点压力太大,使用主从从架构解决

redis集群中的主从是怎样的?

集群中有N个节点,至少一个从节点

分布式锁

官方推荐了redlock

  1. 高可用,超过半数的节点可用,就能保证加锁成功
  2. 可重入,避免死锁
  3. 排他性
  4. 避免误删,自由持锁者可以解锁

缓存异常

雪崩

统一时间缓存大面积失效

解决方案:缓存的过期时间附加一个随机值,避免同时失效

穿透

请求缓存中不存在的数据

解决方案:

  1. 不存在的数据也进行缓存(出现穿透很可能是遭到攻击,该方案会导致出现大量无意义缓存)
  2. bimap,布隆过滤,快速高效的校验数据是否存在。占空间很少
  3. 接口层校验,比如id<0的请求直接拦截

击穿

某个并发量极高热点数据过期
解决方案:

  1. 这种数据不设置过期时间,(注意淘汰策略不要设置成allkeys-random)
  2. 加互斥锁,只允许一个请求进入数据库查询

预热

系统上后,直接将数据加载到缓存内,避免用户请求时再去刷新缓存。

  1. 写一个脚本,上线后跑一下
  2. 数据量不大,自己把页面点一下

缓存降级

访问量剧增,非核心服务出现问题影响大核心服务,系统可以自动降级,也可以配置开关实现人工降级。

比如雪崩导致数据库压力骤增,打爆了数据库。此时可以让非核心服务的请求直接返回404,而不去请求数据库。

你可能感兴趣的:(Redis知识点)