本文档风哥主要介绍Podman集群主从,包括集群的概念、主从架构、集群组件以及集群的部署、主从复制和负载均衡等内容。风哥教程参考Podman官方文档和集群相关资料,适合容器管理员和开发人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 集群概念
集群是指由多个服务器组成的系统,这些服务器协同工作,提供高可用性、可扩展性和负载均衡。Podman集群是指使用Podman容器技术部署和管理的集群系统。更多视频教程www.fgedu.net.cn
- 高可用性:集群中的服务器可以相互备份,当某个服务器故障时,其他服务器可以接管其工作
- 可扩展性:集群可以通过添加服务器来扩展系统容量
- 负载均衡:集群可以将请求分发到不同的服务器,提高系统的处理能力
- 容错性:集群可以在部分服务器故障的情况下继续工作
- 一致性:集群中的数据保持一致,确保数据的可靠性
1.2 主从架构
主从架构是一种常见的集群架构,其中一个服务器作为主节点(Master),负责处理写操作和管理集群,其他服务器作为从节点(Slave),负责处理读操作和备份数据。主从架构的工作原理是主节点将数据变更同步到从节点,确保数据的一致性。
1.3 集群组件
集群的组件主要包括:
- 主节点:负责处理写操作和管理集群
- 从节点:负责处理读操作和备份数据
- 复制机制:负责将主节点的数据变更同步到从节点
- 负载均衡:负责将请求分发到不同的节点
- 监控系统:负责监控集群的运行状态
- 故障转移:负责在主节点故障时将从节点提升为主节点
Part02-生产环境规划与建议
2.1 集群策略
生产环境中Podman集群的策略:
## 高可用性策略
– 多节点部署:部署多个节点,确保系统的高可用性
– 故障转移:配置自动故障转移,当主节点故障时,自动将从节点提升为主节点
– 健康检查:定期检查节点的健康状态,及时发现和解决问题
– 备份策略:定期备份集群数据,确保数据安全
## 可扩展性策略
– 水平扩展:通过添加节点来扩展系统容量
– 垂直扩展:通过增加节点的资源来扩展系统容量
– 弹性伸缩:根据负载自动调整节点数量
– 负载均衡:将请求分发到不同的节点,提高系统的处理能力
## 安全性策略
– 网络隔离:隔离集群网络,防止外部攻击
– 身份认证:配置节点间的身份认证,确保集群安全
– 数据加密:加密集群数据,保护数据安全
– 访问控制:配置访问控制,限制对集群的访问
## 监控策略
– 监控节点:监控集群节点的运行状态
– 监控服务:监控集群服务的运行状态
– 监控性能:监控集群的性能指标
– 监控告警:设置告警,及时通知集群异常
2.2 集群需求
生产环境中Podman集群的需求:
## 功能需求
– 高可用性:确保系统的高可用性,减少 downtime
– 可扩展性:支持系统的水平和垂直扩展
– 负载均衡:将请求分发到不同的节点
– 数据一致性:确保集群中的数据保持一致
– 故障转移:在主节点故障时,自动将从节点提升为主节点
## 性能需求
– 响应时间:系统的响应时间满足业务需求
– 吞吐量:系统的吞吐量满足业务需求
– 并发处理:支持多用户并发访问
– 数据处理能力:处理大量数据的能力
## 技术需求
– 兼容性:与现有系统兼容
– 可维护性:便于维护和管理集群
– 安全性:确保集群的安全性
– 可靠性:确保集群的可靠运行
## 非功能需求
– 成本效益:成本合理,效益明显
– 易用性:易于使用和管理
– 可移植性:便于在不同环境中部署
– 可扩展性:支持未来业务的扩展
2.3 集群工具
生产环境中Podman集群的工具:
- 容器编排:Kubernetes、Podman Compose
- 负载均衡:HAProxy、Nginx
- 监控工具:Prometheus、Grafana
- 日志管理:ELK Stack、Journald
- 配置管理:Ansible、Chef、Puppet
- 自动化工具:Jenkins、GitLab CI/CD
Part03-生产环境项目实施方案
3.1 集群部署
3.1.1 集群部署配置
# 部署MySQL主节点
$ podman run -d –name fgedu-mysql-master \
–cpus 2 \
–memory 4g \
-e MYSQL_ROOT_PASSWORD=fgedu123 \
-e MYSQL_REPLICATION_USER=repl \
-e MYSQL_REPLICATION_PASSWORD=repl123 \
-v fgedu-mysql-master-data:/var/lib/mysql:z \
-p 3306:3306 \
docker.io/library/mysql:8.0
# 部署MySQL从节点
$ podman run -d –name fgedu-mysql-slave \
–cpus 2 \
–memory 4g \
-e MYSQL_ROOT_PASSWORD=fgedu123 \
-e MYSQL_REPLICATION_USER=repl \
-e MYSQL_REPLICATION_PASSWORD=repl123 \
-v fgedu-mysql-slave-data:/var/lib/mysql:z \
-p 3307:3306 \
docker.io/library/mysql:8.0
# 部署Redis主节点
$ podman run -d –name fgedu-redis-master \
–cpus 1 \
–memory 2g \
-e REDIS_PASSWORD=fgedu123 \
-v fgedu-redis-master-data:/data:z \
-p 6379:6379 \
docker.io/library/redis:7.0
# 部署Redis从节点
$ podman run -d –name fgedu-redis-slave \
–cpus 1 \
–memory 2g \
-e REDIS_PASSWORD=fgedu123 \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_MASTER_HOST=fgedu-redis-master \
-e REDIS_MASTER_PORT=6379 \
-e REDIS_MASTER_PASSWORD=fgedu123 \
-v fgedu-redis-slave-data:/data:z \
-p 6380:6379 \
docker.io/library/redis:7.0
# 部署PostgreSQL主节点
$ podman run -d –name fgedu-postgres-master \
–cpus 2 \
–memory 4g \
-e POSTGRES_PASSWORD=fgedu123 \
-e POSTGRES_USER=fgedu \
-e POSTGRES_DB=fgedudb \
-v fgedu-postgres-master-data:/var/lib/postgresql/data:z \
-p 5432:5432 \
docker.io/library/postgres:15
# 部署PostgreSQL从节点
$ podman run -d –name fgedu-postgres-slave \
–cpus 2 \
–memory 4g \
-e POSTGRES_PASSWORD=fgedu123 \
-e POSTGRES_USER=fgedu \
-e POSTGRES_DB=fgedudb \
-v fgedu-postgres-slave-data:/var/lib/postgresql/data:z \
-p 5433:5432 \
docker.io/library/postgres:15
# 查看容器状态
$ podman ps
# 输出日志
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7890123456ab docker.io/library/mysql mysqld 2 minutes ago Up 2 minutes ago 0.0.0.0:3306->3306/tcp fgedu-mysql-master
1234567890ab docker.io/library/mysql mysqld 2 minutes ago Up 2 minutes ago 0.0.0.0:3307->3306/tcp fgedu-mysql-slave
5678901234ab docker.io/library/redis redis-server 2 minutes ago Up 2 minutes ago 0.0.0.0:6379->6379/tcp fgedu-redis-master
9012345678ab docker.io/library/redis redis-server 2 minutes ago Up 2 minutes ago 0.0.0.0:6380->6379/tcp fgedu-redis-slave
abcdef123456 docker.io/library/postgres postgres 2 minutes ago Up 2 minutes ago 0.0.0.0:5432->5432/tcp fgedu-postgres-master
fedcba654321 docker.io/library/postgres postgres 2 minutes ago Up 2 minutes ago 0.0.0.0:5433->5432/tcp fgedu-postgres-slave
3.2 主从复制
3.2.1 主从复制配置
## MySQL主从复制
# 配置主节点
$ podman exec -it fgedu-mysql-master mysql -u root -p
# 输出日志
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 MySQL Community Server – GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
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> CREATE USER ‘repl’@’%’ IDENTIFIED BY ‘repl123’;
mysql> GRANT REPLICATION SLAVE ON *.* TO ‘repl’@’%’;
mysql> FLUSH PRIVILEGES;
mysql> SHOW MASTER STATUS;
# 输出日志
+——————+———-+————–+——————+——————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+——————+———-+————–+——————+——————-+
| binlog.000001 | 156 | | | |
+——————+———-+————–+——————+——————-+
mysql> exit
# 配置从节点
$ podman exec -it fgedu-mysql-slave mysql -u root -p
mysql> CHANGE MASTER TO
-> MASTER_HOST=’fgedu-mysql-master’,
-> MASTER_USER=’repl’,
-> MASTER_PASSWORD=’repl123′,
-> MASTER_LOG_FILE=’binlog.000001′,
-> MASTER_LOG_POS=156;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
# 输出日志
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: fgedu-mysql-master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000001
Read_Master_Log_Pos: 156
Relay_Log_File: relay-bin.000001
Relay_Log_Pos: 324
Relay_Master_Log_File: binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
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: 156
Relay_Log_Space: 536
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: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 12345678-1234-1234-1234-1234567890ab
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
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:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
mysql> exit
## Redis主从复制
# 查看主节点状态
$ podman exec -it fgedu-redis-master redis-cli -a fgedu123 info replication
# 输出日志
# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.3,port=6379,state=online,offset=100,lag=0
master_replid:1234567812345678123456781234567812345678
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
# 查看从节点状态
$ podman exec -it fgedu-redis-slave redis-cli -a fgedu123 info replication
# 输出日志
# Replication
role:slave
master_host:fgedu-redis-master
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:100
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:1234567812345678123456781234567812345678
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
## PostgreSQL主从复制
# 配置主节点
$ podman exec -it fgedu-postgres-master psql -U fgedu -d fgedudb
fgedudb=# CREATE ROLE repl WITH REPLICATION PASSWORD ‘repl123’ LOGIN;
fgedudb=# ALTER SYSTEM SET wal_level = ‘logical’;
fgedudb=# ALTER SYSTEM SET max_wal_senders = 10;
fgedudb=# ALTER SYSTEM SET max_replication_slots = 10;
fgedudb=# SELECT pg_reload_conf();
fgedudb=# exit
# 配置从节点
$ podman exec -it fgedu-postgres-slave bash
# 停止PostgreSQL
$ pg_ctl stop -D /var/lib/postgresql/data
# 备份主节点数据
$ pg_basebackup -h fgedu-postgres-master -U repl -D /var/lib/postgresql/data -Fp -Xs -P
# 创建recovery.conf文件
$ cat > /var/lib/postgresql/data/recovery.conf << EOF
standby_mode = 'on'
primary_conninfo = 'host=fgedu-postgres-master port=5432 user=repl password=repl123'
trigger_file = '/var/lib/postgresql/data/trigger'
EOF
# 启动PostgreSQL
$ pg_ctl start -D /var/lib/postgresql/data
# 查看从节点状态
$ psql -U fgedu -d fgedudb -c "SELECT * FROM pg_stat_replication;"
# 输出日志
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state
----+----------+--------+------------------+-------------+-----------------+-------------+---------------+--------------+-------+----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------
123 | 16384 | repl | walreceiver | 172.17.0.4 | | 5432 | 2026-04-10 10:00:00+00 | | streaming | 0/123456 | 0/123456 | 0/123456 | 0/123456 | | | | 0 | async
$ exit
3.3 负载均衡
3.3.1 负载均衡配置
# 部署HAProxy负载均衡
$ podman run -d –name fgedu-haproxy \
–cpus 1 \
–memory 2g \
-v /Podman/fgdata/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:z \
-p 8080:8080 \
-p 3308:3308 \
-p 6381:6381 \
-p 5434:5434 \
docker.io/library/haproxy:2.7
# 配置HAProxy
$ cat > /Podman/fgdata/haproxy.cfg << EOF
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend mysql
bind *:3308
mode tcp
default_backend mysql_servers
backend mysql_servers
mode tcp
balance roundrobin
server mysql-master fgedu-mysql-master:3306 check
server mysql-slave fgedu-mysql-slave:3306 check
frontend redis
bind *:6381
mode tcp
default_backend redis_servers
backend redis_servers
mode tcp
balance roundrobin
server redis-master fgedu-redis-master:6379 check
server redis-slave fgedu-redis-slave:6379 check
frontend postgres
bind *:5434
mode tcp
default_backend postgres_servers
backend postgres_servers
mode tcp
balance roundrobin
server postgres-master fgedu-postgres-master:5432 check
server postgres-slave fgedu-postgres-slave:5432 check
frontend stats
bind *:8080
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:admin
EOF
# 重启HAProxy
$ podman restart fgedu-haproxy
# 查看HAProxy状态
$ podman exec -it fgedu-haproxy haproxy -v
# 输出日志
HA-Proxy version 2.7.10 2023/09/01 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2025.
Known bugs: http://www.haproxy.org/bugs/bugs-2.7.10.html
Running on: Linux 5.14.0-284.11.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 12 10:20:25 EDT 2023 x86_64
# 访问HAProxy统计页面
# 访问 http://localhost:8080/stats
# 用户名:admin,密码:admin
Part04-生产案例与实战讲解
4.1 MySQL集群主从
4.1.1 MySQL集群主从实战
## 步骤1:部署MySQL主从节点
# 部署MySQL主节点
$ podman run -d –name fgedu-mysql-master \
–cpus 2 \
–memory 4g \
-e MYSQL_ROOT_PASSWORD=fgedu123 \
-e MYSQL_REPLICATION_USER=repl \
-e MYSQL_REPLICATION_PASSWORD=repl123 \
-v fgedu-mysql-master-data:/var/lib/mysql:z \
-p 3306:3306 \
docker.io/library/mysql:8.0
# 部署MySQL从节点
$ podman run -d –name fgedu-mysql-slave \
–cpus 2 \
–memory 4g \
-e MYSQL_ROOT_PASSWORD=fgedu123 \
-e MYSQL_REPLICATION_USER=repl \
-e MYSQL_REPLICATION_PASSWORD=repl123 \
-v fgedu-mysql-slave-data:/var/lib/mysql:z \
-p 3307:3306 \
docker.io/library/mysql:8.0
## 步骤2:配置主从复制
# 配置主节点
$ podman exec -it fgedu-mysql-master mysql -u root -p
mysql> CREATE USER ‘repl’@’%’ IDENTIFIED BY ‘repl123’;
mysql> GRANT REPLICATION SLAVE ON *.* TO ‘repl’@’%’;
mysql> FLUSH PRIVILEGES;
mysql> SHOW MASTER STATUS;
# 输出日志
+——————+———-+————–+——————+——————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+——————+———-+————–+——————+——————-+
| binlog.000001 | 156 | | | |
+——————+———-+————–+——————+——————-+
mysql> exit
# 配置从节点
$ podman exec -it fgedu-mysql-slave mysql -u root -p
mysql> CHANGE MASTER TO
-> MASTER_HOST=’fgedu-mysql-master’,
-> MASTER_USER=’repl’,
-> MASTER_PASSWORD=’repl123′,
-> MASTER_LOG_FILE=’binlog.000001′,
-> MASTER_LOG_POS=156;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
# 输出日志
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: fgedu-mysql-master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000001
Read_Master_Log_Pos: 156
Relay_Log_File: relay-bin.000001
Relay_Log_Pos: 324
Relay_Master_Log_File: binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
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: 156
Relay_Log_Space: 536
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: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 12345678-1234-1234-1234-1234567890ab
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
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:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
mysql> exit
## 步骤3:测试主从复制
# 在主节点创建数据库和表
$ podman exec -it fgedu-mysql-master mysql -u root -p
mysql> CREATE DATABASE fgedudb;
mysql> USE fgedudb;
mysql> CREATE TABLE fgedu_users (
-> id INT AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(100) NOT NULL,
-> email VARCHAR(100) NOT NULL
-> );
mysql> INSERT INTO fgedu_users (name, email) VALUES
-> (‘User 1’, ‘user1@fgedu.net.cn’),
-> (‘User 2’, ‘user2@fgedu.net.cn’),
-> (‘User 3’, ‘user3@fgedu.net.cn’);
mysql> SELECT * FROM fgedu_users;
# 输出日志
+—-+——-+——————+
| id | name | email |
+—-+——-+——————+
| 1 | User 1 | user1@fgedu.net.cn |
| 2 | User 2 | user2@fgedu.net.cn |
| 3 | User 3 | user3@fgedu.net.cn |
+—-+——-+——————+
mysql> exit
# 在从节点验证数据
$ podman exec -it fgedu-mysql-slave mysql -u root -p
mysql> USE fgedudb;
mysql> SELECT * FROM fgedu_users;
# 输出日志
+—-+——-+——————+
| id | name | email |
+—-+——-+——————+
| 1 | User 1 | user1@fgedu.net.cn |
| 2 | User 2 | user2@fgedu.net.cn |
| 3 | User 3 | user3@fgedu.net.cn |
+—-+——-+——————+
mysql> exit
## 步骤4:部署负载均衡
# 部署HAProxy
$ podman run -d –name fgedu-haproxy \
–cpus 1 \
–memory 2g \
-v /Podman/fgdata/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:z \
-p 3308:3308 \
-p 8080:8080 \
docker.io/library/haproxy:2.7
# 配置HAProxy
$ cat > /Podman/fgdata/haproxy.cfg << EOF
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend mysql
bind *:3308
mode tcp
default_backend mysql_servers
backend mysql_servers
mode tcp
balance roundrobin
server mysql-master fgedu-mysql-master:3306 check
server mysql-slave fgedu-mysql-slave:3306 check
frontend stats
bind *:8080
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:admin
EOF
# 重启HAProxy
$ podman restart fgedu-haproxy
# 测试负载均衡
$ mysql -h localhost -P 3308 -u root -p
# 输出日志
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 123
Server version: 8.0.32 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
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> USE fgedudb;
mysql> SELECT * FROM fgedu_users;
# 输出日志
+—-+——-+——————+
| id | name | email |
+—-+——-+——————+
| 1 | User 1 | user1@fgedu.net.cn |
| 2 | User 2 | user2@fgedu.net.cn |
| 3 | User 3 | user3@fgedu.net.cn |
+—-+——-+——————+
mysql> exit
4.2 Redis集群主从
4.2.1 Redis集群主从实战
## 步骤1:部署Redis主从节点
# 部署Redis主节点
$ podman run -d –name fgedu-redis-master \
–cpus 1 \
–memory 2g \
-e REDIS_PASSWORD=fgedu123 \
-v fgedu-redis-master-data:/data:z \
-p 6379:6379 \
docker.io/library/redis:7.0
# 部署Redis从节点
$ podman run -d –name fgedu-redis-slave \
–cpus 1 \
–memory 2g \
-e REDIS_PASSWORD=fgedu123 \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_MASTER_HOST=fgedu-redis-master \
-e REDIS_MASTER_PORT=6379 \
-e REDIS_MASTER_PASSWORD=fgedu123 \
-v fgedu-redis-slave-data:/data:z \
-p 6380:6379 \
docker.io/library/redis:7.0
## 步骤2:验证主从复制
# 查看主节点状态
$ podman exec -it fgedu-redis-master redis-cli -a fgedu123 info replication
# 输出日志
# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.3,port=6379,state=online,offset=100,lag=0
master_replid:1234567812345678123456781234567812345678
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
# 查看从节点状态
$ podman exec -it fgedu-redis-slave redis-cli -a fgedu123 info replication
# 输出日志
# Replication
role:slave
master_host:fgedu-redis-master
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:100
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:1234567812345678123456781234567812345678
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
## 步骤3:测试主从复制
# 在主节点设置数据
$ podman exec -it fgedu-redis-master redis-cli -a fgedu123 set fgedu:key1 value1
# 输出日志
OK
# 在从节点验证数据
$ podman exec -it fgedu-redis-slave redis-cli -a fgedu123 get fgedu:key1
# 输出日志
“value1”
# 在主节点设置更多数据
$ podman exec -it fgedu-redis-master redis-cli -a fgedu123 mset fgedu:key2 value2 fgedu:key3 value3
# 输出日志
OK
# 在从节点验证数据
$ podman exec -it fgedu-redis-slave redis-cli -a fgedu123 mget fgedu:key1 fgedu:key2 fgedu:key3
# 输出日志
1) “value1”
2) “value2”
3) “value3”
## 步骤4:部署负载均衡
# 部署HAProxy
$ podman run -d –name fgedu-haproxy \
–cpus 1 \
–memory 2g \
-v /Podman/fgdata/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:z \
-p 6381:6381 \
-p 8080:8080 \
docker.io/library/haproxy:2.7
# 配置HAProxy
$ cat > /Podman/fgdata/haproxy.cfg << EOF
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend redis
bind *:6381
mode tcp
default_backend redis_servers
backend redis_servers
mode tcp
balance roundrobin
server redis-master fgedu-redis-master:6379 check
server redis-slave fgedu-redis-slave:6379 check
frontend stats
bind *:8080
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:admin
EOF
# 重启HAProxy
$ podman restart fgedu-haproxy
# 测试负载均衡
$ podman exec -it fgedu-haproxy redis-cli -h localhost -p 6381 -a fgedu123 get fgedu:key1
# 输出日志
"value1"
$ podman exec -it fgedu-haproxy redis-cli -h localhost -p 6381 -a fgedu123 mget fgedu:key1 fgedu:key2 fgedu:key3
# 输出日志
1) "value1"
2) "value2"
3) "value3"
4.3 PostgreSQL集群主从
4.3.1 PostgreSQL集群主从实战
## 步骤1:部署PostgreSQL主从节点
# 部署PostgreSQL主节点
$ podman run -d –name fgedu-postgres-master \
–cpus 2 \
–memory 4g \
-e POSTGRES_PASSWORD=fgedu123 \
-e POSTGRES_USER=fgedu \
-e POSTGRES_DB=fgedudb \
-v fgedu-postgres-master-data:/var/lib/postgresql/data:z \
-p 5432:5432 \
docker.io/library/postgres:15
# 部署PostgreSQL从节点
$ podman run -d –name fgedu-postgres-slave \
–cpus 2 \
–memory 4g \
-e POSTGRES_PASSWORD=fgedu123 \
-e POSTGRES_USER=fgedu \
-e POSTGRES_DB=fgedudb \
-v fgedu-postgres-slave-data:/var/lib/postgresql/data:z \
-p 5433:5432 \
docker.io/library/postgres:15
## 步骤2:配置主从复制
# 配置主节点
$ podman exec -it fgedu-postgres-master psql -U fgedu -d fgedudb
fgedudb=# CREATE ROLE repl WITH REPLICATION PASSWORD ‘repl123’ LOGIN;
fgedudb=# ALTER SYSTEM SET wal_level = ‘logical’;
fgedudb=# ALTER SYSTEM SET max_wal_senders = 10;
fgedudb=# ALTER SYSTEM SET max_replication_slots = 10;
fgedudb=# SELECT pg_reload_conf();
fgedudb=# exit
# 配置从节点
$ podman exec -it fgedu-postgres-slave bash
# 停止PostgreSQL
$ pg_ctl stop -D /var/lib/postgresql/data
# 备份主节点数据
$ pg_basebackup -h fgedu-postgres-master -U repl -D /var/lib/postgresql/data -Fp -Xs -P
# 创建recovery.conf文件
$ cat > /var/lib/postgresql/data/recovery.conf << EOF
standby_mode = 'on'
primary_conninfo = 'host=fgedu-postgres-master port=5432 user=repl password=repl123'
trigger_file = '/var/lib/postgresql/data/trigger'
EOF
# 启动PostgreSQL
$ pg_ctl start -D /var/lib/postgresql/data
# 查看从节点状态
$ psql -U fgedu -d fgedudb -c "SELECT * FROM pg_stat_replication;"
# 输出日志
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state
----+----------+--------+------------------+-------------+-----------------+-------------+---------------+--------------+-------+----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------
123 | 16384 | repl | walreceiver | 172.17.0.4 | | 5432 | 2026-04-10 10:00:00+00 | | streaming | 0/123456 | 0/123456 | 0/123456 | 0/123456 | | | | 0 | async
$ exit
## 步骤3:测试主从复制
# 在主节点创建表和数据
$ podman exec -it fgedu-postgres-master psql -U fgedu -d fgedudb
fgedudb=# CREATE TABLE fgedu_users (
-> id SERIAL PRIMARY KEY,
-> name VARCHAR(100) NOT NULL,
-> email VARCHAR(100) NOT NULL
-> );
fgedudb=# INSERT INTO fgedu_users (name, email) VALUES
-> (‘User 1’, ‘user1@fgedu.net.cn’),
-> (‘User 2’, ‘user2@fgedu.net.cn’),
-> (‘User 3’, ‘user3@fgedu.net.cn’);
fgedudb=# SELECT * FROM fgedu_users;
# 输出日志
id | name | email
—-+——–+———————+
1 | User 1 | user1@fgedu.net.cn
2 | User 2 | user2@fgedu.net.cn
3 | User 3 | user3@fgedu.net.cn
(3 rows)
fgedudb=# exit
# 在从节点验证数据
$ podman exec -it fgedu-postgres-slave psql -U fgedu -d fgedudb
fgedudb=# SELECT * FROM fgedu_users;
# 输出日志
id | name | email
—-+——–+———————+
1 | User 1 | user1@fgedu.net.cn
2 | User 2 | user2@fgedu.net.cn
3 | User 3 | user3@fgedu.net.cn
(3 rows)
fgedudb=# exit
## 步骤4:部署负载均衡
# 部署HAProxy
$ podman run -d –name fgedu-haproxy \
–cpus 1 \
–memory 2g \
-v /Podman/fgdata/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:z \
-p 5434:5434 \
-p 8080:8080 \
docker.io/library/haproxy:2.7
# 配置HAProxy
$ cat > /Podman/fgdata/haproxy.cfg << EOF
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend postgres
bind *:5434
mode tcp
default_backend postgres_servers
backend postgres_servers
mode tcp
balance roundrobin
server postgres-master fgedu-postgres-master:5432 check
server postgres-slave fgedu-postgres-slave:5432 check
frontend stats
bind *:8080
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:admin
EOF
# 重启HAProxy
$ podman restart fgedu-haproxy
# 测试负载均衡
$ psql -h localhost -p 5434 -U fgedu -d fgedudb
# 输出日志
Password for user fgedu:
psql (15.0 (Debian 15.0-1.pgdg110+1))
Type "help" for help.
fgedudb=> SELECT * FROM fgedu_users;
# 输出日志
id | name | email
—-+——–+———————+
1 | User 1 | user1@fgedu.net.cn
2 | User 2 | user2@fgedu.net.cn
3 | User 3 | user3@fgedu.net.cn
(3 rows)
fgedudb=> exit
Part05-风哥经验总结与分享
5.1 集群最佳实践
Podman集群主从的最佳实践:
- 高可用性:部署多个节点,确保系统的高可用性
- 数据一致性:确保集群中的数据保持一致
- 负载均衡:将请求分发到不同的节点,提高系统的处理能力
- 监控管理:建立完善的监控机制,及时发现和解决问题
- 安全管理:确保集群的安全性和隐私性
- 灾备方案:制定集群的灾备方案,确保数据安全
- 文档记录:详细记录集群的设计和运维信息
- 培训提升:提升团队的集群运维能力
5.2 集群实施清单
Podman集群主从实施清单:
## 规划阶段
– [ ] 业务需求分析:明确业务需求和集群目标
– [ ] 技术选型:选择合适的数据库和集群方案
– [ ] 架构设计:设计集群架构和网络拓扑
– [ ] 资源规划:规划硬件和软件资源
## 部署阶段
– [ ] 环境准备:准备Podman容器环境
– [ ] 主节点部署:部署主节点
– [ ] 从节点部署:部署从节点
– [ ] 主从复制配置:配置主从复制
– [ ] 负载均衡部署:部署负载均衡
## 测试阶段
– [ ] 功能测试:测试集群的功能
– [ ] 性能测试:测试集群的性能
– [ ] 高可用性测试:测试集群的高可用性
– [ ] 故障转移测试:测试集群的故障转移
## 运维阶段
– [ ] 监控配置:配置集群的监控
– [ ] 性能优化:优化集群的性能
– [ ] 安全管理:管理集群的安全
– [ ] 灾备方案:实施集群的灾备方案
## 优化阶段
– [ ] 性能调优:根据运行情况调优集群
– [ ] 功能扩展:根据业务需求扩展集群功能
– [ ] 技术升级:升级集群的技术栈
– [ ] 经验总结:总结集群实施经验
5.3 集群案例分析
Podman集群主从案例分析:
## 案例一:电商系统MySQL集群
### 业务需求
– 高可用性:确保系统24/7运行
– 可扩展性:支持业务增长
– 负载均衡:提高系统处理能力
– 数据一致性:确保数据的可靠性
### 技术方案
– 数据库:MySQL 8.0
– 集群架构:主从复制
– 负载均衡:HAProxy
– 监控工具:Prometheus、Grafana
### 实施过程
1. 部署MySQL主节点
2. 部署MySQL从节点
3. 配置主从复制
4. 部署HAProxy负载均衡
5. 配置监控系统
### 实施效果
– 系统可用性达到99.99%
– 处理能力提升3倍
– 故障恢复时间从小时级缩短到分钟级
– 数据一致性得到保障
## 案例二:金融系统PostgreSQL集群
### 业务需求
– 高安全性:确保数据安全
– 高可靠性:确保系统稳定运行
– 数据一致性:确保数据的准确性
– 合规性:满足监管要求
### 技术方案
– 数据库:PostgreSQL 15
– 集群架构:主从复制
– 负载均衡:HAProxy
– 监控工具:ELK Stack
### 实施过程
1. 部署PostgreSQL主节点
2. 部署PostgreSQL从节点
3. 配置主从复制
4. 部署HAProxy负载均衡
5. 配置监控系统
### 实施效果
– 系统可用性达到99.99%
– 数据安全性得到保障
– 满足监管合规要求
– 系统性能得到提升
## 案例三:游戏系统Redis集群
### 业务需求
– 高性能:满足游戏实时性要求
– 高可用性:确保游戏服务不中断
– 可扩展性:支持用户增长
– 数据一致性:确保游戏数据的可靠性
### 技术方案
– 数据库:Redis 7.0
– 集群架构:主从复制
– 负载均衡:HAProxy
– 监控工具:Prometheus、Grafana
### 实施过程
1. 部署Redis主节点
2. 部署Redis从节点
3. 配置主从复制
4. 部署HAProxy负载均衡
5. 配置监控系统
### 实施效果
– 系统响应时间减少50%
– 系统可用性达到99.99%
– 支持百万级并发用户
– 数据一致性得到保障
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
