0

我正在通过 UDP(在 Linux 下)为缓存应用程序(类似于 memcached)开发自己的协议,该应用程序仅对对象执行 INSERT/READ/UPDATE/DELETE 操作,我不确定哪种设计是最好的:

  1. 每个数据包发送一个请求。(客户端准备好请求并立即发送到服务器)
  2. 每个数据包发送多个请求。(客户端将请求排入数据包中,当它已满时(接近 MTU 大小)将其发送到服务器)

请求(即记录数据)的大小可以从32字节到1400字节,我不知道平均会是哪个,这完全取决于用户的应用程序。

  1. 如果选择每个数据包单个请求,我将不得不管理很多小数据包,并且内核将被中断很多次。这将减慢操作,因为内核在从用户空间切换到系统时必须保存寄存器。数据传输也会有开销,如果用户的应用程序发送很多32字节的请求(udp的数据包开销约为28字节),网络流量会翻倍,对传输速度的影响很大。然而,高网络流量并不一定意味着低性能,因为 NIC 有自己的处理器并且不会使 CPU 停顿。如果出现网络瓶颈,可以安装额外的网卡。使用单个数据包的最大优势是服务器和客户端将非常简单,我将节省指令并提高速度,

  2. 如果我对每个数据包使用多个请求,我将拥有更少但更大的数据包,因此可以通过网络传输更多数据。我将减少系统调用的数量,但服务器的复杂性将需要更多的内存和更多的指令来执行,因此我们不知道我们是否可以通过这种方式更快地执行。CPU可能会成为瓶颈,但加CPU或网卡哪个更便宜?

应用程序应该有大量的数据负载,例如在最新的 CPU 上每秒 100,000 个请求。我不知道该怎么做。我正在考虑“每个数据包单个请求”,但在我重写我已经为多个请求处理编写的所有代码之前,我想征求建议。

提前致谢。

4

2 回答 2

1

你更关心什么:延迟还是带宽

  • If latency, send the request as soon as possible even if that means a lot of "slack" at the ends of packets and more packets overall.
  • If bandwidth, bundle multiple requests to eliminate the "slack" and send fewer packets overall.

NOTE: The network, not the CPU, will likely be your major bottleneck in either case, unless you are running over an extremely fast network. And even if you do, the INSERT/READ/UPDATE/DELETE in the database will likely spend more CPU and I/O than the CPU work needed for packets.

于 2012-07-15T09:39:26.830 回答
0

每个数据包发送多个请求的另一个权衡是

  • 一方面,UDP 的不可靠特性可能会导致您一次丢弃多个请求,从而使重新传输的成本更高。
  • 另一方面,内核将使用更少的缓冲区来传递数据,从而减少数据丢失的机会

但是,如果不了解部署架构(例如 NIC、交换机和路由器以及其他网络硬件的缓冲区大小),则分析是不完整的。

但建议从一个相对简单的实现开始(每个数据包一个请求),但是以这样的方式编写代码,以便在需要时增加更多复杂性不会太困难。

于 2012-07-14T20:37:35.760 回答