Redis 相关

这是一篇笔者使用 Redis 后,重新了解 Redis 的要点记录。

致谢

把这篇博客献给我初次参与创业的公司新枝科技

它是一个开放而又包容的团队,在这里开始了我大学生涯的后端之路,感谢他。

笔记

Redis是一个开源的、由C语言编写的,基于内存的数据结构存储,可用作于数据库、缓存、消息中间件。

数据类型底层

常用数据类型有hash、string、list、set、sortedset,Key-Value形式,其中Key一定是string。

string -> SDS -> set,get,decr,incr,mget

hash -> ziplist/hashtable -> hget,hset,hgetall

list -> ziplist/linkedlist -> lpush,rpush,lpop,rpop,lrange

set -> intset/hashtable -> sadd,spop,smembers,sunion

zset -> ziplist/skiplist -> zadd,zrange,zrem,zcard

简单动态字符串 SDS

char buf[]; //字节数组

int len; //字符串长度

int free; //未使用长度

哈希表 hashtable

dict 结构内部包含两个 hashtable,通常情况下只有一个 hashtable 是有值的,数据结构类似于Java的 hashmap 。

但是在 dict 扩容缩容时,需要分配新的 hashtable,然后进行渐进式搬迁/渐进式 rehash ,这时候两个 hashtable 存储的分别是旧的 hashtable 和新的 hashtable 。待搬迁结束后,旧的 hashtable 被删除,新的 hashtable 取而代之。

Redis 的字典默认的 hash 函数是 siphash

压缩列表 ziplist

压缩列表是一块连续的内存空间,元素之间紧挨着存储,没有任何冗余空隙。

hash 中K、V紧挨着排列。

zset 中V、score紧挨着排列。

双向链表 linkedlist

普通的双向链表。

小整数集合 intset

intset 始终保持从小到大有序。

跳跃链表 skiplist

拔高某一部分,形成一个新的链表结构,便于查找。

优点

  • 纯内存操作。

  • 单线程,避免了上下文切换

  • 非阻塞I/O多路复用机制/事件驱动。

问题

缓存雪崩

缓存数据设置的过期时间相同,且Redis将这部分数据全部删光了。这就会导致在这段时间内,这些缓存同时失效,全部请求到数据库中。

缓存穿透

缓存穿透是指查询一个一定不存在的数据。由于缓存不命中,这将导致这个不存在的数据每次请求都要到数据库去查询,失去了缓存的意义。

缓存、数据库双写一致

  • 先更新数据库 再删除缓存

  • 先删除缓存 再更新数据库

过期策略

  • 定时删除

    到时间点上就把所有过期的键删除了。

  • 惰性删除 - Redis使用

    每次从键空间取键的时候,判断一下该键是否过期了,如果过期了就删除。

  • 定期删除 - Redis使用

    每隔一段时间去删除过期键,限制删除的执行时长和频率。

持久化方式

  • RDB(快照)

    将某一时刻的所有数据保存到一个RDB文件中。

  • AOF(append-only-file 文件追加)

    当Redis服务器执行写命令的时候,将执行的写命令保存到AOF文件中。

RDB

  • SAVE会阻塞Redis服务器进程,服务器不能接收任何请求,直到RDB文件创建完毕为止。

  • BGSAVE创建出一个子进程负责创建RDB文件,已过期的键不会保存在RDB文件中

AOF重写

  • AOF重写由Redis自行触发,在后台子进程进行。

  • AOF重写不需要读取现有的AOF文件,AOF重写是通过读取服务器当前数据库的数据来实现的。

内存淘汰机制

Redis 集群

主从架构

特点

  • 服务器负责接收请求

  • 服务器负责接收请求

  • 从服务器的数据由主服务器复制过去

优势

  • 读写分离(主服务器负责写,从服务器负责读)

  • 高可用(某一台从服务器挂了,其他从服务器还能继续接收请求,不影响服务)

  • 处理更多的并发量(每台从服务器都可以接收读请求读QPS就上去了)

主从复制

  • 同步(sync)

    将从服务器的数据库状态更新至主服务器的数据库状态。

  • 命令传播(command propagate)

    主服务器的数据库状态被修改,导致主从服务器的数据库状态不一致,让主从服务器的数据库状态重新回到一致状态。

哨兵机制(Sentinel)

如果主服务器挂了,我们可以将从服务器升级为主服务器,等到旧的主服务器重连上来,会将它变成从服务器。

过程称为主备切换/故障转移,用于实现Redis的高可用性。

引用

本作品采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0)进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

最后更新于