Skip to content

Commit 289130b

Browse files
committed
Improve image pull performance from http 1.1 container registries
Private registries that does not support http 2.0 such as Azure Container Registry streams back content in a max of 16KB chunks (max TLS record size). The small chunks introduce an overhead when copying the layers to the content store sine each chunk incurs the overhead of grpc message that has to be sent to the content store. This change reduces this overhead by buffering the chunks into 1MB chunks and only then writes a message to the content store. Below is a per comparsion between the 2 approaches using a couple of large images that are being pulled from the docker hub (http 2.0) and a private Azure CR (http 1.1) in seconds. image | Buffered copy | master ------- |---------------|---------- docker.io/pytorch/pytorch:latest | 55.63 | 58.33 docker.io/nvidia/cuda:latest | 72.05 | 75.98 containerdpulltest.azurecr.io/pytorch/pytorch:latest | 61.45 | 77.1 containerdpulltest.azurecr.io/nvidia/cuda:latest | 77.13 | 85.47 Signed-off-by: Amr Mahdi <[email protected]>
1 parent 656b487 commit 289130b

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

content/helpers.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,31 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
230230
}
231231

232232
func copyWithBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
233-
buf := bufPool.Get().(*[]byte)
234-
written, err = io.CopyBuffer(dst, src, *buf)
235-
bufPool.Put(buf)
233+
bufRef := bufPool.Get().(*[]byte)
234+
defer bufPool.Put(bufRef)
235+
buf := *bufRef
236+
for {
237+
nr, er := io.ReadAtLeast(src, buf, len(buf))
238+
if nr > 0 {
239+
nw, ew := dst.Write(buf[0:nr])
240+
if nw > 0 {
241+
written += int64(nw)
242+
}
243+
if ew != nil {
244+
err = ew
245+
break
246+
}
247+
if nr != nw {
248+
err = io.ErrShortWrite
249+
break
250+
}
251+
}
252+
if er != nil {
253+
if er != io.EOF && er != io.ErrUnexpectedEOF {
254+
err = er
255+
}
256+
break
257+
}
258+
}
236259
return
237260
}

0 commit comments

Comments
 (0)