基本
概念
redis: REmote DIctionary Server
key-value 存储系统,非关系型数据库。
开源的使用 ANSI C 语言编写
支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
值(value)可以是
字符串(String)
哈希(Hash)
列表(list)
集合(sets)
有序集合(sorted sets)
特性
性能极高
Redis 以其极高的性能而著称,能够支持每秒数十万次的读写操作
高性能的读写能力:Redis 能读的速度是 110000次/s,写的速度是 81000次/s。这种高性能主要得益于 Redis 将数据存储在内存中,从而显著提高了数据的访问速度。
原子性操作
Redis 的所有操作都是原子性的,这意味着操作要么完全执行,要么完全不执行。这种特性对于确保数据的一致性和完整性至关重要,尤其是在高并发环境下处理事务时。
支持发布/订阅模式:Redis 内置了发布/订阅模式(Pub/Sub),允许客户端之间通过消息传递进行通信。这使得 Redis 可以作为消息队列和实时数据传输的平台。
单线程模型:尽管 Redis 是单线程的,但它通过高效的事件驱动模型来处理并发请求,确保了高性能和低延迟。单线程模型也简化了并发控制的复杂性。
安装
sudo apt install redis-server
起 server
redis-server
另一窗口
起redis-cli,输入ping 回复PONG
命令
获取所有key keys *
清空当前数据库 flushdb
lua 脚本
Redis在服务器中嵌入了Lua环境
为什么使用:
减少网络开销: 使用脚本功能完成同样的操作只需要发送一个请求即可,减少了网络往返时延。
$ redis-cli --eval path/to/redis.lua KEYS[1] KEYS[2] , ARGV[1] ARGV[2] …
–eval,告诉redis-cli读取并运行后面的lua脚本
path/to/redis.lua,是lua脚本的位置
KEYS[1] KEYS[2],是要操作的键,可以指定多个,在lua脚本中通过KEYS[1], KEYS[2]获取
ARGV[1] ARGV[2],参数,在lua脚本中通过ARGV[1], ARGV[2]获取。
注意:KEYS和ARGV中间的 ‘,’ 两边的空格,不能省略。
EVALSHA命令
eval sha1id numkeys key [key …] arg [arg …]
在脚本比较长的情况下,如果每次调用脚本都需要将整个脚本传给Redis会占用较多的带宽。
为了解决这个问题,Redis提供了EVALSHA命令,允许开发者通过脚本内容的SHA1摘要来执行脚本,该命令的用法和EVAL一样,只不过是将脚本内容替换成脚本内容的SHA1摘要。
Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中,执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了则执行脚本,否则会返回错误:“NOSCRIPT No matching script. Please use EVAL.”
在程序中使用EVALSHA命令的一般流程如下。
1)先计算脚本的SHA1摘要,并使用EVALSHA命令执行脚本。
2)获得返回值,如果返回“NOSCRIPT”错误则使用EVAL命令重新执行脚本。
虽然这一流程略显麻烦,但值得庆幸的是很多编程语言的Redis客户端都会代替开发者完成这一流程。执行EVAL命令时,先尝试执行EVALSHA命令,如果失败了才会执行EVAL命令。
SCRIPTLOAD “lua-script” 将脚本加入缓存,但不执行, 返回:脚本的SHA1摘要
SCRIPT EXISTS lua-script-sha1 判断脚本是否已被缓存
例子
开始的数据库
lua脚本
local name=redis.call("get",KEYS[1])
local age=redis.call("get",KEYS[2])
if name=="lilei" then
redis.call("set",KEYS[1],ARGV[1])
redis.call("incr",KEYS[2])
else
redis.call("set", "111", "222")
end
执行
redis-cli --eval ./01.lua name age , aaa
执行后
lua脚本摘要
一个Lua脚本很长的话,那么直接这么调用Lua脚本的话非常不方便,所以Redis当中提供了一个命令script load来为手动给每一个命令生成摘要,这里之所以要说手动的原因是即使我们不使用这个命令,每次调用完Lua脚本的时候,Redis也会为每个Lua脚本生成一个摘要。
例子
127.0.0.1:6379> script load "return redis.call('set', KEYS[1], ARGV[1])"
"55b22c0d0cedf3866879ce7c854970626dcef0c3"
127.0.0.1:6379> evalsha "55b22c0d0cedf3866879ce7c854970626dcef0c3" 1 name abc
OK
127.0.0.1:6379> get name
"abc"
script exists 摘要:判断一个摘要是否存在。0表示不存在,1表示存在
script flush:清除所有Lua脚本缓存
例子
当我们的Lua脚本很长时,直接在命令窗口中写脚本是不直观的,也很难发现语法问题,所以Redis当中也支持我们直接把先把脚本写入文件中,然后直接调用文件。
比如我们新建一个test.lua脚本:
redis.call('set',KEYS[1],ARGV[1])
return redis.call('get',KEYS[1])
参考
https://www.runoob.com/redis/redis-tutorial.html
redis使用lua脚本 https://www.cnblogs.com/aspirant/p/16772759.html
Redis 如何调试Lua 脚本 https://zhuanlan.zhihu.com/p/353860023