目录导航
前言
在分布式专题的开篇,我们曾提到,如今成熟的互联网架构,对于分库分表的应用必不可少!
从本节开始,我们聊一聊分库分表之MyCat,看看MyCat如何突破数据库性能瓶颈,MyCat的实战应用以及MyCat企业级高可用方案。
MyCat共计分为三节,分别是:
- MyCat入门
- MyCat配置文件详解
- MyCat高可用
数据库性能瓶颈主要原因
我们拿某电商系统的数据库设计为例:
上图为A公司最原始的数据库设计方案。
我们再看A公司核心单表的数据量:
会员表:4300w+
会员订单表:2.7亿+
订单商品表:7亿+
这样的数据库设计显然是不合理的:
- 数据库连接(连接实例)
在单数据库实例下,无法同时满足各个子系统高峰时并发访问,并且会随着时间的推移,活动的上线等业务,满足需求的能力也渐行渐远。
- 表数据量(空间存储)
表空间:通常MySql的单表数据量在1000w~1500w之间,数据行数控制在500w行以内(具体的性能测试在此不做细谈)。而上面案例展示的单表则远超1500w。
硬盘级索引:如果命中不了,则会全表的扫描;命中索引,我们知道索引是硬盘级的,它是存储在硬盘里面,那么就会有大量的IO操作。
- 硬件资源限制(QPS\TPS)
- 内存大小
- 机械硬盘&固态硬盘
数据性能优化方案
通过上面的案例我们不难分析,这样的数据库设计是需要优化的:
-
SQL优化
关于SQL优化部分,我们在前面已经讲过:
MySql 性能优化 - 01 - MySql索引机制
MySql 性能优化 - 02 - MySql运行机理
MySql 性能优化 - 03 - 深入理解InnoDB
MySql 性能优化 - 04 - MySql调优 -
缓存
关于缓存问题,我们在前面已经讲过:
Redis:
Redis01-Redis的使用
Redis02-Redis的原理分析
Redis03-Redis的分布式
Redis04-Redis的应用实战
MongoDB:
MongoDB01-应用场景及实现原理
MongoDB02-常用命令及配置
MongoDB03-手写基于MongoDB的ORM框架
MongoDB04-基于MongoDB实现网络云盘实战
MongoDB05-MongoDB高可用及MongoDB4.0新特性 -
读写分离
-
分库分表
知其然也要知其所以然,关于读写分离与分库分表的历史演进过程,不妨回忆这篇:分布式专题-漫谈分布式架构01-分布式架构的演进过程
在本节,我们将终结剩下的两部分MySql优化方案。
读写分离
区别读、写多数据源方式进行数据的存储和加载。
数据的存储(增删改)一般指定写数据源,数据的读取查询指定读数据源(读写分离会基于主从复制)
图解读写分离:
从主从形式上可以划分为:
下图M:mater (主)、S:slave(从)
-
一主一从
-
互为主从
-
一主多从
-
级联主从
读写分离能够解决哪些问题?
- 数据库连接
- 硬件资源限制
分库分表
对数据的库表进行拆分,用分片的方式对数据进行管理。分库分表分为垂直拆分与水平拆分。
垂直拆分
图解垂直拆分:
垂直拆分能够解决哪些问题?
- 数据库连接
- 硬件资源限制
水平拆分
图解水平拆分:
水平拆分能够解决哪些问题?
- 表数据量大的问题
- 数据库连接
- 硬件资源限制
MyCat入门
MyCat官网导航:http://www.mycat.org.cn/
- 一个彻底开源的,面向企业应用开发的大数据库集群
- 支持事务、ACID、可以替代MySQL的加强版数据库
- 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
- 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
- 一个新颖的数据库中间件产品
通俗点讲,应用层可以将它看作是一个数据库的代理(或者直接看成加强版数据库)
MySql主从复制
案例
环境准备:
Linux1: 192.168.200.111
Linux2: 192.168.200.112
MySql 版本为5.5.8
步骤:
- Linux1 与Linux2 上分别安装MySql ,并且安装db_store与db_user表
sql
脚本在本文末链接中已贴出
- 配置主从
配置文件设置Linux1 为Master ,Linux2 为Slave
Master操作
- 接入mysql并创建主从复制的用户
mysql > create user m2ssync identified by 'Qq123!@#';
- 给新建的用户赋权
mysql > GRANT REPLICATION SLAVE ON *.* TO 'm2ssync'@'%' IDENTIFIED BY 'Qq123!@#';
- 指定服务ID,开启binlog日志记录,在my.cnf中加入
server-id=137
log-bin=dbstore_binlog
binlog-do-db=db_store
- 通过命令查看Master db状态.
SHOW MASTER STATUS;
Slave操作
- 指定服务器ID,指定同步的binlog存储位置,在my.cnf中加入
server-id=101
relay-log=slave-relay-bin
relay-log-index=slave-relay-bin.index
read_only=1
replicate_do_db=db_store
my.cnf 文件默认安装在/etc/my.cnf位置,视你的mysql实际配置为准
- 接入slave的mysql服务,并配置
change master to master_host='192.168.200.111', master_port=3306,master_user='m2ssync',
master_password='Qq123!@#',
master_log_file='db_stoere_binlog',
master_log_pos=0;
-
start slave;
-
查看slave服务器状态
show slave status\G ;
- 测试访问
将Linux1机器(192.168.200.111)创建的db_store 库删掉,那么Linux2机器(192.168.200.112)的db_store库也应随之删掉:
同理,新增db_store也会保持同步,这里不再演示。
MySql基于binlog的主从复制原理
关于MySql主从复制原理,我们前面提到过:mysql中binlog的底层原理分析
binlog实现过程
-
master将操作记录到二进制日志(binary log)中
(这些记录叫做二进制日志事件,binary log events) -
Slave通过I/O Thread异步将master的binary log events拷贝到它的中继日志(relay log);
-
Slave执行relay日志中的事件,匹配自己的配置将需要执行的数据,在slave服务上执行一遍从而达到复制数据的目的。
延迟是怎么产生的?
-
当master tps高于slave的sql线程所能承受的范围
-
网络原因
-
磁盘读写耗时
如何判断延迟?
- 使用命令:
mysql> show slave status \G;
当检查到参数 sends_behind_master
为0,判断主动同步延时的参考值,是通过比较sql_thread执行的event的timestamp和io_thread复制好的event的timestamp(简写为ts)进行比较,而得到的这么一个差值。
- mk-heartbeat timestamp进行实践搓的判断
心跳检查机制,通过设置主从数据时间戳来判断。
我们怎么解决延迟问题?
-
配置更高的硬件资源
-
多线程方式:
- 把IO thread 改变成 多线程的方式
- mysql5.6 库进行多线程的方式
- GTID进行多线程的方式
- 应用程序自己去判断(mycat支持)
MyCat读写分离
案例
紧接着上面的案例,我们现在增加一台服务器:
Linux3: 192.168.200.113
使其安装与Linux1和Linux2相同版本的MySql,同时使其安装Mycat:版本为1.6.6
解压以后得到:
MyCat目录解释
- bin 程序目录,存放了 window 版本和 linux 版本可执行文件
./mycat {start|restart|stop|status…}
- conf 目录下存放配置文件
- server.xml 是 Mycat 服务器参数调整和用户授权的配置文件
- schema.xml 是逻辑库定义和表
- rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在 这个目录下
- log4j2.xml配置logs目录日志输出规则
wrapper.conf
JVM相关参数调整
- lib 目录下主要存放 mycat 依赖的一些 jar 文件
- logs目录日志存放日志文件
-
启动MyCat
在/bin 目录下,直接strat即可。 -
修改配置文件,关联 Master 与 Slave 节点
在/conf 目录下,修改配置文件rule.xml,schema.xml,server.xml。这里不全面展开,只展示关键配置,全部配置请参考本文末的提供的配置文件:
server.xml
schema.xml
rule.xml
- 验证测试
在Linux3机器的db_user插入id自增的1~5条用户数据,根据我们的分片规则,设定为奇数放在Master节点,而偶数放在Slave节点上。
- 在Linux3机器上(192.168.200.113)db_user库的user表插入五条数据
-
在Linux1 机器上验证(192.168.200.111)db_user库的user表数据
-
在Linux2 机器上验证(192.168.200.112)db_user库的user表数据
对应到本次的MyCat案例,整体架构图如下:
由此我们也能够理解一些MyCat的名词(对应到本次案例):
-
逻辑库
db_user db_store
-
逻辑表
- 分片表
用户表
用户表按照UID取模分成两片 - 全局表
数字字典表
数据字典,比如存放用户的会员等级。 - ER表
用户地址表
每个用户,都有多个地址,ER表将按照用户的分片规则,和用户能匹配上的地址被分到同一个片上 - 非分片表
门店表,店员表
不需要分片的,数据量较小,和其他表没有关联关系
- 分片表
-
分片规则 如: userID%2(按照userID取2的模)
-
节点
节点主机(写、读节点主机)
后记
-
本节案例演示的SQL脚本及MyCat配置文件
链接:https://pan.baidu.com/s/1xg8vJz-0CyHQD57tcKM2zg
提取码: egux -
Centos 安装 MySql5.5 (tar包安装) https://www.cnblogs.com/wangxc20181130/p/10042603.html
-
Mycat官网文档(PDF版手册)
http://www.mycat.org.cn/document/mycat-definitive-guide.pdf
更多架构知识,欢迎关注本套Java系列文章:Java架构师成长之路