以上错误范例的演示:库存减法
- get 和 set 分成了两步,先拿到库存,再进行计算,再写回去
- 开启多个线程同时运行以上操作,发现结果不符合预期
- 因为 线程1读的时候,线程n也在读,而不是等线程1写回再读的,因此计算结果覆盖了线程1的计算结果。
分布式锁的意义:每个业务之间有相关操作时需要有统一协调的措施
(比如,库存系统,订单系统,它们都会修改库存)
Lua 环境搭建
Lua 官网
Windows 版 Lua
下载地址 Lua IDE
通过 Lua 怎么解决了该问题

Redis 运行机制可能带来的问题

Redis 运行机制

为什么要学习 Redis 中 Lua 的使用
Redis 运行机制
Redis 运行机制带来的问题
通过 Lua 怎么解决了这些问题
课程概览

开发工具箱的网站,不管多长的字符串,都会被加密成一定长的密钥
第四个阶段
第三个阶段
第二阶段架构
第一阶段结构
为什么要学习Redis中的Lua的使用
视频中的代码。
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- DateTime: 2019/10/2 22:18
---
local KEYS = { "list" }
local ARGV = { "N", 4, -1 }
local list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
function slice(list_key, argv_list)
-- 判断是否需要反转
local reverse_flag = #argv_list >= 3 and type(ARGV[3]) == "number" and ARGV[3] < 0
local start = 1
if type(ARGV[1]) == "number" then
start = ARGV[1]
end
local end_ = #list
if type(ARGV[2]) == "number" then
end_ = ARGV[2]
end
local step = 1
if #argv_list >= 3 and type(ARGV[3]) == "number" then
step = ARGV[3]
end
--存储分片结果
local result = {}
--添加分片结果时使用的索引
local result_index = 1
print("start: " .. start .. " end_: " .. end_ .. " step:" .. step)
local for_start = start
local for_end = end_
if reverse_flag then
for_start = #list
for_end = for_end + 1
else
for_end = for_end - 1
end
print("for_start: " .. for_start .. " for_end: " .. for_end .. " step:" .. step)
for var = for_start, for_end, step do
result[result_index] = list[var]
result_index = result_index + 1
end
return result
end
local result_list = slice(KEYS, ARGV)
for i, v in pairs(result_list) do
print(i .. "-->" .. v)
end
Redis中使用Lua的优点
将命令一次性发送到redis服务器,也可以将命令缓存起来,保证所有客户端调用的都是一致的命令,方便维护
减小网络传输开销
保证redis命令执行的原子性
redis-cli
KEYS *
EVAL "redis.call('SET','TestImooc','test')" 0
GET TestImooc
EVAL "return redis.call('SET','TestImooc','test1')" 0
GET TestImooc
EVAL "return redis.call('SET','Test)"
lua中循环写法:
start=7
end_=8
step=1
for var =start,end_,step do
print(var)
end
redis中使用lua脚本命令:
script load
script flush
script exists
redis.call()
redis.pcall()
区别pcall会捕捉异常!
redis中用命令调用lua:
EVAL "redis.call('SET','testImooc','test')" 0
get testImooc
'test'
127.0.0.1:6379> EVAL "return redis.call('SET',KEYS[2],ARGV[3])" 3 imooc1 imooc2 imooc3 imooc4 imooc5 imooc6 imooc7
OK
127.0.0.1:6379> get imooc2
"imooc6"
ubuntu 安装lua apt install lua5.2 即可, 使用的话, lua filename
直接lua回车, 进入交互式模式
基本语法详见LuaAPI:
中文API地址:
https://cloudwu.github.io/lua53doc/manual.html
https://www.runoob.com/lua/lua-tutorial.html
1、Lua介绍
官网:
特点:
轻量级、嵌入式的脚本语言
稳定的、成熟的(起始于1993年)、效率高、可扩展、强大且简单
Windows版的Lua下载地址:
http://luabinaries.sourceforge.net/download.html
(官网访问不稳定,备用地址:https://download.csdn.net/download/javafd/10632132)
选择lua-5.3.4_Win64_bin.zip下载,下载后解压即可
2、编写Hello Imooc
2.1 创建文件Hello.lua,编辑文件内容:print "Hello Lua"
2.2打开命令行,使用lua53.exe执行Hello.lua:lua53.exe Hello.lua
2.3命令行打印Hello Lua,代表成功
4、IDE:ZeroBraneStudioEduPack
下载地址:
https://studio.zerobrane.com/support
(官网访问不稳定,备用地址:https://download.csdn.net/download/javafd/10632132)
解压或安装即可使用。
为什么要学习Redis中的Lua的使用
1、Redis的运行机制
Redis的单线程执行的保证了数据的原子性
2、Redis的运行机制带来的问题
当多客户端并发的多次操作一个key,执行顺序可能会错乱,导致最终数据出现错误
3、通过Luau怎么解决这个问题
Luau打包执行一系列命令,保障执行顺序不会错乱,以解决上述问题