redis

基本概念:Redis(Remote Dictionary Server),即远程字典服务,是基于内存的(Mysql基于硬盘),Key-Value数据库,是NoSQL(非关系型数据库)。

  1. 支持的数据类型

    Key仅支持String类型,而Value支持多种类型:

    • String:采用类似数组的形式储存。
    • List:双向链表实现。
    • Hash:基于拉链法实现,储存时将index00000011相与,去最后两位,以防超出限制。
    • Set:不重复的集合。
    • Sorted Set:多了一个权重参数score,集合内元素能够按score进行排列。
  2. 持久化

    • RDB(Redis DataBase):把目前redis内存中的数据,生成一个快照(RDB文件),保存在硬盘中,如果发生事故,redis可以通过RDB文件,进行文件读取,并将数据重新载入内存中,是一种全量备份。
      • 可手动触发(save命令、bgsave——会fork一个子进程去执行)
      • 可自动触发(配置文件写入save m n,代表m秒内发生n次变化,会自动执行bgsave)。
    • AOF:记录之后所有对redis数据进行修改的操作。如果发生事故,redis可以通过AOF文件,将文件中的数据修改命令全部执行一遍,一次恢复数据。
      • AOF重写,根据当前Redis数据状态生成新AOF文件,替换原本冗余的AOF文件。可手动触发:bgrewriteaof或自动触发:配置文件设置appendonly yes开启。
  3. 缓存

    • 缓存淘汰:

      三种算法:先进先出FIFO、最近最少使用LRU(可以双向链表+哈希表实现:当某个key被访问到了,程序通过哈希表迅速定位节点,并将该节点移至链表开头)、最不经常使用LFU。

    • 过期删除:

      1. 主动删除:设置删除时间间隔,在指定时间后进行主动删除工作。
      2. 惰性删除:程序取值时查看该数据是否过期,如果没过期,则返回;如果过期,则删除。
      3. 定期删除:每隔一段时间,执行主动删除,不跑主动删除时,则执行惰性删除。
    • 缓存一致(Cache Aside)

    • **缓存击穿:**查询某个数据的值,该值不在缓存中,在数据库中有。

      解决方法:

      1. 从MySQL出发,加锁,减少击穿后的直接流量
      2. 从Redis出发,设置热点数据永不过期,或热点数据后台启动一个一步线程,重新把数据回填缓存层
    • **缓存穿透:**查询一个缓存和数据库都不存在的数据。

      解决方法:

      1. 对数据库访问前进行校验,对数据库拦截非法查询请求。
      2. 对于经常被访问的,并且数据库中没有的键,缓存层记录键 = null。
      3. 布隆过滤器:设置k个各不相同的hash映射函数,把在数据库中的有效数据通过这个映射函数得到数组指定位置,并置为1。当输入查询数据的时候,计算这k个hash函数,如果有一位是0,则一定是无效查询。
    • **缓存雪崩:**一大批被缓存的数据,同时失效,这批数据请求全部打到数据库,导致宕机。可以看作多条数据的缓存击穿。

      解决方法(和缓存击穿类似):

      1. 从MySQL出发,加锁,减少击穿后的直接流量
      2. 从Redis出发,设置热点数据永不过期,或热点数据后台启动一个一步线程,重新把数据回填缓存层
      3. 分析失效时间,尽量让失效时间点分散
      4. 对于集群部署的情况,将热点数据分布在不同缓存中
  4. 集群

    • 主从复制:

      有主库(Master)节点和从库(Slave)节点两个角色,写操作作用于主库,读操作作用于从库(可多加几台从库),读写分离。

      • 全量复制:主库执行BGSAVE,生成对应的RDB文件,同时开辟缓存区,是为了记录在RDB文件实行过程中,收到的新数据命令。RDB文件产生后,主库发给从库,从库通过RDB恢复数据。后面主库会把数据变更命令发给从库,从库收到后执行。

      • 断线后重复制:需确定以下信息

        1. 服务器运行id:唯一确定主库身份,以防更换了主库,更换了以后只能全量复制
        2. 复制偏移量:从主节点传输了的字节数
        3. 复制积压缓冲区:这里储存的是最近主节点的数据修改命令
    • 哨兵机制:

      建立哨兵组(不提供数据服务的redis服务器),对主库从库统一进行监控,如果主库坏了,哨兵组进行投票,从从库中重新选出主库。

      每个哨兵每十秒向主库、从库和其他哨兵发送ping,若有哨兵发现主库连接不上,会将其主观下线,并通知其他哨兵ping。若超过半数连接不上,则将其客观下线,执行故障转移,在从库中选个新主库(会选一个老大哨兵,主持新主库的选举)。

      若老主库重新上线,则退化为从库。

    • Cluster集群:

      自动将你的数据切分给多个节点储存,及时这些节点中一部分宕机,也可以继续执行数据操作。

      分区策略:所有键通过CRC16校验函数,对16384取模,分配到不同槽位,每个rediscluster节点负责一部分槽数据的储存。

      查询策略:每个节点都会储存整个集群节点信息,这些信息也被称为元信息。如果执行get操作,节点先验证该key对应的槽编号是不是归本节点关,如果是则保存数据,否则发送正确的节点编号给客户端。