关注微信公众号 “程序员小胖” 每日技术干货,第一时间送达!
引言
Redis是一个开源的内存数据结构存储系统,它支持多种类型的数据结构,如字符串、散列、列表、集合、有序集合等。Redis以其出色的性能和低延迟特性而闻名,这主要得益于其核心数据结构的设计和实现,以及其高性能的存储和访问机制。
核心数据结构
Redis的数据结构设计非常灵活,它不仅支持基本的数据类型,还支持复杂的数据类型,并且提供了丰富的操作命令。
字符串(String)
字符串是Redis中最基本的数据结构,它允许用户将字符串值设置、获取、删除等。
使用场景:
- 缓存数据(如HTML页面、JSON序列化的对象)
SET key value //存入字符串键值对
MSET key value [key value ...] //批量存储字符串键值对
SETNX key value //存入一个不存在的字符串键值对
GET key //获取一个字符串键值
MGET key [key ...] //批量获取字符串键值
DEL key [key ...] //删除一个键
EXPIRE key seconds //设置一个键的过期时间(秒)
- 计数器(如微博点赞数、视频播放次数)
INCR key //将key中储存的数字值加1
DECR key //将key中储存的数字值减1
INCRBY key increment //将key所储存的值加上increment
DECRBY key decrement //将key所储存的值减去decrement
- 分布式锁
SETNX product:10001 true //返回1代表获取锁成功
SETNX product:10001 true //返回0代表获取锁失败
DEL product:10001 //执行完业务释放锁
SET product:10001 true ex 10 nx //防止程序意外终止导致死锁
优点:
- 简单易用
- 可以用于简单的缓存和计数场景
缺点:
- 不适合存储复杂的数据结构
哈希(Hash)
集合是一个无序集合,它通过哈希表实现,具有快速添加、删除和查找操作的特点。
使用场景:
- 存储用户信息
- 记录对象属性(用户信息)
- 缓存关系型数据库的行数据
HMSET user 1:name zhangsan 1:age 18
HMSET user 2:name lisi 1:age 19
HMGET user 1:name 1:age
命令执行结果:
id | name | age |
---|---|---|
1 | zhangsan | 18 |
2 | lisi | 19 |
优点:
- 可以存储复杂的数据结构
- 访问和更新效率高
- 同类数据归类整合储存,方便数据管理
缺点:
- 不适合存储大量数据,因为所有数据都在一个键下
- 过期功能不能使用在field上,只能用在key上
- Redis集群架构下不适合大规模使用
列表(List)
列表是简单的字符串链表,支持从两端插入和删除元素,常用于消息队列等场景。
使用场景:
- 消息队列
Blocking MQ(阻塞队列)= LPUSH + BRPOP
Queue(队列)= LPUSH + RPOP
# 从列表左侧插入元素
LPUSH tasks "process_video"
# 从列表右侧弹出元素
BPOP tasks
- 朋友圈时间线
LPUSH message:{用户id} 1
LPUSH message:{用户id} 2
LPUSH message:{用户id} 3
LPUSH message:{用户id} 4
LRANGE message:{用户id} 0 3
优点:
- 支持双向操作(从头部或尾部添加/移除元素)
- 可以用作队列或栈
缺点:
- 元素数量较多时,访问中间元素较慢
- 列表尾部添加和移除操作很快,但头部操作较慢
集合(Set)
集合是一个无序集合,它通过哈希表实现,具有快速添加、删除和查找操作的特点。
使用场景:
- 微信微博点赞/收藏
1) 点赞
SADD like:{消息ID} {用户ID}
2) 取消点赞
SREM like:{消息ID} {用户ID}
3) 检查用户是否点过赞
SISMEMBER like:{消息ID} {用户ID}
4) 获取点赞的用户列表
SMEMBERS like:{消息ID}
5) 获取点赞用户数
SCARD like:{消息ID}
- 好友关系(共同关注)
SINTER set1 set2 set3 { c }
SUNION set1 set2 set3 { a,b,c,d,e }
SDIFF set1 set2 set3 { a }
- 抽奖活动(随机选取中奖者)
1)点击参与抽奖加入集合
SADD key {userlD}
2)查看参与抽奖所有用户
SMEMBERS key
3)抽取count名中奖者
SRANDMEMBER key [count] / SPOP key [count]
优点:
- 元素唯一,不会重复
- 支持集合间的操作,如并集、交集
缺点:
- 不支持排序
- 不能直接获取集合中的元素
有序集合(Sorted Set)
有序集合是将集合和散列表结合起来,给每个元素设置一个分数,然后根据分数进行排序。
使用场景:
- 排行榜系统
//展示当日排行前十
ZREVRANGE hotNews:20190819 0 9 WITHSCORES
高性能原理
- Redis 为什么快?
因为它所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题。正因为 Redis 是单线程,所以要小心使用 Redis 指令,对于那些耗时的指令(比如keys),一定要谨慎使用,一不小心就可能会导致 Redis 卡顿。
- Redis线程形式
Redis 的单线程主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。
Redis有也有多线程的功能,比如持久化、异步删除、集群数据同步等
- redis支持高并发
Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
结语
Redis之所以能够提供高性能的数据存储和访问,主要得益于其内存存储、单线程模型、高效的数据结构设计以及持久化机制等。了解Redis的核心数据结构和高性能原理,对于我们更好地使用Redis、优化应用性能具有重要意义。