一、数据库切片
二、主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;