Redis重点总结

11/16/2021 Redis

此处填写本题目的摘要

# Redis的优点

  1. 基于内存的:高性能
  2. KV数据库:不使用RDS,因为应用场景是缓存,只存储部分数据,不需要实现数据关系支持
  3. Worker单线程(IO多线程、flash、心跳线程): 支持单个命令的原子操作,多个命令的部分事务(不支持回滚),使用Lua脚本可以实现多命令的原子性事务。
  4. 多种数据类型(每种类型都支持本地方法):相较于Memcache把一部分缓存的逻辑处理交给Redis服务器执行,减少了大量不必要数据的网络IO消耗和caller服务器的缓解析性能。

# Redis的缺点

  1. 单线程的Worker无法充分利用多核CPU的性能,Redis6中使用IO多线程可以在一定程度上利用多核CPU的性能。

# 基本应用场景 (opens new window)

# string类型

string类型的数据也可以进行数值计算或者位运算操作,在底层存储的还是字符串。

# 二进制安全

**二进制安全:**通俗的讲,C语言中,用“0”表示字符串的结束,如果字符串中本身就有“0”字符,那么这个字符串就会被截断,即非二进制安全;若通过某种机制,保证读写字符串时不损害其内容,则是二进制安全。

Redis有二进制安全的特点,即数据传输的时候会按照一定的格式进行编解码,不用关心具体的基本数据类型

  1. session
  2. KV缓存
  3. 数值计算器、计数器(原子性)
  4. fs分布式文件系统(小文件)
  5. 分布式锁
  6. JSON序列化数据存储所有类型的数据结构

# Bitmap

位图的最大长度为为2^32,redis中一个key限制不能大于512M,bit位个数尽量小于2^29-1(536870911),大约5亿。如果UID过大可以使用分桶

  1. 统计一段时间窗口内用户的登录情况,利用bitmap进行登录窗口天数的维护
  2. 用户签到统计,以uid为偏移,位图作为用户的状态
  3. 布隆过滤器

# List

特点是和放入数据的顺序有关

  1. 模拟本地数据结构,做到分布式服务器无状态,模拟简易的消息队列
  2. 朋友圈点赞列表、评论列表
  3. 弹幕

# Sorted Set

  1. 投票排行榜、游戏排行榜

# HashMap

如果一段复杂的schema缓存每次需要取出全部field,可以使用JSON+String进行Redis存储,但是如果这个schema是经常有部分field取出的操作,可以使用HashMap进行存储。

  1. 复杂信息的schema,使用HashMap代替Json序列化复杂的数据结构

# Set

Set的集合操作(Union、And、Or)比较复杂、消耗CPU、会让后续命令执行收到阻塞,所以慎用。

  1. 随机数:抽奖、验证码、扑克牌游戏等
  2. 首页商品的随机展示
  3. 社交网络中共同好友

# Redis持久化

关键词:AOF、RDB、COW、FORK、AOF+RDB、CAP

Redis提供不同级别的持久化方案:

  • RDB(Redis Database)能够在指定时间间隔对数据进行快照存储
  • AOF(Append Only File)记录每次执行的命令,将新执行的命令保持到持久化文件末尾
  • 也可以同时开启RDB+AOF两种方式,进一步可以进行一定配置解决AOF无限增长的问题。

# RDB

优点

  1. 快照功能:RDB的备份文件十分的紧凑,可以根据RDB恢复到不同时间节点的Redis快照版本
  2. 便于容灾:RDB的备份文件十分适合容灾恢复,可以传入远程的数据中心进行备份
  3. 利用Linux机制:RDB在执行持久化工作时会fork(in Linux)一个子进程进行持久化操作,写时复制(Copy-On-Write)让子进程不会立即拷贝全量数据,
  4. 消耗小、效率高:相比于AOF,RDB备份的文件小、恢复快

缺点

  1. 丢数据较多:RDB对数据持久化不是很及时,容易丢失一段时间的数据
  2. 数据大时消耗大:虽然有COW技术,但是如果Redis实例中的数据较多时(10G以上),RDB时fork也会非常耗时,甚至会导致秒级别的阻塞。(但是这种情况不止RDB会耗时、其他的命令也会因为数据量过大而耗时,让Redis可用性下降,这种情况一般会考虑用Redis集群去存储数据)

# AOF

优点

  1. 丢数据较少:AOF又分为多种触发时机,相较于RDB合理配置能够让Redis宕机时丢失的数据较少。
  2. 重写AOF缩小体积:开启子线程对AOF中日志文件进行重写,去除一些失效的日志文件,缩小AOF数据的体积。
  3. fork消耗小:AOF也是通过fork子进程进行持久化操作的,不过每次AOF设计的操作较小,所以不会有Redis数据多fork消耗大的问题。

缺点

  1. 体积大、效率低:相比于RDB,AOF日志文件的体积较大,并且恢复较慢

# RDB+AOF

4.X之后的版本进行AOF重写时,通过RDB方式直接舍弃快照前的历史数据,性能更优秀

# Redis过期淘汰

  1. **精度:**精度可以打到0~1毫秒
  2. **绝对时间点:**Redis通过Unix时间戳进行过期时间存储,这意味着多实例Redis时钟不同步会出现数据不一致问题
  3. **清除策略:**Redis过期淘汰通过主动和被动两种方式,被动就是客户端访问到过期数据时进行过期删除,主动是指每10s执行的定时任务进行过期键清除
  4. **Slave处理过期键:**Slave不会主动处理过期键,而是会通过Master删除过期键后再向Slave同步。当Slave成功当选为Master后会再执行过期键删除策略。

# Redis内存淘汰策略

Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。

可以根据数据和策略两个维度进行考虑,分为下列这张表格这几种类型。

LRU LFU Random TTL None
allkeys allkeys-lru allkeys-lfu allkeys-random
volatile(含过期时间) volatile-lru volatile-lfu volatile-random volatile-ttl
None no-eviction

# Redis的集群模式

# 主从

  • 解决:
    • 单实例宕机
    • QPS扩展
  • 问题:
    • 需要自行配置主从切换触发监控
    • 主从内存配置需要一致(木桶短板效应)
    • 难以在线扩容
    • 写入性能受单机限制
    • 主从切换导致数据不一致(所以基于Redis的分布式锁不可靠)

redis-master-slave

# 哨兵(+主从)

  • 解决:
    • 需要自行配置主从切换触发监控
  • 问题:需要自行配置主从切换触发监控
    • 主从内存配置需要一致(木桶短板效应)
    • 难以在线扩容
    • 写入性能受单机限制
    • 主从切换导致数据不一致(所以基于Redis的分布式锁不可靠)

redis-sentinel

# Cluster(+主从)

这种方式将每次命令按照Redis Key进行分slot操作,映射到不同的Redis实例中,可以让Redis的写入性能得到较大提升,并且支持了横向扩展的能力。至于在哪里和怎样分slot,这就没有统一的答案,一般都有以下三种方式:

  • 在Redis中使用slot算法:Redis官方提供,操作最简单,但是可定制化低。

  • 在客户端处使用分slot算法:低成本客制化,客户端消耗较高,改动成本较大。

  • 在Proxy使用分slot算法:大厂通用,但是带来另一个proxy的高QPS处理问题。

  • 解决:

    • 主从内存配置需要一致(木桶短板效应)
    • 难以在线扩容
    • 写入性能受单机限制
  • 问题:需要自行配置主从切换触发监控

    • 主从切换导致数据不一致(所以基于Redis的分布式锁不可靠)

在这里插入图片描述

上次更新于: 3 months ago