网站建设登记表,网站编程入门,打工网站校企合作建设,网页设计网站建设流程Redis应用
目录
Redis应用
Redis 除了做缓存#xff0c;还能做什么#xff1f; Redis 可以做消息队列么#xff1f;
Redis 可以做搜索引擎么#xff1f;
如何基于 Redis 实现延时任务#xff1f; Redis 除了做缓存#xff0c;还能做什么#xff1f;
分布式锁…Redis应用
目录
Redis应用
Redis 除了做缓存还能做什么 Redis 可以做消息队列么
Redis 可以做搜索引擎么
如何基于 Redis 实现延时任务 Redis 除了做缓存还能做什么
分布式锁通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下我们都是基于 Redisson 来实现分布式锁。关于 Redis 实现分布式锁的详细介绍可以看我写的这篇文章分布式锁详解 。限流一般是通过 Redis Lua 脚本的方式来实现限流。如果不想自己写 Lua 脚本的话也可以直接利用 Redisson 中的 RRateLimiter 来实现分布式限流其底层实现就是基于 Lua 代码令牌桶算法。消息队列Redis 自带的 List 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka有主题和消费组的概念支持消息持久化以及 ACK 机制。延时队列Redisson 内置了延时队列基于 Sorted Set 实现的。分布式 Session 利用 String 或者 Hash 数据类型保存 Session 数据所有的服务器都可以访问。复杂业务场景通过 Redis 以及 Redis 扩展比如 Redisson提供的数据结构我们可以很方便地完成很多复杂的业务场景比如通过 Bitmap 统计活跃用户、通过 Sorted Set 维护排行榜 Redis 可以做消息队列么 实际项目中使用 Redis 来做消息队列的非常少毕竟有更成熟的消息队列中间件可以用。 先说结论可以是可以但不建议使用 Redis 来做消息队列。和专业的消息队列相比还是有很多欠缺的地方。
Redis 2.0 之前如果想要使用 Redis 来做消息队列的话只能通过 List 来实现。 通过 RPUSH/LPOP 或者 LPUSH/RPOP即可实现简易版消息队列 # 生产者生产消息RPUSH myList msg1 msg2
(integer) 2RPUSH myList msg3
(integer) 3
# 消费者消费消息LPOP myList
msg1
不过通过 RPUSH/LPOP 或者 LPUSH/RPOP这样的方式存在性能问题我们需要不断轮询去调用 RPOP 或 LPOP 来消费消息。当 List 为空时大部分的轮询的请求都是无效请求这种方式大量浪费了系统资源。
因此Redis 还提供了 BLPOP、BRPOP 这种阻塞式读取的命令带 B-Blocking 的都是阻塞式并且还支持一个超时参数。如果 List 为空Redis 服务端不会立刻返回结果它会等待 List 中有新数据后再返回或者是等待最多一个超时时间后返回空。如果将超时时间设置为 0 时即可无限等待直到弹出消息
# 超时时间为 10s
# 如果有数据立刻返回否则最多等待10秒
BRPOP myList 10
null
List 实现消息队列功能太简单像消息确认机制等功能还需要我们自己实现最要命的是没有广播机制消息也只能被消费一次。
Redis 2.0 引入了发布订阅 (pub/sub) 功能解决了 List 实现消息队列没有广播机制的问题。 Redis 发布订阅 (pub/sub) 功能
pub/sub 中引入了一个概念叫 channel频道发布订阅机制的实现就是基于这个 channel 来做的。
pub/sub 涉及发布者Publisher和订阅者Subscriber也叫消费者两个角色
发布者通过 PUBLISH 投递消息给指定 channel。订阅者通过SUBSCRIBE订阅它关心的 channel。并且订阅者可以订阅一个或者多个 channel。
我们这里启动 3 个 Redis 客户端来简单演示一下 pub/sub 实现消息队列演示
pub/sub 既能单播又能广播还支持 channel 的简单正则匹配。不过消息丢失客户端断开连接或者 Redis 宕机都会导致消息丢失、消息堆积发布者发布消息的时候不会管消费者的具体消费能力如何等问题依然没有一个比较好的解决办法。
为此Redis 5.0 新增加的一个数据结构 Stream 来做消息队列。Stream 支持
发布 / 订阅模式按照消费者组进行消费借鉴了 Kafka 消费者组的概念消息持久化 RDB 和 AOFACK 机制通过确认机制来告知已经成功处理了消息阻塞式获取消息
Stream 的结构如下 这是一个有序的消息链表每个消息都有一个唯一的 ID 和对应的内容。ID 是一个时间戳和序列号的组合用来保证消息的唯一性和递增性。内容是一个或多个键值对类似 Hash 基本数据类型用来存储消息的数据。
这里再对图中涉及到的一些概念进行简单解释
Consumer Group消费者组用于组织和管理多个消费者。消费者组本身不处理消息而是再将消息分发给消费者由消费者进行真正的消费last_delivered_id标识消费者组当前消费位置的游标消费者组中任意一个消费者读取了消息都会使 last_delivered_id 往前移动。pending_ids记录已经被客户端消费但没有 ack 的消息的 ID。
下面是Stream 用作消息队列时常用的命令
XADD向流中添加新的消息。XREAD从流中读取消息。XREADGROUP从消费组中读取消息。XRANGE根据消息 ID 范围读取流中的消息。XREVRANGE与 XRANGE 类似但以相反顺序返回结果。XDEL从流中删除消息。XTRIM修剪流的长度可以指定修建策略MAXLEN/MINID。XLEN获取流的长度。XGROUP CREATE创建消费者组。XGROUP DESTROY 删除消费者组XGROUP DELCONSUMER从消费者组中删除一个消费者。XGROUP SETID为消费者组设置新的最后递送消息 IDXACK确认消费组中的消息已被处理。XPENDING查询消费组中挂起未确认的消息。XCLAIM将挂起的消息从一个消费者转移到另一个消费者。XINFO获取流(XINFO STREAM)、消费组(XINFO GROUPS)或消费者(XINFO CONSUMERS)的详细信息
Stream 使用起来相对要麻烦一些这里就不演示了。
总的来说Stream 已经可以满足一个消息队列的基本要求了。不过Stream 在实际使用中依然会有一些小问题不太好解决比如在 Redis 发生故障恢复后不能保证消息至少被消费一次。
综上和专业的消息队列相比使用 Redis 来实现消息队列还是有很多欠缺的地方比如消息丢失和堆积问题不好解决。因此我们通常建议不要使用 Redis 来做消息队列你完全可以选择市面上比较成熟的一些消息队列比如 RocketMQ、Kafka。不过如果你就是想要用 Redis 来做消息队列的话那我建议你优先考虑 Stream这是目前相对最优的 Redis 消息队列实现。
Redis 可以做搜索引擎么
Redis 是可以实现全文搜索引擎功能的需要借助 RediSearch 这是一个基于 Redis 的搜索引擎模块。
RediSearch 支持中文分词、聚合统计、停用词、同义词、拼写检查、标签查询、向量相似度查询、多关键词搜索、分页搜索等功能算是一个功能比较完善的全文搜索引擎了。
相比较于 Elasticsearch 来说RediSearch 主要在下面两点上表现更优异一些
性能更优秀依赖 Redis 自身的高性能基于内存操作Elasticsearch 基于磁盘。较低内存占用实现快速索引RediSearch 内部使用压缩的倒排索引所以可以用较低的内存占用来实现索引的快速构建。
对于小型项目的简单搜索场景来说使用 RediSearch 来作为搜索引擎还是没有问题的搭配 RedisJSON 使用。
对于比较复杂或者数据规模较大的搜索场景还是不太建议使用 RediSearch 来作为搜索引擎主要是因为下面这些限制和问题
数据量限制Elasticsearch 可以支持 PB 级别的数据量可以轻松扩展到多个节点利用分片机制提高可用性和性能。RedisSearch 是基于 Redis 实现的其能存储的数据量受限于 Redis 的内存容量不太适合存储大规模的数据内存昂贵扩展能力较差。分布式能力较差Elasticsearch 是为分布式环境设计的可以轻松扩展到多个节点。虽然 RedisSearch 支持分布式部署但在实际应用中可能会面临一些挑战如数据分片、节点间通信、数据一致性等问题。聚合功能较弱Elasticsearch 提供了丰富的聚合功能而 RediSearch 的聚合功能相对较弱只支持简单的聚合操作。生态较差Elasticsearch 可以轻松和常见的一些系统/软件集成比如 Hadoop、Spark、Kibana而 RedisSearch 则不具备该优势。
Elasticsearch 适用于全文搜索、复杂查询、实时数据分析和聚合的场景而 RediSearch 适用于快速数据存储、缓存和简单查询的场景。 如何基于 Redis 实现延时任务 类似的问题 订单在 10 分钟后未支付就失效如何用 Redis 实现红包 24 小时未被查收自动退还如何用 Redis 实现 基于 Redis 实现延时任务的功能无非就下面两种方案
Redis 过期事件监听Redisson 内置的延时队列
Redis 过期事件监听的存在时效性较差、丢消息、多服务实例下消息重复消费等问题不被推荐使用。
Redisson 内置的延时队列具备下面这些优势
减少了丢消息的可能DelayedQueue 中的消息会被持久化即使 Redis 宕机了根据持久化机制也只可能丢失一点消息影响不大。当然了你也可以使用扫描数据库的方法作为补偿机制。消息不存在重复消费问题每个客户端都是从同一个目标队列中获取任务的不存在重复消费的问题。