En respuesta a las preguntas sobre rendimiento que a menudo surgen durante el uso, ofrezco los siguientes tres conjuntos de mejores prácticas:
❄ Si el requisito de generación de ID no supera los 5 W/s, no es necesario modificar ningún parámetro de configuración.
❄ Si supera los 5W piezas/s y es inferior a 50W piezas/s, se recomienda modificar: SeqBitLength=10
❄ Si supera los 50W bits/s y se acerca a los 500W bits/s, se recomienda modificar: SeqBitLength=12
En resumen, aumentar SeqBitLength dará como resultado un mejor rendimiento, pero los ID generados serán más largos.
❄ Este es un algoritmo de copo de nieve optimizado (deriva de copo de nieve), que genera identificaciones más cortas y rápidas.
❄ Admite la expansión automática de entornos de contenedores como k8s (registro automático de WorkerId) y puede generar una identificación digital única en un entorno independiente o distribuido.
❄ Admite de forma nativa C#/Java/Go/C/Rust/Python/Node.js/PHP (extensión C)/SQL/ y otros lenguajes, y proporciona llamadas dinámicas seguras a bibliotecas (FFI) multiproceso.
❄ Compatible con todos los algoritmos de copo de nieve (modo de segmento numérico o modo clásico, fabricantes grandes o pequeños), puede realizar cualquier actualización o cambio en el futuro.
❄ Esta es la herramienta de generación de ID de Snowflake más completa en la historia de la informática. 【A agosto de 2022】
? Como arquitecto, desea resolver el problema de las claves primarias únicas en una base de datos, especialmente en un sistema distribuido con múltiples bases de datos.
? Quiere que la clave principal de la tabla de datos utilice la menor cantidad de espacio de almacenamiento, indexe más rápido y seleccione, inserte y actualice más rápido.
? Debe considerar que al dividir bases de datos y tablas (fusionar bases de datos y tablas), el valor de la clave principal se puede usar directamente y puede reflejar el tiempo comercial.
Si dicho valor de clave principal es demasiado largo y excede el valor máximo del tipo de número js del front-end, el tipo largo debe convertirse al tipo de cadena y se sentirá un poco frustrado.
? Aunque Guid puede incrementarse automáticamente, ocupa mucho espacio y la velocidad de indexación es lenta. No desea utilizarlo.
Puede haber más de 50 instancias de aplicación y cada solicitud simultánea puede alcanzar los 10 W/s.
? Para implementar aplicaciones en un entorno de contenedor, admitir replicación horizontal y expansión automática.
¿No desea depender de la operación de incremento automático de redis para obtener ID de clave primaria continuas, porque las ID continuas plantean riesgos para la seguridad de los datos comerciales?
? Quiere que el sistema funcione durante más de 100 años.
La identificación generada es demasiado larga.
La cantidad de concurrencia instantánea no es suficiente.
El problema de la devolución de tiempo no se puede resolver.
No se admite la generación posterior al suplemento de ID de pedido anticipado.
Puede depender de sistemas de almacenamiento externos.
✔ Números enteros, que aumentan monótonamente con el tiempo (no necesariamente continuos), son más cortos y no excederán el valor máximo del tipo de número js en 50 años. (configuración predeterminada)
✔ Más rápido, de 2 a 5 veces más rápido que el algoritmo tradicional de copo de nieve, se pueden generar 500.000 en 0,1 segundos (basado en el i7 de bajo voltaje de octava generación).
✔ Soporte de procesamiento de devolución de llamada de tiempo. Por ejemplo, si la hora del servidor se retrasa 1 segundo, este algoritmo puede adaptarse automáticamente para generar una identificación única para el momento crítico.
✔Admite la inserción manual de nuevas identificaciones. Cuando la empresa necesita generar nuevas identificaciones en un tiempo histórico, los bits reservados de este algoritmo pueden generar 5000 identificaciones por segundo.
✔ No depende de ninguna base de datos o caché externa. (La biblioteca dinámica que registra automáticamente WorkerId en el entorno k8s se basa en redis)
✔ Funciones básicas, listas para usar de inmediato, no se requieren archivos de configuración, conexiones de bases de datos, etc.
(Parámetros: secuencia de aumento automático de 10 bits, 1000 valores máximos de deriva)
Solicitudes continuas | 5K | 5W | 50W |
---|---|---|---|
Algoritmo tradicional de copo de nieve | 0.0045s | 0,053s | 0,556s |
Algoritmo de deriva de nieve | 0.0015s | 0,012s | 0,113s |
? Máximo rendimiento: 500 W/s ~ 3000 W/s. (Todos los datos de prueba se calculan en base al i7 de bajo voltaje de octava generación)
Cuando se produce la devolución de la hora del sistema, el algoritmo utiliza el número de secuencia reservado de la serie de tiempo pasada para generar una nueva ID.
? El número de identificación generado por la devolución de llamada se coloca primero de forma predeterminada y también se puede ajustar para que aparezca más tarde.
? Permitir que el tiempo vuelva a la base preestablecida de este algoritmo (los parámetros son ajustables).
? El ID generado por este algoritmo es un número entero (ocupa hasta 8 bytes de espacio). El siguiente es el ID generado según la configuración predeterminada:
129053495681099 (运行1年,长度:15)
387750301904971 (运行3年,长度:15)
646093214093387 (运行5年,长度:15)
1292658282840139 (运行10年,长度:16)
9007199254740992 (运行70年,达到 js Number 最大值,长度:16)
165399880288699493 (运行1000年,等同普通雪花算法运行1年,长度:18)
El valor de ID generado por este algoritmo es del 1% al 10% del valor máximo de js Number, que es una milésima parte del valor del algoritmo de copo de nieve ordinario, pero la velocidad de generación es más rápida que la del algoritmo de copo de nieve ordinario.
? El valor máximo del tipo de número js: 9007199254740992. Este algoritmo puede tardar 70 años en alcanzar el valor máximo de número de js manteniendo el rendimiento de simultaneidad (5 W+/0,01 s) y un máximo de 64 WorkerIds (6 bits).
? 每增加 1位 WorkerIdBitLength 或 SeqBitLength,生成的ID数字值将会乘以2(基础长度可参考前一节“ID示例”),反之则除以2。
La explicación de cuánto tiempo se puede usar se refiere a cuándo el número de identificación generado puede crecer hasta exceder el valor máximo de largo (64 bits con signo, 8 bytes).
• En la configuración predeterminada, hay 71.000 ID únicos disponibles.
? Cuando se admiten 1024 nodos trabajadores, las identificaciones están disponibles durante 4480 años sin duplicación.
? Cuando se admiten 4096 nodos trabajadores, las identificaciones están disponibles durante 1120 años sin duplicación.
❄ WorkerIdBitLength , la longitud de bits del código de máquina, determina el valor máximo de WorkerId, el valor predeterminado es 6 y el rango de valores es [1, 19]. De hecho, algunos idiomas usan el tipo ushort sin firmar (uint16) para recibir. este parámetro, por lo que el valor máximo es 16. Si se utiliza un signo corto (int16), el valor máximo es 15.
❄ WorkerId , código de máquina, el parámetro más importante , sin valor predeterminado, debe ser globalmente único (o único dentro del mismo DataCenterId), debe configurarse mediante programación , la condición predeterminada (WorkerIdBitLength toma el valor predeterminado), el valor máximo es 63, el valor máximo teórico es 2 ^ WorkerIdBitLength -1 (los diferentes lenguajes de implementación pueden limitarse a 65535 o 32767, el principio es el mismo que el de la regla WorkerIdBitLength). No puede ser el mismo en diferentes máquinas o diferentes instancias de aplicación. Puede configurar este valor a través de la aplicación u obtener el valor llamando a un servicio externo. En respuesta a la necesidad de registrar automáticamente WorkerId, este algoritmo proporciona una implementación predeterminada: registrar automáticamente la biblioteca dinámica de WorkerId a través de redis; consulte "HerramientasAutoRegisterWorkerId" para obtener más detalles.
Nota especial : si un servidor implementa varios servicios independientes, debe especificar un WorkerId diferente para cada servicio.
❄ SeqBitLength , longitud de bits de secuencia, valor predeterminado 6 , rango de valores [3, 21] (se recomienda no menos de 4), determina la cantidad de ID generadas por milisegundo. Si el número de solicitudes por segundo no supera los 5W, simplemente mantenga el valor predeterminado de 6, si supera los 5W y no supera los 50W, se recomienda asignar un valor de 10 o más, y así sucesivamente. Requisito de regla: WorkerIdBitLength + SeqBitLength no supera 22.
❄ MinSeqNumber , número de secuencia mínimo, valor predeterminado 5, rango de valores [5, MaxSeqNumber], los primeros 5 números de secuencia por milisegundo corresponden a los números 0-4 son bits reservados, de los cuales 1-4 son bits reservados correspondientes a la devolución de llamada de tiempo, 0 Es un bit reservado para nuevos valores manuales.
❄ MaxSeqNumber , el número de secuencia máximo, el rango de configuración es [MinSeqNumber, 2^SeqBitLength-1], el valor predeterminado es 0, el número de secuencia máximo real es el valor máximo (2^SeqBitLength-1), si no es 0 , es el número de secuencia máximo real, generalmente no es necesario configurarlo, a menos que varias máquinas compartan el WorkerId para generar ID en segmentos (en este caso, el número de secuencia mínimo debe configurarse correctamente).
❄ BaseTime , tiempo base (también conocido como: tiempo de punto base, tiempo de origen, tiempo de época), tiene un valor predeterminado (2020), es una marca de tiempo de milisegundos (un número entero, .NET es un tipo DatetTime), su función es: usar al generar ID La diferencia (en milisegundos) entre la hora del sistema y la hora base se utiliza como marca de tiempo para generar la ID. Generalmente no es necesario establecer el tiempo base. Si cree que el valor predeterminado es demasiado antiguo, puede restablecerlo. Sin embargo, tenga en cuenta que es mejor no cambiar este valor en el futuro.
La segunda versión planea agregar parámetros:
❄ DataCenterId , ID del centro de datos (ID de la sala de computadoras, valor predeterminado 0), asegúrese de que sea globalmente único.
❄ DataCenterIdBitLength , longitud del ID del centro de datos (predeterminado 0).
❄ TimestampType , tipo de marca de tiempo (0 milisegundos, 1 segundo), valor predeterminado 0.
1️⃣ Llame en modo singleton. Este algoritmo utiliza un único hilo para generar ID y las llamadas de varias partes serán mutuamente excluyentes. Dentro de la misma instancia de la aplicación, la persona que llama utiliza subprocesos múltiples (o paralelo) para llamar a este algoritmo, lo que no aumentará la velocidad de salida de ID.
2️⃣ Especifique un WorkerId único. El sistema externo debe garantizar la unicidad global de WorkerId y asignarlo al parámetro de entrada de este algoritmo.
3️⃣ Utilice diferentes WorkerIds al implementar varias instancias en una sola máquina. No todas las implementaciones admiten la unicidad simultánea entre procesos. Para estar seguro, al implementar varias instancias de aplicaciones en el mismo host, asegúrese de que cada WorkerId sea único.
4️⃣ Manejo de excepciones. El algoritmo generará todas las excepciones y el sistema externo debería detectarlas y manejarlas bien para evitar provocar una caída mayor del sistema.
5️⃣ Comprenda detenidamente la definición de IdGeneratorOptions, que será útil para integrar y utilizar este algoritmo.
6️⃣ Utilice el algoritmo de deriva de nieve. Aunque el código contiene la definición del algoritmo tradicional de copo de nieve y puede especificar (Método = 2) en el punto de entrada para habilitar el algoritmo tradicional, se recomienda utilizar el algoritmo de deriva de copo de nieve (Método = 1, el valor predeterminado). Después de todo, tiene mejor capacidad de estiramiento y mayor rendimiento.
7️⃣ No modifiques el algoritmo central. Este algoritmo tiene muchos parámetros internos y una lógica compleja. Si no domina la lógica central, no modifique el código central ni lo utilice en un entorno de producción a menos que haya sido verificado mediante una gran cantidad de pruebas científicas y meticulosas.
8️⃣ Las políticas de configuración dentro del dominio de la aplicación son las mismas. Cuando el sistema ha estado ejecutándose durante un período de tiempo y el proyecto necesita pasar de especificar WorkerId mediante programación a registrar WorkerId automáticamente, asegúrese de que todas las instancias en uso en el mismo dominio de aplicación adopten una estrategia de configuración consistente. Esto no es solo para WorkerId. , pero también incluye otros parámetros de configuración.
9️⃣ Gestiona bien el tiempo del servidor. El algoritmo Snowflake se basa en la hora del sistema. No ajuste manualmente la hora del sistema operativo en gran medida. Si debe realizar ajustes, recuerde asegurarse de que la hora del sistema cuando se reinicie el servicio sea mayor que la hora de la última vez que se cerró. (Nota: Los pequeños cambios en la hora del sistema causados por la sincronización de hora o la devolución de llamada de clase mundial o a nivel de red no tienen ningún impacto en este algoritmo)
Los cambios de configuración se refieren al ajuste de los parámetros operativos (propiedades del objeto IdGeneratorOptions) después de que el sistema haya estado funcionando durante un período de tiempo.
1. El primer principio es: BaseTime solo puede ser más antiguo (más alejado del presente), de modo que el valor de ID generado sea mayor que el valor máximo histórico, lo que garantiza que no haya superposición de tiempo ni se generen ID duplicados. [ No se recomienda ajustar BaseTime después de que el sistema esté en ejecución]
2. Se permite aumentar WorkerIdBitLength o SeqBitLength en cualquier momento, pero la operación de "disminución" debe usarse con precaución, porque esto puede causar que la ID generada en el futuro sea la misma que la configuración anterior. [Permitir que se aumente cualquier valor de xxxBitLength después de que el sistema esté en ejecución]
3. Si se debe reducir uno de WorkerIdBitLength o SeqBitLength, se debe cumplir la condición: la suma de los dos nuevos xxxBitLength debe ser mayor que la suma de los valores anteriores. [ No se recomienda reducir cualquier valor de BitLength después de la ejecución]
4. Las tres reglas anteriores no están controladas lógicamente en este algoritmo. Los usuarios deben realizar cambios de configuración después de confirmar que la nueva configuración cumple con los requisitos.
El generador de ID único se basa en WorkerId. Cuando los servicios empresariales requieren replicación horizontal e indiscriminada (expansión automática), esto requiere la capacidad de registrar automáticamente un WorkerId globalmente único antes de generar un ID único.
Este algoritmo proporciona una biblioteca dinámica de código abierto (implementada en lenguaje Go), que puede registrar automáticamente WorkerId a través de redis en entornos de contenedores como k8s.
Registrar WorkerId a través de redis no es la única forma. También puede desarrollar un servicio de configuración centralizado. Cuando se inicia cada servicio de punto final, el WorkerId único se obtiene a través del servicio central.
Por supuesto, si su servicio no necesita expandirse automáticamente, no necesita registrar WorkerId automáticamente, sino establecer valores únicos globalmente para ellos.
Existen muchos métodos, como desarrollar un servicio de generación de ID centralizado que genere ID utilizables para cada servicio de punto final (individual o por lotes).
Enlace de imagen: https://github.com/yitter/IdGenerator/blob/master/Tools/AutoRegisterWorkerId/regprocess.jpg
Ruta del código fuente:/Go/source/regworkerid/reghelper.go
Enlace de descarga: https://github.com/yitter/IdGenerator/releases/download/v1.3.3/workeridgo_lib_v1.3.3.zip
// 注册一个 WorkerId,会先注销所有本机已注册的记录
// address: Redis连接地址,单机模式示例:127.0.0.1:6379,哨兵/集群模式示例:127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库,示例:1
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster,非哨兵模式传入空字符串即可
// minWorkerId: WorkerId 最小值,示例:30
// maxWorkerId: WorkerId 最大值,示例:63
// lifeTimeSeconds: WorkerId缓存时长(秒,3的倍数),推荐值15
extern GoInt32 RegisterOne(char* server, char* password, GoInt32 db, char* sentinelMasterName, GoInt32 minWorkerId, GoInt32 maxWorkerId, GoInt32 lifeTimeSeconds);
// 注销本机已注册的 WorkerId
extern void UnRegister();
idioma | github |
---|---|
?DO# | Ver ejemplo |
¿Java? | Ver ejemplo |
? Ir | Ver ejemplo |
? Óxido | Ver ejemplo |
?Pitón | Ver ejemplo |
?DO | Ver ejemplo |
? C (extensión PHP) | Ver ejemplo |
? Delfos (Pascal) | Ver ejemplo |
? | Ver ejemplo |
?Mecanografiado | Ver ejemplo |
?v | Ver ejemplo |
?D | Ver ejemplo |
Dirección de código abierto: https://github.com/yitter/IdGenerator
Grupo QQ: 646049993