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

2024-01-02

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

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

    $ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50

在此基准测试中,我们分配了 50 个客户端向我们的 Redis 服务器推送 1,000,000 个请求。

但是在使用其他一些客户端工具时(例如redis-lua https://github.com/nrk/redis-lua or webdis https://github.com/nicolasff/webdis),CPU最大占用率小于60%。

我浏览了一些代码webdis and redis-lua. webdis依赖于取决于hiredis, and redis-lua是用Lua实现的,依赖于socket(lua-socket).

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

我还浏览了一些代码redis-benchmark.c。基准测试的主要工作是在aeMain。似乎是redis-benchmark使用 Redis 的快速代码和我的测试客户端(webdis and redis-lua) 不要。

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

  1. Use redis-lua
  2. 使用类似的工具webdis

然而,这两者并没有最大化Redis的CPU利用率(低于60%)。还有其他选择吗?

或者,是否可以在外部充分利用 redis-serverredis-benchmark工具本身?


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

我建议您在 redis-benchmark 运行时测量延迟,看看它是否可以满足您的需求,然后再尝试增加 Redis CPU 消耗。 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 基准页面 http://redis.io/topics/benchmarks first.

如果您在与 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 匮乏的虚拟机上运行,​​否则瓶颈可能是在这种情况下的网络。我认为低于 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)
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 个项目,所以 lua-redis 解析速度很快,不会消耗 CPU。在这种情况下,所有的CPU消耗都将在服务器端。

最后的话

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

  • https://github.com/agladysh/lua-hiredis https://github.com/agladysh/lua-hiredis(基于hiredis)
  • https://github.com/agladysh/ljffi-hiredis https://github.com/agladysh/ljffi-hiredis(基于hiredis,使用luajit FFI)

您可能想尝试一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何提高Redis服务器的CPU使用率? 的相关文章

  • 在Windows上使用gcc 5.3.0编译Lua 5.2.4模块

    我需要用 gcc 5 3 0 编译 Lua 5 2 4 模块 在 Windows 上 在此之前 我按照以下步骤构建 Lua 5 2 4 gcc c DLUA BUILD AS DLL c ren lua o lua obj ren luac
  • 如何在Redis中正确存储图片?

    决定将图像存储在Redis中 如何正确执行 现在我这样做 redis gt set image path here is the base64 image code 我不确定这是否正常 将图片存储在Redis中是完全可以的 Redis 键和
  • Tarantool 中的冲突解决(如何在发生冲突时修复主-主模式下的复制)

    在多master场景下使用Tarantool如何实现冲突解决 我正在开发一项应该具有高可用性的服务 因此决定使用 nginx 作为 tarantool 两个节点 禁用只读选项 的负载均衡器 带有备份指令 它会重试对其他节点的失败请求 但如果
  • 集合成员的 TTL

    Redis 是否可以不为特定键而是为集合的成员设置 TTL 生存时间 我正在使用 Redis 文档提出的标签结构 数据是简单的键值对 标签是包含与每个标签对应的键的集合 例如 gt SETEX id id 1 100 Lorem ipsum
  • 批量将Dictionary中的数据设置到Redis中

    我正在使用 StackExchange Redis DB 插入键值对字典Batch如下 private static StackExchange Redis IDatabase database public void SetAll
  • 在redis中存储多个嵌套对象

    我想在redis中存储多个复杂的json数据 但不知道如何 这是我的 json 结构 users user01 username ally email email protected cdn cgi l email protection u
  • 如何通过ARM模板输出返回Redis的primaryKey?

    我正在尝试借助下面列出的 ARM 模板来部署 Redis 然后返回其主密钥 Azure 门户中 Redis 的 访问密钥 gt 主 下可用的秘密字符串 但是 我从管道 AzureResourceManagerTemplateDeployme
  • 模式 ^u.meta(\.|$) 未按预期工作

    我有这个模式 u meta 预期行为 u meta 将匹配所有角色 例如 u meta u meta admin u meta admin system u meta 它不应该匹配如下所示的内容 u meta admin u meta ad
  • Netlogo 之间的时间差异

    谁能解释为什么以下两个部分之间存在性能差异 从统计上看 第二个计时器调用报告的数字比第一个计时器调用报告的数字要小 我唯一的想法是 Netlogo 可能会将海龟缓存在内存中 这是预期的行为还是存在错误 to setup clear all
  • 将值存储在 lua 的 userdata 对象中

    我想做的是这样的 object foo bar print object foo 其中 对象 是用户数据 我已经用谷歌搜索了一段时间 使用关键字 newindex 和 lua rawset 但我找不到任何可以实现我想要的功能的示例 我想用
  • JedisPoolConfig 不可分配给 GenericObjectPoolConfig

    我有一个基于 Spring 的 Java Web 应用程序托管在 Heroku 上 我正在尝试使用 Redis 实现来利用 Spring 缓存抽象 当服务器启动时 我收到一条错误消息 Type redis clients jedis Jed
  • SQLite 性能基准 - 为什么 :memory: 这么慢...只有磁盘速度的 1.5 倍?

    为什么 sqlite 中的 memory 这么慢 我一直在尝试查看使用内存中的 sqlite 与基于磁盘的 sqlite 是否可以获得任何性能改进 基本上我想用启动时间和内存来换取非常快速的查询not在应用程序过程中击中磁盘 然而 以下基准
  • 基准测试 - CPU 时间大于实际时间?

    我测量了 Linux 上排序算法的 cpu 时间和 wall time 我在用着getrusage测量 cpu 时间和clock gettime CLOCK MONOTONIC以获得墙上的时间 虽然我注意到 cpu 时间比 wall tim
  • 为什么 C++ 的初始分配比 C 的大得多?

    当使用相同的代码时 只需更改编译器 从 C 编译器到 C 编译器 就会改变分配的内存量 我不太确定这是为什么 并且想更多地了解它 到目前为止 我得到的最好的回答是 可能是 I O 流 这不是很具有描述性 让我对 C 的 你不用为你不使用的东
  • Redis 客户端忽略其上设置的配置选项并尝试连接到默认 IP 127.0.01

    在AWS中 我使用ElastiCache Redis服务器并使用节点作为后端和 promise redis 包 这就是我尝试连接到我的 redis 服务器端点的方法 client redis createClient host my red
  • 如果没有过期的内容,Redis maxmemory-policy volatile-lru 是否会被驱逐?

    我有一个 redis 服务器 设置了maxmemory policy set to volatile lru 文档表明 当达到内存限制时 这将从设置过期的条目集中逐出 在这种情况下 redis 是否只驱逐过期的项目 如果内存中的所有内容都设
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • Flask-SocketIO redis 订阅

    我在用着https github com miguelgrinberg Flask SocketIO https github com miguelgrinberg Flask SocketIO实现 WebSocket 服务器 我需要从另一
  • 如何在Redis中存储聚合目录树搜索结果

    我有一个很大的产品目录树 目前包含约 36000 个类别和约 100 万个产品 即叶子 它的结构如下 最大深度为 5 Cat1 Cat11 Cat111 Cat1111 Product1 Cat1112 Product1 Cat1113 P
  • Redis 会话序列化器 3.2 和 4.2 之间不匹配

    我有一个基于 Spring Cloud 的应用程序在多个 spring boot 服务器上运行 所有服务器使用 EnableRedisHttpSession共享相同的Spring Session 我现在想将第三方小部件集成到我的应用程序中

随机推荐

  • 循环遍历数据表

    出色地 我有一个包含多列和多行的数据表 我想动态循环数据表 基本上输出应该如下所示 不包括大括号 Name DataColumn Tom DataRow Peter DataRow Surname DataColumn Smith Data
  • Spark迭代HDFS目录

    我在 HDFS 上有一个目录 我想迭代这些目录 有没有简单的方法可以使用 SparkContext 对象对 Spark 执行此操作 您可以使用org apache hadoop fs FileSystem https hadoop apac
  • Stack(int = 10),这个语法是什么意思(C++)?

    template
  • C++/CLI 前向声明

    我有一个标题 如下所示 namespace Dummy ref class ISYSession namespace Afw
  • TFS 向[请求者]用户生成电子邮件警报

    这可能吗 我和我的一位同事正在寻找这种解决方案一段时间 但我们在 Google 上找不到类似的解决方案 事情很简单 当 Requested By 用户破坏了 TFS 2010 上的构建时 我们希望通过电子邮件自动提醒他或她 我们如何才能做到
  • 如何将通知号码添加到按钮图标?

    我正在尝试使用 PyQt5 制作 GUI 它将有一个带有图标的通知按钮 我想在图标上添加一个带有通知数量的小气泡 如果无法提供数字 我想使用红点作为备用方法 但是我应该如何跟踪新通知 如通知侦听器 并在窗口运行时更改图标 我一直在谷歌上搜索
  • c# itextsharp PDF 创建,每页带有水印

    我正在尝试使用 itextsharp Java itext 的 C 端口 以编程方式创建多个 PDF 文档 每个页面上都带有水印 我可以在使用 PdfStamper 创建文档后执行此操作 然而 这似乎涉及重新打开文档阅读它 然后创建一个每个
  • 为什么存在 REP LODS AL 指令?

    换句话说 在任何情况下我可能需要这个指示吗 根据英特尔指令手册 该指令的作用如下 将 E CX 字节从 DS E SI 加载到 AL 以 NASM 为例 section data src db 0 1 2 3 section code mo
  • 如何将自定义 Jupyter 内核放置在虚拟环境中?

    我有一个自定义 Jupyter 内核 它使用使用 matplotlib 样式表的自定义 IPython 配置文件运行 IPython 我知道要正常运行它 我会输入 config matplotlib stylelib 中的 matplotl
  • 在 C# 中计算重复日期的正确方法

    在我的项目中 我需要计算重复事件的日期 一开始我只有一个开始日期 时间以及该事件必须如何重复的信息 Every Day Every Week Every 2 Weeks Every 3 Weeks Every Month Every 2 M
  • 如何使用 Nokogiri::XML::Builder 创建元素名称中带有连字符的 XML?

    我正在尝试使用 Nokogiri 构建 XML 文档 有些元素中有连字符 这是一个例子 require nokogiri builder Nokogiri XML Builder new do xml xml foo bar hello e
  • 使用 maven-surefire 运行测试时,Spring-Autowiring 在 @BeforeClass 之后发生

    我在依赖注入 Spring 自动装配 和 maven surefire 方面遇到一些问题 当使用 TestNG 在 eclipse 中运行时 以下测试可以正常工作 服务对象被注入 然后 BeforeClass 方法被调用 Transacti
  • 带圆角半径的自动布局(带砌体)

    我想用 Masonry 布局一个圆形 UIImageView 所以我创建了这样的 UIImageView self imageView mas makeConstraints MASConstraintMaker make make cen
  • 如何保持 ExpandableListView 打开?

    我正在研究 ExpandableListView 我已经完成了工作 现在我只想做的一件事是我不希望 ListView 在单击可扩展列表视图时变为 DropDown 而是希望显示它与所有项目一起打开无需对其进行任何单击即可显示在内部 谁能告诉
  • 正确使用 `for_each_arg` - 转发过多?

    我真的很高兴发现for each arg https twitter com ericniebler status 559119062895431680 这使得处理参数包变得更加容易 template
  • 将 AsyncLayoutInflater 与 DataBinding 结合使用

    我目前使用以下方法来膨胀我的大部分布局DataBindingUtil inflate inflater layoutId parent attachToParent https developer android com reference
  • 通过 OSX ssh rsync 保留别名

    我在 OSX Yosemite 上通过 ssh 进行 rsync 保存别名时遇到了麻烦 rsync av e ssh email protected cdn cgi l email protection Users me stuff Use
  • 使用带有投影的 find() 方法使用 mongodb java driver 3.4 检索数据

    我正在使用 mongodb java 驱动程序 3 4 mongodb数据库中文档按照以下结构保存 id ObjectId 595a9fc4fe3f36402b7edf0e id 123 priceInfo object1 value1 o
  • 从 CSV 数据中删除尾随逗号

    这是在另一个数字后添加逗号的代码 但我想删除最后一个逗号 str MSISDN Append MSISDN x TrimStart 我建议您使用而不是手动附加内容String Join这将使事情一开始就正确 您可以使用 LINQ 来修剪值
  • 如何提高Redis服务器的CPU使用率?

    我的目标是让我们的 Redis 服务器在生产中达到 80 左右的 CPU 利用率 这将有利于我们的后端服务器设计 确保我们不会充分利用 CPU 同时也为增长和峰值留出一些空间 在使用Redis自己的基准测试工具时redis benchmar