Lua在Redis中的应用
转载至笑松小站http://blog.seoui.com/2018/01/27/redis-lua/
redis
从2.6版本开始内置支持Lua
解释器,解释器提供了3个函数来处理redis
的命令redis.call()
redis.pcall()
和 redis.log
,同时redis
也保证脚本会以原子性的方式执行。这是一个很重要的因素。
本文涉及到的命令有 EVAL
EVALSHA
SCRIPT LOAD
SCRIPT FLUSH
SCRIPT EXISTS
SCRIPT KILL
redis.call(), redis.pcall() 函数的区别就是处理错误异常的情况不同,其他的功能是一样的 具体使用哪个看需求而论
redis.call()
执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误redis.pcall()
执行命令的过程中发生错误时,脚本会继续执行,但是会记录错误信息 返回一个带 err 域的 Lua 表(table)redis.log(loglevel, message)
触发redis
记录日志 日志级别有 redis.LOG_DEBUG redis.LOG_VERBOSE redis.LOG_NOTICE redis.LOG_WARNING
EVAL
EVAL
命令对 Lua
脚本进行执行求值。
语法:EVAL script numkeys key [key …] arg [arg …]
script
lua脚本内容 注意的是脚本不应该是Lua
函数。numkeys
表示指定键名参数的个数。key [key ...]
表示脚本对应的key
值列表 在脚本中可以使用KEYS[1]
KEYS[2]
KEYS[3]
KEYS[n]
n从1开始 。arg [arg ...]
命名行中传递的参数列表 在脚本中可以使用ARGV[1]
ARGV[2]
ARGV[3]
ARGV[n]
n从1开始 。
一个示例胜过千言万语的解释
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 id name 3 mytest
|
执行上面脚本返回
1) "id"
2) "name"
3) "2"
4) "mytest"
|
EVALSHA
此命令和EVAL
的区别是EVAL
每次都需要传入脚本的主体内容,对网络带宽不是很友好。而EVALSHA
命令正好可以解决这个问题。
语法: EVALSHA sha1 numkeys key [key …] arg [arg …]
sha1
缓存中的sha
值 这个值可以利用SCRIPT LOAD
生成numkeys
表示指定键名参数的个数。key [key ...]
表示脚本对应的key
值列表 在脚本中可以使用KEYS[1]
KEYS[2]
KEYS[3]
KEYS[n]
n从1开始 。arg [arg ...]
命名行中传递的参数列表 在脚本中可以使用ARGV[1]
ARGV[2]
ARGV[3]
ARGV[n]
n从1开始 。
> SCRIPT LOAD "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"
"a42059b356c875f0717db19a51f6aaca9ae659ea"
> EVALSHA a42059b356c875f0717db19a51f6aaca9ae659ea 2 id name 2 mytest
1) "id"
2) "name"
3) "2"
4) "mytest"
>
|
1、首先利用SCRIPT LOAD
把脚本的主体缓存在redis
中,会返回一个sha的key
2、EVALSHA
执行命令 把sha带上 其他的和eval没有区别。
脚本缓存
redis
保证了所有运行过的脚本都能缓存起来 前面也提到过使用SCRIPT LOAD
也能将脚本缓存并返回sha值,那么也能使用SCRIPT FLUSH
清空脚本缓存
SCRIPT LOAD
加载脚本到缓存中SCRIPT FLUSH
清除所有 Lua 脚本缓存。SCRIPT EXISTS
判断sha值是否已经缓存好了,返回值为 0 和 1 ,后者表示存在于缓存中,在程序开发中非常有用 比如redis
出现了什么异常情况后,脚本缓存被清空了,或者被人为执行了SCRIPT FLUSH
命令,这个时候就可以优先尝试一下SCRIPT EXISTS
命令如果返回0表示不存在 就需要先执行SCRIPT LOAD
先把脚本加载到缓存中之后再执行
SCRIPT KILL
杀死当前正在运行的 Lua
脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效
。
SCRIPT KILL
执行成功返回OK,其他情况返回错误信息
业务场景案例
- spring-cloud-gateway springc cloud 网关限流
- 需要原子操作的零散逻辑
- 分布式限流
- ….
Lua在Redis中的应用的更多相关文章
- redis中lua脚本的简单使用
一.背景 在使用redis的过程中,发现有些时候需要原子性去操作redis命令,而redis的lua脚本正好可以实现这一功能.比如: 扣减库存操作.限流操作等等. redis的pipelining虽然 ...
- Redis中的原子操作(2)-redis中使用Lua脚本保证命令原子性
Redis 如何应对并发访问 使用 Lua 脚本 Redis 中如何使用 Lua 脚本 EVAL EVALSHA SCRIPT 命令 SCRIPT LOAD SCRIPT EXISTS SCRIPT ...
- 在redis中使用lua脚本让你的灵活性提高5个逼格
在redis的官网上洋洋洒洒的大概提供了200多个命令,貌似看起来很多,但是这些都是别人预先给你定义好的,但你却不能按照自己的意图进行定制, 所以是不是感觉自己还是有一种被束缚的感觉,有这个感觉就对了 ...
- 在redis中使用lua脚本
在实际工作过程中,可以使用lua脚本来解决一些需要保证原子性的问题,而且lua脚本可以缓存在redis服务器上,势必会增加性能. 不过lua也会有很多限制,在使用的时候要注意. 在Redis中执行Lu ...
- redis中使用lua脚本
lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...
- 新姿势!Redis中调用Lua脚本以实现原子性操作
背景:有一服务提供者Leader,有多个消息订阅者Workers.Leader是一个排队程序,维护了一个用户队列,当某个资源空闲下来并被分配至队列中的用户时,Leader会向订阅者推送消息(消息带有唯 ...
- 使用redis+lua实现SQL中的select intersect的效果
公众号文章地址 1.需求 业务中需要实现在两个集合中搜索数据,并返回交集. 用SQL的伪代码可以描述如下: select key from set1 where sorted_key between ...
- Lua 与 Redis
Lua 与 Redis 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis - 案例-实现访问频率限制: 实现访问者 $ip 在一定的 ...
- redis中使用java脚本实现分布式锁
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/115.html?1455860390 edis被大量用在分布式的环境中,自 ...
随机推荐
- [Swift]LeetCode145. 二叉树的后序遍历 | Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. Example: Input: [1,null,2, ...
- [Swift]LeetCode211. 添加与搜索单词 - 数据结构设计 | Add and Search Word - Data structure design
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
- [Swift]LeetCode324. 摆动排序 II | Wiggle Sort II
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
- [Swift]LeetCode872. 叶子相似的树 | Leaf-Similar Trees
Consider all the leaves of a binary tree. From left to right order, the values of those leaves form ...
- linux入门--Linux系统的优缺点
1) 大量的可用软件及免费软件 Linux 系统上有着大量的可用软件,且绝大多数是免费的,比如声名赫赫的 Apache.Samba.PHP.MySQL 等,构建成本低廉,是 Linux 被众多企业青睐 ...
- ELK之filebeat、logstash多个topic配置
启动多个进程收集日志.直接output到kafka,output到不同的topiccat filebeat.ymlfilebeat.prospectors:- input_type: log path ...
- C#中为什么会出现空静态构造方法的写法
再过几个小时,就要回家过春节了,今天说些简单点的东西,大家在看C#代码的时候,一定会对这样的写法非常迷茫:在一个类中会出现一个空的静态构造方法.这不是多此一举吗,这样做的目的是什么?今天我就来说说这个 ...
- BBS论坛(二十四)
24.1.编辑板块 cms/js/banners.js $(function () { $('.edit-board-btn').click(function () { var self = $(th ...
- 【Maven】---Linux搭建Nexus3.X私服
Linux搭建Nexus3.X私服 备注:linux版本: ubuntu 同时已经部署好JDK8环境 一.linux安装nexus 1.创建文件夹并进入该目录 cd /usr/local && ...
- C++11 实现生产者消费者模式
代码都类似,看懂一个,基本都能理解了. 共有代码: #include <cstdlib>#include <condition_variable>#include <io ...