前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MHA高可用架构与Atlas读写分离

MHA高可用架构与Atlas读写分离

作者头像
惨绿少年
发布于 2019-05-24 12:35:23
发布于 2019-05-24 12:35:23
1.3K00
代码可运行
举报
文章被收录于专栏:惨绿少年惨绿少年
运行总次数:0
代码可运行

1.1 MHA简介

1.1.1 MHA软件介绍

  MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在10~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

  MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;在复制 框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的 replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现 有的复制部署也是它的优势之处。

  MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中 (通过将从库提升为主库),大概0.5-2秒内即可完成。

  该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

  在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。   MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。   目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。

1.1.2 MHA工作原理

工作原理说明: 1、保存master上的所有binlog事件 2、找到含有最新binlog位置点的slave 3、通过中继日志将数据恢复到其他的slave 4、将包含最新binlog位置点的slave提升为master 5、将其他从库slave指向新的master原slave01 并开启主从复制 6、将保存下来的binlog恢复到新的master上

1、监控所有node节点MHA功能说明:

2、自动故障切换(failover) 前提是必须有三个节点存在,并且有两个从库   (1)选主前提,按照配置文件的顺序进行,但是如果此节点后主库100M以上relay-log 就不会选    (2)如果你设置了权重,总会切换带此节点;一般在多地多中心的情况下,一般会把权重设置在本地节点。   (3)选择s1为新主   (4)保存主库binlog日志 3、重新构建主从   (1)将有问题的节点剔除MHA      进行第一阶段数据补偿,S2缺失部分补全90    (2)s1切换角色为新主,将s2指向新主S1      s2 change master to s1    (3) 第二阶段数据补偿      将保存过来的新主和原有主缺失部分的binlog,应用到新主。   (4)虚拟IP漂移到新主,对应用透明无感知    (5)通知管理员故障切换

1.1.3 MHA高可用架构图

1.1.4 MHA工具介绍

  MHA软件由两部分组成,Manager工具包和Node工具包,具体的说明如下:

  Manager工具包主要包括以下几个工具:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
masterha_check_ssh             #检査 MHA 的 ssh-key^
masterha_check_repl            #检査主从复制情况
masterha_manger                #启动MHA
masterha_check_status          #检测MHA的运行状态^
masterha_mast er_monitor       #检测master是否宕机一
masterha_mast er_switch        #手动故障转移—
masterha_conf_host             #手动添加server倍息一
masterha_secondary_check       #建立TCP连接从远程服务器v
masterha_stop                  #停止MHA

Node工具包主要包括以下几个工具:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
save_binary_1ogs       #保存宕机的master的binlog
apply_diff_relay_logs   #识别relay log的差异
filter_mysqlbinlog           #防止回滚事件一MHA已不再使用这个工具
purge_relay_logs           #清除中继曰志一不会阻塞SQL线程

1.1.5 MHA的优点

1、自动故障转移 2、主库崩溃不存在数据不一致的情况 3、不需要对当前的mysql环境做重大修改 4、不需要添加额外的服务器 5、性能优秀,可以工作再半同步和异步复制框架 6、只要replication支持的存储引擎mha都支持

1.2 环境说明

   在本次的实验中,共需要用到三台主机,系统、软件说明如下。

1.2.1 系统环境说明

db01主机(master)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@db01 ~]# uname -r
2.6.32-696.el6.x86_64
[root@db01 ~]# /etc/init.d/iptables status
iptables: Firewall is not running.
[root@db01 ~]# getenforce 
Disabled
[root@db01 ~]# hostname -I
10.0.0.51 172.16.1.51

db02主机(slave1)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [root@db02 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db02 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db02 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db02 ~]# getenforce 
 8 Disabled
 9 [root@db02 ~]# hostname -I
10 10.0.0.52 172.16.1.52

db03主机(slave1,MHA Manages、Atlas节点)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [root@db03 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db03 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db03 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db03 ~]# getenforce 
 8 Disabled
 9 [root@db03 ~]# hostname -I
10 10.0.0.53 172.16.1.53

1.2.2 mysql软件说明

三台服务器上都全新安装mysql 5.6.36 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# mysql --version
mysql  Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using  EditLine wrapper

  关于mysql数据库具体的安装方法参考:http://www.cnblogs.com/clsn/p/8038964.html#_label3

1.3 基于GTID的主从复制配置

1.3.1 先决条件

  ? 主库和从库都要开启binlog

  ? 主库和从库server-id必须不同

  ? 要有主从复制用户

1.3.2 配置主从复制

db01 my.cnf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log-bin=/data/mysql/mysql-bin
binlog_format=row
secure-file-priv=/tmp 
server-id=51
skip-name-resolve  # 跳过域名解析
gtid-mode=on    # 启用gtid类型,否则就是普通的复制架构
enforce-gtid-consistency=true    #强制GTID的一致性
log-slave-updates=1     # slave更新是否记入日志(5.6必须的)
relay_log_purge = 0 
[mysql]
socket=/tmp/mysql.sock

db02 my.cnf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [root@db02 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=52
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 [mysql]
17 socket=/tmp/mysql.sock

db03 my.cnf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [root@db03 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=53
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 skip-name-resolve
17 [mysql]
18 socket=/tmp/mysql.sock

创建复制用户 (51作为主节点,52、53为从)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GRANT REPLICATION SLAVE ON *.* TO repl@'10.0.0.%' IDENTIFIED BY '123';

从库开启复制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
change master to 
    master_host='10.0.0.51',
    master_user='repl',
    master_password='123',
    MASTER_AUTO_POSITION=1;

启动从库复制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
start slave;

1.3.3 GTID复制技术说明

MySQL GTID简介

  GTID的全称为 global transaction identifier ,可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建。GTID需要在全局的主-备拓扑结构中保持唯一性,GTID由两部分组成:

GTID = source_id:transaction_id

source_id用于标示源服务器,用server_uuid来表示,这个值在第一次启动时生成,并写入到配置文件data/auto.cnf中

transaction_id则是根据在源服务器上第几个提交的事务来确定。

GTID事件结构

GTID在二进制日志中的结构

4

一个GTID的生命周期包括:

1.事务在主库上执行并提交给事务分配一个gtid(由主库的uuid和该服务器上未使用的最小事务序列号),该GTID被写入到binlog中。 2.备库读取relaylog中的gtid,并设置session级别的gtid_next的值,以告诉备库下一个事务必须使用这个值 3.备库检查该gtid是否已经被其使用并记录到他自己的binlog中。slave需要担保之前的事务没有使用这个gtid,也要担保此时已分读取gtid,但未提交的事务也不恩呢过使用这个gtid. 4.由于gtid_next非空,slave不会去生成一个新的gtid,而是使用从主库获得的gtid。这可以保证在一个复制拓扑中的同一个事务gtid不变。由于GTID在全局的唯一性,通过GTID,我们可以在自动切换时对一些复杂的复制拓扑很方便的提升新主库及新备库,例如通过指向特定的GTID来确定新备库复制坐标。

    GTID是用来替代以前classic的复制方法;

    MySQL5.6.2支持 MySQL5.6.10后完善;

GTID相比传统复制的优点:

1.一个事务对应一个唯一ID,一个GTID在一个服务器上只会执行一次 2.GTID是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置 3.减少手工干预和降低服务故障时间,当主机挂了之后通过软件从众多的备机中提升一台备机为主机

GTID的限制:

1.不支持非事务引擎 2.不支持create table ... select 语句复制(主库直接报错)   原理:( 会生成两个sql,一个是DDL创建表SQL,一个是insert into 插入数据的sql。   由于DDL会导致自动提交,所以这个sql至少需要两个GTID,但是GTID模式下,只能给这个sql生成一个GTID )   3.不允许一个SQL同时更新一个事务引擎表和非事务引擎表 4.在一个复制组中,必须要求统一开启GTID或者是关闭GTID 5.开启GTID需要重启(5.7除外) 6.开启GTID后,就不再使用原来的传统复制方式 7.对于create temporary table 和 drop temporary table语句不支持 8.不支持sql_slave_skip_counter

1.3.4 COM_BINLOG_DUMP_GTID

从机发送到主机执行的事务的标识符的主范围

Master send all other transactions to slave

  同样的GTID不能被执行两次,如果有同样的GTID,会自动被skip掉。

  slave1:将自己的UUID1:1发送给master,然后接收到了UUID1:2,UUID1:3 event

  slave2:将自己的UUID1:1,UUID1:2发送给master,然后接收到了UUID1:3事件

GTID组成

  GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29

1.3.5 【示例二】MySQL GTID复制配置

主节点my.cnf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=1
log-bin=mysql-bin
socket=/tmp/mysql.sock
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

从节点my.cnf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=2
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-bin=mysql-bin
log_slave_updates = 1
socket=/tmp/mysql.sock

配置文件注解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server-id=x                    # 同一个复制拓扑中的所有服务器的id号必须惟一
binlog-format=RO               # 二进制日志格式,强烈建议为ROW
gtid-mode=on                   # 启用gtid类型,否则就是普通的复制架构
enforce-gtid-consistency=true  # 强制GTID的一致性
log-slave-updates=1            # slave更新是否记入日志

  复制用户准备(Master主节点)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql>GRANT REPLICATION SLAVE ON *.* TO rep@'10.0.0.%' IDENTIFIED BY '123';

  开启复制(Slave从节点)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql>start slave;
mysql>show slave status\G

  现在就可以进行主从复制测试。

1.4 部署MHA

  本次MHA的部署基于GTID复制成功构建,普通主从复制也可以构建MHA架构。

1.4.1 环境准备(所有节点操作)

安装依赖包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
yum install perl-DBD-MySQL -y

   下载mha软件,mha官网:https://code.google.com/archive/p/mysql-master-ha/

github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

下载软件包

mha4mysql-manager-0.56-0.el6.noarch.rpm mha4mysql-manager-0.56.tar.gz mha4mysql-node-0.56-0.el6.noarch.rpm mha4mysql-node-0.56.tar.gz

在所有节点安装node

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

创建mha管理用户

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';

# 主库上创建,从库会自动复制(在从库上查看)

  创建命令软连接(重要)

  如果不创建命令软连接,检测mha复制情况的时候会报错

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql /usr/bin/mysql

1.4.2 部署管理节点(mha-manager)

在mysql-db03上部署管理节点

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 安装epel源,软件需要
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo 
# 安装manager 依赖包
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
# 安装manager管理软件
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

创建必须目录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mkdir -p /etc/mha
mkdir -p /var/log/mha/app1    ----》可以管理多套主从复制

编辑mha-manager配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# cat  /etc/mha/app1.cnf
[server default]                        
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
user=mha
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

【配置文件详解】

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [server default]
 2 #设置manager的工作目录
 3 manager_workdir=/var/log/masterha/app1
 4 #设置manager的日志
 5 manager_log=/var/log/masterha/app1/manager.log 
 6 #设置master 保存binlog的位置,以便MHA可以找到master的日志,我这里的也就是mysql的数据目录
 7 master_binlog_dir=/data/mysql
 8 #设置自动failover时候的切换脚本
 9 master_ip_failover_script= /usr/local/bin/master_ip_failover
10 #设置手动切换时候的切换脚本
11 master_ip_online_change_script= /usr/local/bin/master_ip_online_change
12 #设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
13 password=123456
14 #设置监控用户root
15 user=root
16 #设置监控主库,发送ping包的时间间隔,尝试三次没有回应的时候自动进行failover
17 ping_interval=1
18 #设置远端mysql在发生切换时binlog的保存位置
19 remote_workdir=/tmp
20 #设置复制用户的密码
21 repl_password=123456
22 #设置复制环境中的复制用户名 
23 repl_user=rep
24 #设置发生切换后发送的报警的脚本
25 report_script=/usr/local/send_report
26 #一旦MHA到server02的监控之间出现问题,MHA Manager将会尝试从server03登录到server02
27 secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02 --user=root --master_host=server02 --master_ip=10.0.0.51 --master_port=3306
28 #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)
29 shutdown_script=""
30 #设置ssh的登录用户名
31 ssh_user=root 
32 
33 [server1]
34 hostname=10.0.0.51
35 port=3306
36 
37 [server2]
38 hostname=10.0.0.52
39 port=3306
40 #设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
41 candidate_master=1
42 #默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
43 check_repl_delay=0

配置ssh信任(密钥分发,在所有节点上执行)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 生成密钥
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
# 分发公钥,包括自己
for i in 1 2 3 ;do ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.5$i ;done

分发完成后测试分发是否成功

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for i in 1 2 3 ;do ssh 10.0.0.5$i  date ;done
或
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
最后一行信息为如下字样即为分发成功:
Thu Dec 28 18:44:53 2017 - [info] All SSH connection tests passed successfully.

1.4.3 启动mha

经过上面的部署过后,mha架构已经搭建完成

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 启动mha
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

启动成功后,检查主库状态

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:3298) is running(0:PING_OK), master:10.0.0.51

1.4.4 切换master测试

查看现在的主库是哪个

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11669) is running(0:PING_OK), master:10.0.0.51

手动停止主库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# /etc/init.d/mysqld stop 
Shutting down MySQL..... SUCCESS!

再停止数据的同时查看日志信息的变化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# tailf /var/log/mha/app1/manager
~~~
Fri Dec 29 15:51:14 2017 - [info]  All other slaves should start replication from
here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

修复主从

① 启动原主库,添加change master to 信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# /etc/init.d/mysqld start 
Starting MySQL. SUCCESS!
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';
mysql> start slave;

② 查看主从复制状态

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show slave status\G
                   Master_Host: 10.0.0.52
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

修复mha

① 修改app1.cnf配置文件,添加回被剔除主机

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# cat  /etc/mha/app1.cnf 
[binlog1]
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog/
no_master=1

[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root
user=mha

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

② mha检查复制状态

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

③ 启动mha程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

到此主库切换成功

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11978) is running(0:PING_OK), master:10.0.0.52

实验结束将主库切换回db01.

① 停止mha

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf 
Stopped app1 successfully.

② 停止所有从库slave(所有库操作)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stop slave;
reset slave all;

③ 重做主从复制(db02、db03)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CHANGE MASTER TO 
  MASTER_HOST='10.0.0.51', 
  MASTER_PORT=3306, 
  MASTER_AUTO_POSITION=1, 
  MASTER_USER='repl', 
  MASTER_PASSWORD='123';

④ 启动slave

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
start slave;

启动之后检查从库是否为两个yes show slave status\G

⑤ mha检查主从复制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

⑥ 启动mha

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

  检查切换是否成功

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:12127) is running(0:PING_OK), master:10.0.0.51

到此主主节点有切回到db01

1.4.5 设置权重

修改[server1]的权重

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[server1]
hostname=10.0.0.51
port=3306
candidate_master=1
check_repl_delay=0

配置说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
candidate_master=1                  ----》不管怎样都切到优先级高的主机,一般在主机性能差异的时候用           
check_repl_delay=0                  ----》不管优先级高的备选库,数据延时多久都要往那切

注:

1、多地多中心,设置本地节点为高权重 2、在有半同步复制的环境中,设置半同步复制节点为高权重 3、你觉着哪个机器适合做主节点,配置较高的 、性能较好的

1.5 配置VIP漂移

1.5.1 IP漂移的两种方式

  ? 通过keepalived的方式,管理虚拟IP的漂移

   ? 通过MHA自带脚本方式,管理虚拟IP的漂移

1.5.2 MHA脚本方式

修改mha配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# grep "script" /etc/mha/app1.cnf 
[server default]
master_ip_failover_script=/usr/local/bin/master_ip_failover

再主配置中添加VIP脚本

脚本内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# cat /usr/local/bin/master_ip_failover 
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
    $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
    $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
);
my $vip = '10.0.0.55/24';
my $key = '0';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

GetOptions(
    'command=s'          => \$command,
    'ssh_user=s'         => \$ssh_user,
    'orig_master_host=s' => \$orig_master_host,
    'orig_master_ip=s'   => \$orig_master_ip,
    'orig_master_port=i' => \$orig_master_port,
    'new_master_host=s'  => \$new_master_host,
    'new_master_ip=s'    => \$new_master_ip,
    'new_master_port=i'  => \$new_master_port,
);

exit &main();

sub main {

    print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

    if ( $command eq "stop" || $command eq "stopssh" ) {

        my $exit_code = 1;
        eval {
            print "Disabling the VIP on old master: $orig_master_host \n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "start" ) {

        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
        print "Checking the Status of the script.. OK \n";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}

sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
     return 0  unless  ($ssh_user);
    `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
    print
    "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

  该脚本为软件自带,脚本获取方法:再mha源码包中的samples目录下有该脚本的模板,对该模板进行修改即可使用。路径如: mha4mysql-manager-0.56/samples/scripts

  脚本修改内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
my $vip = '10.0.0.55/24';
my $key = '0';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

脚本添加执行权限否则mha无法启动

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
chmod +x /usr/local/bin/master_ip_failover

手动绑定VIP(主库)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ifconfig eth0:0 10.0.0.55/24

  检查

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

至此vip漂移配置完成

1.5.3 测试虚拟IP漂移

查看db02的slave信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 mysql> show slave status\G
 2 *************************** 1. row ***************************
 3                Slave_IO_State: Waiting for master to send event
 4                   Master_Host: 10.0.0.51
 5                   Master_User: repl
 6                   Master_Port: 3306
 7                 Connect_Retry: 60
 8               Master_Log_File: mysql-bin.000007
 9           Read_Master_Log_Pos: 191
10                Relay_Log_File: db02-relay-bin.000002
11                 Relay_Log_Pos: 361
12         Relay_Master_Log_File: mysql-bin.000007
13              Slave_IO_Running: Yes
14             Slave_SQL_Running: Yes
15               Replicate_Do_DB: 
16           Replicate_Ignore_DB: 
17            Replicate_Do_Table: 
18        Replicate_Ignore_Table: 
19       Replicate_Wild_Do_Table: 
20   Replicate_Wild_Ignore_Table: 
21                    Last_Errno: 0
22                    Last_Error: 
23                  Skip_Counter: 0
24           Exec_Master_Log_Pos: 191
25               Relay_Log_Space: 564
26               Until_Condition: None
27                Until_Log_File: 
28                 Until_Log_Pos: 0
29            Master_SSL_Allowed: No
30            Master_SSL_CA_File: 
31            Master_SSL_CA_Path: 
32               Master_SSL_Cert: 
33             Master_SSL_Cipher: 
34                Master_SSL_Key: 
35         Seconds_Behind_Master: 0
36 Master_SSL_Verify_Server_Cert: No
37                 Last_IO_Errno: 0
38                 Last_IO_Error: 
39                Last_SQL_Errno: 0
40                Last_SQL_Error: 
41   Replicate_Ignore_Server_Ids: 
42              Master_Server_Id: 51
43                   Master_UUID: c8fcd56e-eb79-11e7-97b0-000c296c7a11
44              Master_Info_File: /application/mysql-5.6.36/data/master.info
45                     SQL_Delay: 0
46           SQL_Remaining_Delay: NULL
47       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
48            Master_Retry_Count: 86400
49                   Master_Bind: 
50       Last_IO_Error_Timestamp: 
51      Last_SQL_Error_Timestamp: 
52                Master_SSL_Crl: 
53            Master_SSL_Crlpath: 
54            Retrieved_Gtid_Set: 
55             Executed_Gtid_Set: c8fcd56e-eb79-11e7-97b0-000c296c7a11:1-3
56                 Auto_Position: 1
57 1 row in set (0.00 sec)

停掉主库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db01 ~]# /etc/init.d/mysqld stop

在db03上查看从库slave信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 mysql>  show slave status\G
 2 *************************** 1. row ***************************
 3                Slave_IO_State: Waiting for master to send event
 4                   Master_Host: 10.0.0.52
 5                   Master_User: repl
 6                   Master_Port: 3306
 7                 Connect_Retry: 60
 8               Master_Log_File: mysql-bin.000009
 9           Read_Master_Log_Pos: 191
10                Relay_Log_File: db03-relay-bin.000002
11                 Relay_Log_Pos: 361
12         Relay_Master_Log_File: mysql-bin.000009
13              Slave_IO_Running: Yes
14             Slave_SQL_Running: Yes
15               Replicate_Do_DB: 
16           Replicate_Ignore_DB: 
17            Replicate_Do_Table: 
18        Replicate_Ignore_Table: 
19       Replicate_Wild_Do_Table: 
20   Replicate_Wild_Ignore_Table: 
21                    Last_Errno: 0
22                    Last_Error: 
23                  Skip_Counter: 0
24           Exec_Master_Log_Pos: 191
25               Relay_Log_Space: 564
26               Until_Condition: None
27                Until_Log_File: 
28                 Until_Log_Pos: 0
29            Master_SSL_Allowed: No
30            Master_SSL_CA_File: 
31            Master_SSL_CA_Path: 
32               Master_SSL_Cert: 
33             Master_SSL_Cipher: 
34                Master_SSL_Key: 
35         Seconds_Behind_Master: 0
36 Master_SSL_Verify_Server_Cert: No
37                 Last_IO_Errno: 0
38                 Last_IO_Error: 
39                Last_SQL_Errno: 0
40                Last_SQL_Error: 
41   Replicate_Ignore_Server_Ids: 
42              Master_Server_Id: 52
43                   Master_UUID: c8fa1d13-eb79-11e7-97b0-000c29d60ab3
44              Master_Info_File: /application/mysql-5.6.36/data/master.info
45                     SQL_Delay: 0
46           SQL_Remaining_Delay: NULL
47       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
48            Master_Retry_Count: 86400
49                   Master_Bind: 
50       Last_IO_Error_Timestamp: 
51      Last_SQL_Error_Timestamp: 
52                Master_SSL_Crl: 
53            Master_SSL_Crlpath: 
54            Retrieved_Gtid_Set: 
55             Executed_Gtid_Set: c8fcd56e-eb79-11e7-97b0-000c296c7a11:1-3
56                 Auto_Position: 1
57 1 row in set (0.00 sec)

在db01上查看vip信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

在db02上查看vip信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 [root@db02 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:0a:b3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fed6:ab3/64 scope link 
       valid_lft forever preferred_lft forever

至此,VIP漂移就测试成功

1.6 配置binlog-server

1.6.1 配置binlog-server

1)前期准备:

1、准备一台新的mysql实例(db03),GTID必须开启。 2、将来binlog接收目录,不能和主库binlog目录一样

2)停止mha

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
masterha_stop --conf=/etc/mha/app1.cnf

3)在app1.cnf开启binlogserver功能

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [binlog1]
    no_master=1
    hostname=10.0.0.53                         ----> 主机DB03
    master_binlog_dir=/data/mysql/binlog/  ----> binlog保存目录

4)开启binlog接收目录,注意权限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mkdir -p /data/mysql/binlog/ 
chown -R mysql.mysql /data/mysql
# 进入目录启动程序
  cd /data/mysql/binlog/ &&\
  mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

  参数说明:-R 远程主机

5)启动mha

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

1.6.2 测试binlog备份

#查看binlog目录中的binlog

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 binlog]# ll
total 44
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001

#登录主库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@mysql-db01 ~]# mysql -uroot -p123

#刷新binlog

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> flush logs;

#再次查看binlog目录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 binlog]# ll
total 48
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001
-rw-r--r-- 1 root root 143 Mar  8 04:00 mysql-bin.000002

1.7 mysql中间件Atlas

1.7.1 atlas简介

  Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。

  同时,有超过50家公司在生产环境中部署了Atlas,超过800人已加入了我们的开发者交流群,并且这些数字还在不断增加。而且安装方便。配置的注释写的蛮详细的,都是中文。

  Atlas官方链接: https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md

  Atlas下载链接: https://github.com/Qihoo360/Atlas/releases

1.7.2 主要功能

  读写分离、从库负载均衡、自动分表、IP过滤

  SQL语句黑白名单、DBA可平滑上下线DB、自动摘除宕机的DB

Atlas相对于官方MySQL-Proxy的优势

1.将主流程中所有Lua代码用C重写,Lua仅用于管理接口 2.重写网络模型、线程模型 3.实现了真正意义上的连接池 4.优化了锁机制,性能提高数十倍

1.7.3 使用场景

  Atlas是一个位于前端应用与后端MySQL数据库之间的中间件,它使得应用程序员无需再关心读写分离、分表等与MySQL相关的细节,可以专注于编写业务逻辑,同时使得DBA的运维工作对前端应用透明,上下线DB前端应用无感知。

  Atlas是一个位于应用程序与MySQL之间中间件。在后端DB看来,Atlas相当于连接它的客户端,在前端应用看来,Atlas相当于一个DB。

  Atlas作为服务端与应用程序通讯,它实现了MySQL的客户端和服务端协议,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节,同时为了降低MySQL负担,它还维护了连接池.

1.7.4 企业读写分离及分库分表其他方案介绍

Mysql-proxy(oracle) Mysql-router(oracle) Atlas (Qihoo 360) Atlas-sharding (Qihoo 360) Cobar(是阿里巴巴(B2B)部门开发) Mycat(基于阿里开源的Cobar产品而研发) TDDL Smart Client的方式(淘宝) Oceanus(58同城数据库中间件) OneProxy(原支付宝首席架构师楼方鑫开发 ) vitess(谷歌开发的数据库中间件) Heisenberg(百度) TSharding(蘑菇街白辉) Xx-dbproxy(金山的Kingshard、当当网的sharding-jdbc ) amoeba

1.7.5 安装Atlas

  软件获取地址:https://github.com/Qihoo360/Atlas/releases

注意:

1、Atlas只能安装运行在64位的系统上 2、Centos 5.X安装 Atlas-XX.el5.x86_64.rpm,Centos 6.X安装Atlas-XX.el6.x86_64.rpm。 3、后端mysql版本应大于5.1,建议使用Mysql 5.6以上   Atlas (普通) : Atlas-2.2.1.el6.x86_64.rpm   Atlas (分表) : Atlas-sharding_1.0.1-el6.x86_64.rpm

下载安装atlas

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm

至此安装完成

1.7.6 配置Atlas配置文件

  atlas配置文件中的密码需要加密,可以使用,软件自带的加密工具进行加密

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd /usr/local/mysql-proxy/conf/
/usr/local/mysql-proxy/bin/encrypt  密码      ---->制作加密密码

生产密文密码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt 123
3yb5jEku5h4=
[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt mha
O2jBXONX098=

编辑配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vim  /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8

配置文件内为全中文注释,这里有一份较为详细的解释:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [mysql-proxy]
 2 #(必备,默认值即可)管理接口的用户名
 3 admin-username = user
 4 #(必备,默认值即可)管理接口的密码
 5 admin-password = pwd
 6 #(必备,根据实际情况配置)主库的IP和端口
 7 proxy-backend-addresses = 192.168.0.12:3306
 8 #(非必备,根据实际情况配置)从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔。如果想让主库也能分担读请求的话,只需要将主库信息加入到下面的配置项中
 9 proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306
10 #(必备,根据实际情况配置)用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,用户名与密码之间用冒号分隔。主从数据库上需要先创建该用户并设置密码(用户名和密码在主从数据库上要一致)。比如用户名为myuser,密码为mypwd,执行./encrypt mypwd结果为HJBoxfRsjeI=。如果有多个用户用逗号分隔即可。则设置如下行所示:
11 pwds = myuser: HJBoxfRsjeI=,myuser2:HJBoxfRsjeI=
12 #(必备,默认值即可)Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true
13 daemon = true
14 #(必备,默认值即可)设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true
15 keepalive = true
16 #(必备,根据实际情况配置)工作线程数,推荐设置成系统的CPU核数
17 # 对性能和正常运行起到重要作用
18 event-threads = 4
19 #(必备,默认值即可)日志级别,分为message、warning、critical、error、debug五个级别
20 log-level = message
21 #(必备,默认值即可)日志存放的路径
22 log-path = /usr/local/mysql-proxy/log
23 #(必备,根据实际情况配置)SQL日志的开关,可设置为OFFONREALTIMEOFF代表不记录SQL日志,ON代表记录SQL日志,该模式下日志刷新是基于缓冲区的,当日志填满缓冲区后,才将日志信息刷到磁盘。REALTIME用于调试,代表记录SQL日志且实时写入磁盘,默认为OFF
24 sql-log = OFF
25 #(可选项,可不设置)慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数则输出全部日志。
26 sql-log-slow = 10
27 #(可选项,可不设置)关闭不活跃的客户端连接设置。当设置了该参数时,Atlas会主动关闭经过'wait-timeout'时间后一直未活跃的连接。单位:秒
28 wait-timeout = 10
29 #(必备,默认值即可)Atlas监听的工作接口IP和端口;代表客户端应该使用1234这个端口连接Atlas来发送SQL请求。
30 proxy-address = 0.0.0.0:1234
31 #(必备,默认值即可)Atlas监听的管理接口IP和端口 ;代表DBA应该使用2345这个端口连接Atlas来执行运维管理操作。
32 admin-address = 0.0.0.0:2345
33 #(可选项,可不设置)分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项,子表需要事先建好,子表名称为表名_数字,数字范围为[0,子表数-1],如本例里,子表名称为mt_0、mt_1、mt_2
34 tables = person.mt.id.3
35 #(可选项,可不设置)默认字符集,若不设置该项,则默认字符集为latin1
36 charset = utf8
37 #(可选项,可不设置)允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
38 client-ips = 127.0.0.1, 192.168.1
39 #(可选项,极少需要)Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
40 lvs-ips = 192.168.1.1

1.7.7 启动Atlas

编写一个atlas的管理脚本,当然也可以写脚本,可以直接手动的管理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/usr/local/mysql-proxy/bin/mysql-proxyd test start   #启动
/usr/local/mysql-proxy/bin/mysql-proxyd test stop    #停止
/usr/local/mysql-proxy/bin/mysql-proxyd test restart #重启

  注意:test是配置文件的名称

脚本内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 [root@db03 ~]# cat /etc/init.d/atlasd 
 2 #!/bin/sh
 3 #
 4 # atlas:    Atlas Daemon
 5 #
 6 # chkconfig:    - 90 25
 7 # description:  Atlas Daemon
 8 # user:clsn
 9 # Blog: http://blog.nmtui.com
10 # Source function library.
11 
12 Demo=test
13 
14 start()
15 {
16         echo -n $"Starting atlas: "
17         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo start
18 }
19 stop()
20 {
21         echo -n $"Shutting down atlas: "
22         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo stop
23 }
24 status()
25 {
26         echo  $"Atlas status: "
27         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo status
28 }
29 restart()
30 {
31         echo $"Atlas Restart Info: "
32         /usr/local/mysql-proxy/bin/mysql-proxyd $Demo restart
33 }
34 
35 
36 ATLAS="/usr/local/mysql-proxy/bin/mysql-proxyd"
37 [ -f $ATLAS ] || exit 1
38 # See how we were called.
39 case "$1" in
40         start)
41                 start
42                 ;;
43         stop)
44                 stop
45                 ;;
46         restart)
47                 restart
48                 ;;
49         status)
50                 status
51                 ;;
52         *)
53                 echo $"Usage: $0 {start|stop|restart|status}"
54                 exit 1
55 esac
56 exit 0

检查端口是否正常

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# netstat -lntup|grep mysql-proxy
tcp        0      0 0.0.0.0:33060               0.0.0.0:*                   LISTEN      2125/mysql-proxy    
tcp        0      0 0.0.0.0:2345                0.0.0.0:*                   LISTEN      2125/mysql-proxy

1.7.8 Atlas管理操作

  登入管理接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@db03 ~]# mysql -uuser -ppwd -h127.0.0.1 -P2345

  查看帮助信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SELECT * FROM help;

  查看后端的代理库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.52:3306 | up    | ro   |
|           3 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

  平滑摘除mysql

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql>  REMOVE BACKEND 2;
Empty set (0.00 sec)

   检查是否摘除

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
2 rows in set (0.00 sec)

  保存到配置文件中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SAVE CONFIG;

  将节点再添加回来

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> add slave 10.0.0.52:3306;
Empty set (0.00 sec)

  查看是否添加成功

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
|           3 | 10.0.0.52:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

 保存到配置文件中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SAVE CONFIG;

1.7.9 连接数据库查看负载

通过atlas登陆数据,注意,使用的是数据库上的用户及密码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
shell> mysql -umha -pmha -h127.0.0.1 -P33060

第一次查询server_id

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 53    |
+---------------+-------+
1 row in set (0.00 sec)

第二次查询server_id

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 52    |
+---------------+-------+
1 row in set (0.00 sec)

通过上面可以看到负载成功

1.7.10 读写分离的说明

  Atlas会透明的将事务语句和写语句发送至主库执行,读语句发送至从库执行。具体以下语句会在主库执行:

显式事务中的语句

autocommit=0时的所有语句 含有select GET_LOCK()的语句 除SELECT、SET、USE、SHOW、DESC、EXPLAIN外的。

从库负载均衡配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy-read-only-backend-addresses=ip1:port1@权重,ip2:port2@权重

1.7.11 Atlas高级功能

自动分表

  使用Atlas的分表功能时,首先需要在配置文件test.cnf设置tables参数。

tables参数设置格式:数据库名.表名.分表字段.子表数量,比如:

你的数据库名叫school,表名叫stu,分表字段叫id,总共分为2张表,那么就写为school.stu.id.2,如果还有其他的分表,以逗号分隔即可。 用户需要手动建立2张子表(stu_0,stu_1,注意子表序号是从0开始的)。 所有的子表必须在DB的同一个database里。 当通过Atlas执行(SELECT、DELETE、UPDATE、INSERT、REPLACE)操作时,Atlas会根据分表结果(id%2=k),定位到相应的子表(stu_k)。 例如,执行select * from stu where id=3;,Atlas会自动从stu_1这张子表返回查询结果。 但如果执行SQL语句(select * from stu;)时不带上id,则会提示执行stu表不存在。

Atles功能的说明

Atlas暂不支持自动建表和跨库分表的功能。 Atlas目前支持分表的语句有SELECT、DELETE、UPDATE、INSERT、REPLACE。

IP过滤:client-ips

  该参数用来实现IP过滤功能。

  在传统的开发模式中,应用程序直接连接DB,因此DB会对部署应用的机器(比如web服务器)的IP作访问授权。

在引入中间层后,因为连接DB的是Atlas,所以DB改为对部署Atlas的机器的IP作访问授权,如果任意一台客户端都可以连接Atlas,就会带来潜在的风险。

  client-ips参数用来控制连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔写在一行上即可。

  如: client-ips=192.168.1.2, 192.168.2

  这就代表192.168.1.2这个IP和192.168.2.*这个段的IP可以连接Atlas,其他IP均不能连接。如果该参数不设置,则任意IP均可连接Atlas。如果设置了client-ips参数,且Atlas前面挂有LVS,则必须设置lvs-ips参数,否则可以不设置lvs-ips。

SQL语句黑白名单功能: Atlas会屏蔽不带where条件的delete和update操作,以及sleep函数。

1.8 Atlas-Sharding版本

1.8.1 版本介绍

  Sharding的基本思想就是把一个数据表中的数据切分成多个部分, 存放到不同的主机上去(切分的策略有多种), 从而缓解单台机器的性能跟容量的问题.

  sharding是一种水平切分, 适用于单表数据庞大的情景. 目前atlas支持静态的

  sharding方案, 暂时不支持数据的自动迁移以及数据组的动态加入.

  Atlas以表为单位sharding, 同一个数据库内可以同时共有sharding的表和不sharding的表, 不sharding的表数据存在未sharding的数据库组中.

  目前Atlas sharding支持insert, delete, select, update语句, 只支持不跨shard的事务. 所有的写操作如insert, delete, update只能一次命中一个组, 否则会报"ERROR 1105 (HY000):write operation is only allow to one dbgroup!"错误.

  由于sharding取替了Atlas的分表功能, 所以在Sharding分支里面, Atlas单机分表的功能已经移除, 配置tables将不会再有效.

1.8.2 Atlas-Sharding架构

1.8.3 Sharding配置示例

  Atlas支持非sharding跟sharding的表共存在同一个Atlas中, 2.2.1之前的配置可以直接运行. 之前的配置如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy-backend-addresses = 192.168.0.12:3306
proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306 ... 

  这配置了一个master和两个slave,这属于非sharding的组, 所有非sharding的表跟语句都会发往这个组内.

  所以之前没有Sharding的Atlas的表可以无缝的在新版上使用,

注意: 非Sharding的组只能配置一个, 而sharding的组可以配置多个. 下面的配置, 配置了Sharding的组, 注意与上面的配置区分

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[shardrule-0]
table = test.sharding_test

  分表名,有数据库+表名组成 t

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ype = range

  sharding类型:range 或 hash

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
shard-key = id

  sharding 字段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
groups = 0:0-999,1:1000-1999

  分片的group,如果是range类型的sharding,则groups的格式是:group_id:id范围。如果是hash类型的sharding,则groups的格式是:group_id。例如groups = 0, 1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[group-0]
proxy-backend-addresses=192.168.0.15:3306
proxy-read-only-backend-addresses=192.168.0.16:3306
[group-1]
proxy-backend-addresses=192.168.0.17:3306
proxy-read-only-backend-addresses=192.168.0.18:3306

1.8.4 Sharding限制

关于支持的语句

  Atlas sharding只对sql语句提供有限的支持, 目前支持基本的Select, insert/replace, delete,update语句,支持全部的Where语法(SQL-92标准), 不支持DDL(create drop alter)以及一些管理语句,DDL请直连MYSQL执行, 请只在Atlas上执行Select, insert, delete, update(CRUD)语句.

  对于以下语句, 如果语句命中了多台dbgroup, Atlas均未做支持(如果语句只命中了一个dbgroup, 如 select count(*) from test where id < 1000, 其中dbgroup0范围是0 - 1000, 那么这些特性都是支持的)Limit Offset(支持Limit)

Order by Group by Join ON Count, Max, Min等函数

增加节点

  注意: 暂时只支持range方式的节点扩展, hash方式由于需要数据迁移, 暂时未做支持.

  扩展节点在保证原来节点的范围不改变的情况下, 如已有dbgroup0为范围0 - 999, dbgroup1为范围 1000-1999, 这个时候可以增加范围>2000的节点. 如增加一个节点为2000 - 2999, 修改配置文件, 重启Atlas即可.

1.9 参考文献

[1] http://www.cnblogs.com/cenalulu/p/4309009.html [2] https://yq.aliyun.com/articles/57731 [3] https://www.jianshu.com/p/b68e429d09c7 [4] https://www.cnblogs.com/yyhh/archive/2015/12/29/5084844.html [5] http://blog.csdn.net/jhq0113/article/details/44302703 [6] http://blog.csdn.net/jhq0113/article/details/44239823 [7] https://www.guokr.com/blog/475765/ [8] http://blog.csdn.net/bluishglc/article/details/6161475/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-01-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
springboot(十一):Spring boot中mongodb的使用
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多。由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置漏洞被攻击,数据被删,引起了人们的注意,感兴趣的可以看看这篇文章:场屠戮MongoDB的盛宴反思:超33000个数据库遭遇入侵勒索,同时也说明了很多公司生产中大量使用mongodb。 mongodb简介 MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行
纯洁的微笑
2018/04/19
2.3K0
尚医通-MongoDB
NoSQL(NoSQL = Not Only SQL),意即反SQL运动,指的是非关系型的数据库,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入
用户9615083
2022/12/30
4.1K0
尚医通-MongoDB
芋道 Spring Boot MongoDB 入门
MongoDB 中的许多概念在 MySQL 中具有相近的类比。本表概述了每个系统中的一些常见概念。
芋道源码
2020/04/15
2.7K0
芋道 Spring Boot MongoDB 入门
MongoDB
​ MongoDB 是由 C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。
OY
2022/09/28
4.7K0
MongoDB
Springboot 整合 MongoDB
这节我们将整合 Spring Boot 与 Mongo DB 实现增删改查的功能,并且实现序列递增。
用户7630333
2023/12/07
7030
Springboot 整合 MongoDB
springboot之Mongo
MongoDB 是一个高性能,开源,无模式的文档型数据库,是当前 NoSql 数据库中比较热门的一种。
Vincent-yuan
2020/11/24
1.5K0
SpringBoot入门建站全系列(二十六)Mongodb非关系型数据库的使用
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
品茗IT
2019/09/09
4630
【探花交友】学习MongoDB快速入门上手
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
陶然同学
2023/02/24
3.5K0
【探花交友】学习MongoDB快速入门上手
Spring Boot 与 Kotlin 使用MongoDB数据库
下面就来简单介绍一下 MongoDB,并且通过一个例子来介绍 SpringBoot中对 MongoDB访问的配置和使用。
全科
2018/08/15
1.7K0
Spring和Mongodb非关系型数据库整合详解
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
品茗IT
2019/09/12
9260
SpringBoot整合MongoDB多数据源
依赖 // build.gradle implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' 配置文件 # application.yml spring: data: mongodb: primary: uri: mongodb://localhost:27017/db1 secondary: uri: mongodb://localhost:
wo.
2021/06/15
8100
[Java基础篇]Spring Boot整合MongoDB
1970 年 EFCodd 提出的关系模型的论文“Arelational model of data for large shared databases”,这部分数据有很大一部分关系数据库管理系统(RDBMS)来。简单。
苏州程序大白
2022/04/14
1.1K0
[Java基础篇]Spring Boot整合MongoDB
Spring Boot 2.x基础教程:使用MongoDB
前段时间因为团队调整,大部分时间放在了团队上,这系列的更新又耽误了一下。但既然承诺持久更新,那就不会落下,今天开始继续更新这部分的内容!
程序猿DD
2021/03/09
1.8K0
SpringBoot整合mongoDB
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。 这一片文章介绍一个springboot整合mongodb,如果你了解整合mysql之类的
dalaoyang
2018/06/14
6620
springboot 整合 MongoDB 实现登录注册,html 页面获取后台参数的方法
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
Krry
2018/09/10
4.2K0
springboot 整合 MongoDB 实现登录注册,html 页面获取后台参数的方法
【探花交友】day03—MongoDB基础
在tanhua-server工程创建SettingsController完成代码编写
陶然同学
2023/04/08
3.2K0
【探花交友】day03—MongoDB基础
SpringBoot整合Spring Data Mongodb
文章目录 1. SpringBoot整合Spring Data Mongodb 1.1. 简介 1.2. 何时使用 1.3. 安装 1.4. 概念解析 1.5. 使用 1.6. 分页查询 1.7. 常用的查询关键字 1.8. 事务 1.9. 源码 SpringBoot整合Spring Data Mongodb 简介 MongoDB是一款面向文档的数据库,类似json(Bson)的数据存储格式 何时使用 数据量大 数据价值较低 安装 docker pull mongo docker run --name
爱撒谎的男孩
2019/12/31
1.7K0
Spring Data MongoDB问题汇总
Spring Data除了常用的JPA(Hibernate)关系型数据库的模块外,还有其他用于非关系型数据库的数据交互模块:比如Redis、MongoDB、Elasticsearch等。
雨临Lewis
2022/01/12
2.1K0
springboot整合mongodb
想写这篇文章有好久了,可是一直没有时间坐下来去好好去写这一篇自己喜欢的文章了,也算是自己的一次总结吧。
码农王同学
2020/03/25
4580
Spring Cloud整合MongoDB示例
1. 文档型数据库:MongoDB 中的数据以JSON-like的BSON(Binary JSON)格式存储,数据模型更加灵活,每个文档可以有不同的字段和结构,这不同于关系型数据库的严格表格结构。
用户7353950
2024/04/15
4700
Spring Cloud整合MongoDB示例
相关推荐
springboot(十一):Spring boot中mongodb的使用
更多 >
LV.1
smart嵌入式技术经理
目录
  • 1.1 MHA简介
    • 1.1.1 MHA软件介绍
    • 1.1.2 MHA工作原理
    • 1.1.3 MHA高可用架构图
    • 1.1.4 MHA工具介绍
    • 1.1.5 MHA的优点
  • 1.2 环境说明
    • 1.2.1 系统环境说明
    • 1.2.2 mysql软件说明
  • 1.3 基于GTID的主从复制配置
    • 1.3.1 先决条件
    • 1.3.2 配置主从复制
    • 1.3.3 GTID复制技术说明
    • 1.3.4 COM_BINLOG_DUMP_GTID
    • 1.3.5 【示例二】MySQL GTID复制配置
  • 1.4 部署MHA
    • 1.4.1 环境准备(所有节点操作)
    • 1.4.2 部署管理节点(mha-manager)
    • 1.4.3 启动mha
    • 1.4.4 切换master测试
    • 1.4.5 设置权重
  • 1.5 配置VIP漂移
    • 1.5.1 IP漂移的两种方式
    • 1.5.2 MHA脚本方式
    • 1.5.3 测试虚拟IP漂移
  • 1.6 配置binlog-server
    • 1.6.1 配置binlog-server
    • 1.6.2 测试binlog备份
  • 1.7 mysql中间件Atlas
    • 1.7.1 atlas简介
    • 1.7.2 主要功能
    • 1.7.3 使用场景
    • 1.7.4 企业读写分离及分库分表其他方案介绍
    • 1.7.5 安装Atlas
    • 1.7.6 配置Atlas配置文件
    • 1.7.7 启动Atlas
    • 1.7.8 Atlas管理操作
    • 1.7.9 连接数据库查看负载
    • 1.7.10 读写分离的说明
    • 1.7.11 Atlas高级功能
  • 1.8 Atlas-Sharding版本
    • 1.8.1 版本介绍
    • 1.8.2 Atlas-Sharding架构
    • 1.8.3 Sharding配置示例
    • 1.8.4 Sharding限制
  • 1.9 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档