Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

document transport read/write pause, buffer sizes, low/high water marks, etc. #17

Closed
vstinner opened this issue Mar 28, 2017 · 8 comments

Comments

@vstinner
Copy link
Contributor

Asyncio performance and concurrency depends on parameters which are badly documented in the reference documentation:

@vstinner
Copy link
Contributor Author

cc @1st1 @GMLudo @methane @asvetlov etc.

@vstinner
Copy link
Contributor Author

Maybe we can do deeper and mention kernel parameters, Linux tcp sysctls:

  • /proc/sys/net/ipv4/tcp_mem
  • /proc/sys/net/core/rmem_default and /proc/sys/net/core/rmem_max: The default and maximum amount for the receive socket memory
  • /proc/sys/net/core/wmem_default and /proc/sys/net/core/wmem_max: The default and maximum amount for the send socket memory
  • /proc/sys/net/core/optmem_max : The maximum amount of option memory buffers
  • net.ipv4.tcp_no_metrics_save
  • net.core.netdev_max_backlog: Set maximum number of packets, queued on the INPUT side, when the interface receives packets faster than kernel can process them.
  • etc.

@vstinner
Copy link
Contributor Author

Ah, another useful information for performance: since Python 3.6, asyncio now sets the TCP_NODELAY option on newly created sockets.

"TCP_NODELAY is intended to disable/enable segment buffering so data can be sent out to peer as quickly as possible, so this is typically used to improve network utilisation."

(Windows doc) "Disables the Nagle algorithm for send coalescing. This socket option is included for backward compatibility with Windows Sockets 1.1"

Ah, I also found "TCP_QUICKACK is used to send out acknowledgements as early as possible than delayed under some protocol level exchanging, and it's not stable/permanent, subsequent TCP transactions (which may happen under the hood) can disregard this option depending on actual protocol level processing or any actual disagreements between user setting and stack behaviour." on the Internet. I never saw this option before.

@vstinner
Copy link
Contributor Author

It seems like aiohttp uses set_writer_buffer_limits(0), see:

And https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/

  • "Unfortunately, this isn't enough. As the docs warn us, drain doesn't actually block until all data is written; it only guarantees that the unwritten data is less than the "high water mark"
  • "To really fix the problem, we need to get rid of this high-water mark thing. This can be done by calling transport.set_write_buffer_limits(0) on the underlying transport object; then drain will only return once the send buffer is completely empty."

@ludovic-gasc
Copy link
Collaborator

For me, it's a try-error approach to find the right parameters for the kernel.

@asvetlov
Copy link

It seems like aiohttp uses set_writer_buffer_limits(0)
Yes, we disabled it for backpressure support and implemented own buffering.

@asvetlov
Copy link

Perhaps the projects need a new page for information about performance tuning.
Albeit I didn't see such page in Twisted/Tornado docs :)

@vstinner
Copy link
Contributor Author

I added a new performance page: commit d91afb3.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants