首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提高Redis服务器的CPU利用率?

如何提高Redis服务器的CPU利用率?
EN

Stack Overflow用户
提问于 2013-04-25 08:13:00
回答 1查看 6.7K关注 0票数 4

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

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

代码语言:javascript
复制
    $ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50

在这个基准上,我们分配了50个客户端将1,000,000个请求推送到Redis服务器。

但是,在使用其他一些客户端工具(如雷迪斯-卢阿webdis)时,最大CPU使用率不到60%。

我在webdisredis-lua中浏览了一些代码。webdis依赖于hiredisredis-lua在Lua中实现,并且依赖于套接字(lua-socket)。

与Redis基准测试相比,这些客户端是否太慢,并且无法最大化Redis CPU消耗?

我还浏览了redis-benchmark.c中的一些代码。基准测试的主要工作是用aeMain完成的。redis-benchmark似乎使用来自Redis的快速代码,而我的测试客户端(webdisredis-lua)则不使用。

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

  1. 使用redis-lua
  2. 使用像webdis这样的工具

但是,这两种方法并不能最大限度地提高Redis的CPU利用率(不足60%)。还有别的选择吗?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-25 12:19:37

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

我建议您在Redis工作时测量延迟,在尝试增加Redis CPU消耗之前,看看它是否可以满足您的需要。redis-cli的--延迟选项可用于此:

  • 启动redis服务器
  • 尝试redis-cli -延迟,注意avg值,停止它。
  • 在另一个窗口中,启动基准测试,并确保它运行一段时间。
  • 尝试redis-cli -延迟,注意avg值,停止它。
  • 停止基准测试
  • 比较这两个avg值

现在,如果您真的想增加Redis CPU的消耗,那么您需要一个高效的客户端程序(比如redis-benchmark),它可以同时处理多个连接,或者是客户机程序的多个实例。

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

webdis是用C实现的,它有一个高效的客户端库,但是必须解析http/json协议,这些协议比Redis协议更冗长、更复杂。在大多数操作中,它可能比Redis本身消耗更多的CPU。因此,您不会使用单个webdis实例填充Redis。

下面是一些例子,让Redis能够满足多个Lua客户端的需求。

如果还没有完成,我建议您先看看Redis基准页面

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

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

代码语言:javascript
复制
# 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程序应该使用流水线来最大化吞吐量和减少系统活动。

代码语言:javascript
复制
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个核心才能使用这种方法来饱和红宝石(一个6核盒应该很好)。

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

除了在缺乏CPU的虚拟机上运行之外,在这种情况下,瓶颈可能是网络。我不认为你可以用少于1 GbE链接的任何东西来填满红宝石。

一定要尽可能地对查询进行管道处理(请参阅前面的Lua程序),以避免网络延迟瓶颈,并降低CPU上的网络中断(填充以太网数据包)的成本。尝试在不绑定到网卡的核心上运行Redis (并处理网络中断)。您可以使用像htop这样的工具来检查最后一点。

如果可能的话,尝试在网络的其他机器上运行Lua客户端。再一次,你将需要大量的Lua客户来饱和Redis (6-10应该可以)。

在某些情况下,一个惟一的Lua过程就足够了:

现在,如果每个查询都足够昂贵,就可以使用单个Lua客户机填充Redis。下面是一个示例:

代码语言:javascript
复制
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的最坏情况)。因此,每次执行查询时,服务器都会扫描500 K项。因为只有10个项被返回,所以它们被lua快速解析,而lua不会消耗CPU。在这种情况下,所有的CPU消耗将在服务器端。

最后一词

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

你也许想试试。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16209605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档