Bump the chunk_size to use CPU more efficiently

The chunk_size used for downloading images was 1KiB for some time. That
is okay for relatively small images but the client side of CPU can be a
bottleneck especially for large images. Bump the default chunk_size from
1KiB to 1MiB so we can use the client side CPU more efficiently.

[1KiB chunk_size - current]

$ time openstack image save IMAGE_689MB --file /dev/null

real    0m16.633s
user    0m12.633s
sys     0m1.365s

-> ~331 Mbps

[1MiB chunk_size - patched]

$ time openstack image save IMAGE_689MB --file /dev/null

real    0m4.896s
user    0m3.361s
sys     0m0.724s

-> ~1,125 Mbps

Story: 2010759
Task: 48044
Change-Id: Ib877d292f8adbf2fa0c51065f2917b3f1e263483
This commit is contained in:
Nobuto Murata 2023-05-18 11:06:59 +09:00
parent 692b7f39e3
commit a72d46a955
5 changed files with 11 additions and 9 deletions

View File

@ -35,9 +35,9 @@ def download_image_stream(conn):
with open("myimage.qcow2", "wb") as local_image:
response = conn.image.download_image(image, stream=True)
# Read only 1024 bytes of memory at a time until
# Read only 1 MiB of memory at a time until
# all of the image data has been consumed.
for chunk in response.iter_content(chunk_size=1024):
for chunk in response.iter_content(chunk_size=1024 * 1024):
# With each chunk, add it to the hash to be computed.
md5.update(chunk)

View File

@ -121,7 +121,7 @@ class ImageCloudMixin:
name_or_id,
output_path=None,
output_file=None,
chunk_size=1024,
chunk_size=1024 * 1024,
):
"""Download an image by name or ID
@ -132,7 +132,7 @@ class ImageCloudMixin:
image data to. Only write() will be called on this object. Either
this or output_path must be specified
:param int chunk_size: size in bytes to read from the wire and buffer
at one time. Defaults to 1024
at one time. Defaults to 1024 * 1024 = 1 MiB
:returns: When output_path and output_file are not given - the bytes
comprising the given Image when stream is False, otherwise a
:class:`requests.Response` instance. When output_path or

View File

@ -25,7 +25,9 @@ def _verify_checksum(md5, checksum):
class DownloadMixin:
def download(self, session, stream=False, output=None, chunk_size=1024):
def download(
self, session, stream=False, output=None, chunk_size=1024 * 1024
):
"""Download the data contained in an image"""
# TODO(briancurtin): This method should probably offload the get
# operation into another thread or something of that nature.

View File

@ -386,7 +386,7 @@ class Proxy(proxy.Proxy):
image,
stream=False,
output=None,
chunk_size=1024,
chunk_size=1024 * 1024,
):
"""Download an image
@ -411,7 +411,7 @@ class Proxy(proxy.Proxy):
When ``False``, return the entire contents of the response.
:param output: Either a file object or a path to store data into.
:param int chunk_size: size in bytes to read from the wire and buffer
at one time. Defaults to 1024
at one time. Defaults to 1024 * 1024 = 1 MiB
:returns: When output is not given - the bytes comprising the given
Image when stream is False, otherwise a :class:`requests.Response`

View File

@ -776,7 +776,7 @@ class Proxy(proxy.Proxy):
*,
stream=False,
output=None,
chunk_size=1024,
chunk_size=1024 * 1024,
):
"""Download an image
@ -800,7 +800,7 @@ class Proxy(proxy.Proxy):
When ``False``, return the entire contents of the response.
:param output: Either a file object or a path to store data into.
:param int chunk_size: size in bytes to read from the wire and buffer
at one time. Defaults to 1024
at one time. Defaults to 1024 * 1024 = 1 MiB
:returns: When output is not given - the bytes comprising the given
Image when stream is False, otherwise a :class:`requests.Response`