分布式集群架构方案

写在前面:本文写作前景为在b站上看到的一个三高(高可用、高并发、高性能)的分布式集群架构方案,并对其中的pxc集群以及haproxy负载均衡进行了试验。如若文中出现错误,欢迎广大网友提出。
保护知识产权,本文参考了如下博客文章

  • pxc集群搭建
    https://www.jianshu.com/p/eae6b12c1cd5
  • haproxy负载均衡
    https://blog.csdn.net/qq_21108311/article/details/82973763
  • 分布式集群理解
    https://www.cnblogs.com/zyxblogPHP/p/10706206.html
    如有侵权请联系删除

一 为什么需要分布式与集群

为什么需要分布式?举一个简单的例子如果应用程序和服务器在同一台机器上时,如果这台服务负载达到上限需要将整个应用迁到一个更高的性能的机器上。如果采用分布式架构,如果是数据库服务器性能达到上限只需要增加数据库服务器的性能。将数据库、应用程序、缓存等分开也可以方便对各部分进行管理。

为什么需要集群?以校园网为例,校园网采用单一的数据库节点。当选课开始或者成绩公布时,大量请求涌入,由于压力过大这台服务器突然宕机整个系统就会崩溃。采用集群的方案,如果一台数据库宕机还会有其它数据库保证整个服务正常进行。
采用分布式的集群如果某一节点性能不够,最简单的方式就可以采用增加节点的服务器。

二 MySQL集群

MySQL集群方案有两种,分别为pxc(Percona XtraDB Cluster)和Replication,这两种方案各有优缺点。
pxc为强一致性集群方案,数据同步为双向同步,集群中的每一个节点都可以是主节点。例如:当向pxc集群中的某一台数据库发出写操作后,只有当集群中所有节点都写入完成才会返回写入成功。这种方式可以保证每个节点的数据都是一致的,当然性能也受集群中最慢的节点影响。
Replication方案为读写分离方案数据,数据同步为单向同步。当向主库进行写操作后会进过一段延迟写入从库,所以其一致性较弱。从库写入数据后不会同步到主库
总结如下:

特点 pxc Replication
速度
一致性
应用场景 财务、账户、订单 新闻、帖子、日志

这里选择pxc集群搭建
数据备份方案:Xtrabackup热备

三 负载均衡与双机热备

三大主流负载均衡器,Nginx,HAProxy,LVS,简单对比如下

- Nginx HAProxy LVS
免费
虚拟主机 支持 支持 不支持
支持协议 http http、tcp tcp
配置 简单 简单 复杂
负载算法 轮询、加权轮询、ip哈希 轮询、加权轮询、原地址保持、请求URL、根据cookie 轮询、加权轮询、最小连接、权重最小连接

可参考链接:https://www.cnblogs.com/HacTF/p/7774106.html
这里选择HAproxy作为负载均衡器,HAproxy还提供一个监控界面来查看当前HAProxy的运行状态。
关于双机热备
为什么采用双机热备?在pxc集群中,如果一台MySQL挂掉会有其它MySQL保证系统的正常运行,但是如果HAProxy挂掉整个pxc集群都将无法访问。在这里就需要一个备份HAProxy在主HAproxy挂掉后及时接替主HAProxy的工作保证系统的正常。
怎样进行双机热备方案?采用keepalived。keepalived是以VRRP(Vritrual Router Redundancy Protocol,虚拟路由冗余协议)协议为基础用来保证集群高可用性,防止单点故障的一个软件。
keepalived工作原理:keepalived将提供一个双机浮动的vip(虚拟ip),这样可以简单实现一个双机热备高可用功能。即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到VRRP包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。以此保证路由器的高可用。
keepalived的配置可用自行查找资料
pxc集群负载均衡与双机热备理解

pxc集群负载均衡与双机热备

四 Redis集群

redis-cluste集群方案是redis官方在3.0版本后提供的分布式集群方案。在该方案中不存在中心节点。集群中每个节点存储的数据都不一样,并且节点之间互相连接。
redis-cluster中有一个“槽”的概念,在一个集群中一共有16384个槽。每一个key会经过计算算出数据存在哪一个槽中,计算方式为CRC16(key) mode 16384。不论是存或者取数据key都会先经过此运算计算槽。在物理机中,集群会把不同的槽映射到不同的物理机中。例如,集群中有三台机器,A对应槽为0-5500,B对应槽为5501-11000,C对应槽为11001-16384。当新增一个节点时cluster会从各节点拿出一部分槽分配到新节点上。例如,A:1501-5500,B:7001-11000,C:12501-16384,D:0-1500,5501-7000,11001-12500。
每个节点都会通过通讯共享槽与集群中各个节点的关系。当客户端向redis cluster中的任一节点发送请求,当前节点会计算key对应的槽,如果该槽正好在该节点上则返回key对应的数据,如果该槽不在该节点上会返回moved重定向异常,客户端从重定向异常中获取正确目标的节点,然后从目标节点中请求数据。该方式保证了获取数据最多需要两次请求。

Redis Cluster moved重定向

需要注意的是,如果集群中某一节点挂掉该节点的数据就会无法访问。为保证集群的高可用性,redis cluster加入了主从模式,一个主节点对应多个从节点。主节点提供数据,从节点从主节点复制数据,保证主从节点数据一致。如果主节点挂掉,从节点会接替主节点,随后故障主节点修复该节点会自动降级为从节点。
关于redis cluster集群我找到一篇比较详细的文章,可以参考:https://www.cnblogs.com/williamjie/p/11132211.html

五 应用程序与前端

关于应用程序的部署,因为各语言的方案不同,Java有Tomcat,Python有uWSGI和Gunicorn。
在应用程序部署好后也需要负载均衡器做负载,为防止负载均衡器意外挂掉也需要进行双机热备。Nginx是一款开源,高性能,轻量级的负载均衡器和反向代理服务器。双机热备方案同样使用keepalived争抢虚拟ip的形式。以Python为例:


后端应用程序负载均衡与双机热备

具体方案不再缀述。
由于前段方案也是Nginx负载和keepalived双机热备的方式,这里也不再缀述。

六 总体架构

在这里前后端分离的分布式总体架构已经明确了。请求从前端服务器开始,Nginx对前端服务器做负载均衡,为防止Nginx挂掉使用keepalived争抢虚拟ip方式进行双机热备。对数据的请求由后端应用程序开始,请求到达后端的Nginx,由Nginx进行反向代理与负载均衡,为防止Nginx意外挂掉同样使用keepalived进行双机热备。如果访问热点数据则先在redis集群里寻找,如果redis集群中没有则向pxc数据库集群中进行请求。pxc集群同样需要使用HAProxy做负载均衡,为防止HAProxy挂掉使用keepalived做双机热备。


分布式集群架构图

七 pxc集群搭建与负载均衡

注:这里不详细描述具体步骤,详细步骤可参考最上面附的两篇博客
环境准备:Centos7(1核2G,阿里云)、docker
关于docker的操作可以参考https://yeasy.gitbooks.io/docker_practice/content/
或者docker --help,这里主要涉及的有操作有网段network,卷 volume,镜像image,容器container,可分别用docker network --help查看相应的操作。
前提准备:
前往阿里云控制台的安全组实例配置中把将要使用的端口开放,创建网段,创建卷
可配置阿里云的镜像加速器(强烈建议)
集群搭建
创建网段:docker network create --subnet=172.19.0.0/24 pxc-test-network
创建卷:docker volume create pxc-test-volume1
拉取镜像:docker pull percona/percona-xtradb-cluster:5.7
可将镜像重命名:docker tag percona/percona-xtradb-cluster:5.7 pxc
创建第一个节点,pxc集群创建第一个节点数据库实例化会比较慢,如果第一个节点没有完成实例化或者实例化失败后面的节点加入的时候会失败。
docker run -d -p 7306:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -v pxc-test-volume1:/var/lib/mysql --name=pxc_node1 --net=pxc-test-network --ip=172.19.0.2 pxc
可以是Navicat或者其它软件连接MySQL,如果连接成功则证明第一个节点创建成功。
创建第二个节点并加入集群:
docker run -d -p 7307:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -e CLUSTER_JOIN=pxc_node1 -v pxc-test-volume2:/var/lib/mysql --name=pxc_node2 --net=pxc-test-network --ip=172.19.0.3 pxc
创建第三个节点并加入集群:
docker run -d -p 7308:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=pxc_cluster -e CLUSTER_JOIN=pxc_node1 -v pxc-test-volume3:/var/lib/mysql --name=pxc_node3 --net=pxc-test-network --ip=172.19.0.4pxc
参数解释:

  • MYSQL_ROOT_PASSWORD:MySQL用户密码,用户是root
  • CLUSTER_NAME:集群名字
  • CLUSTER_JOIN:与某个节点同步

HAProxy负载均衡
拉取镜像docker pull haproxy
编写配置文件并将配置文件映射到docker容器内这里为/data/haproxy/haproxy.cfg(后附上配置文件详情)
启动容器docker run -it -d -p 8001:8888 -p 8002:3306 -v /data/haproxy:/usr/local/etc/haproxy --name haproxy_node1 --privileged --net=pxc-test-network --ip 172.19.0.07 docker.io/haproxy
进入容器:docker exec -it haproxy bash
启用配置文件:haproxy -f /usr/local/etc/haproxy/haproxy.cfg
然后可放问监控界面,http://你的ip:port/dbs,输入用户名和密码(在配置文件配置)
要记得在MySQL中创建haproxy的用户,在一个节点创建就行了pxc会自动同步
CREATE USER 'haproxy@'%' IDENTIFIED BY ''

HAProxy监控界面

遇到的坑

  1. 拉取pxc的镜像总是卡住,解决:配置阿里云镜像加速
  2. 一开始集群节点为五个,后来启动HAProxy容器的时候不就该容易无法启动pxc主节点也老是挂掉,整到晚上一点。第二天free -h查看内存就剩几十M,推测内存不够于是在一台新的阿里云服务器上配置HAProxy,成功!
  3. pxc集群为五个节点的时候,往节点写入数据成功,然后查这一条数据失败,docker查看主节点容易挂掉,顿时懵逼。首先想是不是配置有问题,后来推测是不是因为内存不够,集群节点改为三个,成功!

附:HAProxy配置文件haproxy.cfg

global
        #工作目录
        chroot /usr/local/etc/haproxy
        #日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info
        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
        #监控界面的访问的IP和端口
        bind  0.0.0.0:8888
        #访问协议
        mode        http
        #URI相对地址
        stats uri   /dbs
        #统计报告格式
        stats realm     Global\ statistics
        #登陆帐户信息,用户名:密码
        stats auth  root:root
#数据库负载均衡
listen  proxy-mysql
        #访问的IP和端口(前面ip=0代表任何ip都可访问)
        bind  0.0.0.0:3306
       #网络协议
        mode  tcp
        #负载均衡算法(轮询算法)
        #轮询算法:roundrobin
        #权重算法:static-rr
        #最少连接算法:leastconn
        #请求源IP算法:source 
        balance  roundrobin
        #日志格式
        option  tcplog
        #在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测
        option  mysql-check user haproxy
        server  NODE1 47.100.48.93:7306 check weight 1 maxconn 2000
        server  NODE2 47.100.48.93:7307 check weight 1 maxconn 2000
        server  NODE3 47.100.48.93:7308 check weight 1 maxconn 2000
        server  NODE4 47.100.48.93:7309 check weight 1 maxconn 2000
        server  NODE5 47.100.48.93:7310 check weight 1 maxconn 2000
        #使用keepalive检测死链
        option  tcpka

你可能感兴趣的:(分布式集群架构方案)