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

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


The following commit(s) were added to refs/heads/master by this push:
     new 98d55d88c3e [opt](point query) use fastUniqueId instead of 
UUID.randomUUID to reduce contention (#63028)
98d55d88c3e is described below

commit 98d55d88c3e3351756e0c8afec44461cf8779a38
Author: HonestManXin <[email protected]>
AuthorDate: Thu May 7 20:46:23 2026 +0800

    [opt](point query) use fastUniqueId instead of UUID.randomUUID to reduce 
contention (#63028)
    
    ```
    "mysql-nio-pool-52" #340 daemon prio=5 os_prio=0 tid=0x00007f3ac801d800 
nid=0x3e35cd waiting for monitor entry [0x00007f39742d7000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at 
sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:215)
            - waiting to lock <0x00007f3f9c218f58> (a 
sun.security.provider.SecureRandom)
            at 
sun.security.provider.NativePRNG$RandomIO.implNextBytes(NativePRNG.java:534)
            at 
sun.security.provider.NativePRNG$RandomIO.access$400(NativePRNG.java:331)
            at 
sun.security.provider.NativePRNG.engineNextBytes(NativePRNG.java:220)
            at java.security.SecureRandom.nextBytes(SecureRandom.java:468)
            at java.util.UUID.randomUUID(UUID.java:145)
            at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:555)
            at 
org.apache.doris.qe.MysqlConnectProcessor.handleExecute(MysqlConnectProcessor.java:246)
            at 
org.apache.doris.qe.MysqlConnectProcessor.handleExecute(MysqlConnectProcessor.java:294)
    ```
    In high‑concurrency point‑query scenarios, a large number of requests
    require generating a UUID for internal identification. When the request
    rate is high, frequent calls to `UUID.randomUUID()` can introduce
    contention and become a minor performance bottleneck.
    
    For query, the UUID is only required to provide a unique identifier for
    request correlation, and cryptographic strength is not necessary. To
    reduce contention and improve throughput, this change introduces
    `fastUniqueId`, which generates RFC‑4122 compatible UUID v4 values using
    `ThreadLocalRandom`.
    
    By using a per‑thread random generator instead of the shared random
    source used by `UUID.randomUUID()`, UUID generation scales better under
    high concurrency while still preserving the standard UUID format.
---
 .../apache/doris/common/util/UniqueIdUtils.java    | 75 ++++++++++++++++++++++
 .../java/org/apache/doris/qe/StmtExecutor.java     | 16 ++---
 .../apache/doris/foundation/util/UUIDUtils.java    | 53 +++++++++++++++
 3 files changed, 133 insertions(+), 11 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/util/UniqueIdUtils.java 
b/fe/fe-core/src/main/java/org/apache/doris/common/util/UniqueIdUtils.java
new file mode 100644
index 00000000000..7160dcb6db2
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/UniqueIdUtils.java
@@ -0,0 +1,75 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.common.util;
+
+import org.apache.doris.thrift.TUniqueId;
+
+import java.security.SecureRandom;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class UniqueIdUtils {
+
+    private static class Holder {
+        static final SecureRandom numberGenerator = new SecureRandom();
+    }
+
+    /**
+     * Generates a random RFC‑4122 version 4 UUID using {@link 
java.util.concurrent.ThreadLocalRandom}.
+     *
+     * <p>This implementation avoids the shared random source used by
+     * {@link java.util.UUID#randomUUID()}, reducing contention in 
high‑concurrency
+     * environments and improving throughput.</p>
+     *
+     * <p><b>Trade‑off:</b> {@code ThreadLocalRandom} is not cryptographically 
secure.
+     * It should be used for high‑throughput identifiers (e.g. request or 
trace IDs),
+     * not for security‑sensitive tokens.</p>
+     */
+    public static TUniqueId fastUniqueId() {
+        final Random ng = ThreadLocalRandom.current();
+        long mostSigBits = ng.nextLong();
+        long leastSigBits = ng.nextLong();
+        // format to uuid v4
+        mostSigBits &= 0xFFFFFFFFFFFF0FFFL;
+        mostSigBits |= 0x0000000000004000L;
+        leastSigBits &= 0x3FFFFFFFFFFFFFFFL;
+        leastSigBits |= 0x8000000000000000L;
+        return new TUniqueId(mostSigBits, leastSigBits);
+    }
+
+    public static TUniqueId randomUniqueId() {
+        // copy from java.util.UUID.randomUUID
+        final SecureRandom ng = Holder.numberGenerator;
+        byte[] data = new byte[16];
+        ng.nextBytes(data);
+        data[6] &= 0x0f;  /* clear version        */
+        data[6] |= 0x40;  /* set to version 4     */
+        data[8] &= 0x3f;  /* clear variant        */
+        data[8] |= 0x80;  /* set to IETF variant  */
+        long msb = 0;
+        long lsb = 0;
+        for (int i = 0; i < 8; i++) {
+            msb = (msb << 8) | (data[i] & 0xff);
+        }
+        for (int i = 8; i < 16; i++) {
+            lsb = (lsb << 8) | (data[i] & 0xff);
+        }
+        return new TUniqueId(msb, lsb);
+    }
+
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
index c5dc61d15f5..11d633a5644 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
@@ -62,6 +62,7 @@ import org.apache.doris.common.util.DebugPointUtil.DebugPoint;
 import org.apache.doris.common.util.DebugUtil;
 import org.apache.doris.common.util.NetUtils;
 import org.apache.doris.common.util.TimeUtils;
+import org.apache.doris.common.util.UniqueIdUtils;
 import org.apache.doris.common.util.Util;
 import org.apache.doris.datasource.FileScanNode;
 import org.apache.doris.datasource.tvf.source.TVFScanNode;
@@ -166,7 +167,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.UUID;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.regex.Matcher;
@@ -561,8 +561,7 @@ public class StmtExecutor {
 
     // query with a random sql
     public void execute() throws Exception {
-        UUID uuid = UUID.randomUUID();
-        TUniqueId queryId = new TUniqueId(uuid.getMostSignificantBits(), 
uuid.getLeastSignificantBits());
+        TUniqueId queryId = UniqueIdUtils.fastUniqueId();
         if (Config.enable_print_request_before_execution) {
             LOG.info("begin to execute query {} {}",
                     DebugUtil.printId(queryId), originStmt == null ? "null" : 
originStmt.originStmt);
@@ -572,7 +571,6 @@ public class StmtExecutor {
 
     public void queryRetry(TUniqueId queryId) throws Exception {
         TUniqueId firstQueryId = queryId;
-        UUID uuid;
         int retryTime = Config.max_query_retry_time;
         retryTime = retryTime <= 0 ? 1 : retryTime + 1;
         // If the query is an `outfile` statement,
@@ -595,8 +593,7 @@ public class StmtExecutor {
                     throw e;
                 }
                 TUniqueId lastQueryId = queryId;
-                uuid = UUID.randomUUID();
-                queryId = new TUniqueId(uuid.getMostSignificantBits(), 
uuid.getLeastSignificantBits());
+                queryId = UniqueIdUtils.fastUniqueId();
                 int randomMillis = 10 + (int) (Math.random() * 10);
                 if (i > retryTime / 2) {
                     randomMillis = 20 + (int) (Math.random() * 10);
@@ -971,9 +968,7 @@ public class StmtExecutor {
             try {
                 // reset query id for each retry
                 if (i > 0) {
-                    UUID uuid = UUID.randomUUID();
-                    TUniqueId newQueryId = new 
TUniqueId(uuid.getMostSignificantBits(),
-                            uuid.getLeastSignificantBits());
+                    TUniqueId newQueryId = UniqueIdUtils.fastUniqueId();
                     AuditLog.getQueryAudit().log("Query {} {} times with new 
query id: {}",
                             DebugUtil.printId(queryId), i, 
DebugUtil.printId(newQueryId));
                     context.setQueryId(newQueryId);
@@ -2022,8 +2017,7 @@ public class StmtExecutor {
         if (LOG.isDebugEnabled()) {
             LOG.debug("INTERNAL QUERY: {}", originStmt.toString());
         }
-        UUID uuid = UUID.randomUUID();
-        TUniqueId queryId = new TUniqueId(uuid.getMostSignificantBits(), 
uuid.getLeastSignificantBits());
+        TUniqueId queryId = UniqueIdUtils.fastUniqueId();
         context.setQueryId(queryId);
         if (originStmt.originStmt != null) {
             context.setSqlHash(DigestUtils.md5Hex(originStmt.originStmt));
diff --git 
a/fe/fe-foundation/src/main/java/org/apache/doris/foundation/util/UUIDUtils.java
 
b/fe/fe-foundation/src/main/java/org/apache/doris/foundation/util/UUIDUtils.java
new file mode 100644
index 00000000000..0feff359ebc
--- /dev/null
+++ 
b/fe/fe-foundation/src/main/java/org/apache/doris/foundation/util/UUIDUtils.java
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.foundation.util;
+
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class UUIDUtils {
+
+    /**
+     * Generates a random RFC‑4122 version 4 UUID using {@link 
java.util.concurrent.ThreadLocalRandom}.
+     *
+     * <p>This implementation avoids the shared random source used by
+     * {@link java.util.UUID#randomUUID()}, reducing contention in 
high‑concurrency
+     * environments and improving throughput.</p>
+     *
+     * <p><b>Trade‑off:</b> {@code ThreadLocalRandom} is not cryptographically 
secure.
+     * It should be used for high‑throughput identifiers (e.g. request or 
trace IDs),
+     * not for security‑sensitive tokens.</p>
+     */
+    public static UUID fastUUID() {
+        final Random ng = ThreadLocalRandom.current();
+        long mostSigBits = ng.nextLong();
+        long leastSigBits = ng.nextLong();
+        // format to uuid v4
+        mostSigBits &= 0xFFFFFFFFFFFF0FFFL;
+        mostSigBits |= 0x0000000000004000L;
+        leastSigBits &= 0x3FFFFFFFFFFFFFFFL;
+        leastSigBits |= 0x8000000000000000L;
+
+        return new UUID(mostSigBits, leastSigBits);
+    }
+
+    public static UUID randomUUID() {
+        return UUID.randomUUID();
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to