52
52
import javax .annotation .Nullable ;
53
53
54
54
import software .amazon .awssdk .core .exception .SdkException ;
55
+ import software .amazon .awssdk .services .s3 .S3AsyncClient ;
55
56
import software .amazon .awssdk .services .s3 .S3Client ;
57
+ import software .amazon .awssdk .services .s3 .internal .crt .S3CrtAsyncClient ;
56
58
import software .amazon .awssdk .services .s3 .model .CompleteMultipartUploadRequest ;
57
59
import software .amazon .awssdk .services .s3 .model .CompleteMultipartUploadResponse ;
58
60
import software .amazon .awssdk .services .s3 .model .GetBucketLocationRequest ;
83
85
import software .amazon .awssdk .transfer .s3 .model .Copy ;
84
86
import software .amazon .awssdk .transfer .s3 .model .CopyRequest ;
85
87
88
+ import software .amazon .s3 .analyticsaccelerator .S3SdkObjectClient ;
89
+ import software .amazon .s3 .analyticsaccelerator .S3SeekableInputStreamConfiguration ;
90
+ import software .amazon .s3 .analyticsaccelerator .S3SeekableInputStreamFactory ;
91
+ import software .amazon .s3 .analyticsaccelerator .common .ConnectorConfiguration ;
92
+
86
93
import org .apache .hadoop .fs .impl .prefetch .ExecutorServiceFuturePool ;
87
94
import org .slf4j .Logger ;
88
95
import org .slf4j .LoggerFactory ;
@@ -309,6 +316,13 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
309
316
*/
310
317
private S3Client s3Client ;
311
318
319
+ /**
320
+ * CRT-Based S3Client created of analytics accelerator library is enabled
321
+ * and managed by the S3AStoreImpl. Analytics accelerator library can be
322
+ * enabled with {@link Constants#ANALYTICS_ACCELERATOR_ENABLED_KEY}
323
+ */
324
+ private S3AsyncClient s3AsyncClient ;
325
+
312
326
// initial callback policy is fail-once; it's there just to assist
313
327
// some mock tests and other codepaths trying to call the low level
314
328
// APIs on an uninitialized filesystem.
@@ -335,6 +349,12 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
335
349
*/
336
350
private ExecutorServiceFuturePool futurePool ;
337
351
352
+
353
+ // If true, S3SeekableInputStream from Analytics Accelerator for Amazon S3 will be used.
354
+ private boolean analyticsAcceleratorEnabled ;
355
+
356
+ private boolean analyticsAcceleratorCRTEnabled ;
357
+
338
358
private int executorCapacity ;
339
359
private long multiPartThreshold ;
340
360
public static final Logger LOG = LoggerFactory .getLogger (S3AFileSystem .class );
@@ -497,6 +517,11 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
497
517
*/
498
518
private boolean s3AccessGrantsEnabled ;
499
519
520
+ /**
521
+ * Factory to create S3SeekableInputStream if {@link this#analyticsAcceleratorEnabled} is true.
522
+ */
523
+ private S3SeekableInputStreamFactory s3SeekableInputStreamFactory ;
524
+
500
525
/** Add any deprecated keys. */
501
526
@ SuppressWarnings ("deprecation" )
502
527
private static void addDeprecatedKeys () {
@@ -643,8 +668,21 @@ public void initialize(URI name, Configuration originalConf)
643
668
dirOperationsPurgeUploads = conf .getBoolean (DIRECTORY_OPERATIONS_PURGE_UPLOADS ,
644
669
s3ExpressStore );
645
670
671
+
672
+ this .analyticsAcceleratorEnabled =
673
+ conf .getBoolean (ANALYTICS_ACCELERATOR_ENABLED_KEY , ANALYTICS_ACCELERATOR_ENABLED_DEFAULT );
674
+ this .analyticsAcceleratorCRTEnabled =
675
+ conf .getBoolean (ANALYTICS_ACCELERATOR_CRT_ENABLED ,
676
+ ANALYTICS_ACCELERATOR_CRT_ENABLED_DEFAULT );
677
+
646
678
this .isMultipartUploadEnabled = conf .getBoolean (MULTIPART_UPLOADS_ENABLED ,
647
- DEFAULT_MULTIPART_UPLOAD_ENABLED );
679
+ DEFAULT_MULTIPART_UPLOAD_ENABLED );
680
+
681
+ if (this .analyticsAcceleratorEnabled && !analyticsAcceleratorCRTEnabled ) {
682
+ // Temp change: Analytics Accelerator with S3AsyncClient do not support Multi-part upload.
683
+ this .isMultipartUploadEnabled = false ;
684
+ }
685
+
648
686
// multipart copy and upload are the same; this just makes it explicit
649
687
this .isMultipartCopyEnabled = isMultipartUploadEnabled ;
650
688
@@ -771,6 +809,26 @@ public void initialize(URI name, Configuration originalConf)
771
809
// thread pool init requires store to be created
772
810
initThreadPools ();
773
811
812
+ if (this .analyticsAcceleratorEnabled ) {
813
+ LOG .info ("Using S3SeekableInputStream" );
814
+ if (this .analyticsAcceleratorCRTEnabled ) {
815
+ LOG .info ("Using S3 CRT client for analytics accelerator S3" );
816
+ this .s3AsyncClient = S3CrtAsyncClient .builder ().maxConcurrency (600 ).build ();
817
+ } else {
818
+ LOG .info ("Using S3 async client for analytics accelerator S3" );
819
+ this .s3AsyncClient = store .getOrCreateAsyncClient ();
820
+ }
821
+
822
+ ConnectorConfiguration configuration = new ConnectorConfiguration (conf ,
823
+ ANALYTICS_ACCELERATOR_CONFIGURATION_PREFIX );
824
+ S3SeekableInputStreamConfiguration seekableInputStreamConfiguration =
825
+ S3SeekableInputStreamConfiguration .fromConfiguration (configuration );
826
+ this .s3SeekableInputStreamFactory =
827
+ new S3SeekableInputStreamFactory (
828
+ new S3SdkObjectClient (this .s3AsyncClient ),
829
+ seekableInputStreamConfiguration );
830
+ }
831
+
774
832
// The filesystem is now ready to perform operations against
775
833
// S3
776
834
// This initiates a probe against S3 for the bucket existing.
@@ -1822,6 +1880,7 @@ private FSDataInputStream executeOpen(
1822
1880
final Path path ,
1823
1881
final OpenFileSupport .OpenFileInformation fileInformation )
1824
1882
throws IOException {
1883
+
1825
1884
// create the input stream statistics before opening
1826
1885
// the file so that the time to prepare to open the file is included.
1827
1886
S3AInputStreamStatistics inputStreamStats =
@@ -4257,9 +4316,13 @@ public void close() throws IOException {
4257
4316
protected synchronized void stopAllServices () {
4258
4317
try {
4259
4318
trackDuration (getDurationTrackerFactory (), FILESYSTEM_CLOSE .getSymbol (), () -> {
4260
- closeAutocloseables (LOG , getStore ());
4319
+
4320
+ closeAutocloseables (LOG , getStore (), s3SeekableInputStreamFactory );
4321
+
4261
4322
store = null ;
4262
4323
s3Client = null ;
4324
+ s3AsyncClient = null ;
4325
+ s3SeekableInputStreamFactory = null ;
4263
4326
4264
4327
// At this point the S3A client is shut down,
4265
4328
// now the executor pools are closed
0 commit comments