Redis中的Lua脚本(五)

news2025/1/14 18:33:04

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.coloradmin.cn/o/1609109.html

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

相关文章

TaskWeaver使用记录

TaskWeaver使用记录 1. 基本介绍2. 总体结构与流程3. 概念细节3.1 Project3.2 Session3.3 Memory3.4 Conversation3.5 Round3.6 Post3.7 Attachment3.8 Plugin3.9 Executor 4. 代码特点5. 使用过程5.1 api调用5.2 本地模型使用5.3 添加插件 6. 存在的问题与使用体验6.1 判别模型…

C语言 | Leetcode C语言题解之第40题组合总和II

题目: 题解: int** ans; int* ansColumnSizes; int ansSize;int* sequence; int sequenceSize;int** freq; int freqSize;void dfs(int pos, int rest) {if (rest 0) {int* tmp malloc(sizeof(int) * sequenceSize);memcpy(tmp, sequence, sizeof(int…

Web前端 JavaScript笔记7

js的执行机制 js是单线程 同步:前面一个任务执行结束之后,执行后一个 异步:异步任务,引擎放在一边,不进入主线程,而进入任务队列的任务 js通过浏览器解析,浏览器靠引擎解析 回调函数同步任务执行…

锂电池寿命预测 | Matlab基于GRU门控循环单元的锂电池寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 锂电池寿命预测 | Matlab基于GRU门控循环单元的锂电池寿命预测 Matlab基于GRU的锂电池剩余寿命预测 基于GRU的锂电池剩余寿命预测(单变量) 运行环境Matlab2020及以上 锂电池的剩余寿命预测是…

探索早期投资的奥秘:符文(Runes)生态系统的崛起

随着加密市场的迅速发展,投资者们对早期项目的关注越来越高。在这个充满变数和机遇的领域里,抢占先机意味着可能获得巨大的回报。符文(Runes)生态系统作为近期备受瞩目的项目之一,引发了众多投资者的兴趣。本文将深入探…

Java数据结构-二叉树

目录 1. 树与二叉树1.1 树1.2 二叉树1.3 树的相关概念1.4 特殊的二叉树1.5 二叉树性质1.6 二叉树的存储与表示方法 2. 二叉树遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 3. 二叉树基本操作3.1 求树的所有结点个数3.2 求叶子结点个数3.3 求第k层结点个数3.4 求二叉树…

笔记-----BFS宽度优先搜索

对于BFS:宽搜第一次搜到就是最小值,并且基于迭代,不会爆栈。 Flood Fill 模型 如果直译的话就是:洪水覆盖,意思就是像是从一个点一圈圈的往外扩散,如果遇见能够连通的就扩散,如果遇见无法联通的…

医院的工作手机、平板等智能终端的安全管理

移动互联网的时代,在医疗行业,特别是各级省市的医院,在各个科室的日常办公及业务开展都依赖计算机及智能终端设备如平板、手机等,这样能提高医务人员的办公效率,从而更好的为患者服务。 在医院信息化发展过程中&#…

vue中使用水印

1. 在utils下创建watermark.js const watermark {}/**** param {要设置的水印的内容} str* param {需要设置水印的容器} container* param {需要设置水印的每一块的宽度} canWidth* param {需要设置水印的每一块的高度} canHeight* param {需要设置水印的字体} canFont* para…

line 1:20 no viable alternative at input ‘point,‘

背景 遇到一个蛋疼的问题,搞得老夫难受的一,解决了索性记录下 Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession61b0005f] was not registered for synchronization because synchronization is not activ…

C# 报输入字符串格式不正确的原因

先放错误代码 23 class Voicewater 24 { 25 public void voicealarm(int tem) 26 { 27 Console.WriteLine("现在的温度是{}度了",tem); 28 } 29 } 解决方法…

盲人盲杖:科技革新,助力视障人士独立出行

在我们的社会中,盲人朋友们以其坚韧的精神风貌,生动诠释着生活的多样与可能。然而,当我们聚焦于他们的日常出行,那些普通人视为寻常的街道、路口,却成为他们必须面对的严峻挑战。如何切实提升盲人盲杖的功能&#xff0…

PostgreSql-Install

PostgreSql源码安装 一、源代码下载二、操作系统配置三、编译安装四、启动数据库五、相关命令 PostgreSQL是一个强大的 开源对象关系数据库系统,它使用并扩展了SQL语言,并结合了许多功能,可以安全地存储和扩展最复杂的数据工作负载。 一、源…

【C语言】指针详解(五)

目录 1.字符指针 1.1常量字符串 2.指针数组 3.数组指针 1.字符指针 字符指针就是指向字符的指针,字符指针可以存储字符变量的地址。 举例如下: 定义指针变量pa存a的地址,改变*pa的值,a也会随之改变 。 1.1常量字符串 &#x1f…

开发工具——postman使用教程详解

一、概念 1、Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件,Postman分为Postman native app和Postman Chrome app两个版本。目前Chrome app已停止维护,官方不推荐使用该版本。 2、官网下载地址:http://www.getpostman.com…

MATLAB实现禁忌搜索算法优化柔性车间调度fjsp

禁忌搜索算法的流程可以归纳为以下几个步骤: 初始化: 利用贪婪算法或其他局部搜索算法生成一个初始解。清空禁忌表。设置禁忌长度(即禁忌表中禁止操作的期限)。邻域搜索产生候选解: 通过特定的搜索算子(如…

微信小程序地图polyline坐标太多异常显示BUG

描述 微信小程序map地图上显示polyline线,点位超过1250个出现bug,(仅真机上出现,模拟器上正常) 这里以加载四川省边界为例, 以下是示例代码 // 读取geojson数据 uni.request({url: https://geo.datav.aliyun.com/a…

用 element ui 实现季度选择器

由于在数据项目中经常以各种时间条件查询数据,所以时间选择器(DatePicker)组件是很常用的组件。但是在我使用的 Element UI 中,缺少了季度选择器的功能。 简易实现 一开始我根据时间范围使用 select 去遍历,如 2024-Q1、2023-Q4…

Node.js 基础学习

文章目录 1. Node.js1.1 是什么?1.2 作用 2. 命令行工具2.1 命令的结构2.2 常用命令 3. Node.js 注意点3.1 Node.js 中不能使用DOM 和BOM 的API3.2 Node.js 中顶级对象叫做global 4. Buffer4.1 Buffer 特点4.2 Buffer 创建方式4.3 Buffer 操作与注意点 5. 计算机基础…

Rust入门-引用借用

一、引用借用,是什么、为什么、怎么用 所有权上篇我们已经讨论过了,所以这篇我们讨论Rust的引用借用 1、引用借用 是什么? Rust 通过借用(Borrowing) 这个概念来达成上述的目的,获取变量的引用,称之为借用(borrowin…