Mycat+Mysql主从复制+haproxy+keepalived实现高可用的分库分表集群方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jhsfja/article/details/80586731

一, 部署架构

1.1架构图

这里写图片描述

1.2 软件版本

操作系统: CentOS2-7-X86_64-DVD-1708.iso
JDK 版本: jdk1.8.0_11
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

二,Mysql源码编译安装

2.1安装环境:

操作系统:CentOS2-7-x86_64-DVD-1708.iso
Mysql 版本:mysql-5.6.26.tar.gz

2.2源码安装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

增加如下行:

-A INPUT -p tcp -m state –state NEW -m tcp –dport 3306 -j ACCEPT

重启防火墙:

service iptables restart

3) 新增 mysql 用户组:

groupadd mysql

4) 新增 mysql 用户, 并添加到 mysql 用户组:

useradd -r -g mysql mysql

5) 新建 MySQL 执行文件目录(后面会把编译好的 mysql 程序安装到这个目录):

 mkdir -p /usr/local/mysql

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 需要的依赖包:

 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 目录:

# cd /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 路径!)

# 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/mysql5.6.26/source_downloads/gmoc k-1.6.0.zip
解决方法:
cd mysql 目录下面会发现有一个 source_downloads 目录,需要解压 unzip gmock-1.6.0.zip,然后再重新执行上述配置过程。也可以去掉-DENABLE_DOWNLOADS=1 这个选项,不编译谷歌的测试包也没有什么问题,但是之前的某些版本会出现无法编译的问题

11) cmake 结束后开始编译源码,这一步时间会较长,请耐心等待:

# make

12) 安装编译好的程序:

# make install

(注意:如果需要重装 mysql,在/usr/local/src/mysql-5.6.26 在执行下 make install 就可以了,不需要再 cmake 和 make)

13) 清除安装临时文件:

# make clean

14) 修改 mysql 目录拥有者为 mysql 用户

# chown -Rf mysql:mysql /usr/local/mysql
# chown -Rf mysql:mysql /home/mysql

15) 进入 mysql 执行程序的安装路径:

# cd /usr/local/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,需要更改该配置文件的所有者:

# chown -Rf mysql:mysql /etc/my.cnf

18) 编辑/etc/my.cnf(建议将配置文件放到此c处,相关参数酌情进行优化配置)

[client]

port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
character-set-server = utf8
collation-server = utf8_general_ci
log_bin_trust_function_creators=true
lower_case_table_names=1
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 = 300query_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

19)复制服务启动脚本:

# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql

20)启动mysql服务:

# service mysql start

Starting MySQL.. SUCCESS!

21)设置 MySQL 开机自动启动服务:

# chkconfig mysql on

22)设置 MySQL 数据库 root 用户的本地登录密码(初始用户没有密码):

# mysqladmin -u root password ‘111111’

23)允许root用户远程连接(根据实际情况进行操作)

# mysql -uroot -p111111
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '111111' WITH
GRANT OPTION;
mysql> flush privileges;
mysql> exit;

24)运行安全设置脚本(可选操作)

# /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 是否能开机自动启动:

# reboot

三,Mysql主从复制配置(基于bin-log)

3.1 配置注意事项

 主从服务器操作系统版本和位数一致
 两台数据库服务器的的 selinux 都要 disable(永久关闭 selinux, 请修改/etc/selinux/config,将 SELINUX 改为 disabled)
 Master和Slave数据库的版本要一致
 Master和Slave数据库中数据要一致
 Master开启二进制日志,Master和Slave的server_id在局域网内必须唯一

3.2 Master上的配置

3.2.1修改 Master 的配置文件/etc/my.cnf

vi /etc/my.cnf
## 在 [mysqld] 中增加以下配置项
## 设置 server_id,一般设置为 IP
server_id=170
## 复制过滤: 需要备份的数据库, 输出 binlog
binlog-do-db=iuim 
## 开启二进制日志功能, 可以随便取, 最好有含义
log-bin=iuim_mysql_bin_log
## 为每个 session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
## 主从复制的格式(mixed,statement,row,默认格式是 statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为 0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免 slave 端复制中断。
## 如: 1062 错误是指一些主键重复, 1032 错误是因为主从数据库数据不一致
slave_skip_errors=1062

3.2.2 启动/重启 Master 数据库服务,登录数据库, 创建数据同步用户,并授予相应的权限

    # service mysql restart
Shutting down MySQL..[ OK ]
Starting MySQL..[ OK ]
    # mysql -uroot -p111111

mysql> grant replication slave, replication client on *.* to ‘${user}’@${slaveIp} identified by
‘${password}’;
Query OK, 0 rows affected (0.00 sec)
## 刷新授权表信息
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
## 查看 position 号, 记下 position 号(从机上需要用到这个 position 号和现在的日志文件)
mysql> show master status;
![这里写图片描述](https://img-blog.csdn.net/20180605204737164?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2poc2ZqYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

3.3 Slave上的配置

3.3.1修改mysql配置文件

vi /etc/my.cnf

## 在 [mysqld] 中增加以下配置项
## 设置 server_id,一般设置为 IP
server_id=173
## 复制过滤: 需要备份的数据库,输出 binlog
binlog-do-db=iuim
## 开启二进制日志,以备 Slave 作为其它 Slave 的 Master 时使用
log-bin=iuim-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 配置中继日志(与主节点中配置的log-bin属性相同)
relay_log= iuim_mysql_bin_log
## log_slave_updates 表示 slave 将复制事件写进自己的二进制日志
log_slave_updates=1
3.3.2保存后重启 MySQL 服务,还原备份数据
# service mysql restart
Shutting down MySQL..[ OK ]
Starting MySQL..[ OK ]

3.3.3将初始化sql脚本在master和slave上都执行一次

3.3.4登录 Slave 数据库, 添加相关参数

#mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.26-log Source distribution
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> change master to master_host='192.168.2.170', master_user='${slaveUser}',
master_password='${password}', master_port=3306, master_log_file='iuim-mysql-bin-log.000001',
master_log_pos=435, master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
上面执行的命令的解释:
master_host='192.168.2.170' ## Master 的 IP 地址
master_user='${slaveUser}' ## 用于同步数据的用户(在 Master 中授权的用户)
master_password='${password}' ## 同步数据用户的密码
master_port=3306 ## Master 数据库服务的端口
master_log_file='iuim-mysql-bin-log.000001' ##指定 Slave 从哪个日志文件开始读复制数据(可在 Master 上使用 show master status 查看到日志文件名)
master_log_pos=435## 从哪个 POSITION 号开始读
master_connect_retry=30 ##当重新建立主从连接时,如果连接建立失败,间隔多久后重试。单位为秒, 默认设置为 60 秒, 同步延迟调优参数。

## 查看主从同步状态
mysql> show slave status\G;
![这里写图片描述](https://img-blog.csdn.net/20180605204921429?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2poc2ZqYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
可看到 Slave_IO_State 为空, Slave_IO_Running 和 Slave_SQL_Running 是 No, 表明 此时Slave 还没有开始复制过程。

开启主从同步

mysql> start slave;
Query OK, 0 rows affected (0.00 sec) ## 再查看主从同步状态
mysql> show slave status\G;
这里写图片描述

至此,mysql主从复制配置完成,在master上对iuim库的操作会自动同步到salve上

四, Mycat在Mysql主从复制基础上实现读写分离

1,安装要求

Mycat是基于java开发的,首先确报已经安装了jdk1.7或以上版本的jdk,

2,创建mycat用户并设置密码

# useradd mycat
# passwd mycat

3,安装

上传安装包 到mycat服务器中的/home/mycat目录,并解压到/usr/local/mycat 目录

4,设置mycat环境变量

# vi /etc/profile
## mycat env
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin
# source /etc/profile

5,配置mycat

1) 在配置mycat前,请确报mysql主从复制安装完成并正常运行,mysql主从复制在mysql中配置,mycat不负责数据同步问题
配置mycat的schema.xml,如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
 <schema name="iuim" checkSQLschema="false" sqlMaxLimit="100">
        <table name="users" dataNode="dn1,dn2" rule="sharding-by-murmur" primaryKey="id"/>
 </schema>
    <dataNode name="dn1" dataHost="user_data_host1" database="iuim"/>
    <dataNode name="dn2" dataHost="user_data_host2" database="iuim"/>
    <dataHost name="user_data_host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
        <heartbeat>show slave status</heartbeat>
        <!-- 一对主从复制的节点,注意master节点配置在前面,slave节点配置在后面-->
        <writeHost host="host_master1" url="192.168.2.170:3306" user="root" password="111111"></writeHost>
        <writeHost host="host_slave1" url="192.168.2.171:3306" user="root" password="111111"></writeHost>
    </dataHost>

    <dataHost name="user_data_host2" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <heartbeat>show slave status</heartbeat>
        <!-- 一对主从复制的节点,注意master节点配置在前面,slave节点配置在后面-->
        <writeHost host="host_master2" url="192.168.2.172:3306" user="root" password="111111"></writeHost>
        <writeHost host="host_slave2" url="192.168.2.174:3306" user="root" password="111111"></writeHost>
    </dataHost>
</mycat:schema>

配置mycat的server.xml,如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
    <system>
        <property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
        <property name="useHandshakeV10">1</property>
        <property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
        <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
        <property name="sequnceHandlerType">2</property>
        <property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
        <property name="processorBufferPoolType">0</property>
        <property name="handleDistributedTransactions">0</property>
        <!-- off heap for merge/order/group/limit      1开启   0关闭-->
        <property name="useOffHeapForMerge">1</property>

        <!--单位为m -->
        <property name="memoryPageSize">64k</property>

        <!--单位为k -->
        <property name="spillsFileBufferSize">1k</property>

        <property name="useStreamOutput">0</property>

        <!--单位为m-->
        <property name="systemReserveMemorySize">384m</property>


        <!--是否采用zookeeper协调切换  -->
        <property name="useZKSwitch">false</property>

        <!-- XA Recovery Log日志路径 -->
        <!--<property name="XARecoveryLogBaseDir">./</property>-->

        <!-- XA Recovery Log日志名称 -->
        <!--<property name="XARecoveryLogBaseName">tmlog</property>-->
        <!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
        <property name="strictTxIsolation">false</property>
</system>
  <!—使用mycat连接mysql的用户名与密码->
    <user name="iuim_user">
        <property name="password">123456</property>
        <property name="schemas">iuim</property>
</user>
</mycat:server>

6、防火墙中打开 8066 和 9066 端口

MyCat 的默认数据端口为 8066, mycat 通过这个端口接收数据库客户端的访问请求。管理端口为 9066, 用来接收 mycat 监控命令、查询 mycat 运行状况、重新加载配置文件等

7,启动mycat(对应的, 重启: mycat restart , 关闭: mycat stop )

# cd /usr/local/mycat/bin/
# ./mycat start

8,MyCat 连接测试

五,HAProxy集群安装(实现Mycat HA)

5.1 mycat节点2部署

参照第四章另外部署一台mycat服务器

5.2 配置Mycat状态检查服务(在mycat节点主机上配置)

1)1、如果 xinetd 还没有安装,可使用如下命令安装:

# yum install xinetd

2)2、检查/etc/xinetd.conf 的末尾是否有 includedir /etc/xinetd.d ,没有就加上

# vi /etc/xinetd.conf

3) 检查 /etc/xinetd.d 目录是否存在,不存在刚创建

# mkdir /etc/xinetd.d/

4) 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 服务脚本

# 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/mycatstatus |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 服务
# vi /etc/services
在末尾加入:

mycat_status 48700/tcp # mycat_status
    保存后, 重启 xinetd 服务
# service xinetd restart

8) 验证 mycat_status 服务是否成功启动

    # netstat -antup|grep 48700

这里写图片描述

能看到上图这样的信息,说明服务配置成功。
9) MyCat 服务主机的防火墙上打开 48700 端口
10) 脚本测试:

# /usr/local/bin/mycat_status

5.3 haproxy安装

  1. 上传haproxy-1.5.16.tar.gz 到 /usr/local/src, 解压安装
# cd /usr/local/src/
# tar -zxvf haproxy-1.5.16.tar.gz
# cd haproxy-1.5.16
  1. 安装编译所需的依赖插件
# yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
  1. 编译
# 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 这三个包需要安装不然不支持
4,创建安装目录
        # mkdir /usr/local/haproxy
5,执行安装
        # make install PREFIX=/usr/local/haproxy
6,创建配置文件目录
# mkdir -p /usr/local/haproxy/conf
# mkdir -p /etc/haproxy/
7,从配置文件模版复制配置文件,并添加配置文件软连接
# 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
8,拷贝错误页面, 并添加目录软连接(HTTP 模式选配)
# cp -r /usr/local/src/haproxy-1.5.16/examples/errorfiles /usr/local/haproxy/
# ln -s /usr/local/haproxy/errorfiles /etc/haproxy/errorfiles
9,拷贝开机启动文件,并赋予可执行权限
# 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
10,添加 haproxy 命令脚本软连接
    # ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin
11,设置 HAProxy 开机启动
# chkconfig --add haproxy
# chkconfig haproxy on

5.4,HAProxy配置Mycat负载均衡集群

1,修改 haproxy.cfg 配置文件
    # 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 haproxy-01 ## 定义当前节点的名称,用于 HA 场景中多 haproxy 进程共享同一个 IP 地址时
description 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.1.203:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
server mycat_02 192.168.1.204:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
## 格式: server <name> <address>[:[port]] [param*]
### serser 在后端声明一个 server,只能用于 listen 和 backend 区段。
### <name>为此服务器指定的内部名称,其将会出现在日志及警告信息中
### <address>此服务器的 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 的值要做相应调整
1, 根据以上 HAProxy 配置文件要求做以下配置
(1) 添加 haproxy 用户组和用户

# groupadd haproxy
# useradd -g haproxy haproxy

(2)创建 chroot 运行的路径

# mkdir /usr/share/haproxy

(3)防火墙中打开 3306 端口和 48800 端口
2, 开启 rsyslog 的 haproxy 日志记录功能
默认情况下 haproxy 是不记录日志的,如果需要记录日志,还需要配置系统的 syslog, 在 linux 系
统中是 rsyslog 服务。 syslog 服务器可以用作一个网络中的日志监控中心, rsyslog 是一个开源工具,被
广泛用于 Linux 系统以通过 TCP/UDP 协议转发或接收日志消息。 安装配置 rsyslog 服务:

# yum install rsyslog ## 没安装的情况下执行安装
# vi /etc/rsyslog.conf

M o d L o a d i m u d p 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
Shutting down system logger: [ OK ]
Starting system logger: [ OK ]

(等到 HAProxy 服务启动后,就能在/var/log/haproxy.log 中看到日志了)
3, 配置系统内核的 IP 包转发功能

# vi /etc/sysctl.conf.ipv4.ip_forward = 1


使配置生效


# sysctl -p

4, 启动 HAProxy

haproxy 23921 1 0 23:27 ? 00:00:00 /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p
/var/run/haproxy.pid
root 23924 23179 0 23:27 pts/1 00:00:00 grep haproxy

5, 使用 MySQL 客户端通过 HAProxy 连接 MyCat

6, 登录 HAProxy 的状态信息统计页面
http://192.168.56.xx1:48800/admin-status(访问地址,用户密码(admin/admin)见配置)
这里写图片描述

六,Keepalived安装(实现HAProxy HA)

6.1 HAProxy 节点 2 的部署

HAProxy 主机 2参考第五章进行安装
注意配置文件的调整:
多节点部署时 haproxy.cfg 配置文件中的 node 、 description 配置的值要做相应调整。
HAProxy 节点 1 的状态信息页: http://192.168.56.xx1:48800/admin-status
这里写图片描述
HAProxy 节点 2 的状态信息页: http://192.168.56.xx2:48800/admin-status
这里写图片描述

6.2 keepalived安装

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
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

# vi /etc/keepalived/keepalived.conf

内容如下:

! Configuration File for keepalived
global_defs {
## keepalived 自带的邮件提醒需要开启 sendmail 服务。建议用独立的监控或第三方 SMTP
router_id 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 ens33## 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同,我的是ens33
virtual_router_id 91 ## 虚拟路由的 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.2.XX ## 虚拟 ip,可以定义多个,每行一个
}
}

BACKUP 节点配置文件

vi /etc/keepalived/keepalived.conf

内容如下:

! Configuration File for keepalived
global_defs {
router_id haproxy-02
}
vrrp_script chk_haproxy {
script "/etc/keepalived/haproxy_check.sh"
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth1
virtual_router_id 91
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_haproxy
}
virtual_ipaddress {
192.168.2.xx
}
}
  1. 编写 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

启动 Keepalived

# service keepalived start

Starting keepalived: [ OK ]
Keepalived 服务管理命令:
停止: service keepalived stop
启动: service keepalived start
重启: service keepalived restart
查看状态: service keepalived status
6.3 通过vip连接mysql

猜你喜欢

转载自blog.csdn.net/jhsfja/article/details/80586731