分库设计中的主键选择

分库设计中的主键选择

ID:28193968

大小:76.12 KB

页数:3页

时间:2018-12-08

分库设计中的主键选择_第1页
分库设计中的主键选择_第2页
分库设计中的主键选择_第3页
资源描述:

《分库设计中的主键选择》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

1、分库设计中的主键选择在先前的文章《又拍网架构中的分库设计》屮,我有提到过MySQL分库设计中的主键选择问题。在这篇文章里我想对这个问题进行展开讨论,以此作为对上一篇文章的一个补充。前面提到又拍网采用了全局唯一的字段作为主键。比如拿照片表为例,虽然不同用户的照片数据存放在不同的Shard(或者说MySQL节点/实例,请参考《又拍M架构中的分库设计》)上,但是每一张照片拥有整个站点唯一的ID作为标示。为什么要全局唯一?我们在对数据库集群作扩容吋,为了保证负载的平衡,需要在不同的Shard之间进行数据的移动,如果主键不唯一,我们就没办法这样随意的移动数据。起初,

2、我们考虑采用组合主键來解决这个W题。一般会以user_id和一个自增的photo_id來作为主键,这的确能解决移动数据可能带来的主键冲突问题,但是就像在“又拍网架构中的分库设计”中描述的那样当Shard之间的数据发生关系后,我们需要用更多的字段来组成主键以保证唯一性,因此主键的索引会变的很大,从而影响查询性能,同吋也会影响写入性能。其次,每个Shard由两台MySQL服务器组成,而这两台服务器采用master-master的复制方式,以保证每个Shard—直可写。master-master复制方式必须保证在两台服务器上各自插入的数据有不同的主键,不然当复制

3、到另外一台吋就会出现主键重复错误。如果我们保证主键全局唯一,就自然的解决了这个问题。在没有采用数据拆分的设计当中,如果要用自增字段,可以参考这篇文章里的解决办法。可能的解决方案»UUTD或许可以采用UUID作为主键,但是UUID好长的一串,放在URL里好难看啊,有木有?当然这个不是关键所在,更重要的原因还是性能。UUTD的生成没有顺序性,所以在写入时,需要随机更改索引的不同位置,这就耑要更多的10操作,如果索引太大而不能存放在内存中的话就更是如此。而UUID索引时,一个key耑要32个字节(当然如果采用二进制形式存储的话可以压缩到16个字节),因此整个索引

4、也会相对比较大。»MySQL自増字段在单个MySQL数据库的应川中一般设置一个自增的字段就可以了,而在水平分库的设计当巾,这种方法显然不能保证全局唯一。那么我们可以单独建立一个库用來生成ID,在Shard中的每张表在这个TD库中都有一个对应的表,而这个对应的表只有一个卞•段,这个卞段是自增的。当我们需要插入新的数据,我们首先在ID库中的相应表中插入一条记录,以此得到一个新的ID,然后将这个TD作为插入到Shard巾的数据的主键。这个方法的缺点就是耑要额外的插入操作,如果ID库变的很大,性能也会随之降低。所以一定要保证TD库的数据集不要太大,一个办法是定期清

5、理前面的记录。引入其它工具Redis、Memcached等都支持原子性的increment操作,而且因为它们的优秀性能以减少写入时的额外开销,也许我们W以拿它们当作序列生成器。Memcached的问题在于不持久性,所以我们不会考虑。而Redis也不是实时持久的,当然也可以配置成实时的,但那样怪係的。当然也有一些持久的工具,比如KyotoCabinet、TokyoCabinet、MongoDB等等,传说中性能都不错,但是引入其它工具会增加架构的复杂程度,也会增加维护成本。我们的团队很小,精力有限,我们奉行够用就好的原则,也就是没有特别的原因,在W以接受的情况

6、下,尽量用我们熟悉的工具解决问题。所以,我们还是来考虑一下怎么样用MySQL来解决这个问题吧。更好的方案我们一开始就是采用了上而所描述的MySQL自增字段的方法,后来看到《TicketServers:DistributedUniquePrimaryKeysontheCheap》这篇文章里所描述的方法,豁然幵朗。我经常这样想:如果没有那些开源产品、没有那些无私分享经验的人,光凭我们自己的能力能做到什么程度。很感谢那些人,所以我也尽W:多的分享一些己的经验。我先描述一下Flickr那篇文章里所描述的方法,他们使用了REPLACEINTO这个MySQL的扩展功能

7、。REPLACEINTO和INSERT的功能一样,但是当使用REPLACEINTO插入新数据行时,如果新插入的行的主键或唯一键⑴N1QUEKey)已有的行重复时,已有的行会先被删除,然后再将新数据行插入。你可以放心,这是原子操作。建立类似下面的表:CREATETABLE'tickets64'('id'bigint(20)unsignedNOTNULLautoincrement,stub'char(1)NOTNULLdefault’’,PRIMARYKEY('id'),UNIQUEKEY'stub'('stub'))ENGTNE=MyISAM;当需要获得全局

8、唯一ID时,执行下面的SQL语句:REPLACEINTO'tick

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。