数据读写流程
- 读操作流程:
- 对于哈希表存储的用户基本信息,使用
HGETALL
命令获取用户所有基本信息字段和值。例如,如果用户ID为 user:1
,则执行 HGETALL user:1
来获取该用户的基本信息。
- 对于有序集合存储的好友列表,使用
ZRANGE
命令按照权重顺序获取好友列表。例如,若有序集合键为 user:1:friends
,则执行 ZRANGE user:1:friends 0 -1 WITHSCORES
可以获取用户 user:1
的所有好友及其权重。
- 写操作流程:
- 更新用户基本信息:使用
HMSET
命令来更新哈希表中的多个字段值。例如,要更新用户 user:1
的姓名和年龄,执行 HMSET user:1 name "new_name" age 25
。
- 更新好友列表:
- 添加好友:使用
ZADD
命令向有序集合中添加新的好友及其权重。比如,要为用户 user:1
添加好友 user:2
且权重为 10,执行 ZADD user:1:friends 10 user:2
。
- 删除好友:使用
ZREM
命令从有序集合中删除指定好友。例如,要删除用户 user:1
的好友 user:2
,执行 ZREM user:1:friends user:2
。
命令多态的具体应用
- 事务(Multi - Exec):
- Redis 的事务命令
MULTI
和 EXEC
可实现命令多态特性。例如,在更新用户基本信息和好友列表可能存在关联操作时,可将相关命令包装在事务中。
- 示例代码(以Python的redis - py库为例):
import redis
r = redis.Redis(host='localhost', port = 6379, db = 0)
pipe = r.pipeline()
pipe.multi()
pipe.hmset('user:1', {'name': 'new_name', 'age': 25})
pipe.zadd('user:1:friends', {'user:2': 10})
pipe.execute()
- 在这个事务中,
HMSET
和 ZADD
命令被包装在一起,要么所有命令都执行成功,要么都不执行,保证了数据的一致性。
- 乐观锁(WATCH):
WATCH
命令可以实现乐观锁机制。在执行事务之前,使用 WATCH
监控一个或多个键。例如,要更新用户基本信息和好友列表,且确保在监控期间数据未被其他客户端修改:
- 示例代码(以Python的redis - py库为例):
import redis
r = redis.Redis(host='localhost', port = 6379, db = 0)
while True:
try:
r.watch('user:1', 'user:1:friends')
pipe = r.pipeline()
pipe.multi()
pipe.hmset('user:1', {'name': 'new_name', 'age': 25})
pipe.zadd('user:1:friends', {'user:2': 10})
pipe.execute()
break
except redis.WatchError:
continue
- 如果在
WATCH
之后,事务执行之前,被监控的键被其他客户端修改,事务将被取消,程序可以选择重试操作,从而保证数据一致性。
应对网络分区等异常情况
- 使用Redis Sentinel:
- Redis Sentinel 可以监控主服务器和从服务器,并在主服务器发生故障时自动进行故障转移。
- 配置 Sentinel 时,需要在多个节点上部署 Sentinel 实例。例如,在三个节点上配置 Sentinel,每个 Sentinel 实例监控主 Redis 服务器。
- 当网络分区导致主服务器与部分 Sentinel 节点失联时,只要大部分 Sentinel 节点(超过半数)认为主服务器不可达,就会进行故障转移,将一个从服务器提升为主服务器,保证系统的可用性和数据一致性。
- 使用Redis Cluster:
- Redis Cluster 是一种分布式部署方式,它将数据分布在多个节点上。
- 在网络分区时,每个分区内的节点可以继续提供服务,只要分区内有足够的节点来维持数据的可用性。例如,对于哈希表存储的用户基本信息,在不同分区的节点上存储不同用户的信息,在网络分区时,每个分区内的用户基本信息读写操作仍可正常进行,当网络恢复后,Redis Cluster 会自动进行数据的重新平衡和同步,保证数据的最终一致性。