Distribuido ID generación - algoritmo de nieve

El ID único puede ser datos de identificación única para generar un identificador único en un soluciones de sistemas distribuidos Hay muchas maneras comunes sobre las tres formas siguientes:

  • base de datos de dependencia, tal como Oracle o MySQL a partir de secuencias adicionales, etc.
  • de números aleatorios UUID
  • copo de nieve copo de nieve algoritmo

En primer lugar, las deficiencias de los programas de bases de datos y UUID

El uso de una secuencia de incremento de la base de datos:

  • Cuando lectura y escritura por separado, sólo el nodo maestro se puede escribir, puede haber el riesgo de punto único de fallo
  • Sub-mesa y almacenes, migración de datos, consolidación y tantos problemas

UUID de números aleatorios:

  • El uso de la cadena sin sentido, no ordenados
  • cadena UUID almacena, cuando la cantidad de eficiencia de la consulta de datos es relativamente baja

En segundo lugar, en el algoritmo de la nieve

Hay un dicho que la naturaleza no existen dos copos de nieve idénticos. Cada copo de nieve tiene su propia forma única hermosa y única. Snow también dijo que el algoritmo genera identificador único como copos de nieve.

1. La estructura composición

 Generalmente comprende: primero carácter no válido, diferencia marca de tiempo en cuatro partes, la máquina (proceso) que codifica SEQ ID NO composición

2. Características (incremento, ordenado y adecuado para escenarios distribuidos)

  • posición de tiempo: puede ser clasificada según el tiempo y ayudan a acelerar la búsqueda
  • máquina poco Id: se aplicará a cada nodo de un entorno distribuido de identificador multi-nodo puede ser diseñado específicamente para dividir la longitud de la máquina 10 de acuerdo con los nodos de bit y el despliegue, de manera que la división proceso de cinco bits, etc.
  • SEC ID bit: es una serie de auto-energizar ID, el mismo nodo puede soportar el mismo número de milisegundos para generar una pluralidad de ID, 12-bit contador de número de secuencia para cada nodo de soporte genera un número de identificación cada 4096 ms

algoritmo de copo de nieve puede ser modificado de acuerdo a ciertos proyectos, así como sus necesidades.

En tercer lugar, las deficiencias de la nieve algoritmo

algoritmos de nieve en un identificador de sistema autónomo está aumentando, pero en el caso del sistema de múltiples nodos distribuidos, el reloj no garantiza que todos los nodos no están perfectamente sincronizados, es posible que esto no aparecerá un incremento global.

En cuarto lugar, el código que implementa el algoritmo de nieve

Paquete com.lw.coodytest.snawflake; 

/ ** 
 * @Classname SnakeFlake 
 * @description en Twitter distribuye algoritmo de nieve auto-energizante Identificación del copo de nieve (Java) 
 del copo de nieve siguiente estructura * (con cada sección - aparte): <br> 
 * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 0000000000 - 000000000000 <br> 
 * 1 bit identificador, como los tipos a largo básicos se firman en Java, el bit más significativo es el bit de signo, 0 es un número positivo, un número negativo es 1, por lo general Identificación es un número positivo, el bit más significativo se <br> 0 
 * 41 tiempo de corte (milisegundos), se observa que 41 veces la sección transversal de corte de almacenamiento de tiempo de la hora actual, pero la diferencia entre el tiempo de almacenamiento truncado (de corte la hora actual - la hora de inicio de corte ) 
 * valor obtenido), donde el tiempo de inicio de un truncado, en general, el tiempo de empezar a usar el generador de identificación, designado por nuestro programa (después de clase IdWorker programa de atributos horaInicio abajo). 
 * 41 tiempo de corte se puede utilizar 69 años, en = T (1 l << 41 es) / (1000L * 60 * 60 * 24 * 365) = 69 <br> 
 * máquina de bits de datos de 10 bits puede ser desplegado en 1024 los nodos, y que incluye 5 datacenterId <br> 5 workerId 
 * 12 cuenta de secuencia en cuestión de milisegundos, 12 contar el número de secuencia de cada nodo de soporte (la misma máquina, el mismo corte de tiempo) para producir el número de ID 4096 por milisegundo < br> 
 * Ascienden a apenas 64 para un tipo Long. <br>
 * Ventaja del copo de nieve es que el incremento general en el orden del tiempo, y no generan colisiones ID (a diferencia de los centros de datos ID y el ID de la máquina) en todo el sistema distribuido, y alta eficiencia, 
 * a prueba, por segundo puede ser del copo de nieve producir aproximadamente 260.000 ID. 
 @Author LW * 
 * @date 17/03/2020 14:21 
 * / 
público  de clase SnowflakeIdWorker { 

    / ** 
     * Hora de inicio del corte 
     * / 
    privada  estática  final  largo twepoch = 1420041600000L ; 

    / ** 
     * número de bits ocupada por el ID de la máquina 
     * / 
    privada  estática  finales  largas workerIdBits = 5L ; 

    / ** 
     * Identificación identificar los bits de datos ocupados 
     * / 
    privada  estáticas  final  largas datacenterIdBits = 5L ; 

    / **
     * Soporte para una máxima ID de la máquina, el resultado es 31 (este algoritmo cambio puede calcular rápidamente el número máximo de varias número binario decimal puede representar) 
     * / 
    privada  estáticas  finales  largo maxWorkerId 1L = ^ (1L << workerIdBits ); 

    / ** 
     * la máxima identificación de los datos de identificación, como resultado 31 se 
     * / 
    privada  estática  final  largo maxDatacenterId -1L = ^ (-1L << datacenterIdBits); 

    / ** 
     * ocupada en la mediana de la secuencia ID 
     * / 
    privada  estáticas  finales  largas sequenceBits = 12L ; 

    / ** 
     * ID de máquina 12 a la izquierda 
     * / 
    privada  estática  final  largo workerIdShift = sequenceBits; 

    / **
     * Datos de identificación ID a la dada por 17 (+ 12 es 5.) 
     * / 
    Privada  estática  final  largo datacenterIdShift + = sequenceBits workerIdBits; 

    / ** 
     * tiempo de cortar la izquierda 22 (5 + + 12 es 5.). 
     * / 
    Privada  estática  final  largo workerIdBits + + = sequenceBits timestampLeftShift datacenterIdBits; 

    / ** 
     * generar una secuencia de máscara, aquí 4.095 (0b111111111111 = 0xFFF = 4,095) 
     * / 
    privada  estática  final  largo sequenceMask -1L = ^ (-1L << sequenceBits); 

    / ** 
     * trabajo de la máquina ID (0 ~ 31) 
     * / 
    privada  a largo workerId; 

    / ** 
     * centro de datos ID (0 ~ 31)
     * / 
    Privada  largo datacenterId; 

    / ** 
     * milisegundos secuencia (0 ~ 4095) 
     * / 
    privada  largo Secuencia = 0L ; 

    / ** 
     * El tiempo de corte generado previamente ID 
     * / 
    privada  largo LastTimestamp = -1L ; 

    / ** 
     * constructor 
     * 
     * @ param workerId ID de trabajo (~ 31 es 0) 
     * @param datacenterId centro de datos de identificación (~ 31 es 0)
      * / 
    público SnowflakeIdWorker ( largo workerId, largo datacenterId) {
         SI (workerId> maxWorkerId || workerId <0 ) {
            lanzar  nuevo IllegalArgumentException (String.Format ( "trabajador Id puede no ser mayor que% d o menor que 0" , maxWorkerId)); 
        } 
        Si (datacenterId> maxDatacenterId || datacenterId <0 ) {
             lanzar  nuevo IllegalArgumentException (String.Format ( "centro de datos Id puede no ser mayor que% d o menor que 0" , maxDatacenterId)); 
        } 
        Esta .workerId = workerId;
        este .datacenterId = datacenterId; 
    } 

    / ** 
     *获得下一个ID (该方法是线程安全的) 
     * 
     * @return SnowflakeId
      * / 
    público la sincronizada  largo NextID () {
         larga timestamp = TimeGen (); 

        // si la hora actual es menor que la marca de tiempo de la ID de última generación, lo que indica el tiempo de retardo de envío de reloj del sistema debe ser lanzado a través de la 
        IF (timestamp < LastTimestamp) {
             de banda  nueva nuevo un RuntimeException ( 
                    String.Format ( "Clock desplazado hacia atrás ID por negarse a generar milisegundos% d.", LastTimestamp - timestamp)); 
        } 

        // si se genera al mismo tiempo, la secuencia se lleva a cabo en cuestión de milisegundos 
        IF (LastTimestamp == timestamp) { 
            secuencia = (. secuencia de + 1) y sequenceMask;
             // milisegundo secuencia de desbordamiento 
            IF (secuencia == 0) {
                 // el bloqueo de la siguiente milisegundo, obtener una nueva marca de tiempo 
                timestamp = tilNextMillis (LastTimestamp); 
            } 
        } 
        // tiempo de cambio de sello, el restablecimiento de secuencia milisegundos 
        la otra cosa { 
            Secuencia = 0L ; 
        } 

        // última vez que el ID generado corte 
        LastTimestamp = timestamp; 

        // cambio a la lucha y ORed juntos forman un ID de 64 bits 
        de retorno ((timestamp - twepoch) << timestampLeftShift)
                 | (datacenterId << datacenterIdShift)
                 | (workerId << workerIdShift)
                 | secuencia; 
    } 

    / **
     * El bloqueo de la siguiente milisegundo, hasta que una nueva marca de tiempo 
     * 
     * @param LastTimestamp última vez la generación de ID de sección 
     * @return actual marca de tiempo
      * / 
    protegida  largo tilNextMillis ( largo LastTimestamp) {
         larga timestamp = TimeGen ();
         el tiempo ( timestamp <= LastTimestamp) { 
            timestamp = TimeGen (); 
        } 
        retorno marca de tiempo; 
    } 

    / ** 
     * devuelve la hora actual en milisegundos 
     * 
     * @return hora actual (ms)
      * / 
    protegida  largoTimeGen () {
         regreso System.currentTimeMillis (); 
    } 

    Pública  estática  vacío main (String [] args) { 
        SnowflakeIdWorker idWorker = nueva SnowflakeIdWorker (0, 0 );
        para ( int i = 0; i <1,000; i ++ ) {
             largo id = idWorker.nextId (); 
            System.out.println (Long.toBinaryString (id)); 
            System.out.println (id); 
        } 
    } 
    
}

 

Supongo que te gusta

Origin www.cnblogs.com/lwcode6/p/12511125.html
Recomendado
Clasificación