O 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:
- Comparar com o último tempo de construção
- Quando o tempo de retorno de chamada é curto, pode bloquear a espera
- 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 从一个随机数开始。
随机范围选择,需要在以下几点取一个平衡:
- 随机范围太大:将会造成 sequence 浪费,并发降低
可通过调大 sequence 占用 bit 解决
- 太小:将会导致后续分库分表扩容后,数据又倾斜了
建议:取一个未来可能的最大分表数。
控制路由目标表
当分库分表数据已经发生倾斜不均匀了,该如何解决呢?
假设共有 4 个实例、分库为 16、分表数为 128,数据倾斜将造成第一个实例数据过多、性能降低。需要将后续数据落在其它实例上既不落在 0-31 表上,以降低第一个实例压力,待数据分布均匀后,再使用前面的算法。
基于 sequence 随机开始,有以下方案:
方案一
将 sequence 随机开始,递增后的值,执行一下路由算法,当其落在其它实例上时,才返回;否则继续递增。
优点:简单 缺点:id 生成器通常为中间件团队的服务,并且后续需要恢复之前的算法,修改麻烦
方案二
我们知道新的 sequence 要求:
- 与老 sequence 一一映射不会重复
- 与老 sequence 一样,单调递增
- 路由后落在指定的表里
为了讲解方便,我们假设分了 8 张表:0-7。需要使新的 sequence 落在 表 3-6 上。假设 x 轴为从 ID 服务器得到原始 sequence,则 y 可能的值分布如图所示:x、y 都从 0 开始
可以找到规律:y 为从0开始,第 x+1 个有效的值。
当路由运算后落在表3-6上,即为有效
在实现时,注意以下几点:
- 正确解析出原始 sequence,并用新 sequence 组装新的 ID
- 新 sequence 的最大值,不能大于其占用 bit 所位能代表的最大值
当超过时,可等待后取下一个时间的 sequence
- 由于新老 sequence 是一一映射,所以可以提前缓存结果,避免 cpu 消耗
以上两种方案都有一个影响:会浪费更多的 sequence,使最大并发降低,使用时请结合实际情况。
总结
本文介绍了雪花算法原理及其在使用过程中可能出现的问题和解法。如果你在使用中有碰到其它问题或者有更好的解法,请评论留言吧!
推荐阅读
招贤纳士
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