MySQL 分库分表

MySQL 分库分表

原文:超详细的mysql分库分表方案

为什么需要引入 分库分表?

随着业务量的增长,数据量也会随时增加。

数据量大的表的查询性能就会变低,DDL执行时间也会变长

MySQL 表限制

以 MySQL数据库为例

使用默认的 InnoDB存储引擎

此时创建一个表名为 orders 的表就会自动生成 orders.idb 的数据文件。文件大小受操作系统 Block 大小限制,下面是 ext3 文件系统块大小和最大尺寸对应关系:

操作系统块大小最大文件尺寸最大文件系统尺寸
1KB16GB2TB
2KB256GB8TB
4KB2TB16TB
8KB16TB32TB

查看操作系统页大小及块大小

[root@wudg ~]# getconf PAGESIZE
4096
## 查看磁盘 /dev/vda 下的分区
[root@wudg ~]# fdisk -l /dev/vda

Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0008de3e

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    83884031    41940992   83  Linux

[root@wudg ~]# tune2fs -l /dev/vda1 | grep Block
Block count:              10485248    ## 分区的块数量
Block size:               4096        ## 块大小
Blocks per group:         32768       ## 每个组的块数

分表

TABLE_SIZE = AVG_ROW_SIZE * ROWS

要么字段太多,要么表记录数太多

单表建议不超过 500w条记录

产生不同分表方案:

  • 垂直分表(切分字段):主键保持一致,字段分表存储(如把类型为 text 的字段拆分)
  • 水平分表(切分记录):按主键取模、按月份、

如果使用了数据库中间件就会自动实现查询重写,例如 mycat、sharding-sphere

MySQL 分区表

CREATE TABLE orders (
	id BIGINT (20) NOT NULL auto_increment COMMENT 'id',
	order_id VARCHAR (20) NOT NULL COMMENT '订单ID',
	user_id BIGINT (20) NOT NULL COMMENT '用户ID',
	PRIMARY KEY (id, user_id),
	KEY idx_user_id (user_id)
) PARTITION BY HASH (user_id) PARTITIONS 20;

分库

主备,读写分离

  • 按业务拆库:如库存数据和订单数据分库存储
  • 按表分库:
    • 垂直分库
    • 水平分库

通过上述的分库分表后,仍会遇到三类问题

  1. MySQL master 写操作性能瓶颈
  2. 分库分表后 SQL 解析处理,服务调用链路变长,系统变得不稳定
  3. 分库分表后动态扩容不好实现

拆分后的问题

垂直拆分

  • 跨库 join 问题
  • 分布式事务问题

img

水平拆分

  • 分布式全局唯一ID:雪花算法
  • 数据扩容问题

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×