一、数据库切片 二、主node高可用方案 三、前端应用程序R/W分离 四、MHA的介绍 五、MHA的配置过程 六、Master恢复为slave 七、手动切换主备
MySQL分布式实现:
CAP:一致性,可用性,网络分区容错性
consistent:
available
AP:多数分布式,满足AP,对一致性进行妥协
C:妥协,保证最终一致性
MySQL的复制:
master:二进制日志(statement,row) //基于行和基于语句的记录
slave:中级日志(IO thread)(SQL thread)
r/w:master
r:slave //只读 read_only=1,但是无法拒绝拥有super权限的,可lock 全局锁
master/master: 没有分担写操作
一、数据库切分:
垂直切分: //将一个库中的多章表,进行切割,也称为分库
//任何单台server,存储的都不是全部的数据
中间件:知道数据分布在哪个节点,负责分发
水平切分:分表,sharding
把一个表,分割成n个片段
示例:
id号奇数A表
id号偶数B表
当进行查询id>20的就比较麻烦
举例:
原库:{产品表、订单表、用户表}
垂直拆分:把产品和用户表放到单独一个server上,订单表放到单独一个server上
水平拆分:用户表通过性别,拆分为{男用户表+女用户表}
拆分规则:
按照范围切分、按照hash值区分
//但是当涉及到多个片段查询的时候,相对麻烦。
必须要使用前端中间件
cobar:前端框架,通用框架
gizzard:
分片方案1:
=====================分片示意图
[A'][A] [B] [C] //分片A,B,C
【】 【】 【】
【】 【】 【】
【】 【】 【】
//[]:主分片,【】:从分片//对分片进行主从
//w请求到[],r请求到【】,实现负载均衡
问题:主分片宕机,数据将不完整
解决方案;
[A]:做高可用,使用keepalive或者corosync
vip:进行HA
进行HA:前提,主备需要使用共享存储。
//因此不建议使用。
分片方案2:第三方辅助性工具
===========================
[A] [B] [C] //分片A,B,C
{E} 【】 【】 【】
【】 【】 【】
【】
E:监控A分片的主节点和所有分片节点
一旦主节点故障,选用一个slave为主
并配置其他slave更改其master
二、主node高可用方案
MySQL Replication//在mysql主从中,提升slave为master node的解决方案。
MMM: multi Master mysql //多主节点的mysql,现在活跃度较低。
MHA:master HA//活跃度较高
Galera-Cluster //基于wresp协议工作,也较为常用
//MMM和MHA是建立在原有的主从复制集群上的
//Galera-Cluster无需配置主从。在更底层的存储级别,多主模型的实现。
通过wresp协议在全局实现复制,任何一节点都可读写
//没有主从之分,都是可读可写的,所有的都是主,所有的都是从
MM,MHA只是对master进行监控,故障时自动进行故障转移,提升slave为master来实现
//都需要借助于第三方node是否故障
slave切换为master后,原有的master即使恢复也不会更换master
三、使用MHA或者MMM进行高可用。前端应用程序,如何进行读写分离?
方法一:在程序内部实现,r和w分离以及负载均衡算法实现
|程 序|
========
| \
V V
[w] [r][r][r]
//一旦slave添加了一个,就需要修改程序的配置文件
万一master宕机?业务将会终止
解决方案:两个master,
|程 序| //在程序中说明两个master,双w,可以在两个node上进行keepalived的vip流动
========
| \
V V
[w][w'] [r][r][r]
方法二:中间件//
1.该中间件完成rw分离,能够理解sql语句的r和w语句和负载均衡
2.连接池connection pool //连接缓冲,队列server
现在较新的rw分离器,已经可以实现切片的功能
amiba //读写分离,后来就可以支持分片
现在的很多nosql可自动实现数据分片。
分片关键:
100w件商品,可能只有3w可能是热销的,切分:必须要保证把热区数据,分散开来。
=====//分片后
【】 【】 【】 //master
[] [] [] //slave
然后对主从进行HA:使用MHA或者
Galera-Cluster让所有node都rw
阿里巴巴的cobar
360的atlas
golang的kingshard
http://blog.csdn.net/hu_wen/article/details/53635976
方法三、逻辑层//使用nosql
========================= //逻辑层,例如每32M为一个分片
【1,2,4'】 【1',3'】 【2',3,4】
A B C
//对shard进行冗余,一旦A宕机,不影响使用副本,
而且逻辑层发现1,2,4的副本不够,将会重新分布分片的个数,
例如保证每个shard的分片至少3个等。
存储分类:
1.结构化存储
2.NoSQL:非结构化存储 ,k/v存储{redis},文档式存储{mongodb}
3.分布式存储:分布式fs,jpg,gif等
但是一个数据进行分片后,将很难执行事务
1.使用分布式事务 2pc,3pc //耗时,并效率低,问题较多
2.放弃事务?
其实关系数据库中的约束是最为影响性能的,是影响系统扩展的一个障碍
四、MHA介绍
heartbeat+drbd //不好用
mysql cluster //mysql集群官方给的,几乎没有人使用
semi-synchronous Replication(5.5+) //半同步复制
Global Transaction ID //mysql 5.5+ ,全局事务id
每一个事务都有唯一ID
自动故障转移//提升slave为master
===================================================
【Dead master】 【Latest slave】 【other slave 】
【lost envents】【 】
//master一旦宕机,会有部分数据是丢失的。
MHA会读取dead master上的lost events,然后查找各slave的中级日志中最新的,然后将其应用到该slave上
MHA强依赖于SSH服务
MHA:提供master 自动故障转移
MHA在监控到master节点故障时,会提升其中拥有最新数据的slave节点成为master
MHA还提供master节点的在线切换功能,即按需切换master/slave节点的切换
Manager节点:通常单独部署在一个独立管理多个master/slave集群
//manager绝对不能放在一个master上
node :数据节点
//注意一个manager可以管理多个主从集群(application)。
MHA组件:
manager 节点:
masterha_check_ssh :MHA依赖于ssh环境监测工具
masterha_check_repl:MySQL复制环境监测工具
masterha_manager:MHA服务主程序;
masterha_check_status:MHA的环境状态探测工具
masterha_master_monitor:MySQL master节点的高可用性能监测工具
masterha_master_switch:master节点切换工具
master_conf_host :添加或者删除配置的node
masterha_stop:添加或删除配置的节点
node:手册
save_binary_logs:保存和复制master的二进制日志
apply_diff_relay_logs:识别差异的中继日志事件并应用于其它slave
filter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs:清除中继日志(不会阻塞SQL线程)
自定义扩展:
secondary_check_script:通过多条网络路由检测master的可用性
master_ip_failover_script:更新application使用的masterip
shutdown_script:强制关闭master节点
report_script:发送报告
init_conf_load_script:加载初始配置参数
master_ip_online_change_script:更新master节点的ip地址
//原有的万一没有fail,只是检测到down了
书籍《MHA手册》
master和node都要开启中级日志&二进制日志,因为
master一旦故障后,重新启用后就需要用到中级日志了
serverid 一定不能相同
五、MHA的配置过程
======================================
1.host文件相同
master和各slave都需要有一个账号贡献给 manager节点
node1:manager 192.168.1.67 node2:master192.168.1.68 node3:slave192.168.1.69 node4:slave 192.168.1.70
2.配置主从复制
node2:master
vim my.cnf [mysqld] innodb_file_per_table=1 skip_name_resolve=1 log-bin=master-bin relay-log=relay-bin //master可以暂时不开启,在转换为slave启动时开启也可以 server-id=1 systemctl start mariadb > show master status //mysql-bin.0000003 245 > grant replication slave,replication client on *.* to 'repluser'@'192.168.1.%' identified by 'replpass';
node3: slave
vim my.cnf [mysqld] innodb_file_per_table=1 skip_name_resolve=1 log-bin=master-bin relay-log=relay-bin //master可以暂时不开启,在转换为slave启动时开启也可以 server-id=2 read_only=1 relay_log_purge=0 systemctl start mariadb > change master to master_host='192.168.1.68' master_user='repluser',master_pass='replpass',master_log_file='master_bin.000003', master_pos=245; > show slave status //mysql-bin.0000003 245 > start slave //启动进程,链接用户也会被复制过来
node4:slave
vim my.cnf [mysqld] innodb_file_per_table=1 skip_name_resolve=1 log-bin=master-bin relay-log=relay-bin //master可以暂时不开启,在转换为slave启动时开启也可以 server-id=3 read_only=1 relay_log_purge=0 systemctl start mariadb > change master to master_host='192.168.1.68' master_user='repluser',master_pass='replpass',master_log_file='master_bin.000003', master_pos=245; > show slave status //mysql-bin.0000003 245 > start slave //启动进程,链接用户也会被复制过来
=========================
在master上创建一个拥有管理权限的用户
> grant all on *.* to 'mhauser'@'192.168.1.%' identified by 'mhapass';
//这个用户会自动同步到slave
注意:建议在真正使用的时候,把其中一个node配置为半同步复制
用于:故障修复
3.互联
任何一个主机都能密钥登录其他主机。
可以让所有的主机都使用同一个秘钥对儿
示例:
master:ssh-keygen
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
ssh node1 //链接自己进行测试
chmod go= .ssh/authorized_keys
scp -p .ssh/id_rsa .ssh/authorized_keys node2:/root/.ssh
scp -p .ssh/id_rsa .ssh/authorized_keys node3:/root/.ssh
scp -p .ssh/id_rsa .ssh/authorized_keys node4:/root/.ssh
ssh node2 'ifconfig eno16777736' //测试
//连接过后,使用密码
4.MHA安装
mha4mysql-manager-0.55.el6.noarch.rpm
mha4mysql-node-0.55.el6.noarch.rpm
//googlecode 代码托管
配合好base和epel yum源
manager:
yum install mha4mysql-node mha4mysql-manager
master&slave
yum install mha4mysql-node
=======================配置文件讲解
配置文件:MHA用于管理多个主从集群,每一个主从复制集群是一个application
global配置,为各application提供默认配置
application:配置
server:
[server default] user=mhaadmin //能够连接至个mysql主机,并拥有管理权限的主机 password= manager_workdir= //可以不存在会自行创建 manager_log= remote_workdir= //远程的每一个node上为mha工作提供的工作目录 ssh_user=root repl_user=//拥有复制权限的用户 repl_password= ping_interval= [server1] hostname= ssh_port= candidate_master=1//是否可以成为master节点 [server2] hostname= ssh_port= candidate_master=1//默认就启用了 [server3] hostname= ssh_port= #no_master=1 //不能成为master节点,#注释
5.配置文件修改
manager:
mkdir /etc/masterha
vim /etc/masterha/app1.cnf
====================================
[server default] user=mhauser //超级权限登录mysql password=mhapass manager_workdir=/data/masterha/app1 manager_log=/data/masterha/app1/manager.log remote_workdir=/data/masterha/app1 ssh_user=root repl_user=repluser repl_password=replpass ping_interval=1 [server1] hostname=192.168.1.68 candidate_master=1 //默认就是1,可以不配置 [server2] hostname=192.168.1.69 candidate_master=1 [server3] hostname=192.168.1.70 candidate_master=1
6.检测和测试:
1.检测ssh
#masterha_check_ssh --conf=/etc/masterha/app1.cnf
All SSH connection tests passwd successfully //表示成功
2.检查主从复制是否ok
#masterha_check_repl --conf=/etc/masterha/app1.cnf
192.168.1.68 (current master)
MySQL replication Health is OK.
7.启动MHA
nohup master_manager --conf=/etc/masterha/app1.conf > /data/masterha/app1/manager.log 2>&1 &
宕机测试:
master_manager --conf=/etc/masterha/app1.conf > /data/masterha/app1/manager.log //让其在前台工作
注意:mha在完成故障转移的主备切换后,会自动退出的。需要手动再次启动
建议:写脚本实现
测试: 在master上 killall msyqld_safe mysqld
在manager上前台运行的master_manager进程会在选举slave为master后终止,
现在node3 69变成了master
问题1:假如master修复后,需要上线成为slave
1.需要在master 2上进行备份,并记录binary log文件及其position
然后把这些数据导入到slave,然后开始复制。
2.新加的slave从备份的位置开始复制
六、启用node2为slave //原先的主
vim my.cnf [mysqld] innodb_file_per_tab=1 skip_name_resolve=1 log-bin=master-bin relay-bin=master-bin relay-log=relay-bin server-id=1 read_only=1 relay_log_purge=1 rm -rf /var/lib/mysql/* systemctl start mariadb.service mysql > change master to master_host='192.168.1.69',master_user='repluser',master_password='replpass', mysql> start slave //提示错误,复制线程没有启动 systemctl stop mariadb.service systemctl start mariadb.service msyql > grant replication slave,replication client on *.* to 'repluser'@'192.168.1.%' identified by 'replpass'; mysql > grant all on *.* to ‘mhauser'@'192.168.1.%' identified by 'mhapss'; mysql > change master to master_host='192.168.1.69',master_user='repluser',master_password='replpass',master_log_file='master-bin.000003', master_log_pos=245; mysql > start slave
#masterha_check_repl --conf=/etc/masterha/app1.cnf
#masterha_check_status --conf=/etc/master/app1.cnf
#masterha_stop --conf=...
七、手动切换主备MHA
1.预备工作
分别在Master和Slave执行如下,方便mha检查复制:
grant all privileges on *.* to 'root'@'10.1.1.231' identified by 'rootpass'; grant all privileges on *.* to 'root'@'10.1.1.234' identified by 'rootpass'; grant replication slave on *.* to 'jpsync'@'10.1.1.231' identified by 'jppasswd'; grant replication slave on *.* to 'jpsync'@'10.1.1.234' identified by 'jppasswd';
flush privileges;
//创建超级用户+复制用户
2.设置master为read-only
mysql> set global read_only=1; mysql> show variables like 'read_only'; #masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.cnf --new_master_host=10.1.1.231 --new_master_port=63306 #masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.cnf --new_master_host=10.1.1.231 --new_master_port=63306 —interactive=0
3.切换后让10.1.1.231为主,10.1.1.234为从,操作步骤:
231上执行:mysql> show master status;
mysql-master-bin.000003 120
234上执行:
change master to master_host='10.1.1.231',master_port=63306,
master_user='jpsync',master_password='jppasswd',
master_log_file='mysql-master-bin.000013',master_log_pos=120;
4.验证:
231:master
mysql> show slave hosts;
在master上插入记录,在slave上查询
5.更新配置文件
my.cnf //master库
skip_slave_start //防止重启数据库,启动slave进程,导致数据不一致。
my.cnf //slave库
read_only=1
relay_log_purge=0
master:
mysql> show processlist;
mysql> show master status;
slave:
mysql> show slave status\G;