文章目录
一、MySQL中间件代理服务器
数据库主要分为两大类:关系型数据库与 NoSQL 数据库(非关系型数据库)。
数据库主要分为两大类:关系型数据库与 NoSQL 数据库。
关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(Redis、memcached)、永久性键值存储(ROMA、Redis)、面向文档的数据库(MongoDB、CouchDB)、面向列的数据库(Cassandra、HBase),每种 NoSQL 都有其特有的使用场景及优点。
Oracle,mysql 等传统的关系数据库非常成熟并且已大规模商用,为什么还要用 NoSQL 数据库呢?主要是由于随着互联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高。
RDBMS和NOSQL的特点及优缺点:
MySQL 中间件应用
Mycat
Mycat应用场景
- Mycat适用的场景很丰富,以下是几个典型的应用场景:
- 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换。
- 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片。
- 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化报表系统,借助于Mycat的分表能力,处理大规模报表的统计。
- 替代Hbase,分析大数据,作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择。
Mycat部署
mycat安装目录结构说明
- bin:mycat命令,启动、重启、停止等运行目录
- catlet: catlet为Mycat的一个扩展功能
- conf :mycat 配置信息,重点关注
- lib:mycat引用的jar包,Mycat是java开发的
- logs :日志文件,包括Mycat启动的日志和运行的日志
- version.txt:mycat版本说明
mycat常用配置文件
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
- server.xml:Mycat软件本身相关的配置文件,设置账号、参数等。
-schema.xml:Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制。
-rule.xml:Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等。
mycat
Mycat的日志文件都在logs目录里面:
-wrapper.log:mycat启动日志
- mycat.log :mycat详细工作日志
实现读写分离
环境准备:
mycat服务器上不能装mysql!
master 服务器 192.168.232.10
slave服务器 192.168.232.20
mycat服务器192.168.232.40
主从复制这里不做具体介绍。
安装mycat
主机需要安装java,mycat是基于java。
bash
yum install java -y
下载mycat的二进制包
tar zxvf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /apps/
解压mycat包至/apps
echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh
设置环境变量
source /etc/profile.d/mycat.sh
bash
tail -f /apps/mycat/logs/wrapper.log
启动成功后,日志末尾会出现successfully
客户端连接数据库
客户端上也需要安装mysql,初始连接密码为123456,且需要加端口号8066。
bash
mysql -uroot -p123456 -h 192.168.232.40 -P8066
修改mycat配置文件
bash
vim /apps/mycat/conf/server.xml
去掉44行行注释,对应的在51行行末注释,删除50行行末注释
修改45行端口号3306
配置Mycat的连接信息(账号密码),在110 和111行。
其他参数解释
bash
110 <user name="root" defaultAccount="true">
111 <property name="password">123456</property>
112 <property name="schemas">TESTDB</property>
113 <property name="defaultSchema">TESTDB</property>
116 <!-- 表级 DML 权限设置 -->
117 <!--
118 <privileges check="false">
119 <schema name="TESTDB" dml="0110" >
120 <table name="tb01" dml="0000"></table>
121 <table name="tb02" dml="1111"></table>
122 </schema>
123 </privileges>
124 -->
127 <user name="user">
128 <property name="password">user</property>
129 <property name="schemas">TESTDB</property>
130 <property name="readOnly">true</property>
131 <property name="defaultSchema">TESTDB</property>
user 用户配置节点
name 逻辑用户名,客户端登录MyCAT的用户名,也就是客户端用来连接Mycat的用户名。
password 客户端登录MyCAT的密码
schemas 数据库名,这里会和schema.xml中的配置关联,可配置多个,多个用逗号分开,例如:db1,db2
privileges 配置用户针对表的增删改查的权限
readOnly mycat 逻辑库所具有的权限。true为只读,false为读写都有,默认为false
注意
1.#server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息
2.#逻辑库名(如上面的TESTDB,也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败!这里只定义了一个标签,所以把多余的都注释了。如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库!
修改mycat配置文件/apps/mycat/conf/schema.xml
schema.xml是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的。
bash
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
<dataNode name="dn1" dataHost="localhost1" database="hellodb" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="host1" url="192.168.232.10:3306" user="root" password="Admin@123">
<readHost host="host2" url="192.168.232.20:3306" user="root" password="Admin@123"/>
</writeHost>
</dataHost>
</mycat:schema>
主服务器上授权
bash
GRANT ALL ON *.* TO 'root'@'192.168.91.%' IDENTIFIED BY 'Admin@123';
这个账号主要是让mycat远程登录上来的,赋予一定的权限,
且注意这个用户名要和mycat配置文件里的用户名一致。
重启mycat服务
bash
mycat restart
tail -f /apps/mycat/logs/wrapper.log
登录上去的截图。
客户端测试读写分离
主从服务器上都打开通用日志
bash
set global general_log=1;打开通用日志
show variables like 'general%';查看通用日志是否开启
tail -f /var/lib/mysql/localhost.log
这是通用日志的位置。
二、MySQL高可用
高可用解决方案
- MMM: Multi-Master Replication Manager for MySQL,Mysql主主复制管理器是一套灵活的脚本程序,基于perl实现,用来对mysql replication进行监控和故障迁移,并能管理mysql MasterMaster复制的配置(同一时间只有一个节点是可写的)
bash
官网: http://www.mysql-mmm.org
https://code.google.com/archive/p/mysql-master-master/downloads
- MHA:Master High Availability,对主节点进行监控,可实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,出于机器成本的考虑,淘宝进行了改造,目前淘宝TMHA已经支持一主一从。
bash
官方网站:https://code.google.com/archive/p/mysql-master-ha/
https://github.com/yoshinorim/mha4mysql-manager/releases
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58
- Galera Cluster:wsrep(MySQL extended with the Write Set Replication)通过wsrep协议在全局实现复制;任何一节点都可读写,不需要主从复制,实现多主读写。
- GR(Group Replication):MySQL官方提供的组复制技术(MySQL 5.7.17引入的技术),基于原生复制技术Paxos算法,实现了多主更新,复制组由多个server成员构成,组中的每个server可独立地执行事务,但所有读写事务只在冲突检测成功后才会提交。
这3个节点互相通信,每当有事件发生,都会向其他节点传播该事件,然后协商,如果大多数节点都同意这次的事件,那么该事件将通过,否则该事件将失败或回滚。这些节点可以是单主模型的(single-primary),也可以是多主模型的(multi-primary)。单主模型只有一个主节点可以接受写操作,主节点故障时可以自动选举主节点。多主模型下,所有节点都可以接受写操作,所以没有master-slave的概念。
MHA高可用
集群架构
执行过程:
-
MHA利用 SELECT 1 As Value 指令判断master服务器的健康性,一旦master 宕机,MHA 从宕机崩溃的master保存二进制日志事件(binlog events)。
-
识别含有最新更新的slave。
-
应用差异的中继日志(relay log)到其他的slave。
-
应用从master保存的二进制日志事件(binlog events)。
-
提升一个slave为新的master。
-
使其他的slave连接新的master进行复制。
MHA软件组成
MHA软件由两部分组成,Manager工具包和Node工具包。
Manager工具包
bash
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 故障转移(自动或手动)
masterha_conf_host 添加或删除配置的server信息
masterha_stop --conf=app1.cnf 停止MHA
masterha_secondary_check 两个或多个网络线路检查MySQL主服务器的可用
Node工具包
bash
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用此工具)
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
注意:这些工具通常由MHA Manager的脚本触发,无需人为操作。
实现MHA
架构
MHA管理节点:192.168.232.40
主服务器:192.168.232.10
从服务器1:192.168.232.20
从服务器2:192.168.232.30
MHA管理节点
bash
yum install epel-release.noarch -y
准备mharpm包
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm
yum安装这些包。
其余节点
bash
yum install epel-release.noarch -y
yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
安装客户端即可。
配置ssh
所有节点都需要免密登录。
免密登录脚本
bash
#!/bin/bash
PASS=123123
#设置网段最后的地址,4-255之间,越小扫描越快
END=254
IP=`ip a s ens33 | awk -F'[ /]+' 'NR==3{print $3}'`
NET=${IP%.*}.
rm -f /root/.ssh/id_rsa
[ -e ./SCANIP.log ] && rm -f SCANIP.log
for((i=3;i<="$END";i++));do
ping -c 1 -w 1 ${NET}$i &> /dev/null && echo "${NET}$i" >> SCANIP.log &
done
wait
ssh-keygen -P "" -f /root/.ssh/id_rsa
rpm -q sshpass || yum -y install sshpass
sshpass -p $PASS ssh-copy-id -o StrictHostKeyChecking=no $IP
AliveIP=(`cat SCANIP.log`)
for n in ${AliveIP[*]};do
sshpass -p $PASS scp -o StrictHostKeyChecking=no -r /root/.ssh root@${n}:
done
主节点建立mha文件夹和配置文件
bash
mkdir /etc/mastermha
vim /etc/mastermha/app1.cnf
[server default]
user=mhauser
password=Admin@123
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
ssh_user=root
repl_user=test
repl_password=Admin@123
ping_interval=1
master_ip_failover_script=/usr/local/bin/master_ip_failover
check_repl_delay=0
master_binlog_dir=/data/mysql/
[server1]
hostname=192.168.232.10
candidate_master=1
[server2]
hostname=192.168.232.20
candidate_master=1
[server3]
hostname=192.168.232.30
准备切换脚本
bash
vim 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 = '192.168.232.188/24';
my $gateway = '192.168.232.2';
my $interface = 'ens33';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key $vip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$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" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
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" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
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";
`ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`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";
}
移动脚本位置
bash
cp master_ip_failover /usr/local/bin/
在mha的配置文件中是规定了的。
chmod +x /usr/local/bin/master_ip_failover
加上执行权限。
主从服务器配置
即是一主两从,主从复制配置省略。
注意,要在主上面创建两个用户。
bash
grant replication slave on *.* to test@'192.168.91.%' identified by 'Admin@123';
#建立复制用户
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> grant all on *.* to mhauser@'192.168.91.%' identified by 'Admin@123';
#建立 mha管理账户
Query OK, 0 rows affected, 1 warning (0.00 sec)
设置虚拟地址
在mysql主节点上配置虚拟地址。
bash
ifconfig ens33:1 192.168.232.188/24
运行前进行环境检测
检测免密登录是否成功
bash
masterha_check_ssh --conf=/etc/mastermha/app1.cnf
注意:如果设置了默认字符集起不开。
检测主从复制是否可以
bash
masterha_check_repl --conf=/etc/mastermha/app1.cnf
查看mha是否开启
bash
masterha_check_status --conf=/etc/mastermha/app1.cnf
开启MHA
bash
#开启MHA,默认是前台运行,生产环境一般为后台执行
nohup masterha_manager --conf=/etc/mastermha/app1.cnf &> /dev/null
#非后台
masterha_manager --conf=/etc/mastermha/app1.cnf
#查看状态
masterha_check_status --conf=/etc/mastermha/app1.cnf
测试
mha如何发现主节点宕机
通过发送 SELECT 1 As Value 指令 ,把1 设置成 value 给主, 主无法执行就认为他死了。
查看 mha 服务的日志
模拟关闭主服务器,查看是否会切换至从服务器。
再次查看mba服务日志。
虚拟ip地址也在原来的从服务器上出现。
实验成功。