温馨提示×

Linux环境中Oracle如何实现负载均衡

小樊
39
2025-12-26 08:05:57
栏目: 云计算

Linux环境下Oracle负载均衡实现指南

一、方案总览

  • 数据库层:使用 Oracle RAC 提供连接级负载均衡与高可用。RAC 的负载均衡分为两类:
    1. 客户端负载均衡:客户端在多个节点的 VIP/SCAN 地址间分发新连接;
    2. 服务器端负载均衡:各实例的 PMON 每约 3 秒向监听注册负载与会话信息,监听器据此将新连接定向到负载更低的实例。
  • 应用层/连接层:在不具备 RAC 的场景,可用 HAProxyNginx 做连接转发(TCP 模式)实现连接分发;注意这不是 SQL 层负载均衡,仍需应用配合连接池与重试。
  • 重要区分:Nginx/HAProxy 不能直接均衡 Oracle SQL 会话,它们仅转发字节流;数据库会话粘滞、事务一致性、故障切换等需由 Oracle 自身机制或应用层处理。

二、RAC场景的标准做法

  • 前提条件
    • 已部署 Oracle Grid Infrastructure + RAC,各节点启用 VIP/SCAN
    • 数据库已创建对外 SERVICE_NAME(连接应使用服务名而非实例名);
    • 客户端可解析各节点的 VIP/SCAN 地址(/etc/hosts 或 DNS)。
  • 客户端负载均衡(tnsnames.ora)
    • 在客户端配置服务别名,使用 LOAD_BALANCE=yes,地址列表填入各节点的 VIP/SCAN:1521,连接串中使用 SERVICE_NAME
    • 示例:
      RACDB =
        (DESCRIPTION =
          (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip1)(PORT = 1521))
            (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip2)(PORT = 1521))
          )
          (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = racdb)
          )
        )
      
    • 说明:开启后,SQL*Net 会在地址列表中按算法分发新连接,实现连接层面的均衡。
  • 服务器端负载均衡(remote_listener)
    • 各节点 tnsnames.ora 定义监听列表别名(如 LISTENERS_RACDB),包含所有节点的 VIP/SCAN:1521
    • 每个实例设置参数 remote_listener 指向该别名,使 PMON 的负载/连接注册信息能被其他节点监听感知;
    • 示例:
      -- 服务器端 tnsnames.ora
      LISTENERS_RACDB =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip1)(PORT = 1521))
          (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip2)(PORT = 1521))
        )
      
      -- 每个实例执行
      ALTER SYSTEM SET remote_listener='LISTENERS_RACDB' SCOPE=BOTH SID='racdb1';
      ALTER SYSTEM SET remote_listener='LISTENERS_RACDB' SCOPE=BOTH SID='racdb2';
      
    • 说明:启用后,监听器基于各实例的负载与会话数将新连接定向到更空闲的实例,常与客户端负载均衡配合使用。
  • 可选 透明应用故障切换(TAF)
    • 在客户端连接串中加入 FAILOVER_MODE,实现实例故障时的自动重连与查询接管(SELECT 类型可继续游标)。
    • 示例:
      RACDB_TAF =
        (DESCRIPTION =
          (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip1)(PORT = 1521))
            (ADDRESS = (PROTOCOL = TCP)(HOST = node-vip2)(PORT = 1521))
          )
          (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = racdb)
            (FAILOVER_MODE =
              (TYPE = SELECT)
              (MODE = BASIC)
              (RETRY = 3)
              (DELAY = 5)
            )
          )
        )
      
    • 说明:TAF 提升故障时的连续性与用户体验,但不替代连接级均衡策略。

三、无RAC时的替代方案

  • 前置说明
    • 使用 HAProxy/Nginx 仅能做 TCP 转发,无法在数据库内部对 SQL 进行分发或会话粘滞控制;适合读多写少、短连接或作为连接“前置缓冲”的场景。
  • HAProxy 示例(TCP 转发,端口 1521)
    global
      log /dev/log local0
      log /dev/log local1 notice
      chroot /var/lib/haproxy
      user haproxy
      group haproxy
      daemon
    
    defaults
      log global
      mode tcp
      timeout connect 5000ms
      timeout client  50000ms
      timeout server  50000ms
    
    frontend oracle_front
      bind *:1521
      default_backend oracle_back
    
    backend oracle_back
      balance roundrobin
      server node1 192.168.1.101:1521 check
      server node2 192.168.1.102:1521 check
    
    • 启动:systemctl restart haproxy
  • Nginx 示例(TCP 转发,需启用 stream 模块)
    events { worker_connections 1024; }
    stream {
      upstream oracle_backend {
        server 192.168.1.101:1521;
        server 192.168.1.102:1521;
      }
      server {
        listen 1521;
        proxy_pass oracle_backend;
        proxy_timeout 50s;
      }
    }
    
    • 启动:systemctl restart nginx
  • 使用要点
    • 建议开启 TCP 健康检查连接超时
    • 应用需配置合理的 连接池重试/回退
    • 如需读写分离,应在应用或中间层实现,而非依赖 TCP 转发。

四、验证与运维要点

  • 验证客户端均衡
    • 多次从客户端连接同一服务别名,执行:
      SQL> show parameter instance_name
      
      观察是否在不同实例(如 racdb1/racdb2)间分布。
  • 验证服务器端均衡
    • 在各节点执行:
      $ lsnrctl status
      
      检查服务下各实例的 READY 状态与 Handler 数量;结合业务高峰观察新连接是否更多落在负载较低实例。
  • 验证 TAF
    • 在会话中执行查询后,手动停止目标实例,确认查询是否继续(SELECT 类型)或会话是否快速切换到其他实例。
  • 运维建议
    • 统一使用 SERVICE_NAME 对外发布;按业务划分 服务 并绑定到不同实例集合;
    • 合理设置 local_listenerremote_listener,避免监听注册异常;
    • 监控 v$sessionv$instance、监听日志与告警,定期演练故障切换。

0