面试题答案
一键面试Redis数据结构选型策略
- 关注列表和粉丝列表:使用Redis的
Sorted Set
数据结构。- 理由:
Sorted Set
可以以用户ID作为成员,添加关注或成为粉丝时,将操作时间戳作为分数。这样既可以保证成员唯一性(不会重复关注或重复成为粉丝),又能按关注/成为粉丝的时间顺序排序。例如,用户A关注用户B,ZADD userA_following 1679040000 B
(1679040000为时间戳),获取用户A的关注列表时使用ZRANGE userA_following 0 -1
。
- 理由:
- 共同关注的用户:结合
Sorted Set
和Set
。- 理由:对于每个用户的关注列表使用
Sorted Set
,获取共同关注时,可以利用Set
的交集操作。先将两个用户的关注列表(Sorted Set
)转成Set
,然后使用SINTER
命令获取交集。例如,获取用户A和用户B的共同关注,先ZUNIONSTORE tempSet1 1 userA_following WITHSCORES
,ZUNIONSTORE tempSet2 1 userB_following WITHSCORES
,再SINTER tempSet1 tempSet2
。
- 理由:对于每个用户的关注列表使用
- 互动次数统计和互动记录:
- 互动次数:使用
Hash
数据结构。以用户ID作为键,互动类型(点赞、评论等)作为字段,互动次数作为值。例如,记录用户A对某内容的点赞次数,HINCRBY userA_interaction likes 1
。 - 互动记录:使用
Sorted Set
。以互动记录的唯一标识作为成员,时间戳作为分数。添加互动记录时,ZADD userA_interaction_records 1679040000 interaction_id
,获取按时间排序的互动记录使用ZRANGE userA_interaction_records 0 -1 WITHSCORES
。
- 互动次数:使用
数据结构组合使用提高性能
- 关注和粉丝操作优化:在添加关注或成为粉丝时,同时在关注列表和粉丝列表对应的
Sorted Set
中进行操作,保证数据一致性。并且可以使用管道(Pipeline)技术,将多个相关命令打包发送,减少网络开销。 - 共同关注查询优化:提前计算并缓存一些常用的共同关注结果,比如热门用户之间的共同关注。可以使用
Lua
脚本实现复杂的逻辑,如将关注列表转Set
和求交集等操作在服务端原子性执行,减少网络交互。 - 互动统计和记录优化:对于互动次数统计,
Hash
结构可以批量操作,如一次增加多种互动类型的次数。对于互动记录,在高并发写入时,可以采用分桶策略,根据时间或用户ID等维度将互动记录分散到不同的Sorted Set
中,减少单个数据结构的压力。
Redis配置优化应对高并发
- 内存配置:
- 合理设置最大内存:根据服务器内存情况,使用
maxmemory
配置项设置Redis最大使用内存,避免因内存耗尽导致性能问题。可以采用noeviction
(不删除任何数据,只返回错误)、allkeys-lru
(删除最近最少使用的键)等淘汰策略,根据业务需求选择合适的策略。 - 内存碎片整理:开启内存碎片自动整理,
activedefrag yes
,当内存碎片率达到一定阈值时,Redis会自动进行碎片整理,提高内存利用率。
- 合理设置最大内存:根据服务器内存情况,使用
- 网络配置:
- 调整TCP backlog:通过
tcp-backlog
配置项增大TCP连接队列长度,避免高并发时新连接被拒绝。例如设置为tcp-backlog 511
。 - 优化网络延迟:尽量减少Redis服务器与应用服务器之间的网络跳数,使用高速网络连接。可以调整
tcp-keepalive
配置项,设置合适的心跳包发送频率,保持TCP连接的活跃,减少连接中断的可能性。
- 调整TCP backlog:通过
- 持久化配置:
- 选择合适的持久化方式:
RDB
适合大规模数据恢复,AOF
适合数据安全性要求高的场景。如果对数据恢复速度要求较高且能容忍一定时间内的数据丢失,可以优先使用RDB
;如果对数据完整性要求极高,应采用AOF
。也可以两者结合使用。 - 优化持久化频率:对于
AOF
,可以适当调整appendfsync
策略,如使用everysec
,每秒进行一次刷盘操作,在保证数据安全性的同时,减少I/O开销对性能的影响。对于RDB
,合理设置save
配置项的时间和数据量阈值,避免频繁进行RDB快照。
- 选择合适的持久化方式: