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

Why is the block size for Python httplib's reads hard coded as 8192 bytes

我希望进行快速流式下载 -> 上传以通过 HTTP 将大文件从一台服务器移动到另一台服务器。

在此期间,我注意到 urllib3 使用的 httplib(因此也请求)似乎将它一次从流中获取的数据量硬编码为 8192 字节

https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/Lib/http/client.py#L970

这是为什么? 8192 与其他尺寸相比有何优势?

根据我的发现,块大小应该是资源的页面大小,但由于页面大小仅在 UNIX 上可用,因此它被硬编码为 8192,因此所有其他系统特别是 Windows 不会被阻止。否则没有其他理由对其进行硬编码。

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

Nginx 网络服务器

这是来自 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

然后还有下面的跟贴

What is a good buffer size for socket programming?

What is the best memory buffer size to allocate to download a file from Internet?

Optimum file buffer read size?

如果您查看其中的许多内容,则一致认为缓冲区大小为 8K/16K。并不是说它应该固定到那个位置,而是可配置的,8k/16K 应该足以应对大多数情况。所以我没有看到 Python 默认情况下也使用 8K 的问题。但是是的,它应该是可配置的

Python 3.7 将拥有它 configurable 但如果你不能升级到相同的,那可能对你的事业没有帮助。