Repository navigation
Description
- OS: all
- Java version: 1.8 (probably all)
- google-cloud-java version(s): 1.23.0
Steps to reproduce
- Upload to GCS using the cloud storage library.
- Observe poor throughput (20 MiB/s)_ and that lots of time is spent compressing the content.
On GCE I'm able to achieve 70 MiB/s if I disable gzip encoding when uploading to GCS. With gzip encoding it's much worse at 20 MiB/s. However disabling gzip encoding isn't an option exposed in the interface. This makes google-cloud-java poor in comparison to the REST api it's wrapping.
This is a request to expose the gzip encoding of the stream as a storage option. See code in com.google.cloud.storage.spi.v1.HttpStorageRpc.create there is no code to call StorageRequest.setDisableGZipContent (which defaults to false) on the underling com.google.api.services.storage.StorageRequest:
Storage.Objects.Insert insert = storage.objects()
.insert(storageObject.getBucket(), storageObject,
new InputStreamContent(storageObject.getContentType(), content));
insert.getMediaHttpUploader().setDirectUploadEnabled(true);
setEncryptionHeaders(insert.getRequestHeaders(), ENCRYPTION_KEY_PREFIX, options);
return insert.
... .execute();
Can we please provide this feature to maintain comparable performance with the com.google.api.services.storage.* client?
thanks
Code snippet
Uploading an object to GCS and observe performance, then do so with gzip disabled:
/// USING THE OLD CLIENT
Storage client = getService();
Storage.Objects.Insert insertRequest =
client.objects().insert(bucketName, objectMetadata, contentStream);
/// Currently NO ability to this in google-cloud-java, need this for much faster throughput on GCE.
insertRequest.setDisableGZipContent(true);
insertRequest.getMediaHttpUploader().setDisableGZipContent(true);
insertRequest.getMediaHttpUploader().setDirectUploadEnabled(true);
long start = System.currentTimeMillis();
insertRequest.execute();
long end = System.currentTimeMillis();
System.out.println( String.format("%.02f MiB/s ",(length / (1024*1024.0) )/ ((end - start) / 1000.0)));
Any additional information below
Also, perhaps document somewhere that in order to get any reasonable performance on Java8 it's necessary to disable Galios/Counter mode in java.security: https://stackoverflow.com/questions/25992131/slow-aes-gcm-encryption-and-decryption-with-java-8u20
Activity
ajaaym commentedon Oct 24, 2018
I see that Storage.Objects.Insert extends StorageRequest which extends AbstractGoogleJsonClientRequest which in turn extends AbstractGoogleClientRequest.
setDisableGZipContent is public setter exists on AbstractGoogleClientRequest, so you should be able to call
directly
bmenasha commentedon Oct 24, 2018
Thanks, perhaps there is some miscommunication, i'm complaining about the lack of this feature in this project, google-cloud-java/google-cloud-storage not the library it's wrapping google-api-java-client-services.
thanks
ajaaym commentedon Oct 30, 2018
@bmenasha Thanks for clarification. Using BlobWriteChannel will allow you to send data without compressing.
PadrePadrone commentedon Oct 31, 2018
Hi,
We need this feature as well.
ajaaym commentedon Oct 31, 2018
Please find my answer below.
PadrePadrone commentedon Nov 6, 2018
Hi @ajaaym
Following your recommendation, I replaced the use of storage.create:
Blob blob = clientSetup.storage.create(blobInfo, data.getData());
With using a writer channel:
writeChannel = clientSetup.storage.writer(blobInfo);
writeChannel.setChunkSize(data.getDataSize());
writeChannel.write(ByteBuffer.wrap(data.getData()));
Performance became much worst with the new code.
Is this the expected behaviour?
Is there any additional code I need to write when using the writer channel?
mcantrell commentedon Nov 14, 2018
This is a serious problem with the new storage client. The internal method in HttpStorageRpc does not attempt any configuration on the mediaHttpUploader.
https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/spi/v1/HttpStorageRpc.java#L271
This can severely impair performance for files which are not suitable for gzip compression. For instance, the following test ran with a 1GB binary file produces very different results due to high CPU overhead without significant size reduction:
Without gzip: ~35MB/s
With gzip: ~16.MB/s
I'd think that this deserves a higher priority. We cannot upgrade to the new client library until this is fixed.
mcantrell commentedon Nov 14, 2018
@PadrePadrone
I think the write channel performance is similar to issue #3929. The write operation to the API is tied to the chunk size:
https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java#L45
Unless you want to use large buffers, the performance will likely be slower.
Edit: never mind... I see that you're adjusting the chunk size to the size of the data. I missed that.
mcantrell commentedon Nov 14, 2018
Attaching a test case which demonstrates multiple upload mechanisms:
See StoragePerformanceUploadTest in storage-performance-new.zip
Edit: test file available here
perf: remove all calls to getSqlWithoutComments (#3822)