Przeglądaj źródła

HDDS-1621. writeData in ChunkUtils should not use AsynchronousFileChannel. Contributed by Supratim Deka (#917)

supratimdeka 6 lat temu
rodzic
commit
9fded678ff

+ 12 - 10
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/helpers/ChunkUtils.java

@@ -43,6 +43,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
 import java.nio.channels.AsynchronousFileChannel;
 import java.nio.channels.AsynchronousFileChannel;
+import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.nio.channels.FileLock;
 import java.nio.file.StandardOpenOption;
 import java.nio.file.StandardOpenOption;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchAlgorithmException;
@@ -84,23 +85,20 @@ public final class ChunkUtils {
       throw new StorageContainerException(err, INVALID_WRITE_SIZE);
       throw new StorageContainerException(err, INVALID_WRITE_SIZE);
     }
     }
 
 
-    AsynchronousFileChannel file = null;
+    FileChannel file = null;
     FileLock lock = null;
     FileLock lock = null;
 
 
     try {
     try {
       long writeTimeStart = Time.monotonicNow();
       long writeTimeStart = Time.monotonicNow();
-      file = sync ?
-          AsynchronousFileChannel.open(chunkFile.toPath(),
-              StandardOpenOption.CREATE,
-              StandardOpenOption.WRITE,
-              StandardOpenOption.SPARSE,
-              StandardOpenOption.SYNC) :
-          AsynchronousFileChannel.open(chunkFile.toPath(),
+
+      // skip SYNC and DSYNC to reduce contention on file.lock
+      file = FileChannel.open(chunkFile.toPath(),
               StandardOpenOption.CREATE,
               StandardOpenOption.CREATE,
               StandardOpenOption.WRITE,
               StandardOpenOption.WRITE,
               StandardOpenOption.SPARSE);
               StandardOpenOption.SPARSE);
-      lock = file.lock().get();
-      int size = file.write(data, chunkInfo.getOffset()).get();
+
+      lock = file.lock();
+      int size = file.write(data, chunkInfo.getOffset());
       // Increment volumeIO stats here.
       // Increment volumeIO stats here.
       volumeIOStats.incWriteTime(Time.monotonicNow() - writeTimeStart);
       volumeIOStats.incWriteTime(Time.monotonicNow() - writeTimeStart);
       volumeIOStats.incWriteOpCount();
       volumeIOStats.incWriteOpCount();
@@ -128,6 +126,10 @@ public final class ChunkUtils {
       }
       }
       if (file != null) {
       if (file != null) {
         try {
         try {
+          if (sync) {
+            // ensure data and metadata is persisted. Outside the lock
+            file.force(true);
+          }
           file.close();
           file.close();
         } catch (IOException e) {
         } catch (IOException e) {
           throw new StorageContainerException("Error closing chunk file",
           throw new StorageContainerException("Error closing chunk file",