Explicação detalhada do algoritmo do floco de neve

Equipe técnica Zhengcaiyun.png

Endless.pngO algoritmo Snowflake é um algoritmo de geração de ID distribuído globalmente exclusivo usado internamente pelo Twitter e é de código aberto. Este artigo apresenta o princípio do algoritmo e alguns problemas e soluções de uso prático.

Princípio do algoritmo

O algoritmo floco de neve gera um ID do tipo Long, que ocupa 64 bits. O algoritmo divide os bits nas seguintes partes:

bit de sinal carimbo de data/hora ID da máquina seqüência
Ocupar 1 bit 41 bits 10 bits 12 bits

Bit de sinal: geralmente 0, representando um número positivo

Timestamp: O número de milissegundos, não um timestamp diretamente de 1970, mas representa o tempo utilizável (tempo atual menos o início do uso), aproximadamente 2^41 milissegundos ou cerca de 69 anos.

ID da máquina: os 5 dígitos superiores são a ID do data center e os 5 dígitos inferiores são a ID da máquina

sequência: um contador iniciando em 0 no mesmo milissegundo, o máximo 2^12 é 4096, quando ultrapassar 4096, ele bloqueará e aguardará o próximo milissegundo. Uma única máquina pode suportar cerca de 4 milhões de simultaneidade por segundo.

A implementação do algoritmo é relativamente simples e o código não será postado neste artigo. O ponto é garantir que o ID da máquina seja único, o que pode ser obtido por meio de configuração, banco de dados, redis, zk, etc.

problema e solução

Em cenários de uso real, o algoritmo original pode encontrar os seguintes problemas:

relógio de volta

Os retornos de chamada do relógio podem gerar IDs duplicados, que podem ser resolvidos por:

  1. Comparar com o último tempo de construção
  2. Quando o tempo de retorno de chamada é curto, pode bloquear a espera
  3. Caso contrário, você pode obter um novo ID de máquina novamente

Este esquema pode fazer com que o ID da máquina seja consumido muito rápido, e o timestamp e os bits ocupados da sequência possam ser ajustados. Mas não se preocupe muito, o ID da máquina também pode ser reutilizado, desde que não seja repetido em uso.

Precisão JS de front-end

JS tem inteiros de 32 bits integrados e inteiros seguros do tipo número são de 53 bits. Se mais de 53 bits forem excedidos, a precisão será perdida. Quando se trata do algoritmo do floco de neve, apenas 2^31 milissegundos podem ser usados ​​por cerca de 24 dias para representá-lo corretamente.

Solução: Ajuste o timestamp para segundos: você pode usar 2^31 segundos por cerca de 68 anos. Neste momento, a simultaneidade de máquina única é 4096. Se não for suficiente, você pode reduzir adequadamente o número de bits de identificação de máquina e aumentar o número de bits de sequência para aumentar a simultaneidade.

Sub-biblioteca e sub-tabela

分库分表通常采用取模算法,当路由字段使用了雪花算法时,会有什么问题呢?

数据分布不均匀

在同一时间内,sequence 自增永远从 0 开始。当分库分表采用取模算法时,会导致生成的 ID 一直落在前面的库、表里,造成数据倾斜,影响性能。此种现象在单位时间(毫秒、秒)并发低、或分表较多的场景下尤为突出。

解决方案:sequence 从一个随机数开始。

随机范围选择,需要在以下几点取一个平衡:

  1. 随机范围太大:将会造成 sequence 浪费,并发降低

可通过调大 sequence 占用 bit 解决

  1. 太小:将会导致后续分库分表扩容后,数据又倾斜了

建议:取一个未来可能的最大分表数。

控制路由目标表

当分库分表数据已经发生倾斜不均匀了,该如何解决呢?

假设共有 4 个实例、分库为 16、分表数为 128,数据倾斜将造成第一个实例数据过多、性能降低。需要将后续数据落在其它实例上既不落在 0-31 表上,以降低第一个实例压力,待数据分布均匀后,再使用前面的算法

基于 sequence 随机开始,有以下方案:

方案一

将 sequence 随机开始,递增后的值,执行一下路由算法,当其落在其它实例上时,才返回;否则继续递增。

优点:简单 缺点:id 生成器通常为中间件团队的服务,并且后续需要恢复之前的算法,修改麻烦

方案二

我们知道新的 sequence 要求:

  1. 与老 sequence 一一映射不会重复
  2. 与老 sequence 一样,单调递增
  3. 路由后落在指定的表里

为了讲解方便,我们假设分了 8 张表:0-7。需要使新的 sequence 落在 表 3-6 上。假设 x 轴为从 ID 服务器得到原始 sequence,则 y 可能的值分布如图所示:x、y 都从 0 开始

imagem-20220529201359797

可以找到规律:y 为从0开始,第 x+1 个有效的值。

当路由运算后落在表3-6上,即为有效

在实现时,注意以下几点:

  1. 正确解析出原始 sequence,并用新 sequence 组装新的 ID
  2. 新 sequence 的最大值,不能大于其占用 bit 所位能代表的最大值

当超过时,可等待后取下一个时间的 sequence

  1. 由于新老 sequence 是一一映射,所以可以提前缓存结果,避免 cpu 消耗

以上两种方案都有一个影响:会浪费更多的 sequence,使最大并发降低,使用时请结合实际情况。

总结

本文介绍了雪花算法原理及其在使用过程中可能出现的问题和解法。如果你在使用中有碰到其它问题或者有更好的解法,请评论留言吧!

推荐阅读

基于流量域的数据全链路治理

一次接口响应时间过长的性能分析及排查过程

MySQL 之 innodb 自增锁原理实现

基于父子关系的高效去重算法

招贤纳士

Equipe técnica Zhengcaiyun (Zero), uma equipe cheia de paixão, criatividade e execução, a Base está localizada na pitoresca Hangzhou. Atualmente, a equipe tem mais de 300 parceiros de P&D, incluindo soldados "veteranos" de Ali, Huawei e NetEase, bem como recém-chegados da Universidade de Zhejiang, Universidade de Ciência e Tecnologia da China, Universidade Hangdian e outras escolas. Além do desenvolvimento diário de negócios, a equipe também realiza exploração e prática técnica nas áreas de nuvem nativa, blockchain, inteligência artificial, plataforma low-code, middleware, big data, sistema de materiais, plataforma de engenharia, experiência de desempenho, visualização, etc. E desembarcou uma série de produtos de tecnologia interna e continuou a explorar novos limites da tecnologia. Além disso, a equipe também se dedicou à construção de comunidades. Atualmente, eles contribuem para muitas comunidades excelentes de código aberto, como google flutter, scikit-learn, Apache Dubbo, Apache Rocketmq, Apache Pulsar, CNCF Dapr, Apache DolphinScheduler, alibaba Seata , etc Se você quer mudar, você foi jogado com coisas, e você quer começar a jogar coisas; se você quer mudar, lhe disseram que você precisa de mais ideias, mas você não pode quebrar o jogo; se você quer mudar mudar, você tem a capacidade de fazer isso, mas você não precisa de você, se você quer mudar o que você quer fazer, você precisa de uma equipe para apoiá-lo, mas não há lugar para você liderar as pessoas; se você quer mudar, você tem um bom entendimento, mas sempre fica aquela camada de papel embaçado... um eu melhor. Se você quiser participar do processo de decolar à medida que o negócio decola e promover pessoalmente o crescimento de uma equipe técnica com profundo conhecimento do negócio, um sistema técnico sólido, tecnologia que cria valor e influência de transbordamento, acho que devemos conversa. A qualquer momento, esperando você escrever algo, envie para  [email protected]

Conta pública do WeChat

O artigo é lançado simultaneamente, a conta pública da equipe técnica de Zhengcaiyun, bem-vindo a prestar atenção

政采云技术团队.png

Je suppose que tu aimes

Origine juejin.im/post/7114083293577871396
conseillé
Classement