【问题标题】:GCS slow upload from pod inside kubernetes GKEGCS 从 Kubernetes GKE 中的 pod 缓慢上传
【发布时间】:2016-02-25 17:38:15
【问题描述】:

从 GKE 内的 pod 上传到 GCE 需要很长时间。我希望升级到 kubernetes 1.1 会有所帮助,但它没有。它更快,但没有达到应有的速度。我做了一些基准测试,上传了一个 100MiB 的文件:

  • docker 1.7.2 本地

    花了 {20m51s240ms},大约是 ~{0.07993605115907274}MB/s

  • docker 1.8.3 本地

    花了 {3m51s193ms},大约是 ~{0.4329004329004329}MB/s

  • docker 1.9.0 本地

    花了 {3m51s424ms},大约是 ~{0.4329004329004329}MB/s

  • kubernetes 1.0

    花费了 {1h10s952ms},大约是 ~{0.027700831024930747}MB/s

  • kubernetes 1.1.2 (docker 1.8.3)

    花了 {32m11s359ms},大约是 ~{0.05178663904712584}MB/s

正如您所见,kubernetes 1.1.2 的吞吐量翻了一番,但仍然很慢。如果我想上传 1GB,我必须等待大约 5 个小时,这不是预期的行为。 GKE 在 Google 基础架构中运行,因此我希望它应该更快,或者至少与从本地上传一样快。

我还注意到上传时 CPU 负载非常高 (70%)。它使用n1-highmem-4 机器类型和一个在上传后什么都不做的单个 RC/pod 进行了测试。

我正在使用带有 GAV 坐标 com.google.appengine.tools:appengine-gcs-client:0.5 的 java 客户端

相关代码如下:

InputStream inputStream = ...; // 100MB RandomData from RAM
StorageObject so = new StorageObject().setContentType("text/plain").setName(objectName);
AbstractInputStreamContent content = new InputStreamContent("text/plain", inputStream);
Stopwatch watch = Stopwatch.createStarted();
storage.objects().insert(bucket.getName(), so, content).execute();
watch.stop();

使用手动安装的 gcloud 和 gsutil cp 复制一个 100MB 的文件几乎不需要任何时间(3 秒)。所以这可能是java库的问题?问题依然存在,如何使用 java-library 提高上传时间?

【问题讨论】:

  • 您是否尝试使用 gsutil [1] 上传?如果它仍然很慢,您可以使用 gsutil perfdiag -o output.json gs://your-bucket 进行详细说明。 [1]:cloud.google.com/storage/docs/gsutil/commands/cp
  • @George 感谢您的建议。事实证明,使用 gsutil 非常快。但是要使用它,我必须将 gsutil 和授权安装到容器中,这不是 kubernetes 概念的意图。但这将问题缩小到 java 库。
  • 很高兴听到这个消息:)

标签: google-cloud-storage google-api-java-client kubernetes google-kubernetes-engine


【解决方案1】:

解决方案是启用“DirectUpload”,所以不要写

storage.objects().insert(bucket.getName(), so, content).execute();

你必须写:

    Storage.Objects.Insert insert = storage.objects().insert(bucket.getName(), so, content);
    insert.getMediaHttpUploader().setDirectUploadEnabled(true);
    insert.execute();

我使用此解决方案获得的性能:

  • 花了 {13s515ms},大约是 ~{7.6923076923076925}MB/s

setDirectUploadEnabled 的 JavaDoc:

设置是启用还是禁用直接媒体上传。

如果 value 设置为 true,那么将直接上传 整个媒体内容在一个请求中上传。如果设置了值 为 false 则上传使用可恢复媒体上传协议 以数据块的形式上传。

如果内容大小低于某个特定值,建议直接上传 最低限度。这是因为有最小块写入大小 一些 Google API,因此如果可恢复请求在 第一个块,客户端将不得不从头开始 无论如何。

默认为假。

【讨论】:

    【解决方案2】:

    您看到高 CPU 负载并且缓慢仅影响 Java 而不是 Python gsutil 这一事实与 slow AES GCM issue in Java 8 一致。该问题已在 Java 9 using appropriate specialized CPU instructions 中得到修复。

    如果您可以控制它,那么使用 Java 7 或将 jdk.tls.disabledAlgorithms=SSLv3,GCM 添加到传递给 java -Djava.security.properties 的文件应该可以解决慢速问题,如 this answer 中对一般慢速 AES GCM 问题的解释。

    【讨论】:

    • 很好,我试过了,但不幸的是它没有奏效。情况正好相反,如果我将 GCM 添加到禁用的算法中,它会变慢(大约 40%),SSLv3 没有效果。使用 Oracle JDK 8u65/Linux 64 位测试。
    • 啊,有趣。还有另一件事与我们在其他地方做的 SSL 相关,也可能与特定于 Java 一致,这在 java.security.properties 文件中另外设置:securerandom.source=file:/dev/urandom;默认是 /dev/random,如果它耗尽了熵池,那么事情就会停止。 2uo.de/myths-about-urandom 解释了为什么使用 /dev/urandom 并不是不安全的
    • 感谢您的洞察力,但不幸的是它没有帮助,与本文相符:docs.oracle.com/cd/E13209_01/wlcp/wlss30/configwlss/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2018-12-26
    • 2020-03-31
    • 1970-01-01
    • 2022-01-27
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多