每日任务:主从复制 读写分离 负载均衡
主:54.22.37.21
从1:54.22.37.20
从2:54.22.37.19
平衡:204.175.124.51
实际操作目标:test数据库查询
框架图以下:
简单Mysql负载均衡配备框架图
========================= 主连接点配备 =========================
# 受权一个容许从连接点主从复制的客户repl
grant replication slave on *.* to 'repl'@'54.22.37.%' identified by "xxxxx";
# 打开二进制日志
server-id =21
log-bin = /var/lib/mysql/mysql-bin
log-bin-index = /var/lib/mysql/mysql-bin.index
binlog_format = mixed
expire_logs_days = 10
max_binlog_size = 100M
# 重新启动服务项目
# 备份数据test数据库查询
# 获得master情况
show master status
------------------ ---------- -------------- ------------------ -------------------
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
------------------ ---------- -------------- ------------------ -------------------
| mysql-bin.000007 | 921390 | | | |
------------------ ---------- -------------- ------------------ -------------------
================== 从连接点1(54.22.37.20)配备 =====================
# 试着远程桌面连接一下
# 建立test库并导进test
# 配备同歩日志
server-id = 20
relay-log = /var/lib/mysql/relay-bin
relay-log-index = /var/lib/mysql/relay-bin.index
replicate-do-db = test
slave-skip-errors = all
PS:这儿也没有打开二进制日志,只打开了同歩日志
# 偏向主连接点
stop slave; # 先终止以前的同歩
reset slave; # 清除以前的同歩
change master to master_host="54.22.37.21",master_user="repl",master_password="xxxxx",master_log_file="mysql-bin.000007",master_log_pos=921390; #偏向主连接点
start slave; # 打开同歩
# 查询同歩的情况
show slave status;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 54.22.37.21
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 921390
Relay_Log_File: relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000007
Slave_IO_Running: No
Slave_SQL_Running: Yes
Replicate_Do_DB: test
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 921390
Relay_Log_Space: 154
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path: Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1593
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 86
Master_UUID:
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 200115 20:13:05
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
表明同歩不成功
关键看这好多个地区
Slave_IO_Running: No
Slave_SQL_Running: Yes
Replicate_Do_DB: test
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
同歩不成功的缘故在Last_IO_Error说的很搞清楚,具备同样的UUID,这是由于
主:54.22.37.21
从1:54.22.37.20
从2:54.22.37.19
这三台网络服务器是以一个镜像系统拷出去的,因此 ,她们mysql的UUID是同样的。
大家只需将UUID该成不一样的就可以了:
show variables like "%uuid%"; # 查询当今uuid
select uuid(); # 转化成一个新的uuid,拷贝该uuid
show varialbes like "�tadir" # 查询数据信息文件目录部位,uuid文档的储放部位也在这儿,yum安装的mysql一般在/var/lib/mysql
# 改动/var/lib/mysql/auto.cnf uuid就写在这个文档里
[auto]
server-uuid=dd8d34de-be32-11e9-931e-04155d871a13
将其改动为刚拷贝的uuid
重新启动服务项目
# 再次查验同歩情况
show slave status;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 54.22.37.21
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 921390
Relay_Log_File: relay-bin.000003
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: test
...
同歩取得成功;
================== 从连接点2(54.22.37.19)配备 =====================
做和从连接点1同样的实际操作
在主连接点检测插进几个数据信息试一下,看一下是不是同歩。
================== 负载均衡连接点配备(204.175.124.51) ===============
# 安裝和配备好haproxy(以前章节目录有安裝和配备的流程实际操作)
配备好的haproxy的环境变量內容以下:
global
daemon
nbproc 1
pidfile /usr/local/haproxy/conf/haproxy.pid # 这一待会儿要自身建
defaults
mode tcp # 默认设置的方式(tcp|http|health),tcp是4曾,http是7层,health只回到OK
retries 2 # 2次连接失败就觉得网络服务器不能用,还可以根据后边设定
option redispatch # 当server选择项特定的网络服务器挂了后,强制性定项到别的身心健康的网络服务器
option abortonclose #当网络服务器负荷很高,全自动完毕当今序列解决的较为久的联接
maxconn 4096 # 默认设置最大连接数
timeout connect 5000Ms #网络连接超时時间
timeout client 30000Ms #手机客户端请求超时
timeout server 30000Ms #网络服务器请求超时
log 127.0.0.1 local0 err
listen test1 # 配备负载均衡的连接点,test1是姓名,能够随便
bind 0.0.0.0:3300 # haproxy服务项目监视的IP和端口号,这儿的0.0.0.0便是该设备
mode tcp # 连接数据库,肯定是tcp协议,这儿实际上可以不特定,由于前边早已特定过去了
server s1 54.22.37.19:3306 # 特定从连接点1的IP和端口号
server s2 54.22.37.20:3306 # 特定从连接点2的IP和端口号
PS:因为负载均衡自身就会有mysql,mysql占有了3306端口号。因此 ,haproxy关联3300端口号以避免 矛盾。
haproxy只需特定从连接点,只和从连接点联接。主连接点只有一个只承担写,由业务流程层立即联接,不用由haproxy联接。haproxy会对查看要求平分到2个从连接点。
# 建立haproxy.pid文档
cd /usr/local/haproxy/conf && touch haproxy.cfg && echo 1>haproxy.cfg
chmod 755 haproxy.cfg
================== 从连接点受权客户给负载均衡连接点 ===============
# 在全面启动haproxy服务项目以前,先在全部从连接点建立一个供负载均衡连接点联接到从连接点的客户
我们可以那样,改动从连接点1和从连接点2的环境变量,放多一条 replicate-do-db=mysql,随后重新启动mysql
表明从连接点同歩mysql库
随后在主连接点建立和受权这一供负载均衡连接点应用的客户,那样全部从连接点就也都是有这一客户了
grant all on *.* to "haproxy"@"204.175.124.51" identified by "xxxxx"
建立了haproxy客户给ip 204.175.124.51(负载均衡连接点),有着全部管理权限。
最终返回负载均衡连接点,大家运行haproxy服务项目
haproxy -f /usr/local/haproxy/conf/haproxy.cfg # 特定环境变量运行haproxy,haproxy指令已加上到环境变量
========================= 检测 ========================
最终大家开展检测,假如你的负载均衡连接点沒有设定服务器防火墙,那麼能够立即在当地开展检测:
mysql -h204.175.124.51 -uhaproxy -P3300 -pxxxxx # 这儿如同连mysql一样去连负载均衡连接点的的haproxy服务项目就可以,这儿表层上好像连204.175.124.51的mysql,实际上连的是该连接点的haproxy服务项目。
show variables like "%server_id%"; # 查询所连的连接点的server-id
太多一段时间再实行一次上边的查看,发觉表明的server-id不一样,就表明haproxy将要求分派到2个从连接点,根据联接haproxy能够浏览到2个从连接点。
这儿说一下全部联接的全过程:
网络层——->要求负载均衡连接点的haproxy服务项目
负载均衡连接点haproxy——–>根据一定优化算法,要求两部从连接点中的一台
网络层要求的是负载均衡连接点的haproxy服务项目,而不是它的mysql服务项目,因此 负载均衡连接点的mysql即使关掉了或是压根没安裝mysql都没事儿。
只需负载均衡连接点沒有设定服务器防火墙,网络层在实行mysql -h204.175.124.51 -uhaproxy -P3300 -pxxxxx的情况下都能够联接到haproxy服务项目
在负载均衡连接点上,haproxy服务项目应用在网络层键入的mysql的登录名和登陆密码去要求从服务器,因此 在从连接点受权客户的情况下,受权的ip并不是网络层的IP,也不是从连接点的ip,只是负载均衡连接点的ip,由于这一客户是给负载均衡连接点用的。网络层没法立即连接从连接点,由于从连接点沒有受权客户给网络层。
================== 限定手机客户端联接负载均衡连接点 ===============
最终为了更好地安全起见,要给平衡连接点设定服务器防火墙,限制特殊的ip或是ip段才可以联接负载均衡连接点
我的Linux是Centos 7.2版本号,服务器防火墙是firewalld指令
系统软件是默认设置不打开服务器防火墙的。下面详细介绍一些简易的服务器防火墙专业知识和指令
systemctl status firewalld # 查看防火墙情况
systemctl stop firewalld # 关闭防火墙
systemctl start firewalld # 打开服务器防火墙
systemctl is-enabled firewalld #查看防火墙是不是开机自启
systemctl enable firewalld.service # 开机自启服务器防火墙
systemctl disable firewalld.service # 启动禁止使用服务器防火墙
firewalld-cmd 基础应用
firewall 能够当做全部服务器防火墙服务项目,而firewall-cmd能够当做是在其中的一个作用,能用来管理方法端口号和ip
firewall-cmd --zone=public --list-ports # 查询对外开放的全部端口号
firewall-cmd --zone=public --list-ports # 查询全部对外开放的状况
firewall-cmd --zone=public --add-port=80/tcp --permanent # 对外开放80端口,永久性合理。务必重新加载才可以起效:firewall-cmd --reload
firewall-cmd --zone=public --remove-port=9898/tcp --permanent #关掉特定端口号
firewall-cmd对端口号的实际操作,如开放端口等信息内容,都放到在"/etc/firewall/zones/public.xml"中纪录
上边是对端口号的实际操作。
假如想对于IP和端口设置以下:
firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address='192.168.10.0/24' service name='ssh' drop"
# 表明192.168.10这一IP段的客户没法根据ssh远程桌面连接这一设备 service name='ssh' 表明对哪一个服务项目开展实际操作。
firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv4' source address='192.168.10.50' port port=22 protocol=tcp reject"
# 表明对192.168.10.50这一客户禁掉22端口
firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address='192.168.10.50' port port=22 protocol='tcp' accept"
# 容许该客户联接22端口
drop和reject全是严禁联接,只不过是方法不一样。强烈推荐应用reject。
假如要撤消上一条的设定,例如撤消掉accept这一实际操作,应用--remove-rich-rule就可以
firewall-cmd --permanent --remove-rich-rule="rule family=ipv4 source address='192.168.10.50' port port=22 procotol='tcp' accept"
还记得最终要 firwall-cmd –reload 才可以起效
那麼下面大家设定只容许某ip段的客户联接负载均衡连接点。
# 我的网络服务器默认设置沒有打开服务器防火墙,因此 如今一切网络服务器都能联接我网络服务器的一切端口号,因此 haproxy当然还可以联接
# 如今打开服务器防火墙
service firewalld start
# 这个时候,一切IP都连不上我的一切端口号;因此 自己的博客网无法打开了(80端口),可是能够根据ssh远程控制连接网络,由于firewall默认设置容许ssh服务联接。
# 如今打开80端口,让我的网站网可以浏览:
firewall-cmd --zone=public --add-port=80/tcp --permanent # 这一步大家能够无需设定
# 对173.12.234这一IP段(它是家中的WiFi的IP段)打开3300这一端口号,让它能够联接haproxy服务项目
firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address='173.12.234.0/24' port port=3300 protocol='tcp' accept"
# 让其起效
firewall-cmd --reload
那样仅有这一ip段可以联接haproxy,安全系数大大增加。
在具体开发设计中,应当将负载均衡连接点分派给网络层所属的网络服务器的ip或是IP段,由于仅有这种网络服务器才会去连负载均衡连接点去要求数据信息。
也有,因为从连接点只承担读取数据,因此 从连接点受权客户给负载均衡连接点时,仅用受权select管理权限就可以,无需受权全部管理权限。那样即便有别人连到了haproxy,也没法对数据信息开展删掉或改动。
==================================================================
最终,配备一下Web运用联接mysql群集,以TP5为例子,配备其根目录下/config/database.php。
该Web运用立即布署在负载均衡网络服务器204.175.124.51上。并在主连接点受权一个删改改管理权限的客户zbpblog给Web运用(即负载均衡连接点)
<?php
return [
// 数据库类型
'type' => 'mysql',
// 服务器ip
'hostname' => ["54.22.37.21",'127.0.0.1'], # TP5默认设置该主要参数中第一个连接点是主连接点,以后的连接点是以连接点;这儿尽管只特定了一个从连接点的ip,但实际上这一ip是haproxy代理商,实际上有两个从连接点。倘若沒有应用haproxy开展负载均衡,这儿应当写出 ["54.22.37.21",'54.22.37.20','54.22.37.19']
// 数据库查询名
'database' => 'test', # 主连接点和从连接点的库名全是test
// 登录名
'username' => ['zbpblog',"haproxy"], # 主连接点受权zbpblog给负载均衡连接点,从连接点受权haproxy客户给负载均衡连接点
// 登陆密码
'password' => ['xxxxx',"xxxxx"],
// 端口号
'hostport' => ['3306','3300'], # 负载均衡连接点的haproxy监视的是3300
// 联接dsn
'dsn' => '',
// 连接数据库主要参数
'params' => [],
// 数据库查询编号默认设置选用utf8
'charset' => 'utf8',
// 数据库表作为前缀
'prefix' => '',
// 数据库查询开发者模式
'debug' => true,
// 数据库查询布署方法:0 集中型(单一网络服务器),1 分布式系统(主从关系网络服务器)
'deploy' => 1, # 表明应用mysql分布式系统群集
// 数据库查询读写能力是不是分离出来 主从关系式合理
'rw_separate' => true, # 表明要读写分离,主库写,从库读
// 读写分离后 主网络服务器总数
'master_num' => 1, # 表明只有一个主连接点,假如master_num>1,则默认设置前n个连接点是主连接点,别的为从连接点
// 特定从服务器编号
'slave_no' => [1],
// 全自动载入主库数据信息
'read_master' => false,
// 是不是严苛查验字段名是不是存有
'fields_strict' => true,
// 数据回到种类
'resultset_type' => 'array',
// 全自动载入时间格式字段名
'auto_timestamp' => false,
// 時间字段名取下后的默认设置时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 是不是必须开展SQL特性剖析
'sql_explain' => false,
// Builder类
'builder' => '',
// Query类
'query' => '\\think\\db\\Query',
// 是不是必须断开重新连接
'break_reconnect' => false,
// 断开标志字符串数组
'break_match_str' => [],
];