Lua 如何改进Redis服务器';什么是CPU使用率?

Lua 如何改进Redis服务器';什么是CPU使用率?,lua,redis,benchmarking,Lua,Redis,Benchmarking,我的目标是让我们的Redis服务器在生产中达到大约80%的CPU利用率。这将有利于我们的后端服务器设计,确保我们不会利用CPU不足,同时也为增长和峰值留出一些空间 在使用Redis自己的基准测试工具时,很容易达到100%的CPU使用率: $ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50 在这个基准测试中,我们分配了50个客户端将1000000个请求推送到我们的Redis服务器 但是,在使用其他一些客户端工具(如或)时,最大CPU使用率低

我的目标是让我们的Redis服务器在生产中达到大约80%的CPU利用率。这将有利于我们的后端服务器设计,确保我们不会利用CPU不足,同时也为增长和峰值留出一些空间

在使用Redis自己的基准测试工具时,很容易达到100%的CPU使用率:

    $ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50
在这个基准测试中,我们分配了50个客户端将1000000个请求推送到我们的Redis服务器

但是,在使用其他一些客户端工具(如或)时,最大CPU使用率低于60%

我在
webdis
redislua
中浏览了一些代码
webdis
依赖于
hiredis
redis-lua
在lua中实现,并依赖于socket(
lua-socket

与Redis基准相比,这些客户端是否太慢,无法最大限度地提高Redis的CPU消耗

我还在
redis benchmark.c
中浏览了一些代码。基准测试的主要工作在
aeMain
中完成。似乎
redis基准测试
使用了来自redis的快速代码,而我的测试客户机(
webdis
redis lua
)则没有

目前,我的客户有两种选择:

  • 使用redis lua
  • 使用类似于
    webdis的工具
  • 然而,这两种方法并不能最大限度地提高Redis的CPU利用率(低于60%)。还有其他选择吗


    或者,是否有可能在
    redis benchmark
    工具本身之外充分利用redis服务器?

    我怀疑最大限度地提高redis的CPU使用率将有助于您的后端设计。正确的问题是Redis是否有足够的效率来维持给定延迟下的吞吐量。Redis是一个单线程服务器:在80%的CPU消耗下,延迟可能会非常糟糕

    我建议您在redis benchmark工作时测量延迟,看看它是否适合您的需要,然后再尝试增加redis的CPU消耗。redis cli的--latency选项可用于:

    • 启动redis服务器
    • 尝试redis cli--latency,注意平均值,然后停止
    • 在另一个窗口中,启动基准测试,并确保它运行一段时间
    • 尝试redis cli--latency,注意平均值,然后停止
    • 停止基准测试
    • 比较两个平均值
    现在,如果你真的想增加Redis的CPU消耗,你需要一个高效的客户端程序(比如Redis benchmark),能够同时处理多个连接,或者是客户端程序的多个实例

    Lua是一种快速解释语言,但它仍然是一种解释语言。它将比C代码慢一到两个数量级。Redis在解析/生成其协议方面比lua Redis快得多,因此您将无法使用唯一的lua客户端使Redis饱和(除非您使用O(n)Redis命令-请参阅下文)

    webdis是用C语言实现的,有一个高效的客户端库,但必须解析http/json协议,而http/json协议恰好比Redis协议更详细、更复杂。对于大多数操作,它可能比Redis本身消耗更多的CPU。因此,您也不会让一个webdis实例使Redis饱和

    下面是一些使用多个Lua客户端使Redis饱和的示例

    如果还没有完成,我建议你先看看

    如果您在与Redis相同的框中运行基准测试:

    关键点是将一个内核专用于Redis,并在其他内核上运行客户端程序。在Linux上,您可以为此使用taskset命令

    # Start Redis on core 0
    taskset -c 0 redis-server redis.conf
    
    # Start Lua programs on the other cores
    for 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程序占用的CPU是Redis的4倍多,因此您需要4个以上的内核才能用这种方法使Redis饱和(6个内核的盒子就可以了)

    如果您在不同于Redis的盒子上运行基准测试:

    除非运行在CPU不足的虚拟机上,否则在这种情况下,瓶颈可能是网络。我认为你不能用低于1Gbe的链路让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)
    end
    
    N = 500000
    for 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个项目,所以LuaRedis可以快速解析它们,而不会占用CPU。在这种情况下,所有的CPU消耗都在服务器端

    最后一句话

    可能有比Redis lua更快的Redis客户端:

    • (基于hiredis)
    • (基于hiredis,使用luajit FFI)
    你可能想试试