qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Edmondson <david.edmondson@oracle.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <fam@euphon.net>,
	qemu-block@nongnu.org, Markus Armbruster <armbru@redhat.com>,
	Max Reitz <mreitz@redhat.com>,
	David Edmondson <david.edmondson@oracle.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [RFC PATCH 0/9] block/curl: Add caching of data downloaded from the remote server
Date: Tue, 18 Aug 2020 12:08:36 +0100	[thread overview]
Message-ID: <20200818110845.3825105-1-david.edmondson@oracle.com> (raw)

When using qemu-img to convert an image that is hosted on an HTTP
server to some faster local (or pseudo-local) storage, the overall
performance can be improved by reading data from the HTTP server in
larger blocks and by caching and re-using blocks already read. This
set of patches implements both of these, and adds a further patch
allowing an offset to be added to all of the HTTP requests.

The first patch (block/curl: Add an 'offset' parameter, affecting all
range requests) allows the user to add an arbitrary offset to all
range requests sent to the HTTP server. This is useful if the image to
be read from the HTTP server is embedded in another file (for example
an uncompressed tar file). It avoids the need to first download the
file containing the source image and extract it (both of which will
require writing the image to local storage). It is logically distinct
from the rest of the patches and somewhat use-case specific.

The remaining patches implement block based retrieval of data from the
HTTP server and, optionally, caching of those blocks in memory.

The existing HTTP implementation simply reads whatever data is
requested by the caller, with the option for a user-specified amount
of readahead. This is poor for performance because most IO requests
(from QCOW2, for example) are for relatively small amounts of data,
typically no more than 64kB. This does not allow the underlying TCP
connections to achieve peak throughput.

The existing readhead mechanism is also intended to work in
conjunction with the HTTP driver's attempt to piggy-back a new IO
request on one that is already in flight. This works, but is often
defeated because it relies on the existing IO request *completely*
satisfying any subsequent request that might piggy-back onto it. This
is rarely the case and, particularly when used with "readahead", can
result in the same data being downloaded repeatedly.

The observed performance will depend greatly on the environment, but
when using qemu-img to retrieve a 1GiB QCOW2 image from an HTTPS
server, the following was observed:

| approach                                   | time (hh:mm:ss) |
|--------------------------------------------+-----------------|
| QCOW2 over HTTPS (existing implementation) |        00:00:59 |
| 256kB blocks, 8 cached blocks              |        00:00:42 |
| 2MB blocks, 100 cached blocks              |        00:00:34 |

By way of comparison, aria2c (a dedicated HTTP download client) can
retrieve the same image in 19 seconds. Obviously this is without any
QCOW2 layer.

David Edmondson (9):
  block/curl: Add an 'offset' parameter, affecting all range requests
  block/curl: Remove readahead support
  block/curl: Tracing
  block/curl: Perform IO in fixed size chunks
  block/curl: Allow the blocksize to be specified by the user
  block/curl: Cache downloaded blocks
  block/curl: Allow the user to control the number of cache blocks
  block/curl: Allow 16 sockets/ACB
  block/curl: Add readahead support

 block/curl.c                          | 515 ++++++++++++++++++++++----
 block/io.c                            |   4 +
 block/linux-aio.c                     |   6 +
 block/trace-events                    |  18 +-
 docs/system/device-url-syntax.rst.inc |  15 +
 qapi/block-core.json                  |  11 +-
 6 files changed, 488 insertions(+), 81 deletions(-)

-- 
2.27.0



             reply	other threads:[~2020-08-18 11:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-18 11:08 David Edmondson [this message]
2020-08-18 11:08 ` [RFC PATCH 1/9] block/curl: Add an 'offset' parameter, affecting all range requests David Edmondson
2020-08-18 11:08 ` [RFC PATCH 2/9] block/curl: Remove readahead support David Edmondson
2020-08-18 11:08 ` [RFC PATCH 3/9] block/curl: Tracing David Edmondson
2020-08-18 11:08 ` [RFC PATCH 4/9] block/curl: Perform IO in fixed size chunks David Edmondson
2020-08-18 11:08 ` [RFC PATCH 5/9] block/curl: Allow the blocksize to be specified by the user David Edmondson
2020-08-24 13:19   ` Markus Armbruster
2020-08-24 14:21     ` David Edmondson
2020-08-18 11:08 ` [RFC PATCH 6/9] block/curl: Cache downloaded blocks David Edmondson
2020-08-18 11:08 ` [RFC PATCH 7/9] block/curl: Allow the user to control the number of cache blocks David Edmondson
2020-08-18 11:08 ` [RFC PATCH 8/9] block/curl: Allow 16 sockets/ACB David Edmondson
2020-08-18 11:08 ` [RFC PATCH 9/9] block/curl: Add readahead support David Edmondson
2020-08-19 14:11 ` [RFC PATCH 0/9] block/curl: Add caching of data downloaded from the remote server Stefan Hajnoczi
2020-08-19 14:19   ` David Edmondson
2020-08-25 10:03     ` Max Reitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200818110845.3825105-1-david.edmondson@oracle.com \
    --to=david.edmondson@oracle.com \
    --cc=armbru@redhat.com \
    --cc=fam@euphon.net \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).