ORACLE负载均衡的选择
很多时候都会出现这样的情况,客户说我们也买了负载均衡设备了,那为什么我们的数据库服务器压力怎么这么不均衡呢?有的节点有处理的连接太多,压力太大,有的节点的连接却很少,压力很小?
从互联网到应用服务器,经过负载均衡设备的处理如F5、radware、A10,分散到应用服务器的压力已经很均衡。但是压力从应用服务器分发到数据库之后,又变得不均衡。
这就不得不了解一下oracle负载均衡的机制啦。
ORACLE客户端负载均衡工具
客户端负载均衡,就是说中间件服务器连接到oracle数据库时,使用oracle自身的负载均衡工具把中间件服务器的连接分发到oracle rac的不同节点,这是在中间件服务器层面做的负载均衡。
但是这种负载均衡不是严格均衡的。比如经过负载均衡设备的处理之后,每个中间件服务器有300个连接。通过oracle的客户端负载均衡工具的处理,那么可能其中的200个连接分发到第一个节点,剩下100个连接分发到第二个节点,这样的均衡是不是严格意思上的均衡,不可控。
下面的例子就是使用客户端负载均衡的做法:
在中间件服务器定义的数据库连接串添加负载均衡参数。
lb =
(DESCRIPTION =
(LOAD_BALANCE = yes)
(ADDRESS = (PROTOCOL = TCP)(HOST = node1vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2vip)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = floopydb)
)
)
或者加上故障切换参数 (其实默认就是failover,加不加无所谓,如果连接串中定义的第一个节点故障就连接到第二个节点)
lb =
(DESCRIPTION =
(LOAD_BALANCE = yes)
(FAILOVER = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = node1vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2vip)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = floopydb)
)
)
或者 JDBC连接到RAC
Implement Load Balancing With RAC Configured System Using JDBC
url="jdbc:oracle:thin:@(DESCRIPTION=
(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service_name)))"
下面的连接串是不使用客户端负载均衡的例子
url="jdbc:oracle:thin:@(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service_name)))"
建议客户端使用这种配置。默认就是failover,如果一个节点down掉,应用会自动连接到其他节点。
ORACLE服务器端负载均衡工具
服务器端负载均衡就是指数据库服务器接收到中间件服务器的连接之后,通过服务器端负载均衡工具将这些连接从本节点分发到rac的不同节点来实现负载均衡。这是在数据库服务器层面做的负载均衡。
但是这种负载均衡不是严格意义上的均衡,比如node1接收到300个来自多个中间件服务器的连接,那么可能其中的200个连接都分发到其他节点,这样的均衡是不是严格意思上的均衡,不可控。
数据库正常运行时,pmon进程会将本实例的服务名注册到remote_listener指定的其他节点的监听程序以实现负载均衡。
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
remote_listener string LISTENERS_FUN
[oracle@node1 admin]$ cat tnsnames.ora
LISTENERS_FUN =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = node1vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = node2vip)(PORT = 1521))
)
[oracle@node1 admin]$ lsnrctl status LISTENER_NODE1
Service "fun" has 2 instance(s).
Instance "fun1", status READY, has 1 handler(s) for this service...
Instance "fun2", status READY, has 1 handler(s) for this service...
在两个节点的rac,可以看到每个节点的监听都有2个实例,所以中间件服务器到数据库的连接会不均衡的分发的不同的节点。
建议不要使用服务器端负载均衡,这种负载均衡效果不好,不可控。而且做不到真正的负载均衡。
下面的例子是不使用服务器端负载均衡的情况:
alter system set remote_listener=’’ sid=’*’;
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
remote_listener string
负载均衡的选择
对于应用层而言,一般建议使用硬件负载均衡设备,如F5 radware A01等来实现应用层负载均衡,保证不同的应用服务器的压力基本一致。
对于数据库层负载均衡,一般建议不使用oracle自身的客户端负载均衡和服务器端负载均衡,手工去设置,一半的应用服务器优先连接到1节点,另一半的应用服务器优先连接到2节点(当然如果是土豪的话,可以直接在中间件和数据库之间再使用负载均衡设备)。这样的负载均衡才是完全均衡的。rac的不同节点处理的连接数也都基本一致。
比如,20台应用服务器的情况下,前10台这样连接。
url="jdbc:oracle:thin:@(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=node1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=node2)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service_name)))"
后10台这样连接。
url="jdbc:oracle:thin:@(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=node2) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=node1)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service_name)))"