我怀疑最大限度地提高Redis的CPU使用率会有益于您的后端设计。正确的问题是Redis是否足够有效以在给定的延迟下维持吞吐量。Redis是单线程服务器:CPU消耗80%时,延迟可能非常糟糕。
我建议您在尝试增加Redis CPU消耗之前,在redis-benchmark工作时测量延迟,以查看它是否可以满足您的需求。redis-cli的–
latency选项可用于此目的:
- 启动redis服务器
- 尝试redis-cli –latency,注意avg值,将其停止
- 在另一个窗口中,启动基准测试,并确保其运行一段时间
- 尝试redis-cli –latency,注意avg值,将其停止
- 停止基准
- 比较两个平均值
现在,如果您确实想增加Redis CPU的使用量,则需要一个高效的客户端程序(例如redis-
benchmark),该客户端程序能够同时处理多个连接,或者是客户端程序的多个实例。
Lua是一种快速的解释语言,但仍然是一种解释语言。这将比C代码慢一两个数量级。Redis在解析/生成其协议方面比lua-
redis快得多,因此您将无法使用唯一的Lua客户端使Redis饱和(除非您使用O(n)Redis命令-稍后请参见)。
webdis使用高效的客户端库以C语言实现,但必须解析http /
json协议,该协议比Redis协议更为冗长和复杂。对于大多数操作,它可能比Redis本身消耗更多的CPU。再次重申,您不会使用单个webdis实例饱和Redis。
这是一些使Redis带有多个Lua客户端的示例。
如果尚未完成,建议您首先查看Redis基准页面。
如果您在与Redis相同的框中运行基准测试:
关键是将一个内核专用于Redis,并在其他内核上运行客户端程序。在Linux上,可以为此使用tasket命令。
# Start Redis on core 0taskset -c 0 redis-server redis.conf# Start Lua programs on the other coresfor x in `seq 1 10` ; do taskset -c 1,2,3 luajit example.lua & done
Lua程序应使用流水线以最大化吞吐量并减少系统活动。
local redis = require 'redis'local client = redis.connect('127.0.0.1', 6379)for i=1,1000000 do local replies = client:pipeline(function(p) for j=1,1000 do local key = 'counter:'..tostring(j) p:incrby(key,1) end end)end在我的系统上,Lua程序占用的Redis CPU数量是Redis的4倍以上,因此您需要4个以上的内核才能使Redis达到饱和(6核的盒子应该没问题)。
如果您在与Redis不同的机器上运行基准测试:
除非您在CPU不足的虚拟机上运行,否则瓶颈可能是网络。我不认为您可以使用小于1 GbE的链路来使Redis饱和。
确保尽可能地对查询进行管线化(请参见前面的Lua程序),以避免网络延迟瓶颈,并减少CPU上网络中断的成本(填充以太网数据包)。尝试在未绑定到网卡的核心上运行Redis(并处理网络中断)。您可以使用诸如htop之类的工具来检查这一点。
如果可以,请尝试在网络的其他各种计算机上运行Lua客户端。同样,您将需要大量的Lua客户来使Redis饱和(6-10应该可以)。
在某些情况下,唯一的Lua流程就足够了:
现在,如果每个查询足够昂贵,则可以使用单个Lua客户端使Redis饱和。这是一个例子:
local redis = require 'redis'local client = redis.connect('127.0.0.1', 6379)for i=1,1000 do local replies = client:pipeline(function(p) for j=1,1000 do p:rpush("toto",i*1000+j) end end)endN = 500000for i=1,100000 do local replies = client:pipeline(function(p) for j=1,10 do p:lrange("toto",N, N+10) end end)end该程序使用1M项填充列表,然后使用lrange命令从列表中间获取10个项(Redis最坏的情况)。因此,每次执行查询时,服务器都会扫描500K项。因为仅返回10个项目,所以它们可以通过lua-
redis进行快速解析,而不会消耗CPU。在这种情况下,所有CPU消耗都将在服务器端。
最后的话
Redis客户端可能比redis-lua更快:
- https://github.com/agladysh/lua-hiredis(基于hiredis)
- https://github.com/agladysh/ljffi-hiredis(基于hiredis,使用luajit FFI)
您可能想尝试一下。



