Redis中的Lua脚本(五)

Lua脚本

脚本复制

复制EVALSHA命令

EVALSHA命令式所有与Lua脚本有关的命令中,复制操作最复杂的一个,因为主服务器与从服务器载入Lua脚本的情况可能有所不同,所以主服务器不能像复制EVAL命令、SCRIPT LOAD命令或者SCRIPT FLUSH命令那样,直接将EVALSHA命令传播给从服务器,对于一个在主服务器被成功执行的EVALSHA命令来说,相同的EVALSHA命令在从服务器执行时可能会出现脚本未找到(not found)错误。
举个例子。假设现在有一个主服务器master,如果客户端向主服务器发送命令:

127.0.0.1:6379> SCRIPT LOAD "return 'hello world'"
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"

那么在执行这个SCRIPT LOAD命令之后,SHA1值为5332031c6b470dc5a0dd9b4bf2030dea6d65de91的脚本
就存在于主服务器中了,现在假设一个从服务器slave1开始复制主服务器master,如果master不想办法将脚本:

"return 'hello world'"

传送给slave1载入的话,那么当客户端向主服务器发送命令:

127.0.0.1:6379> EVALSHA "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" 0
"hello world"

的时候,master将成功执行这个EVALSHA命令,而当master将这个命令传播给slave1执行的时候,slave1却会出现脚本未找到错误:

127.0.0.1:6380> EVALSHA "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" 0
(error) NOSCRIPT No matching script. Please use EVAL.

更为复杂的是,因为多个从服务器之间载入Lua脚本的情况也可能各有不同,所以即使一个EVALSHA命令可以在某个从服务器成功执行,也不代表这个EVALSHA命令就一定可以在另一个从服务器成功执行。

例子
  • 举个例子。假设有主服务器master和从服务器slave1,并且slave1一致复制着master,所以master载入的所有Lua脚本,slave1也有载入(通过传播EVAL命令或者SCRIPT LOAD命令来实现)例如说,如果客户端向master发送命令
127.0.0.1:6379> SCRIPT LOAD "return 'hello world'"
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"

那么这个命令也会被传播到slave1上面,所以master和slave1都会成功载入SHA1校验和为 5332031c6b470dc5a0dd9b4bf2030dea6d65de91
的Lua脚本。如果这时,一个新的从服务器slave2开始复制主服务器master,如果master不想办法将脚本:

"return 'hello world'"

传送给slave2的话,那么当客户端向主服务器发送命令:

127.0.0.1:6379> EVALSHA "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" 0
"hello world"

的时候,master和slave1都将成功执行这个EVALSHA命令,而slave2却会发生脚本未找到错误。为了防止以上假设的情况出现,Redis要求主服务器在传播EVALSHA命令的时候,必须确保EVALSHA命令要执行的脚本已经被所有从服务器载入过,如果不能确保这一点的话,主服务器会将EVALSHA命令转换成一个等价的EVAL命令,然后通过传播EVAL命令来代替EVALSHA命令。传播EVALSHA命令,或者将EVALSHA命令转换成命令,都需要用到服务器状态的lua_scripts字典和repl_scriptcache_dict字典

判断传播EVALSHA命令是否安全的方法

主服务器使用服务器状态的repl_scriptcache_dict字典记录自己已经将哪些脚本传播给了所有从服务器:

struct redisServer{
// ...dict *replc_scriptcache_dict;// ...
};

repl_scriptcache_dict字典的键是一个个Lua脚本的SHA1校验和,而字典的值则全部都是NULL,当一个校验和出现在repl_scriptcache_dict字典时,说ing这个校验和对应的Lua脚本已经传播给了所有从服务器,主服务器
可以直接向从服务器传播包含这个SHA1校验和的EVALSHA命令,而不必担心从服务器会出现脚本未找到错误

例子
  • 举个例子。如果主服务器repl_scriptcache_dict字典的当前状态如图所示。那么主服务器可以向从服务器传播以下三个EVALSHA命令,并且从服务器在执行这些EVAlSHA命令的时候不会出现脚本未找到错误:
EVALSHA "2f31ba2bb6d6a0f42cc159d2e2dad55440778de3" ...
EVALSHA "a27e7e8a43702b7046d4f6a7ccf5b60cef6b9bd9" ...
EVALSHA "4475bfb5919b5ad16424cb50f74d4724ae833e72" ...

另一方面,如果一个脚本的SHAR1校验和存在于lua_scripts字典,但是不存在于repl_scriptcache_dict字典,那么说明校验和对应的Lua脚本已经被主服务器载入,但是并没有传播给所有从服务器,如果尝试向从服务器传播包含这个SHA1校验和的EVALSHA命令,那么至少有一个从服务器会出现脚本未找到错误
在这里插入图片描述

  • 举个例子。对于如图所示的lua_scirpts字典,以及上图的repl_scriptcache_dict字典来说,SHA1校验和为:
"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"

的脚本:

"return 'hello world'"

虽然存在于lua_scirpts字典,但是repl_scriptcache_dict字典却并不包含校验和"5332031c6b470dc5a0dd9b4bf2030dea6d65de91"
这说明脚本

"return 'hello world'"

虽然已经载入到主服务器里面,但并未传播给所有从服务器,如果主服务器尝试向从服务器发送命令:

EVALSHA "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" ...

那么至少会有一个从服务器遇上脚本未找到错误
在这里插入图片描述

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

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

相关文章

Ubuntu鼠标自动点击脚本-工具xdotool简单使用

1 安装xdotool sudo apt-get install xdotool2 xdotool基本指令 移动鼠标 #设置屏幕位置 x_ 300 y_ 400 xdotool mousemove x_ y_点击鼠标 xdotool mousemove x_ y_ click 1设置动作间隔 #暂停2s sleep 23简单的bash脚本 move_mouse.sh iterations 2000for ((i0; i&l…

CentOS 7 上安装 MySQL 8.0详细步骤

CentOS 7 上安装 MySQL 8.0.30:详细步骤 准备阶段 下载 MySQL 安装包 前往 MySQL Archives,选择适合 CentOS 7 的安装包。 关闭防火墙和 SELinux # 临时关闭防火墙 systemctl stop firewalld.service # 永久关闭防火墙 systemctl disable firewalld.se…

k8s的服务Service暴露应用

k8s的服务Service暴露应用 Kubernetes(k8s)是一个开源的容器编排系统,用于自动化应用部署、扩展和管理。在k8s中,Service是管理Pod访问的关键组件,它允许你定义如何访问运行在集群中的Pod。本文将详细介绍Service的概…

第七节 LLAVA模型训练流程与方法

文章目录 前言一、训练模式方法二、lora形式fitune训练步骤第一步:lora形式fitune的launch.json配置第二步:train_mem.py第三步:模型参数配置(train())第四步:语言模型加载第五步:语言模型梯度、量化、lora训练方法设定第六步:语言模型的tokenizer第七步:根据model_ar…

[大模型]Qwen-7B-Chat 接入langchain搭建知识库助手

Qwen-7B-Chat 接入langchain搭建知识库助手 环境准备 在autodl平台中租一个3090等24G显存的显卡机器,如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab,并且打开其中的终端开始环境配置…

河北专升本(c语言各种编程题)

目录 第一类、递归调用 第二类、特殊数字 第三类、多维数组 第四类、字符处理 第五类、数学问题 第六类、排序算法 第七类、循环问题 第八类、进制转换 第九类、实际应用 第十类、图形输出 第一类、递归调用 1.汉诺塔:请输入盘子数,输出盘子移动…

05_Flutter屏幕适配

05_Flutter屏幕适配 一.屏幕适配方案 通过指定基准屏宽度,进行适配,基准屏宽度取决于设计图的基准宽度,以iphone 14 pro max为例, devicePixelRatio 物理宽度 / 逻辑宽度(基准宽度) iphone 14 pro max的物理尺寸宽度为1290&…

基于SSM的购物小程序01

4.1系统架构设计 购物系统设计的系统项目的概述设计分析,主要内容有学习平台的具体分析,进行数据库的是设计,数据采用mysql数据库,并且对于系统的设计采用比较人性化的操作设计,对于系统出现的错误信息可以及时做出处…

【Linux系统】地址空间 Linux内核进程调度队列

1.进程的地址空间 1.1 直接写代码&#xff0c;看现象 1 #include<stdio.h>2 #include<unistd.h>3 4 int g_val 100;5 6 int main()7 {8 int cnt 0;9 pid_t id fork();10 if(id 0)11 {12 while(1)13 {14 printf(&…

ConcurrentHashMap使用的时候一定不需要考虑线程安全问题吗

ConcurrentHashMap使用的时候一定不需要考虑线程安全问题吗 不一定 ConcurrentHashMap<String, String> map new ConcurrentHashMap<>();// 查询是否有123 如果没有则报错if (!map.contains("123")) {;}map.put("123","插入成功");…

如何用flutter写一个好的登录页面

编写一个好的登录页面是构建用户友好且安全的移动应用的重要一步。下面是使用Flutter编写一个好的登录页面的一些建议和步骤&#xff1a; 1. 设计用户界面 1.简洁明了的布局&#xff1a;确保界面简洁明了&#xff0c;不要过分复杂&#xff0c;避免用户感到困惑。 2.清晰的输入框…

SQL刷题---2021年11月每天新用户的次日留存率

解题思路&#xff1a; 1.首先算出每个新用户注册的日期,将其命名为表a select uid,min(date(in_time)) dt from tb_user_log group by uid2.计算出每个用户登录的天数,将其命名为表b select uid,date(in_time) dt from tb_user_log union select uid,date(out_time) dt fro…

校园小情书微信小程序源码/社区小程序前后端开源/校园表白墙交友小程序

校园小情书前端代码&#xff0c;好玩的表白墙、树洞、校园论坛&#xff0c;可独立部署&#xff0c;也可以使用我部署的后台服务&#xff0c;毕业设计的好项目。 搭建教程&#xff1a; 一、注册管理后台 1、登录小情书站点进行注册&#xff1a;https://你的域名 2、注册成功…

【前端】vue.config.js打包时不编译

vue.config.js 在将 Vue.js 项目部署到服务器上时&#xff0c;通常不需要修改 vue.config.js 文件&#xff0c;因为该文件通常用于配置开发过程中的一些选项&#xff0c;如开发服务器配置、代理等&#xff0c;而不是用于生产环境的配置。 在生产环境中&#xff0c;Vue 项目会…

使用Docker搭建一主二从的redis集群

文章目录 一、根据基础镜像构建三个docker容器二、构建master机三、配置slave机四、测试 本文使用 主机指代 物理机、 master机指代“一主二从”中的 一主&#xff0c; slave机指代“一主二从”中的 二从 一、根据基础镜像构建三个docker容器 根据本文第一章&#xff08…

小红书笔记写作方法和技巧分享,纯干货!

很多小伙伴感叹小红书笔记流量就是一个玄学&#xff0c;有时精心撰写的笔记却没有人看&#xff0c;自己随便写的笔记却轻轻松松上热门。实际上你还是欠点火候&#xff0c;小红书笔记写作是有一套方法和技巧的&#xff0c;总归是有套路的&#xff0c;如果你不知道&#xff0c;请…

YOLOv5检测框crop、MobileNetv3分类网络

在实际深度学习项目中&#xff0c;目标检测算法检测出的目标也会作为分类网络的输入数据&#xff0c;利用目标检测算法的对被检测图像进行抠图&#xff0c;以抠出来的图来扩充分类网络的数据。本文主要讲解yolov5和mobilenetv3结合使用扩展数据样本。 目录 1、yolov5检测框cro…

CTFHub(web sql注入)(二)

布尔盲注 盲注原理&#xff1a; 将自己的注入语句使用and与?id1并列&#xff0c;完成注入 手工注入&#xff1a; 爆库名长度 首先通过折半查找的方法&#xff0c;通过界面的回显结果找出数据库名字的长度&#xff0c;并通过相同的方法依次找到数据库名字的每个字符、列名…

EasyExcel追加写入数据,分批查询多次写入场景下,注意使用方式【OOM警告】

使用.withTemplate(file) 将临时数据文件和真实数据文件合并的方式&#xff0c;在生产环境大批量数据下&#xff0c;完全不可取&#xff0c;有很高的内存溢出风险 伪代码 public static void writeAppend(String fileName) {String filePath "tempDir".concat(Fil…

【Jupyter notebook】安装-换源-报错问题收集及实测解决法

Jupyter 在一个名为 kernel 的单独进程中运行用户的代码。kernel 可以是不同的 Python 安装在不同的 conda 环境或虚拟环境,甚至可以是不同语言(例如 Julia 或 R)的解释器。 1, 如何查询当前环境下的python 版本 运行 import sys print(sys.executable) %pwd import sy…