MyCat高可用负载均衡集群的实现(HAProxy + Keepalived + MyCat)
- 一、MySQL源码编译安装(CentOS-6.6+MySQL-5.6)
- ①、服务器配置:
- 1、配置网络
- 2、设置主机名
- 3、设置IP与主机名的映射
- 4、两台数据库服务器的的selinux都要disable
- 5、重启操作系统
- ②、源码安装MySQL5.6.26:
- 1、使用下面的命令检查是否安装有MySQL Server:
- 2、改防火墙设置,打开3306端口:
- 3、新增mysql用户组:
- 4、新增mysql用户,并添加到mysql用户组:
- 5、新建MySQL执行文件目录(后面会把编译好的mysql程序安装到这个目录):
- 6、新建MySQL数据库数据文件目录:
- 7、增加PATH环境变量搜索路径:
- 8、安装编译MySQL需要的依赖包:
- 9、进入/usr/local/src目录,上传mysql-5.6.26.tar.gz源代码到/usr/local/src目录:
- 10、开始编译安装mysql-5.6.26:
- 11、cmake结束后开始编译源码,这一步时间会较长,请耐心等待:
- 12、安装编译好的程序:
- 13、清除安装临时文件:
- 14、修改mysql目录拥有者为mysql用户:
- 15、进入mysql执行程序的安装路径:
- 16、执行初始化配置脚本,创建系统自带的数据库和表(注意:路径/home/mysql/data需要换成你自定定义的数据库存放路径):
- 17、初始化脚本在/usr/local/mysql/下生成了配置文件my.cnf,需要更改该配置文件的所有者:
- 18、注意:
- (1)Tips:在启动MySQL服务时,会按照一定次序搜索my.cnf,先在/etc目录下找,找不到则会搜索mysql程序目录下是否有my.cnf
- (2)需要注意CentOS 6版操作系统的最小安装完成后,即使没有安装mysql,在/etc目录下也会存在一个my.cnf文件,建议将此文件更名为其他的名字,否则该文件会干扰源码安装的MySQL的正确配置,造成无法启动。修改/etc/my.cnf操作如下:
- 19、编辑/etc/my.cnf:
- 20、复制服务启动脚本:
- 21、启动MySQL服务:
- 22、设置MySQL开机自动启动服务:
- 23、登录并修改MySQL用户root的密码:
- 24、运行安全设置脚本,强烈建议生产服务器使用(可选):
- 25、重启服务器,检测mysql是否能开机自动启动:
- 二、MySQL主从复制的配置
- ①主从配置的简要步骤
- ②单向主从环境(也称MySQL A/B复制)的搭建
- 1、Master(192.168.0.240)和Slave(192.168.0.241)上都安装了相同版本的数据库(mysql-5.6.26.tar.gz),从节点与主节点安装流程一样。
- 2、修改Master的配置文件/etc/my.cnf
- 在 [mysqld] 中增加以下配置项
- 2.1 复制过滤可以让你只复制服务器中的一部分数据,有两种复制过滤:
- 2.2 MySQL对于二进制日志 (binlog)的复制类型
- 3、启动/重启Master数据库服务,登录数据库,创建数据同步用户,并授予相应的权限
- 4、创建test库、表,并写入一定量的数据,用于模拟现有的业务系统数据库
- 5、为保证Master和Slave的数据一致,我们采用主备份,从还原来实现初始数据一致
- 6、接下来处理Slave(192.168.0.241),配置文件只需修改一项,其余配置用命令来操作
- 7、保存后重启MySQL服务,还原备份数据
- 8、登录Slave数据库,添加相关参数
- 9、主从数据复制同步测试
- (1) 在Master中的test库上变更数据的同步测试;
- (2) 在Master上新建一个ron库
- 10、测试过程中,如果遇到同步出错,可在Slave上重置主从复制设置(选操作):
- 11、MySQL主从数据同步延迟问题的调优
- 三、MyCat在MySQL主从复制基础上实现读写分离
- ①MyCat介绍 ( MyCat官网:[http://mycat.org.cn/](http://mycat.org.cn/) )
- ②MyCat的安装
- 1、设置MyCat的主机名和IP与主机名的映射
- 2、因为MyCat是用Java开发的,因此MyCat运行需要安装JDK(准确来说是JRE就够了),并且需要JDK1.7或以上版本
- 3、创建mycat用户并设置密码
- 4、上传安装包 Mycat-server-1.4-release-20151019230038-linux.tar.gz 到 MyCat服务器中的/home/mycat目录,并解压并移动到 /usr/local/mycat目录
- 5、设置MyCat的环境变量
- ③配置MyCat
- 1、在配置MyCat前,请确认MySQL的主从复制安装配置已完成并正常运行。MySQL主从数据的同步在MySQL中配置,MyCat不负责数据同步的问题。
- 2、配置MyCat的schema.xml
- 3、配置 server.xml
- 4、防火墙中打开8066和9066端口
- 5、修改log日志级别为debug,以便通过日志确认基于MyCat的MySQL数据库集群读写分离的数据操作状态(可以在正式上生产前改成info级别)
- 6、启动MyCat
- 7、MyCat连接测试
- 8、读写分离测试
- (1) 监听MyCat日志
- (2) 读测试
- (3) 写测试
- 四、MyCat集群部署(HAProxy + MyCat)
- ①部署环境规划
- 1、MyCat节点2的部署
- 2、配置MyCat状态检查服务(在MyCat节点主机上配置)
- ②HAProxy介绍
- 1、HAProxy的安装(192.168.0.236)
- ③HAProxy配置MyCat负载均衡集群
- 1、修改haproxy.cfg 配置文件
- 2、根据以上HAProxy配置文件要求做以下配置
- 3、开启rsyslog的haproxy日志记录功能
- 4、配置系统内核的IP包转发功能
- 5、启动HAProxy
- 6、使用MySQL客户端通过HAProxy连接MyCat
- 7、登录HAProxy的状态信息统计页面
- 五、MyCat高可用负载均衡集群的实现(HAProxy + Keepalived + MyCat)
- ①部署环境规划
- ②HAProxy节点2的部署
- ③Keepalived介绍 (官网:[http://www.haproxy.org/](http://www.haproxy.org/) )
- ④Keepalived的安装(192.168.0.236、192.168.0.237)
- ⑤Keepalived + Haproxy的高可用测试
- ⑥通过vip访问数据库、验证vip切换后的数据库访问
一、MySQL源码编译安装(CentOS-6.6+MySQL-5.6)
- 部署环境
- 操作系统:CentOS-6.6-x86_64-bin-DVD1.iso
- MySQL版本:mysql-5.6.26.tar.gz
- 操作用户:root
- 系统IP:192.168.0.240
- 主机名:edu-mysql-01
- 配置:4核、4G内存
①、服务器配置:
1、配置网络
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.240
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=192.168.0.1
2、设置主机名
# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=edu-mysql-01
3、设置IP与主机名的映射
127.0.0.1 edu-mysql-01
192.168.0.240 edu-mysql-01
4、两台数据库服务器的的selinux都要disable
- (永久关闭selinux,请修改/etc/selinux/config,将SELINUX改为disabled)
# vi /etc/selinux/config
SELINUX=disabled
5、重启操作系统
②、源码安装MySQL5.6.26:
1、使用下面的命令检查是否安装有MySQL Server:
# rpm -qa | grep mysql
mysql-libs-5.1.73-3.el6_5.x86_64
- 如果是CentOS7以上,请使用以下命令查看:
# rpm -qa | grep mariadb
mariadb-libs-5.5.41-2.el7_0.x86_64
- (因为没有MySQL服务,因此没必要卸载。mysql-libs是MySQL的必要包)
- (如果有的话可通过下面的命令来卸载掉,rpm -e mysql //普通删除模式)
2、改防火墙设置,打开3306端口:
# vi /etc/sysconfig/iptables
- 增加如下行:
## MySQL
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
- 重启防火墙:
# service iptables restart
3、新增mysql用户组:
4、新增mysql用户,并添加到mysql用户组:
# useradd -r -g mysql mysql
5、新建MySQL执行文件目录(后面会把编译好的mysql程序安装到这个目录):
# mkdir -p /usr/local/mysql
- (-p 参数的作用是:如果最终目录的父目录不存在也会一并创建)
6、新建MySQL数据库数据文件目录:
# mkdir -p /home/mysql/data
# mkdir -p /home/mysql/logs
# mkdir -p /home/mysql/temp
- (注意:上面的logs及temp目录是为了以后将MySQL的数据文件与执行程序文件分离,如果你打算设置到不同的路径,注意修改对应的执行命令和数据库初始化脚本。正式生产环境,建议数据目录和日志目录都使用单独的分区来挂载,不同分区属于不同的磁盘或磁盘组。)
7、增加PATH环境变量搜索路径:
# vi /etc/profile
- ##在profile文件末尾增加两行
# mysql env param
PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
export PATH
- 使PATH搜索路径立即生效:
# source /etc/profile
8、安装编译MySQL需要的依赖包:
- (mysql从5.5版本开始,不再使用./configure编译,而是使用cmake编译器,具体的cmake编译参数可以参考mysql官网文档http://dev.mysql.com/doc/refman/5.5/en/source-configuration-options.html,安装基本依赖包,先用yum安装cmake、automake 、autoconf ,另MySQL 5.5.x需要最少安装的包有:bison,gcc、gcc-c++、ncurses-devel):
# yum install make cmake gcc gcc-c++ bison bison-devel ncurses ncurses-devel autoconf automake
9、进入/usr/local/src目录,上传mysql-5.6.26.tar.gz源代码到/usr/local/src目录:
10、开始编译安装mysql-5.6.26:
- 解压缩源码包:
# tar -zxvf mysql-5.6.26.tar.gz
- 进入解压缩源码目录:
# cd mysql-5.6.26
- 使用cmake源码安装mysql(如果你打算安装到不同的路径,注意修改下面语句中/usr/local/mysql和/home/mysql/data路径!)
[root@edu-mysql-01 mysql-5.6.26]# cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_DATADIR=/home/mysql/data \
-DMYSQL_USER=mysql \
-DMYSQL_TCP_PORT=3306 \
-DENABLE_DOWNLOADS=1
- 上面的这些复制完,回车,然后就开始cmake的过程,一般时间不会很长。
配置解释:
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql 设置安装目录
-DMYSQL_DATADIR=/home/mysql/data 设置数据库存放目录
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock 设置UNIX socket 目录
-DMYSQL_USER=mysql 设置运行用户
-DDEFAULT_CHARSET=utf8 设置默认字符集,默认latin1
-DEFAULT_COLLATION=utf8_general_ci 设置默认校对规则,默认latin1_general_ci
-DWITH_INNOBASE_STORAGE_ENGINE=1 添加InnoDB引擎支持
-DENABLE_DOWNLOADS=1 自动下载可选文件,比如自动下载谷歌的测试包
-DMYSQL_TCP_PORT=3306 设置服务器监听端口,默认3306
-DSYSCONFDIR=/etc 设置my.cnf所在目录,默认为安装目录)
- 执行过程中可能会出现:
- CMake Error: Problem with tar_extract_all(): Invalid argument
- CMake Error: Problem extracting tar: /usr/local/src/mysql-5.6.26/source_downloads/gmock-1.6.0.zip
- 解决方法:
- cd mysql目录下面会发现有一个source_downloads目录,需要解压unzip gmock-1.6.0.zip,然后再重新执行上述配置过程。当然你也可以去掉-DENABLE_DOWNLOADS=1这个选项,不编译谷歌的测试包也没有什么问题,但是之前的某些版本会出现无法编译的问题.
11、cmake结束后开始编译源码,这一步时间会较长,请耐心等待:
12、安装编译好的程序:
# make install
- (注意:如果需要重装mysql,在/usr/local/src/mysql-5.6.26在执行下make install就可以了,不需要再cmake和make)
13、清除安装临时文件:
14、修改mysql目录拥有者为mysql用户:
# chown -Rf mysql:mysql /usr/local/mysql
# chown -Rf mysql:mysql /home/mysql
15、进入mysql执行程序的安装路径:
16、执行初始化配置脚本,创建系统自带的数据库和表(注意:路径/home/mysql/data需要换成你自定定义的数据库存放路径):
# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/home/mysql/data
17、初始化脚本在/usr/local/mysql/下生成了配置文件my.cnf,需要更改该配置文件的所有者:
# ls -lah
[root@edu-mysql-01 mysql] # chown -Rf mysql:mysql /usr/local/mysql/my.cnf
18、注意:
(1)Tips:在启动MySQL服务时,会按照一定次序搜索my.cnf,先在/etc目录下找,找不到则会搜索mysql程序目录下是否有my.cnf
(2)需要注意CentOS 6版操作系统的最小安装完成后,即使没有安装mysql,在/etc目录下也会存在一个my.cnf文件,建议将此文件更名为其他的名字,否则该文件会干扰源码安装的MySQL的正确配置,造成无法启动。修改/etc/my.cnf操作如下:
- 可以:mv /etc/my.cnf /etc/my.cnf.bak
- 也可以:删除掉/etc/my.cnf这个文件:rm /etc/my.cnf
- 如果你需要用于生产环境,不要急着做下面的mysql启动操作。建议把上一步骤中mysql初始化生成的/usr/local/mysql/my.cnf删除,然后把你优化好的mysql配置文件my.cnf放到/etc下。(这是做mysql主从复制和mysql优化的经验!)
- (我们这里使用/etc/my.cnf)
19、编辑/etc/my.cnf:
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
character-set-server = utf8
collation-server = utf8_general_ci
skip-external-locking
skip-name-resolve
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /home/mysql/data
tmpdir = /home/mysql/temp
# server_id = .....
socket = /usr/local/mysql/mysql.sock
log-error = /home/mysql/logs/mysql_error.log
pid-file = /home/mysql/mysql.pid
open_files_limit = 10240
back_log = 600
max_connections=500
max_connect_errors = 6000
wait_timeout=605800
#open_tables = 600
#table_cache = 650
#opened_tables = 630
max_allowed_packet = 32M
sort_buffer_size = 4M
join_buffer_size = 4M
thread_cache_size = 300
query_cache_type = 1
query_cache_size = 256M
query_cache_limit = 2M
query_cache_min_res_unit = 16k
tmp_table_size = 256M
max_heap_table_size = 256M
key_buffer_size = 256M
read_buffer_size = 1M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
lower_case_table_names=1
default-storage-engine = INNODB
innodb_buffer_pool_size = 2G
innodb_log_buffer_size = 32M
innodb_log_file_size = 128M
innodb_flush_method = O_DIRECT
#####################
thread_concurrency = 32
long_query_time= 2
slow-query-log = on
slow-query-log-file = /home/mysql/logs/mysql-slow.log
[mysqldump]
quick
max_allowed_packet = 32M
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
20、复制服务启动脚本:
# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
21、启动MySQL服务:
# service mysql start
- (初次启动会在/usr/local/mysql目录下生成mysql.sock文件)
22、设置MySQL开机自动启动服务:
# chkconfig mysql on
- 设置MySQL数据库root用户的本地登录密码(初始用户没有密码):
# mysqladmin -u root password '123456'
23、登录并修改MySQL用户root的密码:
# mysql -uroot -p
- Enter password:
mysql> use mysql;
- 修改root用户密码:
mysql> update user set Password = password('123456') where User='root';
mysql> flush privileges;
- 允许root远程登录,设置远程登录密码:654321
mysql> use mysql;
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '654321' WITH GRANT OPTION;
mysql> flush privileges;
mysql> exit;
- 注意:真实生产环境,应用操作不要使用root用户。
24、运行安全设置脚本,强烈建议生产服务器使用(可选):
[root@edu-mysql-01 ~]# /usr/local/mysql/bin/mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none): ----->此处输入root密码
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
You already have a root password set, so you can safely answer 'n'.
Change the root password? [Y/n] n -----> 上已为root设置了密码,此处可输n
... skipping.
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] Y ------> 删除匿名用户
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] n -----> 一般不允许root远程登录,可添加普通用户,然后设置允许远程登录
... skipping.
By default, MySQL comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] Y -----> 删除test库及相应权限
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] Y -----> 重新加载权限表使设置生效
... Success!
All done! If you've completed all of the above steps, your MySQL
installation should now be secure.
Thanks for using MySQL!
Cleaning up...
25、重启服务器,检测mysql是否能开机自动启动:
[root@edu-mysql-01 ~] # reboot
二、MySQL主从复制的配置
- 环境
- 操作系统:CentOS-6.6-x86_64-bin-DVD1.iso
- MySQL版本:mysql-5.6.26.tar.gz
- 主节点IP:192.168.0.240 主机名:edu-mysql-01
- 从节点IP:192.168.0.241 主机名:edu-mysql-02
- 主机配置:4核CPU、4G内存
- MySQL主从复制官方文档
http://dev.mysql.com/doc/refman/5.6/en/replication.html
- MySQL主从复制的方式
- MySQL5.6开始主从复制有两种方式:基于日志(binlog)、基于GTID(全局事务标示符),此处使用基于日志(binlog)的复制。
- MySQL主从复制(也称A/B复制)的原理
- (1) Master将数据改变记录到二进制日志(binary log)中,也就是配置文件log-bin指定的文件,这些记录叫做二进制日志事件(binary log events);
- (2) Slave通过I/O线程读取Master中的binary log events并写入到它的中继日志(relay log);
- (3) Slave重做中继日志中的事件,把中继日志中的事件信息一条一条的在本地执行一次,完成数据在本地的存储,从而实现将改变反映到它自己的数据(数据重放)。
- 主从配置需要注意的点
- (1)主从服务器操作系统版本和位数一致;
- (2) Master和Slave数据库的版本要一致;
- (3) Master和Slave数据库中的数据要一致;
- (4) Master开启二进制日志,Master和Slave的server_id在局域网内必须唯一;
①主从配置的简要步骤
1、Master上的配置
- (1) 安装数据库;
- (2) 修改数据库配置文件,指明server_id,开启二进制日志(log-bin);
- (3) 启动数据库,查看当前是哪个日志,position号是多少;
- (4) 登录数据库,授权数据复制用户(IP地址为从机IP地址,如果是双向主从,这里的还需要授权本机的IP地址,此时自己的IP地址就是从IP地址);
- (5) 备份数据库(记得加锁和解锁);
- (6) 传送备份数据到Slave上;
- (7) 启动数据库;
- 以下步骤,为单向主从搭建成功,想搭建双向主从需要的步骤:
- (1) 登录数据库,指定Master的地址、用户、密码等信息(此步仅双向主从时需要);
- (2) 开启同步,查看状态;
2、Slave上的配置
- (1) 安装数据库;
- (2) 修改数据库配置文件,指明server_id(如果是搭建双向主从的话,也要开启二进制日志log-bin);
- (3) 启动数据库,还原备份;
- (4) 查看当前是哪个日志,position号是多少(单向主从此步不需要,双向主从需要);
- (5) 指定Master的地址、用户、密码等信息;
- (6) 开启同步,查看状态。
②单向主从环境(也称MySQL A/B复制)的搭建
1、Master(192.168.0.240)和Slave(192.168.0.241)上都安装了相同版本的数据库(mysql-5.6.26.tar.gz),从节点与主节点安装流程一样。
- 注意:两台数据库服务器的的selinux都要disable(永久关闭selinux,请修改/etc/selinux/config,将SELINUX改为disabled)
2、修改Master的配置文件/etc/my.cnf
# vi /etc/my.cnf
-
在 [mysqld] 中增加以下配置项
## 设置server_id,一般设置为IP
server_id=240
## 复制过滤:需要备份的数据库,输出binlog
#binlog-do-db=roncoo
## 复制过滤:不需要备份的数据库,不输出(mysql库一般不同步)
binlog-ignore-db=mysql
## 开启二进制日志功能,可以随便取,最好有含义
log-bin=edu-mysql-bin
## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
2.1 复制过滤可以让你只复制服务器中的一部分数据,有两种复制过滤:
- (1) 在Master上过滤二进制日志中的事件;
- (2) 在Slave上过滤中继日志中的事件。
2.2 MySQL对于二进制日志 (binlog)的复制类型
- (1) 基于语句的复制:在Master上执行的SQL语句,在Slave上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选着基于行的复制。
- (2) 基于行的复制:把改变的内容复制到Slave,而不是把命令在Slave上执行一遍。从MySQL5.0开始支持。
- (3) 混合类型的复制:默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
3、启动/重启Master数据库服务,登录数据库,创建数据同步用户,并授予相应的权限
# service mysql restart
# mysql -uroot -p
- ##创建数据同步用户,并授予相应的权限
mysql> grant replication slave, replication client on *.* to 'repl'@'192.168.0.241' identified by '123456';
- ##刷新授权表信息
mysql> flush privileges;
- ##查看position号,记下position号(从机上需要用到这个position号和现在的日志文件)
show master status;
4、创建test库、表,并写入一定量的数据,用于模拟现有的业务系统数据库
create database if not exists test default charset utf8 collate utf8_general_ci;
use test;
DROP TABLE IF EXISTS `edu_user`;
CREATE TABLE `edu_user` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(255) NOT NULL DEFAULT '' COMMENT '用户名',
`pwd` varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息表';
INSERT INTO `edu_user` VALUES (1,'张三','123456'),(2,'李四','123456'),(3,'王五','test.com');
5、为保证Master和Slave的数据一致,我们采用主备份,从还原来实现初始数据一致
- ##先临时锁表
mysql> flush tables with read lock;
- ##这里我们实行全库备份,在实际中,我们可能只同步某一个库,那也可以只备份一个库
[root@edu-mysql-01 ~]# mysqldump -p3306 -uroot -p --add-drop-table test > /tmp/edu-master-test.sql;
- Enter password:
[root@edu-mysql-01 ~]# cd /tmp
[root@edu-mysql-01 tmp]# ll
- ##注意:实际生产环境中大数据量(超2G数据)的备份,建议不要使用mysqldump进行比分,因为会非常慢。此时推荐使用 XtraBackup 进行备份。
- ##解锁表
mysql> unlock tables;
- 将Master上备份的数据远程传送到Slave上,以用于Slave配置时恢复数据
[root@edu-mysql-01 ~]# scp /tmp/edu-master-test.sql [email protected]:/tmp/
6、接下来处理Slave(192.168.0.241),配置文件只需修改一项,其余配置用命令来操作
[root@edu-mysql-02 ~]# vi /etc/my.cnf
- ##在 [mysqld] 中增加以下配置项
## 设置server_id,一般设置为IP
server_id=241
## 复制过滤:需要备份的数据库,输出binlog
#binlog-do-db=test
##复制过滤:不需要备份的数据库,不输出(mysql库一般不同步)
binlog-ignore-db=mysql
## 开启二进制日志,以备Slave作为其它Slave的Master时使用
log-bin=edu-mysql-slave1-bin
## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size = 1M
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## 防止改变数据(除了特殊的线程)
read_only=1
- 如果Slave为其它Slave的Master时,必须设置bin_log。在这里,我们开启了二进制日志,而且显式的命名(默认名称为hostname,但是,如果hostname改变则会出现问题)。
relay_log配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志。
当设置log_slave_updates时,你可以让slave扮演其它slave的master。此时,slave把SQL线程执行的事件写进行自己的二进制日志(binary log),然后,它的slave可以获取这些事件并执行它。如下图所示(发送复制事件到其它Slave):
7、保存后重启MySQL服务,还原备份数据
[root@edu-mysql-02 ~]# service mysql restart
- Slave上创建相同库:
create database if not exists test default charset utf8 collate utf8_general_ci; use test;
- 导入数据
[root@edu-mysql-02 ~]# mysql -uroot -p test < /tmp/edu-master-test.sql
8、登录Slave数据库,添加相关参数
- (Master的IP、端口、同步用户、密码、position号、读取哪个日志文件)
[root@edu-mysql-02 ~]# mysql -uroot -p
mysql> change master to master_host='192.168.0.240', master_user='repl', master_password='123456', master_port=3306, master_log_file='edu-mysql-bin.000001', master_log_pos=120, master_connect_retry=30;
- 上面执行的命令的解释:
master_host='192.168.0.240' ## Master的IP地址
master_user='repl' ## 用于同步数据的用户(在Master中授权的用户)
master_password='123456' ## 同步数据用户的密码
master_port=3306 ## Master数据库服务的端口
master_log_file='edu-mysql-bin.000001' ##指定Slave从哪个日志文件开始读复制数据(可在Master上使用show master status查看到日志文件名)
master_log_pos=429 ## 从哪个POSITION号开始读
master_connect_retry=30 ##当重新建立主从连接时,如果连接建立失败,间隔多久后重试。单位为秒,默认设置为60秒,同步延迟调优参数。
- ##查看主从同步状态
mysql> show slave status\G;
- 可看到Slave_IO_State为空, Slave_IO_Running和Slave_SQL_Running是No,表明Slave还没有开始复制过程。
- ##开启主从同步
- ##再查看主从同步状态
mysql> show slave status\G;
- 主要看以下两个参数,这两个参数如果是Yes就表示主从同步正常
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- 可查看master和slave上线程的状态。在master上,可以看到slave的I/O线程创建的连接:
Master : mysql> show processlist\G;
- 1.row 为处理slave的I/O线程的连接。
- 2.row 为处理MySQL客户端连接线程。
- 3.row 为处理本地命令行的线程。
Slave : mysql> show processlist\G;
- 1.row 为I/O线程状态。
- 2.row 为SQL线程状态。
- 3.row 为处理本地命令行的线程。
9、主从数据复制同步测试
(1) 在Master中的test库上变更数据的同步测试;
mysql> INSERT INTO
edu_userVALUES (4,'同步测试1','123456'),(5,'同步测试2','123456');
- Master中添加完之后,登录Slave中查看数据是否已同步。
(2) 在Master上新建一个ron库
mysql> create database if not exists ron default charset utf8 collate utf8_general_ci;
- 在Slave中查看数据库
mysql> show databases;
- 最终的测试结果是,在Master中的操作,都成功同步到了Slave。
10、测试过程中,如果遇到同步出错,可在Slave上重置主从复制设置(选操作):
(1) mysql> reset slave;
(2) mysql> change master to master_host='192.168.0.240',
master_user='repl',
master_password='123456',
master_port=3306,
master_log_file='edu-mysql-bin.00000x',
master_log_pos=xx,
master_connect_retry=30;
- (此时,master_log_file和master_log_pos要在Master中用show master status 命令查看)
- 注意:如果在Slave没做只读控制的情况下,千万不要在Slave中手动插入数据,那样数据就会不一致,主从就会断开,就需要重新配置了。
- 上面所搭建的是单向复制的主从,也是用的比较多的,而双向主从其实就是Master和Slave都开启日志功能,然后在Master执行授权用户(这里授权的是自己作为从服务器,也就是这里的IP地址是Master的IP地址),然后再在Master上进行chang master操作。
11、MySQL主从数据同步延迟问题的调优
- 基于局域网的Master/Slave机制在通常情况下已经可以满足“实时”备份的要求了。如果延迟比较大,可以从以下几个因素进行排查:
- (1) 网络延迟;
- (2) Master负载过高;
- (3) Slave负载过高;
- 一般的做法是使用多台Slave来分摊读请求,再单独配置一台Slave只作为备份用,不进行其他任何操作,就能相对最大限度地达到“实时”的要求了。
- 两个可以减少主从复制延迟的参数(按需配置):
- MySQL可以指定3个参数,用于复制线程重连主库:–master-retry-count,–master-connect-retry,–slave-net-timeout 。其中 master-connect-retry 和 master-retry-count 需要在 Change Master 搭建主备复制时指定,而 slave-net-timeout 是一个全局变量,可以在 MySQL 运行时在线设置。具体的重试策略为:备库过了 slave-net-timeout 秒还没有收到主库来的数据,它就会开始第一次重试。然后每过 master-connect-retry 秒,备库会再次尝试重连主库。直到重试了 master-retry-count 次,它才会放弃重试。如果重试的过程中,连上了主库,那么它认为当前主库是好的,又会开始 slave-net-timeout 秒的等待。slave-net-timeout 的默认值是 3600 秒,master-connect-retry 默认为 60 秒,master-retry-count 默认为 86400 次。也就是说,如果主库一个小时都没有任何数据变更发送过来,备库才会尝试重连主库。这就是为什么在我们模拟的场景下,一个小时后,备库才会重连主库,继续同步数据变更的原因。
这样的话,如果你的主库上变更比较频繁,可以考虑将 slave-net-timeout 设置的小一点,避免主库 Binlog dump 线程终止了,无法将最新的更新推送过来。当然 slave-net-timeout 设置的过小也有问题,这样会导致如果主库的变更确实比较少的时候,备库频繁的重新连接主库,造成资源浪费。
slave-net-timeout=seconds
- 参数说明:当Slave从Master数据库读取log数据失败后,等待多久重新建立连接并获取数据,单位为秒,默认设置为3600秒。
- 在做MySQL Slave的时候经常会遇到很多错误,需要根据具体原因跨过错误继续同步,但有时候是因为网络不稳定、网络闪断造成同步不正常,如果Slave机器非常多的情况下,一个一个登录服务器去stop slave、start slave变得无聊而且重复。从MySQL5.1开始支持的解决方案配置:
master-connect-retry=seconds
- 参数说明:在主服务器宕机或连接丢失的情况下,从服务器线程重新尝试连接主服务器之前睡眠的秒数。如果主服务器.info文件中的值可以读取则优先使用。如果未设置,默认值为60。
通常配置以上2个参数可以减少网络问题导致的主从数据同步延迟。
- 一般网络问题的错误是:
- [ERROR] Error reading packet from server: Lost connection to MySQL server during query (server_errno=xxxx)
- [ERROR] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘edu-mysql-bin.000256’ position 23456
三、MyCat在MySQL主从复制基础上实现读写分离
- 环境
- 操作系统:CentOS-6.6-x86_64-bin-DVD1.iso
- JDK版本:jdk1.7.0_45
- MyCat版本:Mycat-server-1.4-release-20151019230038-linux.tar.gz
- MyCat节点IP:192.168.0.238 主机名:edu-mycat-01 主机配置:4核CPU、4G内存
- MySQL版本:mysql-5.6.26.tar.gz
- 主节点IP:192.168.0.240 主机名:edu-mysql-01 主机配置:4核CPU、4G内存
- 从节点IP:192.168.0.241 主机名:edu-mysql-02 主机配置:4核CPU、4G内存
①MyCat介绍 ( MyCat官网:http://mycat.org.cn/ )
- MyCat的读写分离是基于后端MySQL集群的主从同步来实现的,而MyCat提供语句的分发功能。MyCat1.4开始支持MySQL主从复制状态绑定的读写分离机制,让读更加安全可靠。
②MyCat的安装
1、设置MyCat的主机名和IP与主机名的映射
# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=edu-mycat-01
# vi /etc/hosts
127.0.0.1 edu-mycat-01
192.168.0.238 edu-mycat-01
192.168.0.240 edu-mysql-01
192.168.0.241 edu-mysql-02
2、因为MyCat是用Java开发的,因此MyCat运行需要安装JDK(准确来说是JRE就够了),并且需要JDK1.7或以上版本
## java env
export JAVA_HOME=/usr/local/java/jdk1.7.0_72
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib/rt.jar
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
# source /etc/profile
# java -version
3、创建mycat用户并设置密码
# useradd mycat
# passwd mycat
4、上传安装包 Mycat-server-1.4-release-20151019230038-linux.tar.gz 到 MyCat服务器中的/home/mycat目录,并解压并移动到 /usr/local/mycat目录
$ tar -zxvf Mycat-server-1.4-release-20151019230038-linux.tar.gz
$ su - root
# mv /home/mycat/mycat /usr/local/
# cd /usr/local/mycat/
5、设置MyCat的环境变量
## mycat env
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin
③配置MyCat
1、在配置MyCat前,请确认MySQL的主从复制安装配置已完成并正常运行。MySQL主从数据的同步在MySQL中配置,MyCat不负责数据同步的问题。
- 补充:
- (1) MySQL主从复制配置中,如果涉及到函数或存储过程的同步复制,需要在/etc/my.cnf中的[mysqld]段中增加配置 log_bin_trust_function_creators=true 或在客户端中设置 set global log_bin_trust_function_creators = 1;
- (2) 如果要做读写分离下的主从切换,那么从节点也有可能会变为写节点,因此从节点就不能设置为只读 read_only=1 。
- (3) Linux版本的MySQL,需要设置为MySQL大小写不敏感,否则可能会发生找不到表的问题。可在/etc/my.cnf的[mysqld]段中增加 lower_case_table_names=1 。
2、配置MyCat的schema.xml
- schema.xml是MyCat最重要的配置文件之一,用于设置MyCat的逻辑库、表、数据节点、dataHost等内容
[mycat@edu-mycat-01 conf]$ cd /usr/local/mycat/conf/
[mycat@edu-mycat-01 conf]$ vi schema.xml
show slave status
- MyCat1.4开始支持MySQL主从复制状态绑定的读写分离机制,让读更加安全可靠,配置如下:
- MyCat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性:switchType=“2” 与 slaveThreshold=“100”,此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制,MyCat心跳机制通过检测 show slave status 中的
“Seconds_Behind_Master”, “Slave_IO_Running”, “Slave_SQL_Running” 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延,当Seconds_Behind_Master 大于slaveThreshold时,读写分离筛选器会过滤掉此Slave机器,防止读到很久之前的旧数据,而当主节点宕机后,切换逻辑会检查Slave上的Seconds_Behind_Master是否为0,为0时则表示主从同步,可以安全切换,否则不会切换。
3、配置 server.xml
- server.xml 主要用于设置系统变量、管理用户、设置用户权限等。
[mycat@edu-mycat-01 conf]$ vi server.xml
druidparser
utf8mb4
test.2
rc_schema2,pay_schema2
test.3
rc_schema2,pay_schema2
true
4、防火墙中打开8066和9066端口
- MyCat的默认数据端口为8066,mycat通过这个端口接收数据库客户端的访问请求。
- 管理端口为9066,用来接收mycat监控命令、查询mycat运行状况、重新加载配置文件等。
[root@edu-mycat-01 mycat]# vi /etc/sysconfig/iptables
- 增加
## MyCat
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8066 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 9066 -j ACCEPT
- 重启防火墙:
[root@edu-mycat-01 mycat]# service iptables restart
5、修改log日志级别为debug,以便通过日志确认基于MyCat的MySQL数据库集群读写分离的数据操作状态(可以在正式上生产前改成info级别)
[mycat@edu-mycat-01 conf]$ vi /usr/local/mycat/conf/log4j.xml
- 将level节点的info改为debug
6、启动MyCat
[mycat@edu-mycat-01 bin]$ cd /usr/local/mycat/bin/
- (1) 控制台启动,这种启动方式在控制台关闭后,MyCat服务也将关闭,适合调试使用:
[mycat@edu-mycat-01 bin]$ ./mycat console
- (2) 可以采用以下后台启动的方式:
[mycat@edu-mycat-01 bin]$ ./mycat start
- (对应的,重启: mycat restart , 关闭: mycat stop )
7、MyCat连接测试
- 为了方便,需要在MyCat主机上对MyCat进行操作(把MyCat当是本地MySQL来操作),可以在MyCat节点主机上安装MySQL客户端:
[mycat@edu-mycat-01 bin]$ su - root
[root@edu-mycat-01 bin]# yum install mysql
- 使用安装好的mysql客户端登录MyCat
[mycat@edu-mycat-01 bin]$ mysql -uuser2 -ptest.2 -h192.168.0.238 -P8066
- 此时会出现中文乱码
[root@edu-mycat-01 mycat]# vi /etc/my.cnf
- 增加:
[client]
default-character-set=utf8
8、读写分离测试
(1) 监听MyCat日志
[mycat@edu-mycat-01 ~]$ cd /usr/local/mycat/logs/
[mycat@edu-mycat-01 logs]$ tail -f mycat.log
(2) 读测试
$ mysql -uuser2 -ptest.2 -h192.168.0.238 -P8066
mysql> show databases;
mysql> use rc_schema2;
mysql> show tables;
mysql> select * from edu_user;
- 多次执行 select * from edu_user 语句,MyCat打印出来的日志信息显示读操作请求都是路由到Slave节点(192.168.0.241)。
(3) 写测试
mysql> insert into edu_user (userName, pwd) values('赵六', '123456');
- 多次执行以上插入语句,发现新增数据都是从 Master节点(192.168.0.240)插进入的,并且Slave节点通过Binlog同步了Master节点中的数据。
- 综上,基于MyCat的读写分离集群配置成功。
四、MyCat集群部署(HAProxy + MyCat)
- 软件版本
- 操作系统:CentOS-6.6-x86_64
- JDK版本:jdk1.7.0_72
- HAProxy版本:haproxy-1.5.16.tar.gz
- MyCat版本:Mycat-server-1.4-release-20151019230038-linux.tar.gz
- MySQL版本:mysql-5.6.26.tar.gz
①部署环境规划
名称 |
IP |
主机名 |
配置 |
HAProxy主机1 |
192.168.0.236 |
edu-haproxy-01 |
2核、2G |
MyCat主机1 |
192.168.0.238 |
edu-mycat-01 |
2核、2G |
MyCat主机2 |
192.168.0.239 |
edu-mycat-02 |
2核、2G |
MySQL主节点 |
192.168.0.240 |
edu-mysql-01 |
2核、2G |
MySQL从节点 |
192.168.0.241 |
edu-mysql-02 |
2核、2G |
- HAProxy负责将请求分发到MyCat上,起到负载均衡的作用,同时HAProxy也能检测到MyCat是否存活,HAProxy只会将请求转发到存活的MyCat上。如果一台MyCat服务器宕机,HAPorxy转发请求时不会转发到宕机的MyCat上,所以MyCat依然可用。
1、MyCat节点2的部署
- MyCat主机2(edu-mycat-02,192.168.0.239)请参考上节进行对等部署和做相应配置。
- 注意:edu-mycat-01(192.168.0.238)和 edu-mycat-02(192.168.0.239) 中都要加上(或更新)主机名映射配置。
# vi /etc/hosts
192.168.0.238 edu-mycat-01
192.168.0.239 edu-mycat-02
192.168.0.240 edu-mysql-01
192.168.0.241 edu-mysql-02
2、配置MyCat状态检查服务(在MyCat节点主机上配置)
- MyCat服务主机(edu-mycat-01、edu-mycat-02)上需要增加mycat服务的状态检测脚本,并开放相应的检测端口,以提供给HAProxy对MyCat的服务状态进行检测判断。可以使用xinetd来实现,通过xinetd,HAProxy可以用httpchk来检测MyCat的存活状态。(xinetd即extended internet daemon,xinetd是新一代的网络守护进程服务程序,又叫超级Internet服务器。经常用来管理多种轻量级Internet服务。xinetd提供类似于inetd+tcp_wrapper的功能,但是更加强大和安全。xinetd为linux系统的基础服务)
- 1、如果xinetd还没有安装,可使用如下命令安装:
- 2、检查/etc/xinetd.conf的末尾是否有 includedir /etc/xinetd.d ,没有就加上
- 3、检查 /etc/xinetd.d 目录是否存在,不存在则创建
- 4、增加MyCat存活状态检测服务配置
# touch /etc/xinetd.d/mycat_status
# vi /etc/xinetd.d/mycat_status
- 增加以下内容:(千万要删掉注释)
service mycat_status
{
flags = REUSE
## 使用该标记的socket_type为stream,需要设置wait为no
socket_type = stream ## 封包处理方式,Stream为TCP数据包
port = 48700 ## 服务监听端口
wait = no ## 表示不需等待,即服务将以多线程的方式运行
user = root ## 执行此服务进程的用户
server =/usr/local/bin/mycat_status ## 需要启动的服务脚本
log_on_failure += USERID ## 登录失败记录的内容
disable = no ## 要启动服务,将此参数设置为no
}
- 5、添加 /usr/local/bin/mycat_status 服务脚本
# touch /usr/local/bin/mycat_status
# vi /usr/local/bin/mycat_status
- 增加以下内容:
#!/bin/bash
#/usr/local/bin/mycat_status.sh
# This script checks if a mycat server is healthy running on localhost.
# It will return:
# "HTTP/1.x 200 OK\r" (if mycat is running smoothly)
# "HTTP/1.x 503 Internal Server Error\r" (else)
mycat=`/usr/local/mycat/bin/mycat status | grep 'not running' | wc -l`
if [ "$mycat" = "0" ]; then
/bin/echo -e "HTTP/1.1 200 OK\r\n"
else
/bin/echo -e "HTTP/1.1 503 Service Unavailable\r\n"
fi
- 6、给新增脚本赋予可执行权限
# chmod a+x /usr/local/bin/mycat_status
- 7、在 /etc/services 中加入 mycat_status 服务
- 在末尾加入:
mycat_status 48700/tcp # mycat_status
- 保存后,重启xinetd服务
# service xinetd restart
- 8、验证mycat_status服务是否成功启动
# netstat -antup|grep 48700
- 9、MyCat服务主机的防火墙上打开 48700端口
# vi /etc/sysconfig/iptables
- 增加:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 48700 -j ACCEPT
- 保存后重启防火墙
# service iptables restart
- 脚本测试:
# /usr/local/bin/mycat_status
②HAProxy介绍
- HAProxy官网:http://www.haproxy.org/
- HAProxy各版本的官方文档:http://cbonte.github.io/haproxy-dconv/index.html
- HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
- HAProxy目前主要有三个版本:1.4、1.5、1.6,CentOS6.6自带的RPM包为1.5的。
- HAProxy1.5版开始,支持SSL、DDoS防护等功能,可看官网说明:version 1.5 : the most featureful version, supports SSL, IPv6, keep-alive, DDoS protection, etc…
- MyCat官方推荐使用HAProxy做MyCat的高可用负载均衡代理。
1、HAProxy的安装(192.168.0.236)
- 1、下载(或上传) haproxy-1.5.16.tar.gz 到 /usr/local/src,解压安装
[root@edu-haproxy-01 src]# cd /usr/local/src/
#wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.16.tar.gz
[root@edu-haproxy-01 src]# tar -zxvf haproxy-1.5.16.tar.gz
[root@edu-haproxy-01 src]# cd haproxy-1.5.16
- 2、如需了解安装注意点,可查看HAProxy的软件说明
[root@edu-haproxy-01 haproxy-1.5.16]# less README
- 3、安装编译所需的依赖包
# yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
- 4、编译
# make TARGET=linux2628 ARCH=x86_64 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 PREFIX=/usr/local/haproxy
- ##TARGET是指定内核版本,高于2.6.28的建议设置为linux2628,Linux操作系统内核版本查看命令# uname -r, ARCH指定系统架构,openssl pcre zlib 这三个包需要安装不然不支持
- 5、创建安装目录 /usr/local/haproxy
# mkdir /usr/local/haproxy
- 6、执行安装
[root@edu-haproxy-01 haproxy-1.5.16]# make install PREFIX=/usr/local/haproxy
- 7、创建配置文件目录
# mkdir -p /usr/local/haproxy/conf
# mkdir -p /etc/haproxy/
- 8、从配置文件模版复制配置文件,并添加配置文件软连接
# cp /usr/local/src/haproxy-1.5.16/examples/haproxy.cfg /usr/local/haproxy/conf/
# ln -s /usr/local/haproxy/conf/haproxy.cfg /etc/haproxy/haproxy.cfg
- 9、拷贝错误页面,并添加目录软连接(HTTP模式选配)
# cp -r /usr/local/src/haproxy-1.5.16/examples/errorfiles /usr/local/haproxy/
# ln -s /usr/local/haproxy/errorfiles /etc/haproxy/errorfiles
- 10、拷贝开机启动文件,并赋予可执行权限
# cp /usr/local/src/haproxy-1.5.16/examples/haproxy.init /etc/rc.d/init.d/haproxy
# chmod +x /etc/rc.d/init.d/haproxy
- 11、添加haproxy命令脚本软连接
# ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin
- 12、设置HAProxy开机启动
# chkconfig --add haproxy
# chkconfig haproxy on
③HAProxy配置MyCat负载均衡集群
- HAProxy支持TCP(第四层)和HTTP(第七层)应用的代理,本节课程我们使用HAProxy来做MyCat的负载均衡代理使用的是TCP模式。在4层模式下HAProxy仅在客户端和服务器之间转发双向流量。HAProxy配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端服务器出现故障,HAProxy会自动将该服务器摘除,故障恢复后会自动将该服务器加入进来。
1、修改haproxy.cfg 配置文件
- 具体参数说明可参考官方配置文档 /usr/local/haproxy/doc/haproxy/configuration.txt
或GitHub连接:http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
# vi /usr/local/haproxy/conf/haproxy.cfg
## global配置中的参数为进程级别的参数,通常与其运行的操作系统有关
global
log 127.0.0.1 local0 info ## 定义全局的syslog服务器,最多可以定义2个
### local0是日志设备,对应于/etc/rsyslog.conf中的配置,默认回收info的日志级别
#log 127.0.0.1 local1 info
chroot /usr/share/haproxy ## 修改HAProxy的工作目录至指定的目录并在放弃权限之前执行
### chroot() 操作,可以提升 haproxy 的安全级别
group haproxy ## 同gid,不过这里为指定的用户组名
user haproxy ## 同uid,但这里使用的为用户名
daemon ## 设置haproxy后台守护进程形式运行
nbproc 1 ## 指定启动的haproxy进程个数,
### 只能用于守护进程模式的haproxy;默认为止启动1个进程,
### 一般只在单进程仅能打开少数文件描述符的场中中才使用多进程模式
maxconn 4096 ## 设定每个haproxy进程所接受的最大并发连接数,
### 其等同于命令行选项"-n","ulimit-n"自动计算的结果正式参照从参数设定的
# pidfile /var/run/haproxy.pid ## 进程文件(默认路径 /var/run/haproxy.pid)
node edu-haproxy-01 ## 定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时
description edu-haproxy-01 ## 当前实例的描述信息
## defaults:用于为所有其他配置段提供默认参数,这默认配置参数可由下一个"defaults"所重新设定
defaults
log global ## 继承global中log的定义
mode http ## mode:所处理的模式 (tcp:四层 , http:七层 , health:状态检查,只会返回OK)
### tcp: 实例运行于纯tcp模式,在客户端和服务器端之间将建立一个全双工的连接,
#### 且不会对7层报文做任何类型的检查,此为默认模式
### http:实例运行于http模式,客户端请求在转发至后端服务器之前将被深度分析,
#### 所有不与RFC模式兼容的请求都会被拒绝
### health:实例运行于health模式,其对入站请求仅响应“OK”信息并关闭连接,
#### 且不会记录任何日志信息 ,此模式将用于相应外部组件的监控状态检测请求
option httplog
retries 3
option redispatch ## serverId对应的服务器挂掉后,强制定向到其他健康的服务器
maxconn 2000 ## 前端的最大并发连接数(默认为2000)
### 其不能用于backend区段,对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,
### 从而避免无法应答用户请求。当然,此最大值不能超过“global”段中的定义。
### 此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓存的大小为8KB,
### 再加上其他的数据,每个连接将大约占用17KB的RAM空间,这意味着经过适当优化后 ,
### 有着1GB的可用RAM空间时将维护40000-50000并发连接。
### 如果指定了一个过大值,极端场景中,其最终所占据的空间可能会超过当前主机的可用内存,
### 这可能会带来意想不到的结果,因此,将其设定一个可接受值放为明智绝对,其默认为2000
timeout connect 5000ms ## 连接超时(默认是毫秒,单位可以设置us,ms,s,m,h,d)
timeout client 50000ms ## 客户端超时
timeout server 50000ms ## 服务器超时
## HAProxy的状态信息统计页面
listen admin_stats
bind :48800 ## 绑定端口
stats uri /admin-status ##统计页面
stats auth admin:admin ## 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
mode http
option httplog ## 启用日志记录HTTP请求
## listen: 用于定义通过关联“前端”和“后端”一个完整的代理,通常只对TCP流量有用
listen mycat_servers
bind :3306 ## 绑定端口
mode tcp
option tcplog ## 记录TCP请求日志
option tcpka ## 是否允许向server和client发送keepalive
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www ## 后端服务状态检测
### 向后端服务器的48700端口(端口值在后端服务器上通过xinetd配置)发送 OPTIONS 请求
### (原理请参考HTTP协议) ,HAProxy会根据返回内容来判断后端服务是否可用.
### 2xx 和 3xx 的响应码表示健康状态,其他响应码或无响应表示服务器故障。
balance roundrobin ## 定义负载均衡算法,可用于"defaults"、"listen"和"backend"中,默认为轮询方式
server mycat_01 192.168.0.238:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
server mycat_02 192.168.0.239:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
## 格式:server [:[port]] [param*]
### serser 在后端声明一个server,只能用于listen和backend区段。
### 为此服务器指定的内部名称,其将会出现在日志及警告信息中
### 此服务器的IPv4地址,也支持使用可解析的主机名,但要在启动时需要解析主机名至响应的IPV4地址
### [:[port]]指定将客户端连接请求发往此服务器时的目标端口,此为可选项
### [param*]为此server设定的一系列参数,均为可选项,参数比较多,下面仅说明几个常用的参数:
#### weight:权重,默认为1,最大值为256,0表示不参与负载均衡
#### backup:设定为备用服务器,仅在负载均衡场景中的其他server均不可以启用此server
#### check:启动对此server执行监控状态检查,其可以借助于额外的其他参数完成更精细的设定
#### inter:设定监控状态检查的时间间隔,单位为毫秒,默认为2000,
##### 也可以使用fastinter和downinter来根据服务器端专题优化此事件延迟
#### rise:设置server从离线状态转换至正常状态需要检查的次数(不设置的情况下,默认值为2)
#### fall:设置server从正常状态转换至离线状态需要检查的次数(不设置的情况下,默认值为3)
#### cookie:为指定server设定cookie值,此处指定的值将会在请求入站时被检查,
##### 第一次为此值挑选的server将会被后续的请求所选中,其目的在于实现持久连接的功能
#### maxconn:指定此服务器接受的最大并发连接数,如果发往此服务器的连接数目高于此处指定的值,
#####其将被放置于请求队列,以等待其他连接被释放
- 注意:多节点部署时node 、 description的值要做相应调整。
2、根据以上HAProxy配置文件要求做以下配置
- (1)添加haproxy用户组和用户
# groupadd haproxy
# useradd -g haproxy haproxy
- (2)创建chroot运行的路径
# mkdir /usr/share/haproxy
- (3)防火墙中打开3306端口和48800端口
# vi /etc/sysconfig/iptables
- -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
- -A INPUT -m state --state NEW -m tcp -p tcp --dport 48800 -j ACCEPT
- 重启防火墙
# service iptables restart
3、开启rsyslog的haproxy日志记录功能
- 默认情况下 haproxy是不记录日志的,如果需要记录日志,还需要配置系统的syslog,在linux系统中是rsyslog服务。syslog服务器可以用作一个网络中的日志监控中心,rsyslog是一个开源工具,被广泛用于Linux系统以通过TCP/UDP协议转发或接收日志消息。安装配置rsyslog服务:
# yum install rsyslog
## 没安装的情况下执行安装
# vi /etc/rsyslog.conf
- 把 $ModLoad imudp 和 $UDPServerRun 514前面的 # 去掉
- $ModLoad imudp ## 是模块名,支持UDP协议
- $UDPServerRun 514
- ##允许514端口接收使用UDP和TCP协议转发过来的日志,
- ##而rsyslog在默认情况下,正是在514端口监听UDP
- 确认 #### GLOBAL DIRECTIVES #### 段中是否有 $IncludeConfig /etc/rsyslog.d/*.conf没有则增加上此配置
# cd /etc/rsyslog.d/
## rsyslog服务会来此目录加载配置
# touch haproxy.conf
## 创建haproxy的日志配置文件
# vi /etc/rsyslog.d/haproxy.conf
- 增加以下内容:
local0.* /var/log/haproxy.log
&~
- ##如果不加上面的的"&~"配置则除了在/var/log/haproxy.log中写入日志外,也会写入/var/log/message文件中
- 配置保存后重启rsyslog服务
# service rsyslog restart
- (等到HAProxy服务启动后,就能在/var/log/haproxy.log中看到日志了)
4、配置系统内核的IP包转发功能
# vi /etc/sysctl.conf
- 使配置生效
5、启动HAProxy
# service haproxy start
# ps -ef | grep haproxy
6、使用MySQL客户端通过HAProxy连接MyCat
mysql -uuser2 -proncoo.2 -h192.168.0.236 -P3306
mysql> show databases;
mysql> use rc_schema2;
mysql> show tables;
mysql> select * from edu_user;
写数据测试:
mysql> insert into edu_user (userName, pwd) values('赵六', '123456');
7、登录HAProxy的状态信息统计页面
- http://192.168.0.236:48800/admin-status
- 用户名和密码都是admin,对应的haproxy.cfg配置片段
五、MyCat高可用负载均衡集群的实现(HAProxy + Keepalived + MyCat)
- 软件版本
- 操作系统:CentOS-6.6-x86_64
- JDK版本:jdk1.7.0_72
- Keepalived版本:keepalived-1.2.18.tar.gz
- HAProxy版本:haproxy-1.5.16.tar.gz
- MyCat版本:Mycat-server-1.4-release-20151019230038-linux.tar.gz
- MySQL版本:mysql-5.6.26.tar.gz
①部署环境规划
名称 |
IP |
主机名 |
配置 |
HAProxy主机1 |
192.168.0.236(VIP:192.168.0.235) |
edu-haproxy-01 |
2核、2G |
HAProxy主机2 |
192.168.0.237(VIP:192.168.0.235) |
edu-haproxy-02 |
2核、2G |
MyCat主机1 |
192.168.0.238 |
edu-mycat-01 |
2核、2G |
MyCat主机2 |
192.168.0.239 |
edu-mycat-02 |
2核、2G |
MySQL主节点 |
192.168.0.240 |
edu-mysql-01 |
2核、2G |
MySQL从节点 |
192.168.0.241 |
edu-mysql-02 |
2核、2G |
- 说明:
- (1) HAProxy实现了MyCat多节点的集群高可用和负载均衡,而HAProxy自身的高可用则可以通过Keepalived来实现。因此,HAProxy主机上要同时安装HAProxy和Keepalived,Keepalived负责为该服务器抢占vip(虚拟ip,图中的192.168.0.235),抢占到vip后,对该主机的访问可以通过原来的ip(192.168.0.236)访问,也可以直接通过vip(192.168.0.235)访问。
- (2) Keepalived抢占vip有优先级,在keepalived.conf配置中的priority属性决定。但是一般哪台主机上的Keepalived服务先启动就会抢占到vip,即使是slave,只要先启动也能抢到(要注意避免Keepalived的资源抢占问题)。
- (3) HAProxy负责将对vip的请求分发到MyCat集群节点上,起到负载均衡的作用。同时HAProxy也能检测到MyCat是否存活,HAProxy只会将请求转发到存活的MyCat上。
- (4) 如果Keepalived+HAProxy高可用集群中的一台服务器宕机,集群中另外一台服务器上的Keepalived会立刻抢占vip并接管服务,此时抢占了vip的HAProxy节点可以继续提供服务。
- (5) 如果一台MyCat服务器宕机,HAPorxy转发请求时不会转发到宕机的MyCat上,所以MyCat依然可用。
- 综上:MyCat的高可用及负载均衡由HAProxy来实现,而HAProxy的高可用,由Keepalived来实现。
②HAProxy节点2的部署
- HAProxy主机2(edu-haproxy-02,192.168.0.237)请参考上一节进行对等部署和做相应配置。
- 注意配置文件的调整:
- 多节点部署时haproxy.cfg 配置文件中的node 、 description配置的值要做相应调整。
③Keepalived介绍 (官网:http://www.haproxy.org/ )
- Keepalived 是一种高性能的服务器高可用或热备解决方案,Keepalived可以用来防止服务器单点故障的发生,通过配合Haproxy可以实现web前端服务的高可用。
- Keepalived以VRRP协议为实现基础,用VRRP协议来实现高可用性(HA)。VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个),而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生。MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等;其他设备不拥有该虚拟IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。
- VRRP协议使用多播数据来传输VRRP数据,VRRP数据使用特殊的虚拟源MAC地址发送数据而不是自身网卡的MAC地址,VRRP运行时只有MASTER路由器定时发送VRRP通告信息,表示MASTER工作正常以及虚拟路由器IP(组),BACKUP只接收VRRP数据,不发送数据,如果一定时间内没有接收到MASTER的通告信息,各BACKUP将宣告自己成为MASTER,发送通告信息,重新进行MASTER选举状态。
④Keepalived的安装(192.168.0.236、192.168.0.237)
- Keepalived ( http://www.keepalived.org/download.html )
- 1、上传或下载keepalived(keepalived-1.2.18.tar.gz)到 /usr/local/src 目录
- 2、解压安装
- 安装keepalived需要用到openssl
# yum install gcc gcc-c++ openssl openssl-devel
# cd /usr/local/src
# tar -zxvf keepalived-1.2.18.tar.gz
# cd keepalived-1.2.18
# ./configure --prefix=/usr/local/keepalived
# make && make install
- 3、将keepalived安装成Linux系统服务:
- 因为没有使用keepalived的默认路径安装(默认是/usr/local),安装完成之后,需要做一些工作
- 复制默认配置文件到默认路径
# mkdir /etc/keepalived
# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
- 复制keepalived服务脚本到默认的地址
# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
# ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/
# ln -s /usr/local/keepalived/sbin/keepalived /sbin/
- 设置keepalived服务开机启动
# chkconfig keepalived on
- 4、修改Keepalived配置文件
- (1) MASTER节点配置文件(192.168.0.236)
# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
## keepalived自带的邮件提醒需要开启sendmail服务。建议用独立的监控或第三方SMTP
router_id edu-haproxy-01 ## 标识本节点的字条串,通常为hostname
}
## keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
## 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。
## 如果脚本执行结果非0,并且weight配置的值小于0,则优先级相应的减少。
## 其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_haproxy {
script "/etc/keepalived/haproxy_check.sh" ## 检测haproxy状态的脚本路径
interval 2 ## 检测时间间隔
weight 2 ## 如果条件成立,权重+2
}
## 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
state BACKUP ## 默认主设备(priority值大的)和备用设备(priority值小的)都设置为BACKUP,
## 由priority来控制同时启动情况下的默认主备,否则先启动的为主设备
interface eth0 ## 绑定虚拟IP的网络接口,与本机IP地址所在的网络接口相同,我的是eth0
virtual_router_id 36 ## 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,
## 相同的VRID为一个组,他将决定多播的MAC地址
priority 120 ## 节点优先级,值范围0-254,MASTER要比BACKUP高
nopreempt ## 主设备(priority值大的)配置一定要加上nopreempt,否则非抢占也不起作用
advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认1s
## 设置验证信息,两个节点必须一致
authentication {
auth_type PASS
auth_pass 1111 ## 真实生产,按需求对应该过来
}
## 将track_script块加入instance 配置块
track_script {
chk_haproxy ## 检查HAProxy服务是否存活
}
## 虚拟IP池, 两个节点设置必须一样
virtual_ipaddress {
192.168.0.235 ## 虚拟ip,可以定义多个,每行一个
}
}
- (2)BACKUP节点配置文件(192.168.0.237):
# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id edu-haproxy-02
}
vrrp_script chk_haproxy {
script "/etc/keepalived/haproxy_check.sh"
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 36
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_haproxy
}
virtual_ipaddress {
192.168.0.235
}
}
- 特别注意:如果非抢占模式不生效,在Keepalived的故障节点恢复后会再次导抢占vip,从而因vip切换而闪断带来的风险。按以上配置,配置了Keepalived非抢占模式,配置及注意点如下:
- (1) 主设备、从设备中的 state 都设置为 BACKUP
- (2) 主设备、从设备中都不要配置 mcast_src_ip (本机IP地址)
- (3) 默认主设备(priority值大的Keepalived节点)配置一定要加上 nopreempt,否则非抢占不起作用
- (4) 防火墙配置允许组播(主、备两台设备上都需要配置,keepalived使用224.0.0.18作为Master和Backup健康检查的通信IP)
# iptables -I INPUT -i eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
# iptables -I OUTPUT -o eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
- (eth0为主机的网卡设备名称,生产环境服务器可以用独立网卡来处理组播和心跳检测等)
- 重启防火墙:
# service iptables restart
- 5、编写Haproxy状态检测脚本 /etc/keepalived/haproxy_check.sh (已在keepalived.conf中配置)
- 脚本要求:如果haproxy停止运行,尝试启动,如果无法启动则杀死本机的keepalived进程,keepalied将虚拟ip绑定到BACKUP机器上。内容如下:
# mkdir -p /usr/local/keepalived/log
# vi /etc/keepalived/haproxy_check.sh
#!/bin/bash
START_HAPROXY="/etc/rc.d/init.d/haproxy start"
STOP_HAPROXY="/etc/rc.d/init.d/haproxy stop"
LOG_FILE="/usr/local/keepalived/log/haproxy-check.log"
HAPS=`ps -C haproxy --no-header |wc -l`
date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE
echo "check haproxy status" >> $LOG_FILE
if [ $HAPS -eq 0 ];then
echo $START_HAPROXY >> $LOG_FILE
$START_HAPROXY >> $LOG_FILE 2>&1
sleep 3
if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
echo "start haproxy failed, killall keepalived" >> $LOG_FILE
killall keepalived
fi
fi
- 保存后,给脚本赋执行权限:
# chmod +x /etc/keepalived/haproxy_check.sh
- 6、启动Keepalived
# service keepalived start
- Keepalived服务管理命令:
- 停止:service keepalived stop
- 启动:service keepalived start
- 重启:service keepalived restart
- 查看状态:service keepalived status
⑤Keepalived + Haproxy的高可用测试
- 1、关闭192.168.0.236中的Haproxy,Keepalived会将它重新启动
- 2、关闭192.168.0.236中的Keepalived,VIP(192.168.0.235)会被192.168.0.237抢占
# service keepalived stop
- Keepalived停止后,192.168.0.236节点的网络接口中的VIP(192.168.0.235)将消失
- 3、再通过VIP来访问Haproxy集群,访问到的也是192.168.0.237
- 4、重新启动192.168.0.236中的Keepalived,vip(192.168.0.235)保留在192.168.0.237主机上,不会出现236启动抢占vip的情况。
# service keepalived start
- 5、模拟抢占了vip的节点(192.168.0.237)中的HAProxy故障或启动失败。
- 方式:把237节点中的haproxy.cfg文件重命名为haproxy.cfg_bak,并把haproxy服务进行kill掉,此时keepalived会尝试去启动haproxy,会由于找不到配置文件而启动失败,此时就会进行haproxy_check.sh脚本中的killall keepalived命令,结束keepalived进行。随后就是192.168.0.236节点重新抢占vip
⑥通过vip访问数据库、验证vip切换后的数据库访问
mysql -uuser2 -ptest.2 -h192.168.0.235 -P3306
mysq> show databases;
mysq> use rc_schema2;
mysq> show tables;
mysq> select * from edu_user;