达达的mysql数据库优化之路

https://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=2659597585&idx=1&sn=8479e3d3fc276c639ace540fceb7319e&scene=0#rd

MySQL读写分离的最大问题是主从数据同步延迟


MySQL主从延迟一个重要的原因之一是主从复制是单线程串行执行。 避免或解决mysql主从延迟:
优化MySQL参数,比如增大innodb_buffer_pool_size,让更多操作在MySQL内存中完成,减少磁盘操作。


使用高性能CPU主机。


数据库使用物理主机,避免使用虚拟云主机,提升IO性能。


使用SSD磁盘,提升IO性能。SSD的随机IO性能约是SATA硬盘的10倍。




垂直分库最大的挑战是:不能跨库join,同时需要对现有代码重构。单库时,可以简单的使用join关联表查询;拆库后,拆分后的数据库在不同的实例上,就不能跨库使用join


SQL最佳实践,其中一条便是程序中禁用或少用join,而应该在程序中组装数据,让SQL更简单。一方面为以后进一步垂直拆分业务做准备,另一方面也避免了MySQL中join的性能较低的问题。


业务代码优化,将实时性要求高的某些操作,使用主库做读操作。




Mysql单表数据量越来越大。如订单表, 单表记录数很快将过亿,超出MySQL的极限,影响读写性能。




水平分库面临的第一个问题是,按什么逻辑进行拆分。一种方案是按城市拆分,一个城市的所有数据在一个数据库中;另一种方案是按订单ID平均拆分数据。按城市拆分的优点是数据聚合度比较高,做聚合查询比较简单,实现也相对简单,缺点是数据分布不均匀,某些城市的数据量极大,产生热点,而这些热点以后可能还要被迫再次拆分。


按订单ID拆分则正相反,优点是数据分布均匀,不会出现一个数据库数据极大或极小的情况,缺点是数据太分散,不利于做聚合查询。比如,按订单ID拆分后,一个商家的订单可能分布在不同的数据库中,查询一个商家的所有订单,可能需要查询多个数据库。针对这种情况,一种解决方案是将需要聚合查询的数据做冗余表,冗余的表不做拆分,同时在业务开发过程中,减少聚合查询。




ID生成器是整个水平分库的核心,它决定了如何拆分数据,以及查询存储-检索数据。ID需要跨库全局唯一,否则会引发业务层的冲突。此外,ID必须是数字且升序,这主要是考虑到升序的ID能保证MySQL的性能。同时,ID生成器必须非常稳定,因为任何故障都会影响所有的数据库操作。

我们的ID的生成策略借鉴了Instagram的ID生成算法。具体方案如下:

  • 整个ID的二进制长度为64位

  • 前36位使用时间戳,以保证ID是升序增加

  • 中间13位是分库标识,用来标识当前这个ID对应的记录在哪个数据库中

  • 后15位为自增序列,以保证在同一秒内并发时,ID不会重复。每个shard库都有一个自增序列表,生成自增序列时,从自增序列表中获取当前自增序列值,并加1,做为当前ID的后15位






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值