在当今世界的软件开发中,数据的快速、高效存储和检索是至关重要的。而在这个领域,Redis(Remote Dictionary Server)以其强大的性能和多样化的数据结构而脱颖而出。本文将带您深入探讨Redis的核心数据结构,揭示其背后的魔法。
引言
Redis是一种基于内存的键值存储系统,被广泛应用于缓存、消息队列、实时统计等场景。其独特之处在于,它支持多种灵活且高效的数据结构,使得开发者能够更好地适应各种应用需求。
数据结构:
在Redis中,字符串不仅仅是一串字符。它是Redis最简单、最基础的数据结构,但也是最为强大的。除了存储文本信息外,字符串可以表示数字、二进制数据,甚至是整个序列化对象。这使得Redis在处理各种数据类型时表现得游刃有余。
string应用场景:
1. 单值缓存
2. 对象缓存(json格式数据)
3. 分布式锁
4. 计数器
5. 集群session共享
6. 分布式系统全局序列号(生成一个id对Redis压力过大,可批量生成序列号提升性能)
当数据变得更为复杂时,哈希表成为了处理键值对的不二之选。在Redis中,哈希表可以存储各种字段和与之相关的值,提供了一种非常直观的方式来表示对象或映射。这对于存储用户信息、配置参数等复杂数据结构来说尤为重要。
Hash应用场景:
1. 对象缓存
2. 购物车 (用户id-商品id : 数量)
3. 等等….
hash与string对比:
优点:同类数据归类整合存储,方便数据管理
相比string操作消耗内存更小cpu使用更低
存储更节省空间
缺点:过期功能不能使用
Redis集群架构下不适合大规模使用(会产生大key)
Redis的列表数据结构提供了有序元素的集合。这不仅让您能够按顺序存储数据,还可以轻松地进行插入、删除等操作。这使得列表成为构建队列、栈等数据结构的理想选择,同时也为实时应用提供了便利的数据存储方式。
List应用场景:(左进、右进、左拿、右拿)
1. 栈数据结构 Lpush +Lpop = FIFO
2. 队列 lpush + Rpop
3. 阻塞队列 Lpush + Brpop
4. 微博和微信公众号消息流(大v发布的微博时间排序-时间线) LRANGE KEY START STOP(按时间排序拿指定范围内的条数)
push和pull对比:
Push 操作(LPUSH、RPUSH):
优点:
支持一次性推送多个元素: 可以一次性将多个元素推送到列表的一端,提高了批量处理的效率。
灵活的数据插入: LPUSH 和 RPUSH 允许在列表的不同端口插入元素,适应不同的数据处理需求。
缺点:
单次操作仅能添加一个元素: 每次 push 操作只能添加一个或一组元素,可能会导致在高并发情况下的性能瓶颈。
Pull 操作(LPOP、RPOP):
优点:
返回并移除元素: 在执行 LPOP 或 RPOP 操作时,元素会被从列表中移除并返回,使得可以轻松地实现队列和栈的行为。
适合实现消息队列: LPOP 操作常用于实现简单的消息队列,其中消费者从队列头部取出消息进行处理。
缺点:
单次只能移除一个元素: 每次 pull 操作只能移除一个元素,对于需要一次性获取多个元素的场景,可能需要多次操作
Push 操作适用于需要批量添加元素、灵活插入的场景。
Pull 操作适用于需要从列表中移除并获取元素的场景,特别是实现队列行为的情况。
集合是Redis中用于存储唯一元素的数据结构,且其中的元素是无序的。这使得集合成为处理独立元素的理想选择,例如存储用户标签、好友关系等。Redis对集合的支持让开发者在处理无序数据时游刃有余。
Set应用场景:(取多个集合的并集、交集、合集、差集)朋友圈第二个人点赞查看只能看到自己认识的好友点赞该朋友圈
1. 抽奖小程序(抽奖商品为key,参与此商品的用户添加set集合)
2. 微博微信点赞、收藏、标签
3. 集合操作实现微信微博关注模型(共同关注的人、我关注的人也关注了xxx、可能认识的人)
有序集合是Redis中最具特色的数据结构之一。它是集合的扩展,每个元素都关联了一个分数,通过分数进行排序。这使得有序集合非常适合处理排行榜、时间线等需要有序性的场景。
Zset应用场景:(榜单、排行榜)
1. 点击新闻
2. 前十排名
3. 七日内搜索榜单
4. 七日排行前十
redis的单线程和高性能
Q:Redis是单线程吗
A:Redis的单线程主要是指Redis的网络IO和键值的读写是由一个线程来完成的,这也是Redis对外提供键值存储服务的主要流程,但Redis其他的功能,如持久化、异步删除、集群数据同步等是由额外的线程执行的
Q:Redis单线程为什么还能这么快
A:因为它所有的数据都存放在内存中,运算也都是内存级别,而且单线程避免了多线程的切换性能损耗问题。正因为Redis是单线程所以要小心使用Redis指令,对于耗时的指令(如keys)一定要慎用,不小心就会造成Redis卡顿
Q:Redis单线程如何处理那么多的并发客户端连接
A:Redis的IO多路复用,Redis利用epoll来实现IO多路复用,讲连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器
keys遍历库所有的节点key,当数据量大时避免使用,会导致其它的Redis请求卡顿
Scan:渐进式遍历键 解决遍历所有节点卡顿问题
Scan 0 match key99* count 1000
0:开始扫描的索引
key99*:匹配规则
1000:扫描的节点数量
结语
在Redis的世界里,这些核心数据结构如同魔法般地将复杂的问题变得简单。从基础的字符串到强大的有序集合,Redis为开发者提供了一系列强大的工具,使得数据的存储和处理变得轻松而高效。随着对Redis核心数据结构的深入理解,您将能够更好地利用Redis的潜力,让数据的存储和检索变得更加有趣和令人兴奋。