docker-compose和traefik实现本机PXC集群的快速搭建和负载均衡

docker-compose和traefik实现本机PXC集群的快速搭建和负载均衡

什么是PXC?

Percona XtraDB Cluster (PXC) 是一个完全开源的 MySQL 数据库集群解决方案,它可确保高可用性,防止停机和数据丢失,并为不断增长的环境提供线性可扩展性。它将 Percona Server 和 Percona XtraBackup 与 Galera 库集成在一起,以实现同步多源复制。

PXC有哪些作用

  1. 同步复制:PXC使用Galera Cluster的同步复制技术,保证在所有节点之间的数据一致性。当一个节点接收到一个事务时,它提示事务复制到其他节点,从而实现数据的同步复制。
  2. 故障检测和自动故障转移:PXC具备故障检测和自动故障转移机制作。当一个节点宜机或不可用时,群会检测到并自动将请求路由到其他可用节点,以确保系统的可用性能。
  3. 读写负载均衡:由于PXC的多主复制架构众多,应用程序可以同时在节点上进行读和写操作,从而实现读写负载均值衡。
  4. 数据一致性和事务支持:PXC确保在整个维护集群中的所有节点之间的数据一致性,并提供完全支持ACID特性的事务处理。

PXC是一个强大的MySQL集群解决方案,可以提供高可用性、容错性和可扩展性。

PXC模式和Replication(传统主从)对比

image-20230623103027449

  1. 写操作延迟:PXC模式通常具有较低的写操作延迟,因为所有节点都可以处理写操作。而传统主从复制模式的写操作延迟较高,因为写操作必须由主节点处理并传播到从节点。
  2. 扩展性:PXC模式支持水平扩展,可以通过添加更多节点来增加集群的容量和性能。传统主从复制模式则需要在主节点上进行垂直扩展,增加其处理能力。
  3. 数据一致性:PXC模式通过多数派投票来实现数据一致性,并且在网络分区或节点故障时能够自动处理。传统主从复制模式在进行故障切换时可能会有一些数据丢失,需要手动处理数据一致性。
  4. 可用性:PXC模式在集群中的任何节点出现故障时都能保持可用性,因为所有节点都可以处理读写操作。传统主从复制模式在主节点故障时需要进行故障切换,可能会导致一段时间内的服务中断。

Traefik

image-20230623103137109

Traefik 是一种流行的开源反向代理和负载均衡器,广泛用于容器化环境。它提供了多种优势和功能,使其成为管理传入流量并将其路由到微服务或应用程序的热门选择。以下是常用Traefik的一些原因:

  1. 动态配置:Traefik 提供动态服务的配置和发现。它与 Docker、Kubernetes 和 Swarm 等容器编排器无缝集成,并且可以在部署或删除新服务时自动检测它们。这种动态配置消除了手动更新的需要,并使扩展和管理基础结构变得更加容易。
  2. 负载平衡:Traefik 提供内置的负载平衡功能。它将传入流量分布到应用程序或服务的多个实例之间,从而提高整体性能、可伸缩性和可靠性。Traefik 支持各种负载平衡算法,包括轮询、最少连接和 IP 哈希。
  3. **自动 SSL/TLS:**Traefik 简化了 SSL/TLS 证书的管理。它可以为您的服务自动获取和续订Let’s Encrypt SSL证书,确保客户端和服务器之间的安全通信,而无需手动证书管理。此功能可节省保护应用程序的时间和精力。
  4. 流量路由和中间件:Traefik 提供强大的流量路由功能,并支持基于主机、路径、标头等请求属性的各种路由规则。它还支持中间件,允许您向服务添加其他功能,如身份验证、速率限制、请求重写等。这种灵活性使您能够自定义和控制流量以满足您的特定要求。
  5. 监控和指标:Traefik 提供内置的监控和指标功能。它提供了一个基于 Web 的仪表板和一个 API,用于监视服务的运行状况和性能。此外,Traefik 可以与流行的监控系统(如 Prometheus、InfluxDB 和 Grafana)集成,使您能够收集和可视化有关基础架构的详细指标。
  6. 社区和生态系统:Traefik 拥有一个庞大而活跃的用户和贡献者社区。这是一个不断发展和改进的开源项目。社区提供支持、文档以及众多插件和扩展,以增强 Traefik 的功能并与其他工具集成。

快速开始

#拉取pxc镜像
docker pull percona/percona-xtradb-cluster:5.7.34-31.51
#此次指定版本,8.0后需要配置证书

新建docker-compose.yaml,这里我们选择traefik进行pxc集群的负载均衡,3306为统一的调用端口

version : '3.7'
networks:
  traefik-pxc:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.16.238.0/24
services:
  traefik:
    image: traefik:v2.4
    command:
      - "--providers.docker=true"
      - "--entrypoints.pxc.address=:3301"
      - "--api=true"  # 启用Traefik的API
      - "--api.insecure=true"# 启用Traefik的Web UI
      - "--providers.docker"
    ports:
      - "8080:8080"  # Traefik dashboard
      - "3301:3301"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      - traefik-pxc
  

  db1:
    container_name: db1
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.9
    ports:
      - "30001:3306"
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "MYSQL_ROOT_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
    volumes:
      - ./data/v1/data:/var/lib/mysql
      - ./data/v1/backup:/data
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"



  db2:
    container_name: db2
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.3
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30002:3306"
    volumes:
      - ./data/v2/data:/var/lib/mysql
      - ./data/v2/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db3:
    container_name: db3
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.4
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30003:3306"
    volumes:
      - ./data/v3/data:/var/lib/mysql
      - ./data/v3/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db4:
    container_name: db4
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.5
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30004:3306"
    volumes:
      - ./data/v4/data:/var/lib/mysql
      - ./data/v4/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db5:
    container_name: db5
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.6
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30005:3306"
    volumes:
      - ./data/v5/data:/var/lib/mysql
      - ./data/v5/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

启动traefik

先启动traefik

docker-copmose up -d traefik

启动pxc集群

再启动db1

docker-compose up -d db1

注意:第一个节点启动比较慢,需要等待1分钟时间,可以使用数据据连接工具连接成功后再启动接下来的节点,这里你可以直接连映射的30001端口。

image-20230623100811168

然后我们再去traefik的UI界面8080端口,注意MySQL 连接通常使用 TCP/IP 进行通信,这里我们暴露的统一负载均衡端口为3301,有不了解traefik的同学,可以官方文档里面看一下,个人感觉还是很好上手的,要是只想了解docker的使用,可以看https://doc.traefik.io/traefik/routing/providers/docker/。

image-20230623101316591

image-20230623101519339

发现traefik已经负载成功,接着我们依次启动下面的节点

docker-compose up -d db2
docker-compose up -d db3
docker-compose up -d db4
docker-compose up -d db5

image-20230623101909878

五个节点负载均衡成功

image-20230623102233685

可以看到啊,我们在30001端口的节点创建gopan库,其他节点也同步了,接下来我们写个test再测试一下:

package test

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"testing"
)

func TestName(t *testing.T) {

	// 数据库连接参数
	dbHost := "localhost"
	dbPort := 3301
	dbUser := "root"
	dbPassword := "db123456"
	dbName := "gopan"

	// 构建连接字符串
	dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", dbUser, dbPassword, dbHost, dbPort, dbName)

	// 连接到数据库
	db, err := sql.Open("mysql", dataSourceName)
	if err != nil {
		fmt.Println("Failed to connect to database:", err)
		return
	}
	defer db.Close()

	// 测试连接
	err = db.Ping()
	if err != nil {
		fmt.Println("Failed to ping database:", err)
		return
	}

	fmt.Println("Connected to database successfully!")

	// 进行数据库操作...
}

image-20230623102414902

大功告成!😀😀😀😀😀😀😀

感谢

创作不易,博主花了整整一天弄这个😭😭😭😭😭😭,求求大家给个点赞关注吧!🥺

参考

Docker 通过PXC+Nginx实现高可用强一致性的mysql集群(单机多节点)

mysql pxc集群搭建(docker-compose版)

Traefik Proxy Documentation - Traefik

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值