This is an automated email from the ASF dual-hosted git repository.

mmerli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new b82e2247e6 Allow to use IO uring instead of epoll (#3595)
b82e2247e6 is described below

commit b82e2247e67d6a2b3f2f8cb76bc2b0a7c733b5c5
Author: Matteo Merli <[email protected]>
AuthorDate: Wed Nov 2 10:31:02 2022 -0700

    Allow to use IO uring instead of epoll (#3595)
    
    * Allow to use IO uring instead of epoll
    
    * Removed unused import
    
    * Fixed license file
    
    * Fixed license file
---
 bookkeeper-common/pom.xml                          | 10 ++++
 .../src/main/resources/LICENSE-all.bin.txt         |  3 +
 .../src/main/resources/LICENSE-bkctl.bin.txt       |  3 +
 .../src/main/resources/LICENSE-server.bin.txt      |  3 +
 .../src/main/resources/NOTICE-all.bin.txt          |  2 +
 .../src/main/resources/NOTICE-bkctl.bin.txt        |  2 +
 .../src/main/resources/NOTICE-server.bin.txt       |  2 +
 .../apache/bookkeeper/proto/BookieNettyServer.java |  8 ++-
 .../bookkeeper/proto/PerChannelBookieClient.java   | 12 +++-
 .../org/apache/bookkeeper/util/EventLoopUtil.java  | 64 ++++++++++++++--------
 pom.xml                                            | 18 ++++++
 11 files changed, 101 insertions(+), 26 deletions(-)

diff --git a/bookkeeper-common/pom.xml b/bookkeeper-common/pom.xml
index 29d77bccde..7526bf02e3 100644
--- a/bookkeeper-common/pom.xml
+++ b/bookkeeper-common/pom.xml
@@ -59,6 +59,16 @@
       <groupId>org.jctools</groupId>
       <artifactId>jctools-core</artifactId>
     </dependency>
+    <dependency>
+      <groupId>io.netty.incubator</groupId>
+      <artifactId>netty-incubator-transport-native-io_uring</artifactId>
+      <classifier>linux-x86_64</classifier>
+    </dependency>
+    <dependency>
+      <groupId>io.netty.incubator</groupId>
+      <artifactId>netty-incubator-transport-native-io_uring</artifactId>
+      <classifier>linux-aarch_64</classifier>
+    </dependency>
     <dependency>
       <groupId>com.google.code.findbugs</groupId>
       <artifactId>jsr305</artifactId>
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt 
b/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
index 1e59674231..2ab4db7601 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
@@ -238,6 +238,9 @@ Apache Software License, Version 2.
 - lib/io.netty-netty-transport-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-classes-io_uring-0.0.15.Final.jar
 [11]
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar [11]
 - lib/io.prometheus-simpleclient-0.15.0.jar [12]
 - lib/io.prometheus-simpleclient_common-0.15.0.jar [12]
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt 
b/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
index f2a563691f..439115c3dd 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
@@ -236,6 +236,9 @@ Apache Software License, Version 2.
 - lib/io.netty-netty-transport-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-classes-io_uring-0.0.15.Final.jar
 [11]
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar [11]
 - lib/org.apache.logging.log4j-log4j-api-2.18.0.jar [16]
 - lib/org.apache.logging.log4j-log4j-core-2.18.0.jar [16]
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt 
b/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
index b8ffed69e0..5d69c3c2df 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
@@ -238,6 +238,9 @@ Apache Software License, Version 2.
 - lib/io.netty-netty-transport-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar [11]
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 [11]
+- 
lib/io.netty.incubator-netty-incubator-transport-classes-io_uring-0.0.15.Final.jar
 [11]
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar [11]
 - lib/io.prometheus-simpleclient-0.15.0.jar [12]
 - lib/io.prometheus-simpleclient_common-0.15.0.jar [12]
diff --git a/bookkeeper-dist/src/main/resources/NOTICE-all.bin.txt 
b/bookkeeper-dist/src/main/resources/NOTICE-all.bin.txt
index 89a67fdf84..6d3a4f465d 100644
--- a/bookkeeper-dist/src/main/resources/NOTICE-all.bin.txt
+++ b/bookkeeper-dist/src/main/resources/NOTICE-all.bin.txt
@@ -44,6 +44,8 @@ LongAdder), which was released with the following comments:
 - lib/io.netty-netty-transport-4.1.81.Final.jar
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar
 
 
diff --git a/bookkeeper-dist/src/main/resources/NOTICE-bkctl.bin.txt 
b/bookkeeper-dist/src/main/resources/NOTICE-bkctl.bin.txt
index 092d7f3438..b5f395c9a1 100644
--- a/bookkeeper-dist/src/main/resources/NOTICE-bkctl.bin.txt
+++ b/bookkeeper-dist/src/main/resources/NOTICE-bkctl.bin.txt
@@ -24,6 +24,8 @@ The Apache Software Foundation (http://www.apache.org/).
 - lib/io.netty-netty-transport-4.1.81.Final.jar
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar
 
 
diff --git a/bookkeeper-dist/src/main/resources/NOTICE-server.bin.txt 
b/bookkeeper-dist/src/main/resources/NOTICE-server.bin.txt
index ca62302dc4..4ec329d56b 100644
--- a/bookkeeper-dist/src/main/resources/NOTICE-server.bin.txt
+++ b/bookkeeper-dist/src/main/resources/NOTICE-server.bin.txt
@@ -26,6 +26,8 @@ The Apache Software Foundation (http://www.apache.org/).
 - lib/io.netty-netty-transport-4.1.81.Final.jar
 - lib/io.netty-netty-transport-classes-epoll-4.1.81.Final.jar
 - lib/io.netty-netty-transport-native-epoll-4.1.81.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-x86_64.jar
+- 
lib/io.netty.incubator-netty-incubator-transport-native-io_uring-0.0.15.Final-linux-aarch_64.jar
 - lib/io.netty-netty-transport-native-unix-common-4.1.81.Final.jar
 
 
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieNettyServer.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieNettyServer.java
index 8e24ae70ab..8d3e06c99c 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieNettyServer.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieNettyServer.java
@@ -51,6 +51,8 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
 import io.netty.handler.flush.FlushConsolidationHandler;
 import io.netty.handler.ssl.SslHandler;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
 import io.netty.util.concurrent.DefaultThreadFactory;
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -315,7 +317,9 @@ class BookieNettyServer {
             bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new 
WriteBufferWaterMark(
                     conf.getServerWriteBufferLowWaterMark(), 
conf.getServerWriteBufferHighWaterMark()));
 
-            if (eventLoopGroup instanceof EpollEventLoopGroup) {
+            if (eventLoopGroup instanceof IOUringEventLoopGroup){
+                bootstrap.channel(IOUringServerSocketChannel.class);
+            } else if (eventLoopGroup instanceof EpollEventLoopGroup) {
                 bootstrap.channel(EpollServerSocketChannel.class);
             } else {
                 bootstrap.channel(NioServerSocketChannel.class);
@@ -383,6 +387,8 @@ class BookieNettyServer {
 
             if (jvmEventLoopGroup instanceof DefaultEventLoopGroup) {
                 jvmBootstrap.channel(LocalServerChannel.class);
+            } else if (jvmEventLoopGroup instanceof IOUringEventLoopGroup) {
+                jvmBootstrap.channel(IOUringServerSocketChannel.class);
             } else if (jvmEventLoopGroup instanceof EpollEventLoopGroup) {
                 jvmBootstrap.channel(EpollServerSocketChannel.class);
             } else {
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
index f583524692..cecf682ef9 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
@@ -56,6 +56,9 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
 import io.netty.handler.codec.TooLongFrameException;
 import io.netty.handler.flush.FlushConsolidationHandler;
 import io.netty.handler.ssl.SslHandler;
+import io.netty.incubator.channel.uring.IOUringChannelOption;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUringSocketChannel;
 import io.netty.util.Recycler;
 import io.netty.util.Recycler.Handle;
 import io.netty.util.concurrent.Future;
@@ -541,7 +544,14 @@ public class PerChannelBookieClient extends 
ChannelInboundHandlerAdapter {
         // Set up the ClientBootStrap so we can create a new Channel 
connection to the bookie.
         Bootstrap bootstrap = new Bootstrap();
         bootstrap.group(eventLoopGroup);
-        if (eventLoopGroup instanceof EpollEventLoopGroup) {
+        if (eventLoopGroup instanceof IOUringEventLoopGroup) {
+            bootstrap.channel(IOUringSocketChannel.class);
+            try {
+                bootstrap.option(IOUringChannelOption.TCP_USER_TIMEOUT, 
conf.getTcpUserTimeoutMillis());
+            } catch (NoSuchElementException e) {
+                // Property not set, so keeping default value.
+            }
+        } else if (eventLoopGroup instanceof EpollEventLoopGroup) {
             bootstrap.channel(EpollSocketChannel.class);
             try {
                 // For Epoll channels, configure the TCP user timeout.
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/EventLoopUtil.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/EventLoopUtil.java
index e6679d21f2..74e59febc2 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/EventLoopUtil.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/util/EventLoopUtil.java
@@ -21,6 +21,8 @@ import io.netty.channel.EventLoopGroup;
 import io.netty.channel.SelectStrategy;
 import io.netty.channel.epoll.EpollEventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUring;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
 import java.util.concurrent.ThreadFactory;
 import lombok.experimental.UtilityClass;
 import lombok.extern.slf4j.Slf4j;
@@ -28,6 +30,7 @@ import org.apache.bookkeeper.common.util.affinity.CpuAffinity;
 import org.apache.bookkeeper.conf.ClientConfiguration;
 import org.apache.bookkeeper.conf.ServerConfiguration;
 import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.StringUtils;
 
 
 /**
@@ -36,6 +39,9 @@ import org.apache.commons.lang.SystemUtils;
 @Slf4j
 @UtilityClass
 public class EventLoopUtil {
+
+    private static final String ENABLE_IO_URING = "enable.io_uring";
+
     public static EventLoopGroup getClientEventLoopGroup(ClientConfiguration 
conf, ThreadFactory threadFactory) {
         return getEventLoopGroup(threadFactory, conf.getNumIOThreads(), 
conf.isBusyWaitEnabled());
     }
@@ -54,33 +60,43 @@ public class EventLoopUtil {
             return new NioEventLoopGroup(numThreads, threadFactory);
         }
 
-        try {
-            if (!enableBusyWait) {
-                // Regular Epoll based event loop
-                return new EpollEventLoopGroup(numThreads, threadFactory);
-            }
+        String enableIoUring = System.getProperty(ENABLE_IO_URING);
 
-            // With low latency setting, put the Netty event loop on busy-wait 
loop to reduce cost of
-            // context switches
-            EpollEventLoopGroup eventLoopGroup = new 
EpollEventLoopGroup(numThreads, threadFactory,
-                    () -> (selectSupplier, hasTasks) -> 
SelectStrategy.BUSY_WAIT);
+        // By default, io_uring will not be enabled, even if available. The 
environment variable will be used:
+        // enable.io_uring=1
+        if (StringUtils.equalsAnyIgnoreCase(enableIoUring, "1", "true")) {
+            // Throw exception if IOUring cannot be used
+            IOUring.ensureAvailability();
+            return new IOUringEventLoopGroup(numThreads, threadFactory);
+        } else {
+            try {
+                if (!enableBusyWait) {
+                    // Regular Epoll based event loop
+                    return new EpollEventLoopGroup(numThreads, threadFactory);
+                }
 
-            // Enable CPU affinity on IO threads
-            for (int i = 0; i < numThreads; i++) {
-                eventLoopGroup.next().submit(() -> {
-                    try {
-                        CpuAffinity.acquireCore();
-                    } catch (Throwable t) {
-                        log.warn("Failed to acquire CPU core for thread {} err 
{} {}",
-                                Thread.currentThread().getName(), 
t.getMessage(), t);
-                    }
-                });
-            }
+                // With low latency setting, put the Netty event loop on 
busy-wait loop to reduce cost of
+                // context switches
+                EpollEventLoopGroup eventLoopGroup = new 
EpollEventLoopGroup(numThreads, threadFactory,
+                        () -> (selectSupplier, hasTasks) -> 
SelectStrategy.BUSY_WAIT);
 
-            return eventLoopGroup;
-        } catch (ExceptionInInitializerError | NoClassDefFoundError | 
UnsatisfiedLinkError e) {
-            log.warn("Could not use Netty Epoll event loop: {}", 
e.getMessage());
-            return new NioEventLoopGroup(numThreads, threadFactory);
+                // Enable CPU affinity on IO threads
+                for (int i = 0; i < numThreads; i++) {
+                    eventLoopGroup.next().submit(() -> {
+                        try {
+                            CpuAffinity.acquireCore();
+                        } catch (Throwable t) {
+                            log.warn("Failed to acquire CPU core for thread {} 
err {} {}",
+                                    Thread.currentThread().getName(), 
t.getMessage(), t);
+                        }
+                    });
+                }
+
+                return eventLoopGroup;
+            } catch (ExceptionInInitializerError | NoClassDefFoundError | 
UnsatisfiedLinkError e) {
+                log.warn("Could not use Netty Epoll event loop: {}", 
e.getMessage());
+                return new NioEventLoopGroup(numThreads, threadFactory);
+            }
         }
     }
 }
diff --git a/pom.xml b/pom.xml
index c2a0fcbecc..faeca26668 100644
--- a/pom.xml
+++ b/pom.xml
@@ -155,6 +155,7 @@
     <mockito.version>3.12.4</mockito.version>
     <netty.version>4.1.81.Final</netty.version>
     <netty-boringssl.version>2.0.54.Final</netty-boringssl.version>
+    <netty-iouring.version>0.0.15.Final</netty-iouring.version>
     <ostrich.version>9.1.3</ostrich.version>
     <powermock.version>2.0.9</powermock.version>
     <prometheus.version>0.15.0</prometheus.version>
@@ -467,6 +468,23 @@
         <artifactId>netty-tcnative-boringssl-static</artifactId>
         <version>${netty-boringssl.version}</version>
       </dependency>
+      <dependency>
+        <groupId>io.netty.incubator</groupId>
+        <artifactId>netty-incubator-transport-native-io_uring</artifactId>
+        <version>${netty-iouring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty.incubator</groupId>
+        <artifactId>netty-incubator-transport-native-io_uring</artifactId>
+        <version>${netty-iouring.version}</version>
+        <classifier>linux-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty.incubator</groupId>
+        <artifactId>netty-incubator-transport-native-io_uring</artifactId>
+        <version>${netty-iouring.version}</version>
+        <classifier>linux-aarch_64</classifier>
+      </dependency>
 
       <!-- grpc dependencies -->
       <dependency>

Reply via email to