@@ -79,6 +79,7 @@ public enum BlockInStreamSource {
7979
8080 private boolean mClosed = false ;
8181 private boolean mEOF = false ;
82+ private boolean mEnablePrefetchRead = true ;
8283
8384 /**
8485 * Creates a {@link BlockInStream}.
@@ -120,6 +121,7 @@ public static BlockInStream create(FileSystemContext context, BlockInfo info,
120121 alluxioConf .getBoolean (PropertyKey .USER_SHORT_CIRCUIT_PREFERRED );
121122 boolean sourceSupportsDomainSocket = NettyUtils .isDomainSocketSupported (dataSource );
122123 boolean sourceIsLocal = dataSourceType == BlockInStreamSource .NODE_LOCAL ;
124+ boolean enablePrefetchRead = alluxioConf .getBoolean (PropertyKey .USER_PREFETCH_READ_ENABLED );
123125
124126 // Short circuit is enabled when
125127 // 1. data source is local node
@@ -141,9 +143,9 @@ public static BlockInStream create(FileSystemContext context, BlockInfo info,
141143 // gRPC
142144 LOG .debug ("Creating gRPC input stream for block {} @ {} from client {} reading through {} ("
143145 + "data locates in the local worker {}, shortCircuitEnabled {}, "
144- + "shortCircuitPreferred {}, sourceSupportDomainSocket {})" ,
146+ + "shortCircuitPreferred {}, sourceSupportDomainSocket {}, enablePrefetchRead {} )" ,
145147 blockId , dataSource , NetworkAddressUtils .getClientHostName (alluxioConf ), dataSource ,
146- sourceIsLocal , shortCircuit , shortCircuitPreferred , sourceSupportsDomainSocket );
148+ sourceIsLocal , shortCircuit , shortCircuitPreferred , sourceSupportsDomainSocket , enablePrefetchRead );
147149 return createGrpcBlockInStream (context , dataSource , dataSourceType , blockId ,
148150 blockSize , options );
149151 }
@@ -208,6 +210,8 @@ private static BlockInStream createGrpcBlockInStream(FileSystemContext context,
208210 AlluxioConfiguration conf = context .getClusterConf ();
209211 long chunkSize = conf .getBytes (
210212 PropertyKey .USER_STREAMING_READER_CHUNK_SIZE_BYTES );
213+ boolean enablePrefetchRead = conf .getBoolean (
214+ PropertyKey .USER_PREFETCH_READ_ENABLED );
211215 // Construct the partial read request
212216 ReadRequest .Builder builder = ReadRequest .newBuilder ()
213217 .setBlockId (blockId )
@@ -224,7 +228,7 @@ private static BlockInStream createGrpcBlockInStream(FileSystemContext context,
224228 } else {
225229 factory = new GrpcDataReader .Factory (context , address , builder );
226230 }
227- return new BlockInStream (factory , address , blockSource , blockId , blockSize );
231+ return new BlockInStream (factory , address , blockSource , blockId , blockSize , enablePrefetchRead );
228232 }
229233
230234 /**
@@ -246,11 +250,13 @@ public static BlockInStream createRemoteBlockInStream(FileSystemContext context,
246250 AlluxioConfiguration conf = context .getClusterConf ();
247251 long chunkSize = conf .getBytes (
248252 PropertyKey .USER_STREAMING_READER_CHUNK_SIZE_BYTES );
253+ boolean enablePrefetchRead = conf .getBoolean (
254+ PropertyKey .USER_PREFETCH_READ_ENABLED );
249255 ReadRequest readRequest = ReadRequest .newBuilder ().setBlockId (blockId )
250256 .setOpenUfsBlockOptions (ufsOptions ).setChunkSize (chunkSize ).buildPartial ();
251257 DataReader .Factory factory = new GrpcDataReader .Factory (context , address ,
252258 readRequest .toBuilder ());
253- return new BlockInStream (factory , address , blockSource , blockId , blockSize );
259+ return new BlockInStream (factory , address , blockSource , blockId , blockSize , enablePrefetchRead );
254260 }
255261
256262 /**
@@ -272,6 +278,23 @@ protected BlockInStream(DataReader.Factory dataReaderFactory,
272278 mLength = length ;
273279 }
274280
281+ /**
282+ * Creates an instance of {@link BlockInStream}.
283+ *
284+ * @param dataReaderFactory the data reader factory
285+ * @param address the address of the gRPC data server
286+ * @param blockSource the source location of the block
287+ * @param id the ID (either block ID or UFS file ID)
288+ * @param length the length
289+ * @param enablePrefetchRead whether to enable prefetch
290+ */
291+ @ VisibleForTesting
292+ protected BlockInStream (DataReader .Factory dataReaderFactory ,
293+ WorkerNetAddress address , BlockInStreamSource blockSource , long id , long length , boolean enablePrefetchRead ) {
294+ this (dataReaderFactory , address , blockSource , id , length );
295+ mEnablePrefetchRead = enablePrefetchRead ;
296+ }
297+
275298 @ Override
276299 public long getPos () {
277300 return mPos ;
@@ -318,7 +341,11 @@ public int read(ByteBuffer byteBuffer, int off, int len) throws IOException {
318341 if (mPos == mLength ) {
319342 return -1 ;
320343 }
321- readChunk ();
344+ if (mEnablePrefetchRead ) {
345+ readChunk ();
346+ } else {
347+ readLengthChunk (len );
348+ }
322349 if (mCurrentChunk == null ) {
323350 mEOF = true ;
324351 }
@@ -498,6 +525,21 @@ private void readChunk() throws IOException {
498525 }
499526 }
500527
528+ /**
529+ * Reads a new length from the channel into current chunk.
530+ */
531+ private void readLengthChunk (int length ) throws IOException {
532+ if (mDataReader == null ) {
533+ mDataReader = mDataReaderFactory .create (mPos , length );
534+ } else if (mCurrentChunk != null && mCurrentChunk .readableBytes () == 0 ) {
535+ closeDataReader ();
536+ mDataReader = mDataReaderFactory .create (mPos , length );
537+ }
538+ if (mCurrentChunk == null ) {
539+ mCurrentChunk = mDataReader .readChunk ();
540+ }
541+ }
542+
501543 /**
502544 * Close the current data reader.
503545 */
0 commit comments