Skip to content

Commit a9ff4b9

Browse files
committed
Make max copy size before multipart a setting.
And override it in S3RepositoryAnalysisRestIT to exercise multipart copy.
1 parent 25e3a1b commit a9ff4b9

File tree

6 files changed

+34
-5
lines changed

6 files changed

+34
-5
lines changed

modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3BlobStoreRepositoryTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ long getLargeBlobThresholdInBytes() {
623623
}
624624

625625
@Override
626-
long getLargeCopyThresholdInBytes() {
626+
long getMaxCopySizeBeforeMultipart() {
627627
// on my laptop 10K exercises this better but larger values should be fine for nightlies
628628
return ByteSizeUnit.MB.toBytes(1L);
629629
}

modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,8 @@ long getLargeBlobThresholdInBytes() {
305305
}
306306

307307
// package private for testing
308-
long getLargeCopyThresholdInBytes() {
309-
return MAX_FILE_SIZE.getBytes();
308+
long getMaxCopySizeBeforeMultipart() {
309+
return blobStore.maxCopySizeBeforeMultipart();
310310
}
311311

312312
@Override
@@ -358,7 +358,7 @@ public void copyBlob(
358358
final var s3SourceBlobContainer = (S3BlobContainer) sourceBlobContainer;
359359

360360
try {
361-
if (blobSize > getLargeCopyThresholdInBytes()) {
361+
if (blobSize > getMaxCopySizeBeforeMultipart()) {
362362
executeMultipartCopy(purpose, s3SourceBlobContainer, sourceBlobName, blobName, blobSize);
363363
} else {
364364
// metadata is inherited from source, but not canned ACL or storage class

modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobStore.java

+8
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class S3BlobStore implements BlobStore {
8080

8181
private final ByteSizeValue bufferSize;
8282

83+
private final ByteSizeValue maxCopySizeBeforeMultipart;
84+
8385
private final boolean serverSideEncryption;
8486

8587
private final CannedAccessControlList cannedACL;
@@ -104,6 +106,7 @@ class S3BlobStore implements BlobStore {
104106
String bucket,
105107
boolean serverSideEncryption,
106108
ByteSizeValue bufferSize,
109+
ByteSizeValue maxCopySizeBeforeMultipart,
107110
String cannedACL,
108111
String storageClass,
109112
RepositoryMetadata repositoryMetadata,
@@ -117,6 +120,7 @@ class S3BlobStore implements BlobStore {
117120
this.bucket = bucket;
118121
this.serverSideEncryption = serverSideEncryption;
119122
this.bufferSize = bufferSize;
123+
this.maxCopySizeBeforeMultipart = maxCopySizeBeforeMultipart;
120124
this.cannedACL = initCannedACL(cannedACL);
121125
this.storageClass = initStorageClass(storageClass);
122126
this.repositoryMetadata = repositoryMetadata;
@@ -329,6 +333,10 @@ public long bufferSizeInBytes() {
329333
return bufferSize.getBytes();
330334
}
331335

336+
public long maxCopySizeBeforeMultipart() {
337+
return maxCopySizeBeforeMultipart.getBytes();
338+
}
339+
332340
public RepositoryMetadata getRepositoryMetadata() {
333341
return repositoryMetadata;
334342
}

modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ class S3Repository extends MeteredBlobStoreRepository {
131131
MAX_PART_SIZE_USING_MULTIPART
132132
);
133133

134+
/**
135+
* Maximum size allowed for copy without multipart.
136+
* Objects larger than this will be copied using multipart copy. S3 enforces a minimum multipart size of 5 MiB and a maximum
137+
* non-multipart copy size of 5 GiB. The default is to use the maximum allowable size in order to minimize request count.
138+
*/
139+
static final Setting<ByteSizeValue> MAX_COPY_SIZE_BEFORE_MULTIPART = Setting.byteSizeSetting(
140+
"max_copy_size_before_multipart",
141+
MAX_FILE_SIZE,
142+
MIN_PART_SIZE_USING_MULTIPART,
143+
MAX_FILE_SIZE
144+
);
145+
134146
/**
135147
* Big files can be broken down into chunks during snapshotting if needed. Defaults to 5tb.
136148
*/
@@ -241,6 +253,8 @@ class S3Repository extends MeteredBlobStoreRepository {
241253

242254
private final ByteSizeValue chunkSize;
243255

256+
private final ByteSizeValue maxCopySizeBeforeMultipart;
257+
244258
private final boolean serverSideEncryption;
245259

246260
private final String storageClass;
@@ -308,6 +322,8 @@ class S3Repository extends MeteredBlobStoreRepository {
308322
);
309323
}
310324

325+
this.maxCopySizeBeforeMultipart = MAX_COPY_SIZE_BEFORE_MULTIPART.get(metadata.settings());
326+
311327
this.serverSideEncryption = SERVER_SIDE_ENCRYPTION_SETTING.get(metadata.settings());
312328

313329
this.storageClass = STORAGE_CLASS_SETTING.get(metadata.settings());
@@ -325,11 +341,13 @@ class S3Repository extends MeteredBlobStoreRepository {
325341
coolDown = COOLDOWN_PERIOD.get(metadata.settings());
326342

327343
logger.debug(
328-
"using bucket [{}], chunk_size [{}], server_side_encryption [{}], buffer_size [{}], cannedACL [{}], storageClass [{}]",
344+
"using bucket [{}], chunk_size [{}], server_side_encryption [{}], buffer_size [{}], "
345+
+ "max_copy_size_before_multipart [{}], cannedACL [{}], storageClass [{}]",
329346
bucket,
330347
chunkSize,
331348
serverSideEncryption,
332349
bufferSize,
350+
maxCopySizeBeforeMultipart,
333351
cannedACL,
334352
storageClass
335353
);
@@ -454,6 +472,7 @@ protected S3BlobStore createBlobStore() {
454472
bucket,
455473
serverSideEncryption,
456474
bufferSize,
475+
maxCopySizeBeforeMultipart,
457476
cannedACL,
458477
storageClass,
459478
metadata,

modules/repository-s3/src/test/java/org/elasticsearch/repositories/s3/S3BlobContainerRetriesTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ protected BlobContainer createBlobContainer(
214214
"bucket",
215215
S3Repository.SERVER_SIDE_ENCRYPTION_SETTING.getDefault(Settings.EMPTY),
216216
bufferSize == null ? S3Repository.BUFFER_SIZE_SETTING.getDefault(Settings.EMPTY) : bufferSize,
217+
S3Repository.MAX_COPY_SIZE_BEFORE_MULTIPART.getDefault(Settings.EMPTY),
217218
S3Repository.CANNED_ACL_SETTING.getDefault(Settings.EMPTY),
218219
S3Repository.STORAGE_CLASS_SETTING.getDefault(Settings.EMPTY),
219220
repositoryMetadata,

x-pack/plugin/snapshot-repo-test-kit/qa/s3/src/javaRestTest/java/org/elasticsearch/repositories/blobstore/testkit/analyze/S3RepositoryAnalysisRestIT.java

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ protected Settings repositorySettings() {
6161
.put("base_path", basePath)
6262
.put("delete_objects_max_size", between(1, 1000))
6363
.put("buffer_size", ByteSizeValue.ofMb(5)) // so some uploads are multipart ones
64+
.put("max_copy_size_before_multipart", ByteSizeValue.ofMb(5))
6465
.build();
6566
}
6667
}

0 commit comments

Comments
 (0)