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来实现众多高级和抽象的功能如锁、队列、映射、集合等。