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 四个命令来实现:
- MULTI:开始一个事务块。
- EXEC:执行所有在事务块中的命令。
- WATCH:监视一个或多个 Key,如果在事务执行期间被修改,事务将被中止。
- DISCARD:取消事务,放弃执行事务块中的所有命令。
使用 Redis 事务的基本流程如下:
- 使用 MULTI 命令开始一个事务。
- 依次执行一系列 Redis 命令。
- 使用 EXEC 命令提交事务,Redis 将依次执行所有 Redis 命令。
- 如果在事务执行期间,被监视的 Key 发生了修改,则事务将被中止,使用 WATCH 命令可以监视一个或多个 Key。
- 使用 DISCARD 命令取消事务,Redis 将放弃执行事务块中的所有命令。
持久化策略
AOF
AOF持久化方式是通过将写命令追加到AOF文件中来实现的。Redis的AOF持久化方式有三种不同的策略:always、everysec和no。
- always
在这种模式下,Redis会在每次写命令完成后,立即将写命令追加到AOF文件中。这种模式保证了最高的数据持久化安全性,但是由于需要频繁写入AOF文件,所以会影响Redis的写性能。
- everysec
在这种模式下,Redis会每隔一秒将写命令追加到AOF文件中。这种模式牺牲了一定的数据持久化安全性,但是能够提高Redis的写性能。如果Redis在每秒内发生故障,可能会丢失最后一秒的写操作数据。
- no
在这种模式下,Redis不会主动将写命令追加到AOF文件中,而是只在Redis启动时才将RDB文件加载到内存中。这种模式下,Redis的写性能最高,但是也存在数据丢失的风险。
在选择AOF策略时,需要根据实际业务需求和性能要求进行权衡。如果数据的安全性要求比较高,可以选择always模式,如果对数据的安全性要求不是特别高,但是对性能有一定的要求,可以选择everysec模式,如果对性能要求非常高,可以选择no模式。
RDB
- 全量备份
全量备份就是在某个时间点对Redis的数据进行一次完整备份,将Redis的所有数据保存到磁盘中。全量备份的好处是可以保证数据的完整性,但是备份时会占用一定的系统资源和磁盘空间。
- 增量备份
增量备份就是在全量备份的基础上,只备份增量的数据。这种方式可以节省磁盘空间和备份时间,但是也有可能导致数据的不完整。
在RDB持久化方式中,Redis还提供了一些配置参数,可以控制RDB的生成频率和生成方式,例如:
- save:可以设置在n秒内有m个key被修改,则进行一次快照。
- stop-writes-on-bgsave-error:当后台快照进程出错时,是否停止写入操作。
- rdbcompression:是否对RDB文件进行压缩,以节省磁盘空间。
消息队列
Redis实现消息队列,可以利用LinkedList实现。
LList支持的操作包括:
- LPUSH、RPUSH:在链表的左端或右端插入一个节点。
- LPOP、RPOP:删除链表的左端或右端节点。
- LINDEX:获取链表中指定索引位置的节点值。
- LLEN:获取链表的长度。
- LINSERT:将一个节点插入到指定节点之前或之后。
- LTRIM:截取链表中的一段,保留指定范围内的节点。
LList的时间复杂度为O(1),因此非常适合于高性能的数据读写场景。在Redis中,LList还提供了一些高级操作,例如:
- LPOP/RPOP的阻塞版本:当链表为空时,等待元素插入再返回结果。
- LREM:从链表中删除指定数量的节点,可以按值删除或按索引删除。
- LMOVE:将一个节点从一个链表移动到另一个链表中。
- LSET:设置链表中指定索引位置的节点值。