node.js - 为什么对 Redis 使用异步客户端有意义?

标签 node.js asynchronous redis tornado reactor

在此page listing the redis clients ,我数了8个异步库。我的理解是,像 node.js 或 tornado 这样的框架只有在异步回调函数不互相争夺 I/O 时才有意义,否则你还不如去同步。

但是Redis是单线程的。所以他们实际上是在争夺I/O。 Redis 的单线程特性不会取消异步回调的所有潜在好处吗?为什么在 Redis 中使用异步客户端很有意义?

最佳答案

Redis 的单线程特性与异步客户端的潜在优势无关。尽管具有独特的事件循环,Redis 能够并发管理大量客户端连接。我在单个 Redis 实例上看到了多达 30000 个连接的基准测试。

只需考虑使用 Redis 或 memcached 等内存中键/值存储,性能和延迟主要由网络往返而不是服务器端 CPU 消耗决定。诚然,当网络链路饱和时网络往返的延迟会增加,但这并不意味着当网络远未饱和时它就可以忽略不计。例如,在负载非常轻的 1 GbE 网络上,RTT 延迟接近 200 微秒的情况并不少见。

结果是,除非网络链接接近饱和,否则客户端连接(或异步回调函数)很少相互竞争 I/O。套接字与缓冲区相关联,缓冲区可以分摊网络上读写操作的成本。大多数时候,等待状态不是由于 I/O 竞争,而是由于网络延迟。

有多种方法可以降低网络延迟的影响:

  • 流水线:将多个命令组合在一起,以便为每组命令支付一次网络往返费用(实际上,这是同步流水线)。

  • 非阻塞 I/O:虽然它不会减少往返次数(或它们的单独成本),但异步客户端可以同时管理它们。结果是网络延迟对应用程序吞吐量的影响较小(或没有)。

  • 多个客户端连接:每个客户端连接都有自己的套接字,因此也有自己的缓冲区。更多的缓冲区通常意味着更好的吞吐量。更多连接增加了并发和/或异步处理事物的机会,对整体性能产生积极影响。

这些解决方案都得到 Redis 生态系统的支持,并且可以结合使用以最大限度地提高性能。异步客户端通常允许这种组合。异步客户端的用例是什么?下面是几个例子:

  • 实现异步流水线,以最大限度地减少单个连接上的等待状态。

  • 将 Redis 连接与现有事件循环(例如 libevent、Node.js、Tornado、Twisted 等)集成,而不依赖额外的线程池。

  • 支持多个 Redis 实例的数据分片。在这种情况下,客户端应用程序可能希望并行化对各种实例的访问。使用异步客户端,可以从一个单独的线程方便地完成。

  • 支持基于客户端应用程序与各种主/从实例的预连接的 HA 弹性模型。

事件循环、异步库和/或类似协程的机制是大多数高效 NoSQL 引擎的基石之一。

关于node.js - 为什么对 Redis 使用异步客户端有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27342508/

相关文章:

python - redis publish 是如何工作的?

node.js - 如何使用 child_process.exec(command[, options][, callback]) 在 Node.js 应用程序中编译带有一些用户输入的 C 程序

node.js - 如何使用node.js让Slack机器人在同一 channel 动态回复

c# - C#异步套接字(* Async,SocketAsyncEventArgs)

node.js - 我没有获得 Node.js 的库异步,我错在哪里?

redis - 如何将一个redis实例迁移到n个实例?

node.js - NodeJS 事件循环执行顺序

node.js - 删除 azure blob block 列表express/nodejs

javascript - 了解 JavaScript 中的递归异步调用

lua - 检查redis中的多个键