当前位置: 首页 > 面试题库 >

为什么将异步客户端用于Redis有意义?

郁吉星
2023-03-14
问题内容

在此页面中列出了redis客户,我计算了8个异步库。我的理解是,仅当异步回调函数不为I /
O相互争用时,诸如node.js或Tornado之类的框架才有意义,否则您最好也进行同步。

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


问题答案:

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

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

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

有多种方法可以减少网络延迟的影响:

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

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

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

这些解决方案均受Redis生态系统的支持,可以结合使用以最大化性能。异步客户端通常允许这种组合。异步客户端的用例是什么?这里有一些例子:

  • 实现异步流水线,以最小化单个连接上的等待状态。

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

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

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

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



 类似资料:
  • 异步Redis客户端 连接池(连接池默认开启) use AsyncRedis; //关闭连接池 AsyncRedis::enablePool(false); //开启连接池 AsyncRedis::enablePool(true); 使用AsyncRedis use AsyncRedis; //设置超时时间 AsyncRedis::s

  • 异步Mysql客户端 AsyncMysql::query($sql, $usePool = true) 第二个参数设为false将不会使用连接池中的资源,默认都会从连接池中取,配置连接池数量 => config/database.php 具体使用 use AsyncMysql; //设置超时时间 AsyncMysql::setTimeout(2); $res = (

  • 异步Http客户端 Get方式 1.使用域名形式 use AsyncHttp; //直接使用域名, get方式 $http = new AsyncHttp('http://groupco.com'); //设置2s超时 $http->setTimeout(2); //$http->setCookies(['token' => 'xxxx']);

  • 异步Tcp客户端 串行发包 use AsyncTcp; $tcp = new AsyncTcp('127.0.0.1', 9501); $tcp->setTimeout(2); //串行发送 $res = (yield $tcp->call('hello server!')); $res = (yield $tcp->call('hello serv

  • 我正在使用Android异步Http客户端。我的代码看起来像这样,并且运行良好。 我实现了一个静态HTTP客户端。我的服务器返回这个JSON数据。我不想将其视为字符串并将其转换回JSON。但是当我将其更改为eclipse告诉我 new AsyncHttpResponseHandler(){}类型的onSuccess(JSONObject)方法必须重写或实现超类型方法

  • 为方便测试,我们以RPC中的例子来实现服务端,具体请看文档RPC章节。 纯原生异步 public static function mainServerCreate(ServerManager $server,EventRegister $register): void { // TODO: Implement mainServerCreate() method.