Redis 协议与异步方式

redis pipeline 模式

  • redis pipeline 是一个客户端提供的机制,与 redis 无关。
  • pipeline 不具备事务性。
  • 目的:节约网络传输时间。
  • 通过一次发送多条请求命令,从而减少网络传输时间。
    在这里插入图片描述
  • 时间窗口限流
    • 系统限定某个用户某个行为在指定的时间范围内(动态)只能发生 N 次
# 指定用户 user_id 的某个行为 action 在特定时间内 period 只允许发生该行为的最大次数 max_count
# 维护一次时间窗口,将窗口外的记录全部清理掉,只保留窗口内的记录
local function is_action_allowed(red, userid, action, period, max_count)local key = tab_concat({"hist", userid, action}, ":")local now = zv.time()red:init_pipeline()-- 记录行为red:zadd(key, now, now)-- 移除时间窗口之前的行为记录,剩下的都是时间窗口内的记录red:zremrangebyscore(key, 0, now - period * 100)-- 获取时间窗口内的行为数量red:zcard(key)-- 设置过期时间,避免冷用户持续占用内存 时间窗口的长度 + 1秒red:expire(key, period + 1)local res = red:commit_pipeline()return res[3] <= max_count
end

redis 发布订阅模式

  • 为了支持消息的多播机制,redis 引入了发布订阅模块。
  • 作用:
    • 没有建立连接的服务器之间进行交互。
    • 第三方系统和与 redis 建立连接的服务器之间进行交互。
  • 缺点:不确定消息到达。kafka 分布式消息队列、redis stream 模式可以确保消息到达。
    • 发布订阅的生产者传递过来一个消息,redis 会直接找到相应的消费者并传递过去。假如没有消费者,消息直接丢弃。假如开始有 2 个消费者,一个消费者突然挂掉了,另一个消费者依然能接收到消息。但是,如果刚挂掉的消费者重新连上后,在断开连接期间的消息对于该消费者来说彻底丢失了。
    • redis 停机重启,pubsub 的消息是不会持久化的,所有的消息都被直接丢弃。
  • 使用场景
    • 业务可以接受消息丢失。
    • redis cluster 集群之间通信。
  • 服务器需要和 redis 建立多少连接
    • 5 种基本数据结构的处理,只需要一条连接,可以使用连接池。
    • 如果有阻塞连接的需求,另外建立一条连接。
    • 如果需要发布订阅模式,另外建立一条连接。

在这里插入图片描述

# 订阅频道
subscribe 频道
# 订阅模式频道
psubscribe 频道
# 取消订阅频道
unsubscribe 频道
# 取消订阅模式频道
punsubscribe 频道
# 发布具体频道或模式频道的内容
publish 频道 内容
# 客户端收到具体频道内容
message 具体频道 内容
# 客户端收到模式频道内容
pmessage 模式频道 具体频道 内容subscribe news.A news.B news.C
psubscribe news.*
publish new.B 'zcoder is good'

redis 事务

  • 前提:有并发连接。
  • 事务是用户定义的一系列的数据库操作,要么全部执行,要么全部不执行,是不可分割的单元。
  • redis 事务原理:当使用 MULTI 开启事务时,redis 会创建一个队列,后续的所有命令都会入队,直到使用 EXEC 提交事务。提交事务时会将队列中的所有命令出队执行。因为 redis 处理命令是单线程的,所以在处理队列中的命令时会阻塞其它连接的命令,直到队列中的命令全部处理完。使用 DISCARD 可以清空队列。使用 WATCH 可以观察 key,如果 key 对应的 value 变动,说明其它连接修改了 value,事务的逻辑一致性被破坏,那么调用 EXEC 就会清空该事务的队列,返回 nil。
# 开启事务
MUITI
# 提交事务 
EXEC
# 取消事务
DISCARD# 检测 key 对应的 value 的变动,若在事务执行中,value 变动则取消事务并返回 nil。
# 在事务开启前调用,乐观锁实现(cas) 
WATCH
  • 应用
    • 加倍操作
      WATCH score
      val = GET score
      MULTI
      SET score val * 2
      EXEC
      

lua 脚本

  • redis 中加载了一个 lua 虚拟机,用来执行 lua 脚本。
  • redis lua 脚本的执行是原子性的,当某个脚本正在执行的时候,不会有其他命令或者脚本被执行。
  • lua 脚本中的命令会直接修改数据状态。
  • 先将 lua 脚本提交到 redis 中,redis 会通过 lua 虚拟机解析 lua 脚本,并返回一个 hash 值,这个 hash 值可以代替这个 lua 脚本(通过这个 hash 值去索引对应的 lua 脚本)。
    • 优点:使用较短的字符串代替复杂的 lua 脚本。意味着在网络传输的过程中可以减少发送数据的流量。其次,效率会更高,因为使用的是已经编译好的 lua 脚本。
      在这里插入图片描述
# 测试使用
EVAL script numkeys key [key ...] arg [arg ...]# 线上使用
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
  • 应用
    • 项目启动时,建立 redis 连接并验证,通过 script load 加载项目中使用的 lua 脚本,script load 会返回对应 lua 脚本的 hash 值。
    • 项目中若需要热更新,通过 redis-cli 执行 script flush 然后可以使用订阅发布功能通知所有服务器重新加载 lua 脚本。
    • 若项目中 lua 脚本发生阻塞,可通过 script kill 暂停当前阻塞脚本的执行。
# 从文件中读取 lua脚本内容
cat test.lua | redis-cli script load --pipe
# 加载 lua脚本字符串 生成 sha1
> script load 'local val = KEYS[1]; return val'
"b8059ba43af6ffe8bed3db65bac35d452f8115d8"
# 检查脚本缓存中,是否有该 sha1 散列值的lua脚本
> script exists "b8059ba43af6ffe8bed3db65bac35d452f8115d8"
1) (integer) 1
# 清除所有脚本缓存
> script flush
OK
# 如果当前脚本运行时间过长(死循环),可以通过 script kill杀死当前运行的脚本
> script kill
(error) NOTBUSY No scripts in execution right now.

ACID 特性

  • 原子性(A)
    • 事务是一个不可分割的单位,事务中的操作要么全部成功,要么全部失败。
    • redis 不支持回滚,即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。
  • 一致性(C)
    • 事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测。这里的一致性是指预期的一致性而不是异常后的一致性,所以 redis 也不满足。
      • 这个争议很大:redis 能确保事务执行前后的数据的完整约束,但是并不满足业务功能上的一致性,比如转账功能,一个扣钱一个加钱,可能出现扣钱执行错误,加钱执行正确,那么最终还是会加钱成功,系统凭空多了钱。
  • 隔离性(I)
    • 各个事务之间互相影响的程度,redis 是单线程执行,天然具备隔离性。
  • 持久性(D)
    • redis 只有在 aof 持久化策略的时候,并且需要在 redis.conf 中 appendfsync=always 才具备持久性,实际项目中几乎不会使用 aof 持久化策略。
  • lua 脚本满足原子性和隔离性,不满足一致性和持久性

redis 异步连接

  • 同步连接方案采用阻塞 io 实现。通常用多个线程实现线程池解决效率问题。
    • 优点:代码书写是同步的,业务逻辑没有割裂。
    • 缺点:阻塞当前线程,直至 redis 返回结果。
  • 异步连接方案采用非阻塞 io 实现。
    • 优点:没有阻塞当前线程,就算 redis 没有返回,依然可以往 redis 发送命令。
    • 缺点:代码书写是异步的(回调函数),业务逻辑割裂。
  • 基于 reactor 实现异步连接:
    1. 与 redis 建立连接
    a. 创建 socket, 设置 fd 为非阻塞 io
    b. 调用 connect(fd, &addr, &len)
    c. 将 fd 注册到 epoll, 注册写事件
    d. 如果连接建立成功, fd 的写事件会进行响应, 然后注销写事件
    
    1. 向 redis 发送数据(使用 redis 协议加密,然后通过 tcp 发送过去)
    a. int n = write(fd, buf, sz)如果 n < sz && n != -1 或者 n == -1 && errno = EWOULDBLOCK 说明 fd 对应的发送缓冲区已经满了
    b. 注册写事件, 如果写事件触发, 继续 write(fd, buf, sz),如果发送完毕, 注销写事件
    c. 注册读事件
    
    1. 读取 redis 的返回(通过 tcp 接收数据并分割数据包,然后使用 redis 协议解密)
    a. 读事件触发, int n = read(fd, buf, sz)
    b. 根据 redis 协议分割数据包
    c. 使用 redis 协议解密
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国创证券策略:春季躁动行情有望持续演绎

国创证券指出&#xff0c;商场在连续逼空后总算迎来真正意义上的调整&#xff0c;而指数上也并未能突破3030—3050点压力区&#xff0c;显示现在仍处于中期的下降趋势中的反弹&#xff0c;只是反弹起伏确实是超预期的。周三商场的调整还是近期大涨的巨量获利盘实现压力。由于大…

palworld-server-tool(0.5.7)使用指南

文章目录 说明管理工具&#xff08;docker版本&#xff09;部署教程使用指南RCON指令工具RCON使用广播内容右下角&#xff0c;有加入白明单&#xff0c;和封禁和踢出的功能 游戏中RCON命令使用 说明 本文&#xff0c;主要使简单的使用介绍&#xff08;其实也没有什么指导的&am…

Rocky Linux 运维工具 systemctl

一、​​systemctl​的简介 ​​systemctl​是用于管理系统服务的命令行工具。​systemctl​命令可以启动、停止、重启或重新加载服务&#xff0c;并管理它们。 二、systemctl​的参数说明 序号参数描述1start启动指定系统服务2stop停止指定系统服务3status显示指定系统服务的…

【Micropython教程】点亮第一个LED与流水灯

文章目录 前言MicroPython在线仿真GPIO的工作模式一、有哪些工作模式&#xff1f;1.1 GPIO的详细介绍1.2 GPIO的内部框图输入模式输出部分 一、machine.Pin类1.1 machine.Pin 类的构造对象1.2 machine.Pin 类的方法init方法value方法设置高低电平方法 二、延时函数 三、流水灯总…

JVM(2)

JVM类加载 指的是java进程运行时,需要把.class文件从硬盘加载到内存,并进行一系列校验解析的过程. 核心: .class文件>类对象; 硬盘>内存. 类加载过程 在整个JVM的执行流程中,和程序员关系最密切的就是类加载的过程了,所以我们来看一下类加载的执行流程. 对于一个类…

使用Git从其他分支merge个别文件

项目背景 产品经理&#xff1a;我们本次开发三个功能&#xff0c;列表页功能、详情页功能、系统消息功能&#xff0c;分两次上线&#xff0c;先上列表功能&#xff0c;再上详情页和系统消息。 小明&#xff1a;好的吧。 紧接着&#xff0c;小明就将本次需求分为2个分支&…

camunda7流程跳转和流程退回的实现方法

我们在使用工作流的时候&#xff0c;常常有“流程退回”、“流程跳转”、“自由流”、“动态加签”等这样的需求。Camunda流程平台提供了这样的机制和接口&#xff0c;虽然流程模型定义活动执行顺序的序列流&#xff0c;但有时需要灵活地重新启动活动或取消正在运行的活动&…

k8s-项目测试环境部署

部署规划 概述 项目开发好后&#xff0c;我们需要部署&#xff0c;我们接下来就基于 阿里云云效 阿里云容器镜像服务 k8s 搭建部署环境 阿里云云效 : 放代码&#xff0c;可以做cicd&#xff08;https://www.aliyun.com/product/yunxiao&#xff09; 阿里云容器镜像服务 :…

Unity(第十六部)声音和视频

声音 1、听声音 创建相机的时候&#xff0c;相机自带Audio Listener 多个相机的时候&#xff0c;我们只保留一个Audio Listener就可以 2、声音源&#xff0c;环境音 添加Audio Source就行中文叫声音源 3、脚本执行的声音 using System.Collections; using System.Collection…

Servlet(1)Request 请求对象

1、接收请求数据的流程 浏览器发送HTTP请求到Tomcat服务器HTTP的请求中会包含很多请求数据&#xff08;请求行请求头请求体&#xff09;Tomcat服务器会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中所封装的对象即为Request对象&#xff0c;所以可以从Request对象中…

ubuntu安装新版本的CMake

来到cmake官网选择版本 我需要在嵌入式板子上的Ubuntu18安装使用 故我选择aarch64版本。 按F12进入检查模式得到下载链接。 在板子上运行以下命令&#xff0c;获取安装脚本 wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-aarch64.s…

OpenCV实现目标追踪

目录 准备工作 语言&#xff1a; 软件包&#xff1a; 效果演示 代码解读 &#xff08;1&#xff09;导入OpenCV库 &#xff08;2&#xff09;使用 cv2.VideoCapture 打开指定路径的视频文件 &#xff08;3&#xff09;使用 vid.read() 读取视频的第一帧&#xff0c;ret…

前端视角对Rust的浅析

概述 本文将从 Rust 的历史&#xff0c;前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子&#xff0c;了解 Rust 如何应用到前端&#xff0c;提高前端的生产效率。 Rust简史 2006年&#xff0c;软件开发者Graydon Hoare在Mozilla工作期间&#…

队列的概念及使用

目录 一. 概念 二. 队列的使用 三. 队列模拟实现 四. 循环队列 五. 面试题 一. 概念 队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操…

IDEA基础——Maven配置tomcat

配置方案 一、配置maven-tomcat plugin插件&#xff08;只最高支持到tomcat 8&#xff09;~~1.添加镜像源&#xff0c;获取tomcat 8插件配置~~~~1.1 在pom.xml里先添加镜像源~~~~1.2 添加tomcat插件配置~~ 2. 添加tomact官方发布的插件配置&#xff08;无需添加镜像源&#xff…

本届挑战赛季军方案:基于图网络及LLM AGENT的微服务系统异常检测和根因定位方法

aiboco团队荣获本届挑战赛季军。该团队来自亿阳信通。 方案介绍 本届挑战赛采用开放式赛题&#xff0c;基于建行云龙舟运维平台的稳定性工具和多维监控系统&#xff0c;模拟大型的生活服务APP的生产环境&#xff0c;提供端到端的全链路的日志、指标和调用链数据。参赛队伍在组…

vue中将某个不太规则的json转成对象,或者将对象转成json字符串

vue中将某个不太规则的json转成对象&#xff0c;或者将对象转成json字符串 以我自己做的项目某个不规则的json为例 将json对象转成json字符串&#xff1a; JSON.stringify(jsonData); 将不规则json字符串转成对象并获取对应的属性的值&#xff1a; JSON.parse(jsonData).Name…

云原生精品资料合集(附下载)

云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声&#xff0c;以应用价值为中心的云原生时代已经到&#xff0c;所以IT人员学习云原生正当时&#xff01;最近跟各位大神征集了云原生的教程&#xff0c;行业报告和最佳实践&#xff0c;总有一款适…

蓝桥杯_中断系统

一 中断 中断&#xff0c;即cpu暂停执行当前程序&#xff0c;转而执行另外一段特殊程序&#xff0c;处理结束后。返回之前暂停程序继续执行。 中断向量&#xff0c;中断服务程序的入口地址&#xff0c;每个中断源都对应一个固定的入口地址。 中断服务函数&#xff0c;内核响应中…

【亚马逊云科技】通过Amazon CloudFront(CDN)快速访问资源

文章目录 前言一、应用场景二、【亚马逊云科技】CloudFront&#xff08;CDN&#xff09;的优势三、入门使用总结 前言 前面有篇文章我们介绍了亚马逊云科技的云存储服务。云存储服务主要用于托管资源&#xff0c;而本篇文章要介绍的CDN则是一种对托管资源的快速访问服务&#…