Redis Lua脚本书写

news2025/3/11 6:42:52

目录

1. 级联缓存值

1.1 级联缓存session及相关信息

lua脚本语句

redis运行示例

2. 级联查询

2.1 级联查询session

lua脚本语句

redis运行示例

3. 级联更新

3.1 级联更新accountId对应的用户信息

lua脚本

redis运行示例

 4. 级联续期

4.1 刷新session时级联续期

 lua脚本

redis运行结果

5. 级联删除

5.1 级联删除session

 lua脚本语句

redis运行示例


场景介绍:

(1)web项目中一般会在redis中存sessionId对应的用户信息,保存sessionId—>userInfo的关联关系。

(2)实际开发中有需要根据accountId查询用户缓存的信息,而步骤1只保存了sessionId到userInfo的映射关系。那么如何通过acccountId找到redis中缓存的用户信息呢?要么根据accountId多存一份,但太浪费资源了。这时我们可以通过accountId——映射—>sessionId——映射—>userinfo的链路确定用户信息,利用redis的lua脚本做级联的操作。​

1. 级联缓存值


1.1 级联缓存session及相关信息

(1)缓存session值,即根据sessionId缓存用户信息字符串。
(2)待第一步成功后,缓存accountId,即key为accountId,值为sessionId。

lua脚本语句

local sessionkey = KEYS[1]
local userInfo = ARGV[1] 
local accountId = KEYS[2] 

redis.call('SET', sessionkey, userInfo) 
local result =redis.call('SET', accountId, sessionkey)

return result

注:第一个set执行完,恰好redis挂了,第二个set无法正常执行返回结果,代码中执行lua脚本需要考虑超时时间。

redis运行示例

eval "local sessionkey = KEYS[1] local userInfo = ARGV[1] local accountId = KEYS[2] redis.call('SET', sessionkey, userInfo) local result =redis.call('SET', accountId, sessionkey) return result" 2 aa cc qq

 注:这里2暂时理解为2个key,aa=sessionId,cc=accountId,qq=userInfo。即套用以下公式在redis中执行lua脚本。

EVAL script numkeys key [key …] arg [arg …]

2. 级联查询

2.1 级联查询session

(1)根据accountId查询sessionId

(2)根据sessionId查询用户信息,中间需要判断

lua脚本语句

local accountId = KEYS[1]

local sessionId = redis.call('GET', accountId)

if sessionId then
    local userInfoString = redis.call('GET', sessionId)
    return userInfoString
else
    return nil
end

redis运行示例

eval "local accountId = KEYS[1] local sessionId = redis.call('GET', accountId) if sessionId then local userInfoString = redis.call('GET', sessionId) return userInfoString else return nil end" 1 cc

根据accountId(值cc),找到sessionId(值aa)对应的用户信息qq。

 查找一个不存在的值.

3. 级联更新

3.1 级联更新accountId对应的用户信息

(1)先查询accountId是否存在对应的sessionId

(2)若存在,则更新缓存的用户信息,不存在则报错提示

lua脚本

local accountId = KEYS[1] 
local userInfoString = ARGV[1]

local sessionId = redis.call('GET', accountId) 

if sessionId then 
  redis.call('SET', sessionId, userInfoString) 
  return 1 
else 
return 0 
end

redis运行示例

eval "local accountId = KEYS[1] local userInfoString = ARGV[1] local sessionId = redis.call('GET', accountId) if sessionId then redis.call('SET', sessionId, userInfoString) return 1 else return 0 end" 1 cc newUserInfoString

正常情况更新一条信息

不正常没有更新对应的信息

 4. 级联续期

4.1 刷新session时级联续期

(1)为sessionId进行续期,查询到accountId

(2)再为accountId进行续期

redis lua脚本为不存在的值进行续期,返回0,不报错。因此考虑可以先不查询,直接续期。当然实际使用中,刷新session的用户信息缓存时,绝大部分存在key。

 lua脚本

local sessionId = KEYS[1] 
local ttl = tonumber(ARGV[1]) 

local accountId=redis.call('GET', sessionId)    

if accountId then
	local accountResult=redis.call('EXPIRE', accountId,ttl) 
	local sessionResult=redis.call('EXPIRE', sessionId,ttl) 
	
	return accountResult+sessionResult
end
return 0          

PS:实际上用户信息如果存字符串,以上的lua脚本考虑做字符串处理,从用户信息字符串获取accountId,再为accountId对应的sessionId映射续期。

redis运行结果

eval "local sessionId = KEYS[1] local ttl = tonumber(ARGV[1]) local accountId=redis.call('GET', sessionId) if accountId then local accountResult=redis.call('EXPIRE', accountId,ttl) local sessionResult=redis.call('EXPIRE', sessionId,ttl) return accountResult+sessionResult end return 0" 1 sessionId111 120

5. 级联删除

5.1 级联删除session

(1)删除sessionId对应的缓存的用户信息

(2)再根据accountId删除对应的映射关系

删除存在的key返回1,不存在的key返回0

 lua脚本语句

local sessionId = KEYS[1] 
local accountId = KEYS[2]
local sessionResult=redis.call('DEL', sessionId) 
local accountResult=redis.call('DEL', accountId) 
return sessionResult+accountResult

redis运行示例

eval "local sessionId = KEYS[1] local accountId = KEYS[2] local sessionResult=redis.call('DEL', sessionId) local accountResult=redis.call('DEL', accountId) return sessionResult+accountResult" 2 iii lll

 最后,实际缓存的用户信息并不一定是字符串。缓存字符串速度快,占用空间小,但需要在代码中序列化。缓存对象,占用空间大,速度较前者慢,使用时便捷无须转换。或考虑使用Hash的数据结构。

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

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

相关文章

嵌入式数据库之sqlite3

一、数据库基本概念 数据:能够输入计算机并能被计算机程序识别和处理的信息集合。 数据库:数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。 二、常用的数据库 1.大型数据库 Oracle公司是最早开发关系数据库的厂商之一…

架构设计之分析系统性能问题

我们在讨论高性能架构之前,需要先聊聊什么叫高性能,以及如何量化地测试系统的性能。在02 讲中,我们讨论了一些和并发相关的指标。事实上,并发数正是系统性能的核心指标之一,因为高并发会引起系统资源短缺,来…

【夜深人静学数据结构与算法 | 第二篇】后缀(逆波兰)表达式

目录 前言: 中缀表达式: 后缀表达式: 中缀表达式转后缀表达式: 后缀表达式计算结果: 总结: 前言: 计算机在计算四则运算的时候,由于括号以及运算优先级的存在,并不…

大数据Doris(四十一):Routine Load严格模式和导入案例

文章目录 Routine Load严格模式和导入案例 一、严格模式 二、严格模式导入Kafka数据到Doris Routine Load严格模式和导入案例

【Thunder送书 | 第三期 】「Python系列丛书」

文章目录 前言《Python高效编程——基于Rust语言》《Python从入门到精通》《Python Web深度学习》《Python分布式机器学习》文末福利 | 赠书活动 前言 Thunder送书第三期开始啦!前面两期都是以【文末送书】的形式开展,本期将赠送Python系列丛书&#xff…

下载安装Visual Studio 2017 Community 来编译NIM_PC_DEMO

1、下载vs2017的引导程序 官方并没有为vs2017提供离线安装包,所以我们选择在线安装。 首先我们下载vs2017的引导程序:Visual Studio 2017安装包 包含如下4个文件: vs_Community.exe: 社区版,免费。但是需要登录微软…

第四节 字符串

文章目录 字符串1.1 字符串介绍1.2 字符串的定义1.3 字符串的输入和输出1.3.1 字符串的索引 1.4 字符串切片1.4.1 切片几种写法 1.5 字符串常用函数1.5.1 find()1.5.2 index()1.5.3 扩展知识: rfind()和rindex()1.5.4 count()1.5.5 replace()1.5.6 split()1.5.7 join() 1.6 字符…

C++常用STL容器--list

C常用STL容器--list list基本概念list构造函数list赋值、交换list大小操作list插入、删除list数据获取list反转、排序 list基本概念 功能: 将数据进行链式存储 链表(list) 是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针…

高并发架构设计方法

我们知道,“高并发”是现在系统架构设计的核心关键词。一个架构师如果设计、开发的系统不支持高并发,那简直不好意思跟同行讨论。但事实上,在架构设计领域,高并发的历史非常短暂,这一架构特性是随着互联网,…

Linux之配置网络

目录 Linux之配置网络 网络接口 网络类型符号 类型 设备类型或位置选择 类型 网络连接 网络配置 三种方法 方法1 --- 使用nmtui进行网路配置 方法2 --- 使用nmcli设置 方法3 --- 修改配置文件 方法4 --- cockpit配置示意图 使用ip命令配置临时生效的网络连接 测试网…

chatgpt赋能python:Python收集数据的介绍

Python收集数据的介绍 Python是一个多功能的编程语言,其拥有强大的数据收集和分析功能。为了充分利用Python的数据处理和挖掘功能,一些优秀的数据收集工具被开发出来。在本文中,我们将介绍如何使用Python收集数据,并介绍一些常用…

总结900

目标规划: 月目标:6月(线性代数强化9讲,考研核心词过三遍) 周目标:线性代数强化3讲,英语背3篇文章并回诵,检测 每日规划 今日已做 1.读六级阅读 2.完成学习通考试(没做计划) 3.阅…

[编程工具]Unity配表导出工具TableExporter1.1

[ 目录 ] 0. 前言1. 属性拓展优化(1)反射获取转化函数 TryParse(2)反射获取EmptyReplace(3)属性类型(4)属性拓展 2. 模板处理(1)替换内容(2&#…

chatgpt赋能python:Python如何放大界面——实用技巧

Python如何放大界面——实用技巧 在Python中,很多时候我们需要放大界面来更清楚的展示内容。这篇文章将介绍Python放大界面的方法。 放大界面的原理 在Python中,放大界面的原理实际上就是改变窗口的大小。我们可以通过改变窗口的尺寸实现放大效果。 …

LuatOS-Air AT应用指南--RNDIS

简介 RNDIS是指Remote NDIS,基于USB实现RNDIS实际上就是TCP/IP over USB,就是在USB设备上跑TCP/IP,让USB设备看上去像一块网卡。从而使Windows /Linux可以通过 USB 设备连接网络。 Window系统 window系统支持RNDIS直接用usb连接就可以使用&a…

2023/6/14总结

JS的学习: JavaScript是一种运行在客户端(浏览器)的编程语言,实现人机交互的效果 主要作用: 网页特效表单验证数据交互 JS的组成 ECMAScript 规定了js基础的语法核心知识 Web APIs DOM:操作文档,对页面…

简单的TCP网络程序·线程池(后端服务器)

目录 版本四:线程池 注意事项 文件:Task.hpp -- 任务单独为一个文件 组件:日志修改 新函数:vprintf() 可变参数的提取逻辑 vfprintf()的工作原理 初始化一个va_list 日志准备 获取时间小知识 日志初版 日志启动测试 …

DAY23:二叉树(十三)二叉树的最近公共祖先+二叉搜索树的最近公共祖先

文章目录 236.二叉树的最近公共祖先思路完整版后序遍历的进一步理解为什么左为空右不为空的时候return right这个逻辑是否包含p/q本身就是公共祖先的情况 235.二叉搜索树的最近公共祖先思路关于遍历顺序 递归法最开始的写法debug测试修改版 迭代法最开始的写法为什么最开始这种…

chatgpt赋能python:Python收费介绍

Python收费介绍 什么是Python? Python是一种高级的、解释性、面向对象、纯粹的动态语言,多用于快速应用程序开发、脚本编写、系统管理任务等。它有一个简单直观优美的语法,非常容易学习。 Python的收费形式 Python语言本身是免费的,任何…

chatgpt赋能python:Python如何操作Word文档

Python如何操作Word文档 简介 Python是一种高级编程语言,具有易于学习和使用、高效、可移植性强等优点。相信许多Python开发者都遇到过需要使用Python操作Word文档的情况。本文旨在介绍如何使用Python操作Word文档,使开发者能够方便地实现自己的需求。…