Redis整理

43 阅读5分钟

Key过期策略

Key 可以设置一个过期时间(TTL),当 Key 的 TTL 到期时,Redis 会自动将该 Key 标记为过期,并在后续的操作中删除它。

惰性删除

惰性删除是指当 Key 被访问时,Redis 会检查 Key 是否过期,如果已经过期,则立即删除 Key。

优点:惰性删除可以保证 Key 被及时删除。

缺点:会影响访问性能。

定期删除

Redis 会在后台开启一个定时器,每隔一定时间检查数据库中的 Key,并删除已过期的 Key。

优点:可以保证Redis的稳定和性能。

缺点:不能保证过期的Key会被及时删除。

# 开启过期扫描
expire-check-frequency 300

# 设置定期删除策略
maxmemory-policy allkeys-lru

Redis数据结构

hash

数据结构:数组 + 链表(hash table)。

数组作桶,链表用于处理hash冲突。

List

数据结构:双向链表。

集合(Set)

集合的实现采用了一个哈希表,它将集合中的元素作为键存储,值为 NULL。

有序集合(Sorted Set)

数据结构:跳表

可用于实现:排行榜、计分板等操作。

事务机制

执行策略

Redis 的事务机制使用 MULTI、EXEC、WATCH 和 DISCARD 四个命令来实现:

  1. MULTI:开始一个事务块。
  2. EXEC:执行所有在事务块中的命令。
  3. WATCH:监视一个或多个 Key,如果在事务执行期间被修改,事务将被中止。
  4. DISCARD:取消事务,放弃执行事务块中的所有命令。

使用 Redis 事务的基本流程如下:

  1. 使用 MULTI 命令开始一个事务。
  2. 依次执行一系列 Redis 命令。
  3. 使用 EXEC 命令提交事务,Redis 将依次执行所有 Redis 命令。
  4. 如果在事务执行期间,被监视的 Key 发生了修改,则事务将被中止,使用 WATCH 命令可以监视一个或多个 Key。
  5. 使用 DISCARD 命令取消事务,Redis 将放弃执行事务块中的所有命令。

持久化策略

AOF

AOF持久化方式是通过将写命令追加到AOF文件中来实现的。Redis的AOF持久化方式有三种不同的策略:always、everysec和no。

  1. always

在这种模式下,Redis会在每次写命令完成后,立即将写命令追加到AOF文件中。这种模式保证了最高的数据持久化安全性,但是由于需要频繁写入AOF文件,所以会影响Redis的写性能。

  1. everysec

在这种模式下,Redis会每隔一秒将写命令追加到AOF文件中。这种模式牺牲了一定的数据持久化安全性,但是能够提高Redis的写性能。如果Redis在每秒内发生故障,可能会丢失最后一秒的写操作数据。

  1. no

在这种模式下,Redis不会主动将写命令追加到AOF文件中,而是只在Redis启动时才将RDB文件加载到内存中。这种模式下,Redis的写性能最高,但是也存在数据丢失的风险。

在选择AOF策略时,需要根据实际业务需求和性能要求进行权衡。如果数据的安全性要求比较高,可以选择always模式,如果对数据的安全性要求不是特别高,但是对性能有一定的要求,可以选择everysec模式,如果对性能要求非常高,可以选择no模式。

RDB

  1. 全量备份

全量备份就是在某个时间点对Redis的数据进行一次完整备份,将Redis的所有数据保存到磁盘中。全量备份的好处是可以保证数据的完整性,但是备份时会占用一定的系统资源和磁盘空间。

  1. 增量备份

增量备份就是在全量备份的基础上,只备份增量的数据。这种方式可以节省磁盘空间和备份时间,但是也有可能导致数据的不完整。

在RDB持久化方式中,Redis还提供了一些配置参数,可以控制RDB的生成频率和生成方式,例如:

  • save:可以设置在n秒内有m个key被修改,则进行一次快照。
  • stop-writes-on-bgsave-error:当后台快照进程出错时,是否停止写入操作。
  • rdbcompression:是否对RDB文件进行压缩,以节省磁盘空间。

消息队列

Redis实现消息队列,可以利用LinkedList实现。

LList支持的操作包括:

  1. LPUSH、RPUSH:在链表的左端或右端插入一个节点。
  2. LPOP、RPOP:删除链表的左端或右端节点。
  3. LINDEX:获取链表中指定索引位置的节点值。
  4. LLEN:获取链表的长度。
  5. LINSERT:将一个节点插入到指定节点之前或之后。
  6. LTRIM:截取链表中的一段,保留指定范围内的节点。

LList的时间复杂度为O(1),因此非常适合于高性能的数据读写场景。在Redis中,LList还提供了一些高级操作,例如:

  1. LPOP/RPOP的阻塞版本:当链表为空时,等待元素插入再返回结果。
  2. LREM:从链表中删除指定数量的节点,可以按值删除或按索引删除。
  3. LMOVE:将一个节点从一个链表移动到另一个链表中。
  4. LSET:设置链表中指定索引位置的节点值。