【问题标题】:Why is the block size for Python httplib's reads hard coded as 8192 bytes为什么 Python httplib 读取的块大小硬编码为 8192 字节
【发布时间】:2018-02-10 10:46:29
【问题描述】:

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

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

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

这是为什么? 8192比其他尺寸有什么好处?

【问题讨论】:

  • 最初提交于github.com/python/cpython/commit/…。通过git blame找到。
  • @AshishNitinPatil 啊,谢谢。现在我怀疑 8192 来自补丁 #1065257:bugs.python.org/issue1065257bugs.python.org/file6362/httplib2.patch。但是,我不认为 cmets 解决了 8192?
  • 8k 是块设备的常见块大小,因此读取此块大小或多个块大小的数据块会更有效。这也是一个常见的 http 标头大小限制(例如在 apache 中),因此您可以在单个块中传输标头。你有什么理由不应该是 8k 吗?
  • @wim 我使用 64k 进行了测试,使用迭代器作为源流,在这种情况下传输 5gb 更快。
  • 似乎可以在 3.7 中进行配置,原因与您的用例类似。查看 3 个月前合并的 PR4279

标签: python http httplib


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    Nginx 网络服务器

    这是来自 nginx

    Syntax: client_body_buffer_size size;
    
    Default:    client_body_buffer_size 8k|16k;
    

    设置读取客户端请求正文的缓冲区大小。如果请求正文大于缓冲区,则将整个正文或仅其部分写入临时文件。默认情况下,缓冲区大小等于两个内存页。这是 x86、其他 32 位平台和 x86-64 上的 8K。在其他 64 位平台上通常是 16K

    Apache 网络服务器

    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字节的socket缓冲区。

    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,但如果您无法升级到相同的版本,这可能对您的事业没有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 2018-08-24
      • 1970-01-01
      • 2015-03-17
      • 2016-09-21
      • 1970-01-01
      相关资源
      最近更新 更多