集群的方案
单节点的弊病
-
大型互联网程序用户群体庞大,因此架构必需要特殊设计
-
单节点的数据库没法知足性能的要求
案例15年前,高考成绩能够在网上查(河南几十万考生),那时候基本家里都没电脑,都是去网吧白天去网吧也查不了,太慢了,后来半夜通宵有时候能够查到,也就是说白天基本查不了人太多了。晚上看运气。一个数据库的实例1万多人就没法反应了。
-
单节点的数据库没有冗余设计,没法知足高可用
经常使用的mysql集群设计方案
-
速度快
-
弱一致性
-
低价值
-
场景:日志,新闻,帖子
-
速度慢
-
强一致性
-
高价值
-
场景:订单,帐户,财务
Percona Xtradb Cluster,简称PXC。是基于Galera插件的MySQL集群。相比那些比较传统的基于主从复制模式的集群架构MHA和MM+keepalived,galera cluster最突出特色就是解决了诟病已久的数据复制延迟问题,基本上能够达到实时同步。并且节点与节点之间,他们相互的关系是对等的。自己galera cluster也是一种多主架构。galera cluster最关注的是数据的一致性,对待事物的行为时,要么在全部节点上执行,要么都不执行,它的实现机制决定了它对待一致性的行为很是严格,这也能很是完美的保证MySQL集群的数据一致性。在PXC里面任何一个节点都是可读可写的。在其余的节点必定是能够读取到这个数据。
PXC任意一个节点均可以存在读写的方案,也就是任意一个节点均可以当读或者当写。同步复制。保证强一致性。
Replication方案,主从的方式,他是采用异步的方式。
同步复制,事务在全部节点要提交都提交。要么都不提交
环境搭建
应用IP地址服务配置安装应用安装方式docker-mysql192.168.66.100docker-mysql双核 8g内存docker-mysqldocker
vagrant up复制代码
(2).机器window/mac开通远程登陆root用户下
su -
vagrant
vi /etc/ssh/sshd_config
sudo systemctl restart sshd复制代码
PXC集群安装介绍
PXC既能够在linux系统安装,也能够在docker上面安装。
docker pull percona/percona-xtradb-cluster
docker load </home/soft/pxc.tar.gz复制代码
处于安全,须要给PXC集群实例建立Docker内部网络,都出可虚拟机自带的网段是172.17.0., 这是内置的一个网段,当你建立了网络后,网段就更改成172.18.0.,
docker network create net1
docker network inspect net1
docker network rm net1
docker network create --subnet=172.18.0.0/24 net1复制代码
一旦生成docker容器,不要在容器内保存业务的数据,要把数据放到宿主机上,能够把宿主机的一个目录映射到容器内,若是容器出现问题,只须要吧容器删除,从新创建一个新的容器把目录映射给新的容器。
以前一直有个疑问,若是直接映射目录的吧,存在失败的问题,如今终于知道解决方案了,直接映射docker卷就能够能够忽略这个问题了。
容器中的PXC节点映射数据目录的解决方法
docker volume create name --v1复制代码
mysql pxc搭建
#!/bin/bash
echo "建立网络"
docker network create --subnet=172.18.0.0/24 net1
echo "建立5个docker卷"
docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5
echo "建立节点 node1"
docker run -d -p 3306:3306 --net=net1 --name=node1 \
-e CLUSTER_NAME=PXC \
-e MYSQL_ROOT_PASSWORD=a123456 \
-e XTRABACKUP_PASSWORD=a123456 \
-v v1:/var/lib/mysql \
--privileged \
--ip 172.18.0.2 \
percona/percona-xtradb-cluster
sleep 1m
echo "建立节点 node2"
docker run -d -p 3307:3306 --net=net1 --name=node2 \
-e CLUSTER_NAME=PXC \
-e MYSQL_ROOT_PASSWORD=a123456 \
-e XTRABACKUP_PASSWORD=a123456 \
-e CLUSTER_JOIN=node1 \
-v v2:/var/lib/mysql \
--privileged \
--ip 172.18.0.3 \
percona/percona-xtradb-cluster
sleep 1m
echo "建立节点 node3"
docker run -d -p 3308:3306 --net=net1 --name=node3 \
-e CLUSTER_NAME=PXC \
-e MYSQL_ROOT_PASSWORD=a123456 \
-e XTRABACKUP_PASSWORD=a123456 \
-e CLUSTER_JOIN=node1 \
-v v3:/var/lib/mysql \
--privileged \
--ip 172.18.0.4 \
percona/percona-xtradb-cluster
sleep 1m
echo "建立节点 node4"
docker run -d -p 3309:3306 --net=net1 --name=node4 \
-e CLUSTER_NAME=PXC \
-e MYSQL_ROOT_PASSWORD=a123456 \
-e XTRABACKUP_PASSWORD=a123456 \
-e CLUSTER_JOIN=node1 \
-v v4:/var/lib/mysql \
--privileged \
--ip 172.18.0.5 \
percona/percona-xtradb-cluster
sleep 1m
echo "建立节点 node5"
docker run -d -p 3310:3306 --net=net1 --name=node5 \
-e CLUSTER_NAME=PXC \
-e MYSQL_ROOT_PASSWORD=a123456 \
-e XTRABACKUP_PASSWORD=a123456 \
-e CLUSTER_JOIN=node1 \
-v v5:/var/lib/mysql \
--privileged \
--ip 172.18.0.6 \
percona/percona-xtradb-cluster复制代码
新创建一个aaa数据库 结果均可以用
哇塞就这么简单,成功的搭建了mysql的集群
增长负载均衡方案
目前数据库都是独立的ip,在开发的时候总不能随机链接一个数据库吧。若是想请求,统一的口径,这就须要搭建负载均衡了。虽然上边已经搭建了集群,可是不使用数据库负载均衡,单节点处理全部请求,负载高,性能差。下图就是一个节点很忙,其余节点很闲。
LVS是不知道在虚拟机环境下安装的。
mkdir haproxy/h1
pwd
vi haproxy.cfg复制代码
登陆:admin 密码:abc123456
global
chroot /usr/local/etc/haproxy
log 127.0.0.1 local5 info
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
listen admin_stats
bind 0.0.0.0:8888
mode http
stats uri /dbs
stats realm Global\ statistics
stats auth admin:abc123456
listen proxy-mysql
bind 0.0.0.0:3306
mode tcp
balance roundrobin
option tcplog
option mysql-check user haproxy
server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
option tcpka复制代码
docker run -it -d -p 4001:8888 \
-p 4002:3306 \
-v /root/haproxy/h1:/usr/local/etc/haproxy \
--name h1 --privileged --net=net1 \
--ip 172.18.0.7 haproxy复制代码
docker exec -it h1 /bin/bash
haproxy -f /usr/local/etc/haproxy/haproxy.cfg复制代码
正常的链接haproxy,传递增删盖查,实际上是经过轮询的方式。选择mysql的节点。均匀的分发给mysql的实例。不会吧数据库的请求都集中在一个节点上。把请求分散出去,每一个数据库实例获取到的请求就小不少了。这就是数据库的负载。
查看日志发现,node1没法启动,输入命令查看docker logs node1
It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .复制代码
解决方案
docker volume inspect v1
cd /var/lib/docker/volumes/v1/_data
vi grastate.dat复制代码
高可用负载均衡方案
目前haproxy只有一个,单haproxy不具有高可用,必须冗余设计。haproxy不能造成瓶颈。
haproxy双机互备离不开一个关键的技术,这个技术是虚拟IP,linux能够在一个网卡内定义多个虚拟IP,得把这些IP地址定义到一个虚拟IP。
定义出来一个虚拟IP,这个方案叫双机热备,准备2个keepalived,keepalived 就是为了抢占虚拟IP的,谁手快谁能抢到,没抢到的处于等待的状态。抢到的叫作主服务器,未抢到的叫作备服务器。两个keepalived以前有心跳检测的,当备用的检测到主服务挂了,就立马抢占虚拟IP。
keepalived必须在haproxy所在的容器以内,也能够在docker仓库里面下载一个haproxy-keepalived的镜像。这里直接在容器内安装keepalived。
docker exec -it h1 /bin/bash
echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null
apt-get clean
apt-get update
apt-get install vim
vi /etc/apt/sources.list复制代码
sources.list 添加下面的内容
deb http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb-src http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted复制代码
apt-get clean
apt-get update
apt-get install keepalived
apt-get install vim复制代码
容器内的路径:/etc/keepalived/keepalived.conf
vi /etc/keepalived/keepalived.conf复制代码
-
VI_1 名称能够自定义
-
state MASTER | keepalived的身份(MASTER主服务器,BACKUP备份服务器,不会抢占虚拟机ip)。若是都是主MASTER的话,就会进行互相争抢IP,若是抢到了就是MASTER,另外一个就是SLAVE。
-
interface网卡,定义一个虚拟IP定义到那个网卡上边。网卡设备的名称。eth0是docker的虚拟网卡,宿主机是能够访问的。
-
virtual_router_id 51 | 虚拟路由标识,MASTER和BACKUP的虚拟路由标识必须一致。标识能够是0-255。
-
priority 100 | 权重。MASTER权重要高于BACKUP 数字越大优选级越高。能够根据硬件的配置来完成,权重最大的获取抢到的级别越高。
-
advert_int 1 | 心跳检测。MASTER与BACKUP节点间同步检查的时间间隔,单位为秒。主备之间必须一致。
-
authentication | 主从服务器验证方式。主备必须使用相同的密码才能正常通讯。进行心跳检测须要登陆到某个主机上边全部有帐号密码。
-
virtual_ipaddress | 虚拟ip地址,能够设置多个虚拟ip地址,每行一个。根据上边配置的eth0上配置的ip。
容器内启动
service keepalived start复制代码
宿主机ping这个ip
ping 172.18.0.201复制代码
建立haproxy2容器,并配置与haproxy1相同的环境
由于要保证有2个haproxy 和keepalived,此次就不那么麻烦了。直接对一个镜像里面包括keeplived 和 haproxy。
mkdir haproxy/h2
cd haproxy/h2
vi haproxy.cfg
vi keepalived.cfg复制代码
global
chroot /usr/local/etc/haproxy
log 127.0.0.1 local5 info
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
listen admin_stats
bind 0.0.0.0:8888
mode http
stats uri /dbs
stats realm Global\ statistics
stats auth admin:abc123456
listen proxy-mysql
bind 0.0.0.0:3306
mode tcp
balance roundrobin
option tcplog
option mysql-check user haproxy
server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
option tcpka复制代码
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.18.0.201
}
}复制代码
docker run -it -d --privileged -p 4003:8888\
-p 4004:3306 \
-v /root/haproxy/h2/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg \
-v /root/haproxy/h2/keepalived.conf:/etc/keepalived/keepalived.conf \
--name haproxy-keepalived \
--net=net1 \
--name h2 \
--ip 172.18.0.8 \
pelin/haproxy-keepalived复制代码
宿主机安装keepalived
yum -y install keepalived
vi /etc/keepalived/keepalived.conf
复制代码
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.66.200
}
}
virtual_server 192.168.66.200 8888 {
delay_loop 3
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 172.18.0.201 8888 {
weight 1
}
}
virtual_server 192.168.66.200 3306 {
delay_loop 3
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 172.18.0.201 3306 {
weight 1
}
}复制代码
service keepalived start复制代码
虚拟机端口转发 外部没法访问
WARNING: IPv4 forwarding is disabled. Networking will not work.复制代码
宿主机修改
vi /etc/sysctl.conf
systemctl restart network复制代码
PS:若是经过docker的方式直接拉取haproxy和keepalived镜像,比直接在镜像里面安装应用方便不少,建议各位老铁尽可能避免在容器内安装应用,这样真心麻烦不爽,别人封装的镜像根据pull的量好好看看api就可使用了。像h1若是容器stop后,从新start,还须要进入容器把keeplived给起起来。而h2直接start里面的haproxy和keeplived,同时都起起来了。 两个容器的采用的热备的方案,让用户毫无感知,切换ip的形式真是美滋滋。mysql集群的高性能,高负载,高可用基本完成了,可用按照这个思路搭建不一样的主机下。