redis lua 介绍

使用背景

lua 脚本
所有操作封装到一起,依次执行,整个操作是原子性,不会被其它中断。
批量执行脚本

语法介绍

输出字符串

EVAL "return 'Hello'" 0

有参数

redis> EVAL "return ARGV[1]" 0 Hello
"Hello"
redis> EVAL "return ARGV[1]" 0 Parameterization!
"Parameterization!"

执行redis函数

1 代表key的参数个数
foo key
bar value
相当于set foo bar

> EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 foo bar

缓存脚本

想当于把脚本缓存到客户端,这样能够减少每次执行时传输的数据量
SCRIPT LOAD 加载
EVALSHA 执行脚本

redis> SCRIPT LOAD "return 'Immabe a cached script'"
"c664a3bf70bd1d45c4284ffebb65a6f2299bfc9f"
redis> EVALSHA c664a3bf70bd1d45c4284ffebb65a6f2299bfc9f 0
"Immabe a cached script"

清除脚本

把服务器的缓存脚本清除

SCRIPT FLUSH c664a3bf70bd1d45c4284ffebb65a6f2299bfc9f

场景

更新json 对象

SET mykey '{"name": "原始名字", "age": 30}'
-- Lua 脚本开始
local json = require 'cjson' -- 确保 cjson 库可用

-- 查询 JSON 数据
local data = redis.call('GET', 'mykey')

if data then
    -- 解析 JSON 数据
    local jsonData = json.decode(data)

    -- 修改数据
    jsonData.name = '新的名字' -- 修改字段

    -- 将修改后的数据编码为 JSON 字符串
    local newData = json.encode(jsonData)

    -- 更新到 Redis
    redis.call('SET', 'mykey', newData)
    return '数据更新成功'
else
    return '没有找到数据'
end
-- Lua 脚本结束

实现计数器

-- Lua 脚本开始
local counter_key = KEYS[1] -- 计数器的键
local threshold = tonumber(ARGV[1]) -- 阈值

-- 获取当前计数
local current_count = tonumber(redis.call('GET', counter_key) or 0)

-- 增加计数
current_count = current_count + 1

-- 检查是否达到阈值
if current_count >= threshold then
    current_count = 0 -- 重置计数
end

-- 更新计数到 Redis
redis.call('SET', counter_key, current_count)

return current_count
-- Lua 脚本结束

spring 和lua 结合

lua 脚本定义

-- Lua 脚本
local user_ids = cjson.decode(ARGV[1]) -- 从参数中获取用户 IDs
local age_increment = tonumber(ARGV[2]) -- 从参数中获取年龄增量

local updated_users = {}

for _, user_id in ipairs(user_ids) do
    local user_key = 'user:' .. user_id
    local user_data = redis.call('HGETALL', user_key)

    if #user_data > 0 then
        local user_info = {}
        for i = 1, #user_data, 2 do
            user_info[user_data[i]] = user_data[i + 1]
        end

        -- 更新年龄
        local current_age = tonumber(user_info['age']) or 0
        user_info['age'] = current_age + age_increment

        -- 更新到 Redis
        redis.call('HMSET', user_key, 'name', user_info['name'], 'age', user_info['age'])
        table.insert(updated_users, user_info)
    end
end

return cjson.encode(updated_users)

spring 代码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public List<Object> updateUserAges(List<String> userIds, int ageIncrement) {
        String script = loadLuaScript("scripts/updateUser.lua");
        return (List<Object>) redisTemplate.execute(
                new DefaultRedisScript<>(script, List.class),
                Collections.emptyList(),
                JsonUtils.toJson(userIds), // 将 List 转换为 JSON 字符串
                ageIncrement
        );
    }

    private String loadLuaScript(String path) {
        // 从文件加载 Lua 脚本
        try {
            return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load Lua script", e);
        }
    }
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Lua是一种轻量级脚本语言,Redis内置了Lua解释器,可以使用Lua脚本来执行Redis命令,提高Redis的性能和灵活性。下面是Redis Lua的基础教程。 1. Redis Lua脚本的结构 Redis Lua脚本的结构以函数为单位,每个函数由三部分组成:输入参数、脚本逻辑和返回值。例如: ``` local key = KEYS[1] local value = ARGV[1] redis.call('SET', key, value) return value ``` 其中,KEYS和ARGV是Redis Lua的两个全局表,用于接收Redis命令的键和值。redis.call()用于执行Redis命令,return语句用于返回脚本执行结果。 2. Redis Lua脚本的执行 Redis Lua脚本执行有两种方式:EVAL和EVALSHA。EVAL用于执行Redis Lua脚本,EVALSHA用于执行缓存在Redis中的Lua脚本。例如: ``` redis> EVAL "return 1 + 1" (integer) 2 redis> EVALSHA "sha1" 1 key1 value1 ``` 其中,sha1是Redis Lua脚本的SHA1校验和,1是输入参数的数量,后面是输入参数的列表。 3. Redis Lua脚本的优势 Redis Lua脚本有以下优势: - 原子性:Redis Lua脚本是原子性的,一个脚本会在执行期间被其他客户端请求阻塞,直到该脚本执行完毕。 - 复用性:Redis Lua脚本可以在多个客户端之间共享,减少了网络传输和脚本解析的开销。 - 安全性:Redis Lua脚本不允许执行除Redis命令之外的任何操作,保障了Redis数据库的安全性。 以上是Redis Lua的基础教程,希望能帮助你快速上手Redis Lua脚本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wending-Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值