大流量架构(一)之REDIS篇

本文探讨了在大流量架构中Redis与Lua的整合应用,详细介绍了如何使用Lua脚本在Redis中执行任务,包括独立脚本执行、Lua与Redis交互、以及在生产环境下的部署策略。通过Lua,可以实现原子操作、减少网络开销并提高Redis的效率。
摘要由CSDN通过智能技术生成

大流量架构之Redis篇

Lua 是由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于1993年开发的一种轻量、小巧的脚本语言,用标准 C 语言编写,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

官网:http://www.lua.org/

Redis 在 2.6 版本中推出了脚本功能,允许开发者将 Lua 语言编写的脚本传到 Redis 中执行。使用 Lua 脚本的优点有如下几点:

  1. 减少网络开销:本来需要多次请求的操作,可以一次请求完成,从而节约网络开销;
  2. 原子操作:Redis 会将整个脚本作为一个整体执行,中间不会执行其它命令;
  3. 复用:客户端发送的脚本会存储在 Redis 中,从而实现脚本的复用。

Redis 与 Lua 整合

测试lua执行

在redis中执行简单脚本

登录到客户端后执行

eval   "return 1+1"    0
#命令    脚本        参数个数
带有参数
eval "local msg='hello world' return msg..KEYS[1]" 1 AAA BBB

表是基于1的,也就是说索引以数值1开始。所以在表中的第一个元素就是mytable[1],第二个就是mytable[2]等等。 表中不能有nil值。如果一个操作表中有[1, nil, 3, 4],那么结果将会是[1]——表将会在第一个nil截断。

独立脚本执行

创建一个test1.lua文件,获取key的value
local key=KEYS[1]  

local list=redis.call("get",key);  

return list;
创建一个test2.lua文件,读取redis集合中的数据
local key=KEYS[1]

local list=redis.call("lrange",key,0,-1);

return list;
创建一个test3.lua文件,统计点击次数
local msg='count:'
local count = redis.call("get","count")
if not count then
        redis.call("set","count",1)
end

redis.call("incr","count")

return msg..count+1

执行lua脚本
本地执行
redis-cli --eval test3.lua aaa,bbb

远程执行
redis-cli -h 192.168.2.161 -a密码 --eval /usr/local/luascript/test.lua name age , xiao6

Lua 与 Redis 交互

Lua 脚本获取 EVAL & EVALSHA 命令的参数

通过 Lua 脚本的全局变量 KEYS 和 ARGV,能够访问 EVAL 和 EVALSHA 命令的 key [key …] 参数和 arg [arg …] 参数。

作为 Lua Table,能够将 KEYS 和 ARGV 作为一维数组使用,其下标从 1 开始。

Lua 脚本内部执行 Redis 命令

Lua 脚本内部允许通过内置函数执行 Redis 命令:

redis.call()

redis.pcall()

两者非常相似,区别在于:

若 Redis 命令执行错误,redis.call() 将错误抛出(即 EVAL & EVALSHA 执行出错);

redis.pcall()将错误内容返回。

redis WATCH/MULTI/EXEC 与Lua

redis 原生支持 监听、事务、批处理,那么还需要lua吗?

  • 两者不存在竞争关系,而是增强关系,lua可以完成redis自身没有的功能
  • 在lua中可以使用上一步的结果,也就是可以开发后面操作依赖前面操作的执行结果的应用,MULT中的命令都是独立操作
  • redis可以编写模块增强功能,但是c语言写模块,太难了,lua简单的多
  • 计算向移动数据
  • 原子操作

lua脚本尽量短小并且尽量保证同一事物写在一段脚本内,因为redis是单线程的,过长的执行会造成阻塞,影响服务器性能。

Redis Lua 脚本管理

1.script load 此命令用于将Lua脚本加载到Redis内存中

2.script exists scripts exists sha1 [sha1 …] 此命令用于判断sha1是否已经加载到Redis内存中

3.script flush 此命令用于清除Redis内存已经加载的所有Lua脚本,在执行script flush后,sha1不复存在

4.script kill 此命令用于杀掉正在执行的Lua脚本

死锁

下面代码会进入死循环,导致redis无法接受其他命令。

eval "while true do end" 0 
127.0.0.1:6379> keys *
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

但是可以接受 SCRIPT KILL or SHUTDOWN NOSAVE. 两个命令

SHUTDOWN NOSAVE 不会进行持久化的操作

SCRIPT KILL 可以杀死正在执行的进程

生产环境下部署

加载到redis
redis-cli script load "$(cat test.lua)"

得到sha1值

执行

redis-cli evalsha "6a947bb8a40f4832db1f248970ee61fa80d0c32c" 1 k1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值