分布式下的主键是怎么生成的

数据库演进之路提到了当数据库的压力瓶颈到了,我们可以采用分库分表来分担数据库的压力,分库分表的情况下,主键是怎么设置的?

数据库主键自增长

正常情况下,如果每个数据库都自增长,那就会出现多个数据库id重复的问题,比如下图所示,都出现了id为1,2,3的主键。
image.png
上面的主键生成用redis行不行?虽然redis速度比较快,但是没有实时持久化,可能造成主键的重复。比如此时为9,incr后变成10,然后挂了,此时还没持久化,再生成id的时候还是9,然后incr为10,就有两个id为10的数据。即便做了故障转移,由于是异步同步数据的,有可能数据还没到slave,master就挂了,此时id还是会重复。
除了数据库的压力,自增长的主键还可能泄露商业机密,别人很容易拆到下一个主键是什么。

UUID

才用数据库生成主键,数据库压力就很大,那可以采用应用来生成。比较简单的就是UUID,性能好,不重复。缺点就是不能保证递增,而且UUID字符串比较长,索引性能很差。

时间戳

以当前毫秒作为主键,优点就是简单、递增,缺点就是可能重复。比如当前毫秒同时有10个并发,此时就重复了。为了减少重复,降低到微秒级别,或者在时间戳后面加个随机字符串,依然有重复的风险。

snowflake

snowflake是twitter开源的分布式ID生成算法,生成64位的bit,第一位是0,保证id是正数。后面41位是当前时间戳的二进制形式,再后面10位机器码的二进制,最后12位是计数顺序号,记录同一毫秒内生成的数量。
image.png
如果觉得后面的12位不够,我们可以压缩前面机器码的位数,这样计数顺序号的值就可以更大了。
缺点也很明显,由于这个算法是依赖时间戳的,所以当系统的时间回拨的时候,就可能造成id的重复

你可能感兴趣的:(分布式)