原文链接:http://www.javaarch.net/jiagoushi/709.htm
分布式唯一主键生成策略的一种开销比较小的方法
分布式场景下,经常需要做分库分表,master和master结构,那么此时就会用到全局的唯一主键id。
如果使用mysql的分区策略,master到master的复制,那么此时就需要保证分区的唯一性避免主键冲突。
我们可以使用mysql的自增列,但是mysql却无法保证物理和逻辑数据库的主键唯一性。
mysql5.6以上出现了GUID,但是GUID很大,而且如果需要建索引需要拿性能会比较差。这样对于某些查询只需要索引
或者需要利用索引来满足高并发下的性能的话,GUID会是一个性能瓶颈。
一致性哈希能够来解决GUID和分片问题,在多写少读下比较好,但是mysql确实用来优化为快速的随机读。
所以我们就就试试中心化一个数据库,将单独一个数据库作为自增列生成机器,mysql的replase into和INSERT ... ON DUPLICATE KEY UPDATE是来解决主键冲突的问题,当主键存在时,当前记录会替换更新旧记录
http://dev.mysql.com/doc/refman/5.0/en/replace.html和http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
比如创建64位的自增id:
CREATE TABLE `Tickets64` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`stub` char(1) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=MyISAM
SELECT * from Tickets64 输出:
+-------------------+------+
| id | stub |
+-------------------+------+
| 72157623227190423 | a |
+-------------------+------+
如果我需要一个全局的唯一的64位id,则执行:
REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
这里flickr使用两台数据库作为自增序列生成,但是这里怎么避免单点故障问题还没有有效的方案,只是通过这两台机器做主备和负载均衡。
TicketServer1:
auto-increment-increment = 2
auto-increment-offset = 1
TicketServer2:
auto-increment-increment = 2
auto-increment-offset = 2
原文请查看:http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/