【问题标题】:Redis Performance tuningRedis 性能调优
【发布时间】:2013-05-26 08:11:40
【问题描述】:

我们正在运行一个 Web 应用程序并从 memcached 切换到 redis (2.4) 进行缓存。现在我们对redis的性能有些失望。 Redis 在同一台服务器上运行,我们只使用非常简单的 GET 和 SET 操作。在一些大量使用缓存值的请求上,我们有多达 300 个对 redis 的 GET 请求,但这些请求最多需要 150 毫秒。我们有大约 200,000 个活动密钥,每秒大约有 1,000 个 redis 请求。磁盘 io、ram 或 cpu 没有问题。由于我们现有的代码,我们不能简单地将 redis 请求组合在一起。 Memcached 的速度提高了大约 4 倍。 我们喜欢 redis 的地方在于,我们不需要任何缓存预热,并且将来可以使用更高级的数据存储功能。我们希望 redis 的性能类似于 memcached。所以也许我们在配置中遗漏了一些东西,这基本上是默认配置。

你知道 Redis 性能调优的最佳实践吗?

【问题讨论】:

  • Redis 和什么运行在同一台服务器上?客户端,还是运行 memcached 的客户端? Redis 请求的 150 毫秒听起来像是在访问交换/磁盘,而不是内存,或者您的意思是所有 300 个请求都需要 150 毫秒?
  • 这是一个每秒大约 100 个 apache 请求的 Web 应用程序。 Redis 与 Web 应用程序本身和 mysql 数据库服务器在同一主机上运行,​​但我们计划很快将 apache 移动到 3 个负载均衡服务器。当前服务器有大约 64GB 的 RAM,redis 大约需要 100MB。有足够的可用内存,cpu 或 io 没有问题。服务器不会交换到磁盘。是的,我的意思是 300 个请求需要 150 毫秒,但在相同条件下,memcached 只需要 40 毫秒。
  • 我能想到的唯一一件事是,如果您对所有请求使用到 Redis 的共享连接,而不是每个 Web 请求一个,您可能会遇到 Redis 延迟问题,但每秒 1000 个请求时,您不应该看到那么糟糕的延迟。抱歉,我今天的指导对我没有任何帮助:)

标签: performance caching web-applications redis


【解决方案1】:

首先,您可能想阅读the Redis benchmark page。它很好地总结了调整 Redis 的要点。

即使您不使用流水线,150 毫秒内 300 次 GET 也不是那么有效。这意味着平均延迟为 500 us。但是,它实际上取决于对象的大小。更大的对象,更多的延迟。在我非常旧的 2 GHz AMD 机器上,我可以测量小对象(几个字节)的 150 us 延迟。

要快速检查 Redis 实例的平均延迟,您可以使用:

$ redis-cli --latency

确保使用最新的 Redis 版本(不是 2.4)来获取此选项。 注意:现在 2.4 已经很老了,使用 Redis 2.6 - 如果需要的话,编译你自己的 Redis 版本,真的很简单。

要快速运行基准测试来研究延迟,您可以启动:

$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes

它通过唯一的连接运行,没有流水线,因此可以从吞吐量中推断出延迟。尝试将这些基准测试的结果与您的应用程序测量的数据进行比较。

您可能需要检查以下几点:

  • 您使用哪个 Redis 客户端库?使用哪种开发语言?对于某些脚本语言,您需要安装hiredis 模块以获得高效的客户端。
  • 你的机器是虚拟机吗?在哪个操作系统上?
  • 与 Redis 的连接是否持久? (即,您不应该在应用服务器的每个 HTTP 请求上连接/断开连接)。

为什么使用 memcached 更好?好吧,单个 memcached 实例肯定更具可扩展性,并且可能比单个 Redis 实例响应更快,因为它可以在多个线程上运行。 Redis 速度很快,但是是单线程的——所有命令的执行都是序列化的。因此,当一个命令正在进行连接时,所有其他客户端都必须等待 - 给定命令的不良延迟也会影响所有待处理的命令。一般来说,在低吞吐量下,性能是相当的。

以 1000 q/s(Redis 或 memcached 标准的低吞吐量),我会说您的问题更有可能出在客户端(即客户端库的选择、连接/断开连接等......) ,而不是使用 Redis 服务器本身。

最后我要提一下,如果每个 HTTP 请求生成多个 Redis 查询,请尽可能考虑 pipelining 发送给 Redis 的命令。开发高效的 Redis 应用程序确实是一个关键点。

如果您的应用程序服务器与 Redis 在同一个机器上,您还可以使用 unix 域套接字而不是 TCP 环回连接到 Redis。它略微提高了性能(在不使用流水线的情况下,吞吐量提高了 50%)。

【讨论】:

  • “所有命令的执行都被序列化了”:你能提供更多关于这个语句的细节吗?对我来说,听起来您是在说命令正在运行时没有其他命令,即使在其他连接上也可以运行。 redis是这样实现命令原子性的吗?
【解决方案2】:

检查 redis 是否正在使用操作系统交换内存。如果是这样,那将增加延迟。 要找出答案,请在此处搜索“由交换引起的延迟”:http://redis.io/topics/latency

如果您的服务器硬件支持 NUMA,最好使用 numactl 启动 redis-server。 如果您从带有 NUMA 的 redis-server 开始,请不要忘记在 sysctl 中关闭区域回收模式 (vm.zone_reclaim_mode=0)。

【讨论】:

    【解决方案3】:

    尝试在 Lua 脚本中编写 300 GET 请求。它应该运行得更快,因为即使您的客户端代码在本地运行到 Redis,您也可以节省接触 TCP/IP 堆栈的时间。

    【讨论】:

      猜你喜欢
      • 2020-07-04
      • 2012-06-10
      • 1970-01-01
      • 2015-06-07
      • 2021-07-22
      • 2013-10-17
      • 2018-03-06
      • 2016-06-25
      • 2018-04-20
      相关资源
      最近更新 更多