opengauss教程FG063-openGauss读写分离配置生产实战
本文档详细介绍openGauss数据库读写分离的配置方法,包括应用层、中间件层、代理层等多种实现方式,风哥教程参考openGauss官方文档高可用架构指南、应用开发指南等内容,适合DBA和开发人员进行读写分离配置时参考。
Part01-基础概念与理论知识
1.1 openGauss读写分离基本概念
- 提升读性能:多个备库分担读请求,提升系统读吞吐量
- 减轻主库压力:将读操作从主库转移到备库
- 提高可用性:单点故障时读操作可切换到其他备库
- 扩展性强:可以增加备库数量线性扩展读性能
1.2 openGauss读写分离实现方式
读写分离的三种实现方式:
1. 应用层实现
– 在应用程序代码中实现读写分离逻辑
– 优点:灵活可控,可以根据业务定制
– 缺点:需要修改应用代码,维护成本高
2. 中间件层实现
– 使用数据库中间件(如ShardingSphere、MyCat)
– 优点:对应用透明,集中管理
– 缺点:增加系统复杂度,可能成为性能瓶颈
3. 代理层实现
– 使用数据库代理(如Pgpool-II、HAProxy)
– 优点:对应用完全透明,支持连接池
– 缺点:需要额外部署代理服务
三种方式对比:
方式 | 复杂度 | 性能 | 灵活性 | 维护成本
————–|——–|——|——–|———-
应用层 | 中 | 高 | 高 | 高
中间件层 | 高 | 中 | 中 | 中
代理层 | 低 | 中 | 低 | 低
1.3 openGauss读写分离一致性问题
读写分离面临的主要问题是一致性问题:
1. 复制延迟导致的数据不一致
场景:
T1: 主库执行 INSERT INTO fgedu.users VALUES (1, ‘test’)
T2: 应用立即查询备库 SELECT * FROM fgedu.users WHERE id=1
结果:查询不到数据(复制延迟)
2. 解决方案
a) 强制走主库
– 对一致性要求高的查询强制走主库
– 实现:在SQL中添加hint或配置规则
b) 延迟检测
– 查询前检查复制延迟
– 延迟超过阈值则走主库
c) 会话绑定
– 同一会话的写操作后的读操作走主库
– 实现:在应用中维护会话状态
d) 业务补偿
– 接受短暂的数据不一致
– 通过业务逻辑处理不一致情况
3. 一致性级别
– 强一致性:所有读操作走主库
– 最终一致性:允许短暂延迟,最终数据一致
– 弱一致性:接受一定程度的延迟
Part02-生产环境规划与建议
2.1 openGauss读写分离架构设计
读写分离架构设计:
架构一:应用层读写分离
+—————-+ +——————+
| 应用服务器 | | 应用服务器 |
| (读写分离逻辑) | | (读写分离逻辑) |
+——–+——-+ +——–+———+
| |
+———–+———–+
|
+————-+————-+
| |
+——v——-+ +——–v——-+
| 主库 | | 备库 |
| (写操作) | | (读操作) |
| 192.168.1.10 | | 192.168.1.11 |
+————–+ +—————-+
架构二:中间件层读写分离
+—————-+ +——————+
| 应用服务器 | | 应用服务器 |
| (统一连接串) | | (统一连接串) |
+——–+——-+ +——–+———+
| |
+———–+———–+
|
+———-v———-+
| ShardingSphere |
| (读写分离中间件) |
+———-+———-+
|
+————-+————-+
| |
+——v——-+ +——–v——-+
| 主库 | | 备库 |
| (写操作) | | (读操作) |
+————–+ +—————-+
架构三:代理层读写分离
+—————-+ +——————+
| 应用服务器 | | 应用服务器 |
| (连接代理) | | (连接代理) |
+——–+——-+ +——–+———+风哥提示:
| |
+———–+———–+
|
+———-v———-+
| Pgpool-II |
| (数据库代理) |
+———-+———-+
|
+————-+————-+
| |
+——v——-+ +——–v——-+
| 主库 | | 备库 |
| (写操作) | | (读操作) |
+————–+ +—————-+
2.2 openGauss负载均衡策略
负载均衡策略:
1. 轮询(Round Robin)
– 按顺序将读请求分发到各备库
– 优点:简单公平
– 缺点:不考虑备库性能差异
2. 权重(Weighted)
– 根据备库性能设置权重
– 优点:考虑性能差异
– 缺点:需要动态调整权重学习交流加群风哥微信: itpux-com
3. 最小连接数(Least Connections)
– 将请求分发到当前连接数最少的备库
– 优点:动态负载均衡
– 缺点:需要实时监控连接数
4. 随机(Random)
– 随机选择备库
– 优点:实现简单
– 缺点:可能不均衡
5. 一致性哈希(Consistent Hashing)
– 根据查询条件哈希选择备库
– 优点:相同查询走同一备库,利于缓存
– 缺点:实现复杂
# 推荐配置
– 同配置备库:使用轮询
– 不同配置备库:使用权重
– 高并发场景:使用最小连接数
2.3 openGauss延迟处理策略
延迟处理策略:
1. 延迟检测
– 定期检测备库复制延迟
– 延迟超过阈值将该备库从读列表中移除
2. 延迟阈值设置
– 一般业务:延迟<1秒
- 关键业务:延迟<100毫秒
- 实时业务:延迟<10毫秒
3. 延迟处理
- 延迟超限:读请求转发到其他备库或主库
- 延迟恢复:自动将该备库重新加入读列表
4. 延迟监控脚本学习交流加群风哥QQ113257174
#!/bin/bash
# check_replication_delay.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
MASTER_IP="192.168.1.10"
THRESHOLD=1000 # 延迟阈值1秒
echo "=== 复制延迟检查 ==="
echo "检查时间: $(date)"
# 检查各备库延迟
gsql -h $MASTER_IP -d postgres -c "
SELECT
application_name,
client_addr,
EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) * 1000 as delay_ms
FROM pg_stat_replication
WHERE EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) * 1000 > $THRESHOLD;
” | while read line; do
echo “告警: 备库延迟超过阈值 – $line”
# 发送告警通知
# echo “$line” | mail -s “复制延迟告警” dba@fgedu.net.cn
done
echo “=== 检查完成 ===”
Part03-生产环境项目实施方案
3.1 openGauss应用层读写分离
3.1.1 Java应用读写分离配置
# application.yml更多视频教程www.fgedu.net.cn
spring:
datasource:
master:
driver-class-name: org.opengauss.Driver
jdbc-url: jdbc:opengauss://192.168.1.10:5432/fgedudb
username: fgedu
password: fgedu_pass
hikari:
maximum-pool-size: 20
minimum-idle: 5
slave:
driver-class-name: org.opengauss.Driver
jdbc-url: jdbc:opengauss://192.168.1.11:5432/fgedudb
username: fgedu
password: fgedu_pass
hikari:
maximum-pool-size: 50
minimum-idle: 10
# 读写分离配置类
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(“spring.datasource.master”)
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(“spring.datasource.slave”)
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public DataSource routingDataSource() {
DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
Map
# 使用注解切换数据源
@Service
public class FgeduUserService {
@Autowired
private JdbcTemplate jdbcTemplate;
@WriteOperation # 走主库
public void insertUser(FgeduUser user) {
String sql = “INSERT INTO fgedu.users (id, name, create_time) VALUES (?, ?, ?)”;
jdbcTemplate.update(sql, user.getId(), user.getName(), new Date());
}
@ReadOperation # 走备库
public List
String sql = “SELECT * FROM fgedu.users”;
return jdbcTemplate.query(sql, new UserRowMapper());
}
}
3.2 openGauss中间件读写分离
from DB视频:www.itpux.com
3.2.1 ShardingSphere读写分离配置
# application.yml
spring:
shardingsphere:
datasource:
names: master,slave0,slave1
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.opengauss.Driver
jdbc-url: jdbc:opengauss://192.168.1.10:5432/fgedudb
username: fgedu
password: fgedu_pass
slave0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.opengauss.Driver
jdbc-url: jdbc:opengauss://192.168.1.11:5432/fgedudb
username: fgedu
password: fgedu_pass
slave1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.opengauss.Driver
jdbc-url: jdbc:opengauss://192.168.1.12:5432/fgedudb
username: fgedu
password: fgedu_pass
masterslave:
name: ms_ds
master-data-source-name: master
slave-data-source-names: slave0,slave1
load-balance-algorithm-type: round_robin # 轮询负载均衡
props:
sql.show: true
# 使用方式(对应用透明)
@Service
public class FgeduOrderService {
@Autowired
private JdbcTemplate jdbcTemplate;
# 写操作自动走主库
public void createOrder(FgeduOrder order) {
String sql = “INSERT INTO fgedu.orders (order_id, user_id, amount) VALUES (?, ?, ?)”;
jdbcTemplate.update(sql, order.getOrderId(), order.getUserId(), order.getAmount());
}
# 读操作自动走备库(轮询)
public List
String sql = “SELECT * FROM fgedu.orders WHERE user_id = ?”;
return jdbcTemplate.query(sql, new OrderRowMapper(), userId);
}
}
# 启动日志
INFO [main] o.a.s.core.log.ConfigurationLogger : MasterSlaveRuleConfiguration
masterDataSourceName: master
slaveDataSourceNames: [slave0, slave1]
loadBalanceAlgorithmType: round_robin
3.3 openGauss代理层读写分离
3.3.1 Pgpool-II读写分离配置
# 步骤1:安装Pgpool-II
$ yum install pgpool-II pgpool-II-extensions
# 步骤2:配置pgpool.conf
$ cat > /etc/pgpool-II/pgpool.conf << EOF
# 基本配置
listen_addresses = '*'
port = 9999
socket_dir = '/tmp'
# 后端数据库配置
backend_hostname0 = '192.168.1.10'
backend_port0 = 5432
backend_weight0 = 0
backend_data_directory0 = '/opengauss/fgdata'
backend_flag0 = 'ALWAYS_MASTER'
backend_hostname1 = '192.168.1.11'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/opengauss/fgdata'
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_hostname2 = '192.168.1.12'
backend_port2 = 5432
backend_weight2 = 1
backend_data_directory2 = '/opengauss/fgdata'
backend_flag2 = 'ALLOW_TO_FAILOVER'
# 读写分离配置
load_balance_mode = on
master_slave_mode = on
master_slave_sub_mode = 'stream'
# 负载均衡配置
backend_weight0 = 0 # 主库权重为0,只处理写操作
backend_weight1 = 1 # 备库1权重
backend_weight2 = 1 # 备库2权重
# 健康检查配置
health_check_period = 10
health_check_timeout = 20
health_check_user = 'fgedu'
health_check_password = 'fgedu_pass'
# 连接池配置
max_pool = 4
num_init_children = 32
max_connections = 0
EOF
# 步骤3:配置pcp.conf(管理用户)
$ echo 'fgedu_admin:md5加密密码' >> /etc/pgpool-II/pcp.conf
# 步骤4:配置pool_hba.conf
$ cat > /etc/pgpool-II/pool_hba.conf << EOF
local all all md5
host all all 127.0.0.1/32 md5
host all all 192.168.1.0/24 md5
EOF
# 步骤5:启动Pgpool-II
$ pgpool -n -D
# 步骤6:验证配置
$ psql -h 192.168.1.10 -p 9999 -U fgedu -d fgedudb -c "SHOW pool_nodes;
”
node_id | hostname | port | status | lb_weight | role
———+————–+——+——–+———–+———
0 | 192.168.1.10 | 5432 | up | 0.000000 | primary
1 | 192.168.1.11 | 5432 | up | 0.500000 | standby
2 | 192.168.1.12 | 5432 | up | 0.500000 | standby
(3 rows)
# 应用连接方式
# 应用只需连接Pgpool-II,读写分离对应用完全透明
jdbc-url: jdbc:opengauss://192.168.1.10:9999/fgedudb
Part04-生产案例与实战讲解
4.1 openGauss Java应用读写分离案例
4.1.1 案例背景
某电商平台使用Spring Boot开发,需要实现读写分离提升读性能。
4.1.2 完整配置
# 1. 数据源配置
@Configuration
public class FgeduDataSourceConfig {
@Primary
@Bean(“masterDataSource”)
@ConfigurationProperties(prefix = “spring.datasource.master”)
public DataSource masterDataSource() {
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
