Redis 数据类型
Redis 核心数据结构
🎯 面试重点
- 各数据类型的应用场景
- 底层实现原理
📖 数据类型
String
/**
* String 类型
*
* 场景:
* - 缓存
* - 计数器
* - 分布式锁(SETNX)
*
* 命令:
* SET key value
* GET key
* INCR counter
* SETEX key 10 value
*/
List
/**
* List 类型
*
* 场景:
* - 消息队列(LPUSH + BRPOP)
* - 列表/时间线
*
* 命令:
* LPUSH/RPUSH key value
* LRANGE key 0 -1
*/
Hash
/**
* Hash 类型
*
* 场景:
* - 对象存储
* - 购物车
*
* 命令:
* HSET key field value
* HGET key field
* HGETALL key
*/
Set
/**
* Set 类型
*
* 场景:
* - 交集/并集/差集(共同好友)
* - 去重
*
* 命令:
* SADD key member
* SMEMBERS key
* SINTER set1 set2
*/
ZSet
/**
* ZSet(有序集合)
*
* 场景:
* - 排行榜
* - 延迟队列
*
* 命令:
* ZADD key score member
* ZRANGE key 0 10
* ZRANK key member
*/
📖 面试真题
Q1: Redis 为什么这么快?
答: Redis 之所以快,主要基于以下几个核心设计:
1. 内存存储
- 数据存储在内存中:读写操作直接在内存中进行,速度比磁盘快几个数量级。
- 避免磁盘 I/O:虽然支持持久化,但常规操作不涉及磁盘访问。
2. 单线程模型
- 避免锁竞争:单线程处理所有命令,无需考虑多线程环境下的锁竞争和上下文切换。
- 原子操作保证:所有命令都是原子执行的,不会出现并发问题。
- CPU 不是瓶颈:Redis 的性能瓶颈通常是内存或网络,而非 CPU。
3. I/O 多路复用
- 非阻塞 I/O:使用 epoll、kqueue 等系统调用实现高效的事件驱动模型。
- 单线程处理多连接:一个线程可以同时处理成千上万的客户端连接。
- 减少线程开销:避免了多线程模型中的线程创建、销毁和上下文切换开销。
4. 高效的数据结构
- 专门优化的数据结构:如 SDS(简单动态字符串)、跳跃表、压缩列表等,针对不同场景优化。
- 合理的数据编码:根据数据大小自动选择合适的数据编码方式,节省内存。
5. 其他优化
- 管道(Pipeline):客户端可以一次性发送多个命令,减少网络往返时间。
- Lua 脚本:将多个操作封装成一个原子操作,减少网络通信。
- 渐进式 Rehash:在扩容时不影响正常服务。
6. 与 Memcached 对比
| 特性 | Redis | Memcached | |——|——-|———–| | 数据结构 | 丰富(字符串、列表、哈希等) | 简单(仅键值) | | 持久化 | 支持 RDB 和 AOF | 不支持 | | 内存管理 | 多种淘汰策略 | LRU | | 线程模型 | 单线程(6.0+ 支持多线程 I/O) | 多线程 | | 使用场景 | 缓存、消息队列、计数器等 | 纯缓存 |
总结:Redis 通过内存存储、单线程模型、I/O 多路复用和高效数据结构的组合,实现了极高的性能,适合作为高性能缓存和数据存储解决方案。
⭐ 重点:理解各类型的应用场景