You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by GitBox <gi...@apache.org> on 2022/04/18 09:21:00 UTC

[GitHub] [shardingsphere] destiny-z opened a new issue, #16896: /dangdang/ddframe/rdb/sharding/keygen/DefaultKeyGenerator generates the same sequence in the same timestamp

destiny-z opened a new issue, #16896:
URL: https://github.com/apache/shardingsphere/issues/16896

   we use the **shardingsphere/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/keygen/DefaultKeyGenerator.java** to generate key in the production environment, but we find it will generate the same sequence in the same timestamp in the same pod.
   ![image](https://user-images.githubusercontent.com/9402157/163785601-3f44dea8-dbc0-4f36-97e4-b3c78a733d02.png)
   Here is our KeyGenerator algorithm which is the same as dangdang. The only difference is that we modified the SEQUENCE_BITS and   WORKER_ID_BITS.
   Here is the code.
   ```
   @Slf4j
   public final class KeyGenerator implements ShardingKeyGenerator {
   
       public static final long EPOCH;
   
       private static final long SEQUENCE_BITS = 6L; //原来12位
   
       private static final long WORKER_ID_BITS = 6L; //原来4位
   
       private static final long SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1;
   
       private static final long WORKER_ID_LEFT_SHIFT_BITS = SEQUENCE_BITS;
   
       private static final long TIMESTAMP_LEFT_SHIFT_BITS = WORKER_ID_LEFT_SHIFT_BITS + WORKER_ID_BITS;
   
       private static final long WORKER_ID_MAX_VALUE = 1L << WORKER_ID_BITS;
   
       @Setter
       private static TimeService timeService = new TimeService();
   
       private static long workerId;
   
       private static final Object LOCK = new Object();
   
       private Properties properties = new Properties();
   
       static {
           Calendar calendar = Calendar.getInstance();
           calendar.set(2017, Calendar.NOVEMBER, 1);
           calendar.set(Calendar.HOUR_OF_DAY, 0);
           calendar.set(Calendar.MINUTE, 0);
           calendar.set(Calendar.SECOND, 0);
           calendar.set(Calendar.MILLISECOND, 0);
           EPOCH = calendar.getTimeInMillis();
   
           initWorkerId();
       }
   
       private long sequence;
   
       private long lastTime;
   
       /**
        * Set work process id.
        *
        * @param workerId work process id
        */
       public static void setWorkerId(final long workerId) {
           Preconditions.checkArgument(workerId >= 0L && workerId < WORKER_ID_MAX_VALUE);
           KeyGenerator.workerId = workerId;
       }
   
       static void initWorkerId() {
           // 用zk生成唯一的workId
       }
   
       /**
        * Generate key.
        *
        * @return key type is @{@link Long}.
        */
       @Override
       public Comparable<?> generateKey() {
   
           synchronized (LOCK) {
               long currentMillis = timeService.getCurrentMillis();
               Preconditions.checkState(lastTime <= currentMillis,
                       "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastTime,
                       currentMillis);
               if (lastTime == currentMillis) {
                   if (0L == (sequence = (sequence + 1) & SEQUENCE_MASK)) {
                       currentMillis = waitUntilNextTime(currentMillis);
                   }
               } else {
                   sequence = 0;
               }
               lastTime = currentMillis;
               Long key = ((currentMillis - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS)
                       | (workerId << WORKER_ID_LEFT_SHIFT_BITS)
                       | sequence;
               log.info("generate key[{}] with timestamp:{}, workerId:{}, sequence:{}", key, currentMillis, workerId, sequence);
               return key;
           }
       }
   
       private long waitUntilNextTime(final long lastTime) {
           long time = timeService.getCurrentMillis();
           while (time <= lastTime) {
               time = timeService.getCurrentMillis();
           }
           return time;
       }
   }
   ```
   My concurrency is not large, but sometimes a key conflict occurs, two threads generated the same key.
   How can I fix this problem?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [shardingsphere] destiny-z closed issue #16896: /dangdang/ddframe/rdb/sharding/keygen/DefaultKeyGenerator generates the same sequence in the same timestamp

Posted by GitBox <gi...@apache.org>.
destiny-z closed issue #16896: /dangdang/ddframe/rdb/sharding/keygen/DefaultKeyGenerator generates the same sequence in the same timestamp
URL: https://github.com/apache/shardingsphere/issues/16896


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [shardingsphere] zjcnb commented on issue #16896: /dangdang/ddframe/rdb/sharding/keygen/DefaultKeyGenerator generates the same sequence in the same timestamp

Posted by GitBox <gi...@apache.org>.
zjcnb commented on issue #16896:
URL: https://github.com/apache/shardingsphere/issues/16896#issuecomment-1102454518

   @destiny-z Hello, Can you try it again with` 5.1.1` version? I think you used version are too old.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org