首页 > 解决方案 > tarantool-c 中的 read_reply 太慢了

问题描述

我正在设置一个c服务器并使用 tarantool 作为数据库使用 tarantool-c。但是,每次我设置read_reply()每秒请求时,它就像使用 mysql 一样。如何解决?

标签: tarantool

解决方案


我们与 James 进行了讨论,他分享了代码。该代码实现了 http 服务器,这就是它处理请求的方式:

  • 接受新的传入 http 请求。
  • 向 tarantool 发送请求(使用二进制协议)。
  • 等待 tarantool 的回复(同步,无法处理其他传入的 http 请求)。
  • 响应 http 请求。

问题的根源在于我们无法在 http 服务器和 tarantool 之间使用完整的网络带宽。这样的服务器应该使用 select() / poll() / epoll() (在 Linux 上) / kqueue (在 FreeBSD 上)或 libev 之类的库来确定它是否能够写入套接字,从中读取或接受请求。

让我简要描述一下它应该如何操作,以在 when-X-then-Y 类型的规则集中尽可能多地利用网络(当从一个线程执行时):

  • 当一个新的 http 请求到达时,它应该注册需要向 tarantool 发送请求(让我将其命名为待处理请求)。
  • 当 tarantool 的套接字准备好写入并且至少有一个未决请求时,服务器应该向 tarantool 发送请求,保存其 ID(请参阅tnt_stream.reqid)并将请求写入套接字。
  • 当 tarantool 的套接字准备好读取时,服务器应该从 tarantool 读取回复,将其 ID(参见tnt_reply.sync)与保存的 ID 匹配,并将响应写入 http 客户端,然后关闭客户端的套接字。

如果需要支持 http keepalive / pipelining,则服务器需要检查到 http 客户端的套接字以准备执行 read() / write()。它还需要注册待处理的 http 响应,而不是在它们出现时才写入。

除此之外,HTTP 本身并不容易以正确的方式实现:如果您不控制客户端和服务器的实现,它总是会给您带来惊喜。

因此,我将描述实现自己的 http 服务器的替代方案,这些替代方案与 tarantool 兼容,并且能够以异步方式与它一起操作以实现良好的性能。他们是:

  • 使用http.server tarantool 模块,该模块允许直接在 tarantool 中处理 http 请求,无需外部服务,也无需使用 tarantool 的连接器。
  • 使用nginx_upstream_tarantool nginx 模块,该模块允许使用二进制协议从 nginx 执行对 tarantool 的请求。

这两种方式各有利弊。然而,http.server 的缺点可以通过使用 nginx 作为前端来将请求代理到 tarantool(s) 来克服,从而节省 http.server 的优势。

http.server 缺点:

  • 不支持 https。
  • 单个 CPU 绑定/单个 tarantool 实例绑定。
  • 性能可能比 nginx 差(但不多)。
  • 可能对 HTTP 警告的支持更差(但我不知道)。

http.server 优点:

  • 更容易开始开发。
  • 配置/部署更简单:应用程序配置的一部分不会分布在 tarantool 和 nginx 的配置中。

nginx_upstream_tarantool 的缺点和优点与 http.server 的相反。我还要特别提到,nginx 允许您在多个 tarantool 实例之间平衡负载,这些实例可能形成一个复制组,也可能是分片前端。此功能可用于在所需性能的意义上扩展服务,例如代理到 http.server 以及 nginx_upstream_tarantool。

我猜你也对 http.server 和 nginx_upstream_tarantool 的基准测试结果感兴趣。看看这个测量。但是请注意,它是非常综合的:它执行小请求并以小响应进行回答。实际 RPS 数字可能会因请求和响应的大小、硬件、是否需要 https 等而有所不同。


推荐阅读