【Redis】学习总结

一、数据类型
Redis支持五种数据类型:
【Redis】学习总结
文章图片

二、主从复制机制
Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构
Redis主从复制可以根据是否是全量分为全量同步和增量同步。
1. 全量同步 Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

  • 1)从服务器连接主服务器,发送SYNC命令;
  • 2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
  • 3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  • 4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  • 5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  • 6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。
2. 增量同步 Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
3. 主从同步策略 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
Redis 2.8 以后提供了PSYNC优化了断线重连的效率
三、集群方案
四种主流的redis架构方案
  • 客户端分片
  • Redis Cluster
  • Twemproxy
  • Proxy + Redis Cluster
四、持久化方式
redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Apend Only File)。
1. RDB 概念:是一种快照式的持久化方法,将某一时刻的数据持久化到磁盘中。过程如下
  • redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。
  • 对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。
  • 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
优缺点:
  • 优点:最大化redis的性能,恢复大的数据集时速度更快;
  • 缺点:意外宕机时,会丢失数据(取决于配置的save时间点)
    2. AOFAOF方式是将执行过的写指令记录下来,在数据恢复时按照丛前到后的顺序再将指令执行一遍。
  • AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。
  • 如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。
  • 因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。
  • 在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性。
优缺点
  • 优点:
  • 缺点:体积较大,数据持久慢
五、内存回收机制
1. 过期删除策略
  • 定时删除:对每一个设置了过期时间的key都会创建一个定时器,一旦达到过期时间就立即删除。
    • 优点:可立即清除过期的数据,对内存友好
    • 缺点:占用了大量CPU资源去处理过期数据,会影响Redis的吞吐量和响应时间。
  • 惰性删除:当访问一个key时,才判断是否过期,过期则删除。
    • 优点:最大限度地节省CPU资源。
    • 缺点:对内存十分不友好,极端情况会出现大量过期key没有被再次访问,因此不会被清除,导致占用了大量的内存。
  • 定期删除:每隔一段时间,扫描redis中过期key字段,并清除部分过期的key。
    • 该策略是前两者的一个折中方案,还可以通过调整定时扫描的时间间隔和每次扫描的限定耗时,在不同情况下使得CPU和内存资源达到最优的平衡效果
    2. 内存淘汰策略
  • no-enviction(默认):禁止驱逐数据。不会删除任何数据,拒绝所有写入操作并返回客户端错误信息,此时Redis只响应读操作。
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间(server.db[i].dict)中,移除最近最少使用的 key。
  • allkeys-random:在键空间(server.db[i].dict)中,随机移除某个 key。
  • volatile-lru:在设置了过期时间的键空间(server.db[i].expires)中,移除最近最少使用的 key。
  • volatile-random:在设置了过期时间的键空间(server.db[i].expires)中,随机移除某个 key。
  • volatile-ttl:在设置了过期时间的键空间(server.db[i].expires)中,有更早过期时间的 key 优先移除。
    注:
    lru:Least Recently Used,最近最少使用 lfu:Least Frequently Used,最不经常使用

六、分布式锁
  1. 数据库乐观锁;
  2. 基于Redis的分布式锁;
  3. 基于ZooKeeper的分布式锁。
七、缓存穿透、雪崩、击穿
1. 缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决办法:
  • 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
  • 也可以采用一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
2. 缓存雪崩 【【Redis】学习总结】如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。
解决办法:数据预热、缓存不过期、做二级缓存,或者双缓存策略
3. 缓存击穿 缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
解决方法:使用互斥锁等

    推荐阅读