一句话总结
Redis有5种核心数据类型:String(缓存/计数器)、Hash(对象存储)、List(消息队列/时间线)、Set(去重/交并集)、ZSet(排行榜/延迟队列)。还有Bitmap、HyperLogLog、Geo等特殊类型。
初级理解
五大核心数据类型:
• String(字符串):最基础类型,用于缓存、计数器、分布式锁
• Hash(哈希):键值对集合,适合存储对象(用户信息、商品详情)
• List(列表):双向链表,用于消息队列(LPUSH+BRPOP)、最新列表
• Set(集合):无序不重复,用于数据去重、交集/并集运算
• ZSet(有序集合):带分数的集合,用于排行榜、延迟队列
一句话总结:String存简单值,Hash存对象,List存列表,Set存不重复集合,ZSet存有序集合。
中级深入
典型应用场景:
String:缓存(SET user:1 json)、计数器(INCR article:1:views)、分布式锁(SETNX lock)
Hash:用户信息(HSET user:1 name "张三" age 25)、商品详情
List:消息队列(LPUSH + BRPOP)、朋友圈时间线(LPUSH + LRANGE)
Set:共同好友(SINTER friends:user1 friends:user2)、抽奖(SRANDMEMBER)
ZSet:排行榜(ZADD leaderboard 100 player1)、延迟队列(score=时间戳)
特殊数据类型:
• Bitmap:位操作,用于用户签到、在线状态统计
• HyperLogLog:基数统计,用于UV统计(有微小误差但内存极小)
• Geo:地理位置,用于附近的人、打车距离计算
注意:选择数据类型时要考虑操作的原子性和性能,例如计数器用String的INCR比GET+SET更高效。
高级拓展
底层数据结构:
• String:SDS(Simple Dynamic String)
• Hash:ziplist(小数据量)/ hashtable(大数据量)
• List:ziplist / quicklist(ziplist + linkedlist)
• Set:intset(全整数)/ hashtable
• ZSet:ziplist / skiplist + hashtable
编码转换阈值:
• Hash:元素数 > 512 或 值长度 > 64 时,ziplist → hashtable
• List:元素数 > 128 时,ziplist → quicklist
• ZSet:元素数 > 128 或 值长度 > 64 时,ziplist → skiplist
面试加分项:能说出各数据类型的底层实现和编码转换阈值,说明你对Redis内存优化有深入理解。
实战场景
场景:排行榜设计
-- 添加分数
ZADD leaderboard 100 "player1"
ZADD leaderboard 95 "player2"
-- 获取Top10
ZREVRANGE leaderboard 0 9 WITHSCORES
-- 获取玩家排名
ZREVRANK leaderboard "player1" -- 返回排名(从0开始)
-- 增加分数
ZINCRBY leaderboard 10 "player1"
场景:共同好友
-- 添加好友
SADD friends:user1 user2 user3 user4
SADD friends:user2 user3 user5
-- 交集(共同好友)
SINTER friends:user1 friends:user2 -- 返回 user3
-- 差集(user1有但user2没有的好友)
SDIFF friends:user1 friends:user2 -- 返回 user2, user4
面试模拟
Q:Redis为什么这么快?
A:Redis快的原因:1. 纯内存操作;2. 单线程避免上下文切换;3. IO多路复用(epoll);4. 高效数据结构(如SDS、skiplist)。其中数据结构的选择对性能影响很大。
Q:ZSet的底层是怎么实现的?
A:ZSet使用skiplist(跳表)+ hashtable双重结构。skiplist保证有序性和范围查询性能(O(logN)),hashtable保证O(1)的成员查找。这种组合既保证了有序性,又保证了查找效率。