为什么Python httplib的读取块大小硬编码为8192字节?

14

3
最初提交于 https://github.com/python/cpython/commit/89f507fe8c497b3f70fdcecce8bc240f9af2bbe2 。通过 git blame 找到。 - shad0w_wa1k3r
@AshishNitinPatil 谢谢。现在我怀疑8192来自补丁#1065257:https://bugs.python.org/issue1065257和https://bugs.python.org/file6362/httplib2.patch。但是,我不认为注释涉及8192? - Michal Charemza
8k是块设备的常见块大小,因此以这个块大小或其倍数读取数据块可以更有效率。这也是常见的HTTP头大小限制(例如在Apache中),因此您可以在单个块中传输标头。您有任何理由认为它不应该是8k吗? - wim
1
@wim 我进行了一个测试,使用64k,使用迭代器作为源流,这种情况下5GB的传输速度更快。 - Michal Charemza
4
看起来类似于你的使用案例,它将在3.7中可以配置。请查看3个月前合并的PR4279 - wim
Apache的最大缓冲区大小为8K。为什么是8K?这是出于性能(流量控制)和我相信还有一些安全原因,以防止DoS类型攻击。 - Emmet B
2个回答

13

根据我所了解的,块大小应该与资源页面大小相同,但由于pagesize仅在UNIX上可用,因此将其硬编码为8192,以便所有其他系统特别是Windows不会受到阻塞。否则没有其他理由硬编码它。

来源:https://bugs.python.org/issue21790


4

Nginx webserver

这是来自nginx的内容

Syntax: client_body_buffer_size size;

Default:    client_body_buffer_size 8k|16k;

设置用于读取客户端请求体的缓冲区大小。如果请求体大于缓冲区,则整个请求体或其部分将被写入临时文件。默认情况下,缓冲区大小等于两个内存页。在x86、其他32位平台和x86-64上为8K,在其他64位平台上通常为16K。 Apache WebServer
ProxyIOBufferSize Directive
Description:    Determine size of internal data throughput buffer
Syntax: ProxyIOBufferSize bytes
Default:    ProxyIOBufferSize 8192
Context:    server config, virtual host
Status: Extension
Module: mod_proxy

因此,Apache默认使用8192作为代理缓冲区大小。

Apache客户端

Apache Java客户端文档指出

https://hc.apache.org/httpcomponents-client-4.2.x/tutorial/html/connmgmt.html

  • CoreConnectionPNames.SOCKET_BUFFER_SIZE='http.socket.buffer-size': 决定了在接收/传输HTTP消息时用于缓冲数据的内部套接字缓冲区的大小。此参数期望一个类型为java.lang.Integer的值。如果没有设置此参数,HttpClient将分配8192字节的套接字缓冲区。

Ruby客户端

在Ruby中,默认情况下值为16K

https://github.com/ruby/ruby/blob/814daf855e0aa2c3a1164dc765378d3a092a1825/lib/net/protocol.rb#L172

下面是一些线程:

什么是适合套接字编程的良好缓冲区大小?

从互联网下载文件时分配的最佳内存缓冲区大小是什么?

最佳文件缓冲区读取大小?

如果您查看这些内容,共识在于8K / 16K作为缓冲区大小。并不是说必须固定为那个大小,而是可以配置,对于大多数情况,8k / 16K应该足够好。因此,我认为Python默认使用8K也没有问题。但是,是的,它应该是可配置的。

Python 3.7将具有 可配置性,但如果您无法升级到相同版本,则可能无法帮助您的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接