Redis

Redis 是一个非常流行的开源key-value存储系统,其性能高效,支持多种数据结构。参阅缓存方案对比查看Redis和其他缓存方案的比较。

线程模型

Redis 主要使用单线程模型来处理命令,这意味着它在任何给定时间只在一个线程上执行命令。

尽管是单线程的,Redis 仍然可以支持高并发。这是因为它主要在内存中操作,并且大多数命令的执行时间非常短,这使得即使是单个线程也能以极高的速度处理大量请求。

Redis 使用 I/O 多路复用技术,可以同时处理多个网络连接,这也有助于实现高并发。

支持的数据类型

  • 字符串(Strings)
  • 哈希(Hashes)
  • 列表(Lists)
  • 集合(Sets)
  • 有序集合(Sorted Sets)
  • 位图(Bitmaps)- 基于字符串类型实现的一种数据结构。在 Bitmaps 中,每个元素称为位(bit),其值可以是 0 或 1。
  • 超日志(HyperLogLogs)- 用于高效计算数据集唯一元素个数(基数)的概率数据结构。用于需要统计大量数据的唯一值数量,但又不要求绝对精确的场景。
  • 地理位置(Geospatial Indexes)- 基于 Sorted Sets 实现,允许将经纬度相关的数据存储为键值对。用于地理位置查找,路径规划和地理围栏等场景。
  • 流(Streams)

集群方式

  • Redis集群:提供了数据分片,每个节点只保存部分数据。适用于需要高可用和数据分区的场景。
  • 主从复制:一个主节点和一个或多个从节点,适用于读取操作比写入操作多的情况。
  • 哨兵模式:用于监控主从集群,提供故障转移和服务发现功能,适合需要高可用但不需要分片的环境。

持久化

  • RDB(Redis Database):定期将内部状态快照保存到本地硬盘
    • 优点:RDB是非常紧凑的单文件时间点表示形式,非常适合备份。
    • 优点:适合灾难恢复,作为一个紧凑的文件,可以传输到远程数据中心或 Amazon S3。
    • 优点:提高了 Redis 的性能,因为 Redis 父进程为了持久化需要做的唯一工作就是派生一个子进程,该子进程将完成其余所有工作。父进程永远不会执行磁盘 I/O 或类似操作。
    • 优点:与 AOF 相比,RDB可以更快地在大数据集上重启。
    • 缺点:RDB 牺牲了数据完整性,两次 RDB 之间的数据无法恢复。
  • AOF(Append Only File):Redis 会将操作日志实时保存到本地硬盘
    • 优点:AOF将数据丢失风险降到最低
    • 优点:AOF日志是仅追加日志,因此不会出现查找问题,并且在断电时也不会出现损坏问题。
    • 缺点:对于相同的数据集,AOF 文件通常比等效的 RDB 文件大。
    • 缺点:AOF 可能比 RDB 慢,具体取决于确切的 fsync 策略。一般来说,将 fsync 设置为每秒一次的性能仍然非常高,并且禁用 fsync 后,即使在高负载下,它也应该与 RDB 一样快。

键驱逐策略

在Redis设置了最大内存maxmemory的情况下,当最大内存达到时,通过配置maxmemory-policy键驱逐策略(Eviction Policy)来指导Redis如何驱逐键。以下是支持的算法。

  • LRU(least recently used):移除最近最少使用的;适用于保留最新的数据的场景
  • LFU(least frequently used):移除最不常用的;适用于保留倾向于热数据的场景
  • Random:随机移除;适用于对数据集的访问量是均匀分布的场景
  • TTL:移除剩余最短TTL的键;适用于要提示Redis应该选择移除哪些键的场景

和是否设置了expire时间结合,共有以下不同的策略:

设置了expire 没有设置expire
LRU volatile-lru allkeys-lru
LFU volatile-lfu allkeys-lfu
Random volatile-random allkeys-random
TTL volatile-ttl N/A

与 Java 集成的三方库

  • Jedis:一个小型且直接的 Redis 客户端,它提供了简单易用的 API 来与 Redis 交互。
  • Redisson:提供了许多高级分布式和可扩展数据结构,例如分布式锁、队列等。

扩展性(Lua 脚本)

Redis 支持 Lua 脚本,这意味着可以在服务器端执行复杂的操作,从而减少网络往返次数。Lua 脚本用于创建复杂的事务、自定义命令和进行高级数据处理操作。通过 Lua 脚本,Redis 可以实现更复杂和高效的数据处理逻辑。

Java三方库Redisson使用了Lua来实现众多高级和抽象的功能如锁、队列、映射、集合等。