转载

Spring Cloud Alibaba-UUID(二十一)

分布式系统中我们往往需要进行分库分表,提升性能,这时候我们就会需要一个高性能的全局唯一Id生成器,又称发号器。

常见的发号器

UUID

UUID由MAC地址、时间戳、命名空间、随机/伪随机数、时序等元素构成,JAVA自带,使用简单,同样的,它的缺点也非常的明显。

无序的Id对性能的影响

MySQL tries to leave space so that future inserts do not incur un-necessary page splits (and thus higher IO cost). In an "ideal" world, MySQL tries to keep the index pages at 15/16-th full, but depending on insert order, this fill factor can be as low as 1/2

大部分情况下,我们使用的数据库都是mysql,使用的mysql索引都是InnoDB,而InnoDB是主键构成的B+Tree(每个节点携带数据),所以乱序插入时Innodb需要不停的申请新的page,并且进行tree的重新分布,导致插入速度变慢,查询也有约10%的性能损失和40~50%的空间浪费。

数据库自增

利用数据库的自增,我们也可以方便的进行唯一Id生成,简单方便,但是问题也很明显,首先我插入了一条数据,还要再查询一次才可以知道id,其次简单的自增很容易引发漏洞。如果我们把它作为全局唯一ID的话,在分库分表的情况下,还需要一个专门的数据库表自增(类似redis),查出id,然后在分库分表,性能很差。

Redis

利用incr我们可以很容易的实现id自增且redis是原子性的,不会重号。问题的还是引入了组件,id的生成复杂度提高。

Zookeeper

Zookeeper的话通过带有编号的节点也可以实现全局唯一id的生产,但是使用的比较少,同样的,引入了组件,提高了系统复杂度。

雪花算法

SnowFlake算法生成64位的二进制正整数,然后转换成10进制的数,性能很高,不依赖组件,性能好,适合生产使用。

原文  https://juejin.im/post/5db69183e51d452a3c6ca514
正文到此结束
Loading...