MySQL主从复制与分库分表

主从复制

主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。

  • binlog线程:负责将主服务器上的数据更改写入二进制日志(Binary log)中。
  • I/O线程:负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。
  • SQL线程:负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。

读写分离

主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作。

读写分离能提高性能的原因在于

  • 主从服务器负责各自的读和写,极大程度缓解了锁的争用;
  • 从服务器可以使用MyISAM,提升查询性能以及节约系统开销;
  • 增加冗余,提高可用性。

分库分表

当在主从复制、索引优化并且升级硬件后,数据库性能依然无法达到要求,此时就可以考虑数据库的切分,根据其切分类型,可以分为两种切分方式:垂直切分和水平切分。

垂直切分

垂直切分又分为垂直分库和垂直分表。

垂直分库就是根据业务耦合性,将关联度低的不同表存储在不同的数据库。做法与大系统拆分为多个小系统类似,按业务分类进行独立划分。与”微服务治理”的做法相似,每个微服务使用单独的一个数据库。(例如用户User一个库,商品Producet一个库,订单Order一个库)

垂直分表是针对列进行的。如果某个表的字段较多,可以把不常用的字段或者长度较长的字段拆分到一张新的扩展表中。在字段较多的情况下,通过“大表拆小表”,更有利于维护与开发,也能避免跨页问题(一致性、排序等问题)。MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。

水平切分

因为垂直切分并没有解决单表数据量过大的问题(1000W行切分后还是1000W行),所以当还是无法满足需求的时候,可以进行水平切分。水平切分有以下几种方式:

  • 范围切分:比如按照时间区间或ID区间来切分,这可以使得冷热数据分离。由于是顺序存储,天然适合水平扩展,但是无法解决集中写入瓶颈的问题。
  • Hash切分:通过Hash取模解决了数据访问不均匀的问题,但是在集群扩容的时候,数据迁移量是很大的(使用一致性hash算法能较好的避免这个问题)。

参考资料