Redis列表上的Lua数值函数
2019-2-23 23:41:2
收藏:0
阅读:104
评论:2
我刚开始接触Lua和Redis。我考虑使用Redis来支持一些实时查询。作为概念证明和性能检验,我对列表中的值求和。
docker-compose.yml
version: '3.1'
services:
redis:
image: redis:4.0.13-alpine
ports:
- "6379:6379"
python脚本
import redis
import numpy as np
n = 1000000
redis_host = "localhost"
redis_port = 6379
redis_password = ""
arr = np.random.rand(n)
r = redis.StrictRedis(host=redis_host, port=redis_port, password=redis_password, decode_responses=True)
r.delete('mylist')
r.lpush('mylist', *arr.tolist())
print(np.sum(arr))
lua_sum = """
local result = redis.call('lrange', KEYS[1], 0, -1)
local sum = 0
for i=1, #result, 1 do
sum = sum + result[i]
end
return tostring(sum)
"""
f = r.register_script(lua_sum)
print(f(keys=['mylist']))
使用ipython timeit,Redis版本需要一点多一秒的时间。我可能(幼稚地?)预计至少要比numpy快一个数量级。脚本中是否有任何极其低效的地方?请注意,我意识到这种特定用例可以通过预处理来处理,但这只是一个简单的开始。
编辑 特别是timeit命令:
In [2]: %timeit f(keys=['mylist'])
1 loop, best of 3: 1.31 s per loop
In [3]: %timeit np.sum(arr)
1000 loops, best of 3: 1.04 ms per loop
点赞
用户172363
我认为您真正需要的是类似于redis-benchmark的东西。它已经包含在redis的分布中。
从命令行redis-cli中,我使用类似于您的列表向Redis的空实例添加了如下命令:
127.0.0.1:6379>eval "local result = redis.call('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, 1 do sum = sum + result[i]; end; return tostring(sum);" 0
然后,我运行了redis-benchmark:
$ redis-benchmark -n 100000 script load "local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, 1 do sum = sum + result[i]; end; return tostring(sum);"
script load local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, script load local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, script load local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, script load local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, script load local result = redis.call ('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, ====== script load local result = redis.call('lrange', 'mylist', 0, -1); local sum = 0; for i=1, #result, 1 do sum = sum + result[i]; end; return tostring(sum); ======
100000个请求在1.20秒内完成
50个并发客户端
3字节有效载荷
保持连接: 1
99.99%<=1毫秒
100.00%<=1毫秒
83263.95请求每秒
正如您所看到的,结果与您显示的结果非常不同。100,000次脚本调用完成了1.2秒。
我不知道为什么您的测试表现非常糟糕,但我可以想到几种可能性:
1.您的docker镜像中的内存/处理器限制 2.网络延迟 3.您正在使用的Python-redis库的开销
但基本上,您不应该将Redis用于处理绑定脚本。由于Redis是单线程的,lua脚本将阻塞所有其他脚本的执行,直到它完成。
我建议您使用redis-benchmark进行进一步的了解Redis的性能。
2019-03-16 06:35:49
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

你的 Lua 脚本调用
LRANGE从 Redis 中获取 100 万个数字,即LRANGE key, 0, -1,这非常低效。Redis 需要从列表中读取 100 万个数字,并将这些数据传递给 Lua。这将需要很长时间。另外,你试图在一次调用中将 100 万个数字推送到 Redis,这也是一个非常糟糕的想法,因为它可能会导致 Redis 长时间阻塞。