1.系统架构存在的问题
在系统架构中,如果DBserver只使用单节点服务,那么面对大并发,海量数据的存储,单节点的系统架构将存在很严重的问题,所以,需要实现MySQL集群,来应对大并发、海量数据存储等问题。
2. MySQL数据库的集群方案
2.1 读写分离架构
2.1.1 说明
2.1.2 架构
从该系统架构中,可以看出:
● 数据库从之前的单节点变为多节点提供服务;
● 主节点数据,同步到从节点数据;
● 应用程序需要连接到2个数据库节点,并且在程序内部实现判断读写操作。
这种架构存在2个问题:
● 应用程序需要连接到多个节点,对应用程序而言开发变的复杂
○ 这个问题,可以通过中间件解决
○ 如果在程序内部实现,可以使用Spring的AOP功能实现
●主从之间的同步,是异步完成,也就意味着这是 弱一致性
○ 可能会导致,数据写入主库后,应用程序读取从库,获取不到数据,或者可能会丢失数据
,对于数据安全性要求比较高的应用是不合适的
○ 该问题可以通过PXC集群解决
2.2 中间件架构
通过上面的架构,可以看出,应用程序会连接到多个节点,使得应用程序的复杂度提升,可以通过中间件方式解决
如下:
从架构中,可以看出:
● 应用程序只需要连接到中间件即可,无需连接多个数据库节点
● 应用程序无需区分读写操作,对中间件直接进行读写操作即可
● 在中间件中进行区分读写操作,读发送到从节点,写发送到主节点
该架构也存在问题,中间件的性能成为了系统的瓶颈,那么架构可以改成这样:
这样中间件的可靠性得到了保证,但是也带来了新的问题,应用系统依然要连接到多个中间件,又为应用系统带来了复杂度。
2.3 负载均衡
为了解决以上问题,我们将继续优化架构,在应用程序和中间件之间增加proxy代理,由代理来完成负载均衡的功能,应用程序只需要对接proxy即可。
至此,主从复制架构的高可用架构才算是搭建完成。
2.4 PXC集群
在前面的架构中, 都是基于MySQL主从的架构,那么在主从架构中,就一致性问题依然没有解决,如果在需要强一致性的需求中,显然这种架构是不能应对的,比如:交易数据。
PXC提供了读写强一致性的功能,可以保证数据在任何一个节点写入的同时可以同步到其它节点,也就意味着可以从其他的任何节点进行读取操作,无延迟。
架构如下:
缺点:性能相对于主从架构要低。
2.5 混合架构
在前面的PXC架构中,虽然可以实现事务的强一致性,但是它是通过牺牲了性能换来的一致性,如果在某些业务场景下,如果没有强一致性的需求,那么使用PXC就不合适了。所以,在我们的系统架构中,需要将这两种方式综合起来,这样才是一个较为完善的架构。
3. 搭建主从复制架构
使用MySQL版本为衍生版Percona,版本为5.7.23,并且通过docker进行搭建服务
3.1 主从复制原理
MySQL主(称master) 从(称slave)复制的原理:
● master将数据改变记录到二进制日志(binary)中,也即是配置文件log.bin指定的文件(这些记 录叫做二进制日志事件,binary log events)
● slave将master的binary events拷贝到它的中继日志(relay log)
● slave重做中继日志的事件,将改变反映到它自己的数据(数据重演)
主从配置需要注意的地方
● 主DB server和从DB server数据库的版本一致
● 主DB server和从DB server数据库数据一致
● 主DB server开启二进制日志,主DB server和从DB server的server_id都必须唯一
3.2 主库配置文件my.conf
#开启主从复制,主库的配置
log-bin = mysql-bin
#指定主库server id
server-id = 1
#指定同步的数据库,如果不指定,则同步全部数据库
binlog-do-db = my_test
#执行sql语句查询状态
SHOW MASTER STATUS
3.3 在主库创建同步用户
3.4 从库配置文件my.conf
#指定server_id,只要不重复即可,从库也只有这一个配置,其他都在SQL语句中操作
server_id = 2
#以下执行SQL:
CHANGE MASTER TO
master_host = '127.0.0.1',
master_user = 'slave01',
master_password = '123456',
master_port = 3306,
master_log_file = 'mysql-bin.000006',
master_log_pos = 1120;
#启动slave同步
START SLAVE;
#查看同步状态
SHOW SLAVE STATUS;
3.5 搭建主库
3.6 搭建从库
3.7 主从复制的模式
#修改主库的配置 binlog_format=MIXED
#重启 docker restart percona-master01 && docker logs -f percona-master01
#查看二进制日志相关的配置项 show global variables like 'binlog%';
4 MyCat中间件
4.1 简介
● 一个彻底开源的,面向企业应用开发的大数据库集群
● 支持事务、ACID、可以替代MySQL的加强版数据库
● 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
● 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
● 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
● 一个新颖的数据库中间件产品
4.2 优势
基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得 MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广 泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产 品。
MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证 了MYCAT的产品质量。
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源 项目成了一个摆设。
4.3 关键特性
● 支持SQL92标准
● 支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法
● 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理。
● 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群。
● 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
● 基于Nio实现,有效管理线程,解决高并发问题。
● 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页。
● 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join。
● 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。
● 支持多租户方案
● 支持分布式事务(弱xa)。
● 支持XA分布式事务(1.6.5)。
● 支持全局序列号,解决分布式下的主键生成问题。
● 分片规则丰富,插件化开发,易于扩展。
● 强大的web,命令行监控。
● 支持前端作为MySQL通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。
● 支持密码加密
● 支持服务降级
● 支持IP白名单
● 支持SQL黑名单、sql注入攻击拦截
● 支持prepare预编译指令(1.6)
● 支持非堆内存(Direct Memory)聚合计算(1.6)
● 支持PostgreSQL的native协议(1.6)
● 支持mysql和oracle存储过程,out参数、多结果集返回(1.6)
● 支持zookeeper协调主从切换、zk序列、配置zk化(1.6)
● 支持库内分表(1.6)
● 集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)
4.4 读写分离
MySQL服务部署情况:
schema.xml:
balance属性说明:
负载均衡类型,目前的取值有3 种:
1. balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。
2. balance=“1”,全部的readHost 与stand by writeHost 参与select 语句的负载均衡,简单的说,当双 主 双从模式(M1->S1,M2->S2,并且M1 与M2 互为主备),正常情况下,M2,S1,S2 都参与select 语句的负 载均衡。
3. balance=“2”,所有读操作都随机的在writeHost、readhost 上分发。
4. balance=“3”,所有读请求随机的分发到wiriterHost 对应的readhost 执行,writerHost 不负担读压 力, 注意balance=3 只在1.4 及其以后版本有,1.3 没有。
rule.xml:
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">1</property>
</function>
测试:
--创建表
CREATE TABLE `tb_ad` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` int(10) DEFAULT NULL COMMENT '广告类型',
`title` varchar(100) DEFAULT NULL COMMENT '描述',
`url` varchar(200) DEFAULT NULL COMMENT '图片URL地址',
`created` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='广告表';
--测试插入数据
INSERT INTO `tb_ad` (`id`, `type`, `title`, `url`, `created`, `updated`) VALUES ('1',
'1', 'UniCity万科天空之城', 'http://itcast-haoke.oss-cnqingdao.aliyuncs.com/images/2018/11/26/15432029097062227.jpg', '2018-11-26 11:28:49', '2018-11-26 11:28:51');
--测试结果:主库有写入数据,从库会同步数据