miércoles, 25 de febrero de 2009

Transparent Application Failover - Oracle RAC

Ahora toca el turno a las pruebas de alta disponibilidad que el ambiente Real Application Clucter nos ofrece, el cual es otro de los puntos clave que debemos entender para llevar a cabo una implementación exitosa de cualquier aplicación conectada a una base de datos Oracle en ambiente RAC.
Antecedentes
===========
Iniciaré con una breve explicación de que es Transparent Application Failover (TAF)...


TAF es una característica que permite a los cliente de oracle reconectarse a otra instancia en caso de que ocurriera una falla en la instancia a la cual se encontraba conectado. El servidor envía una notificación para iniciar el proceso de 'failover' en el cliente.

TAF puede operar en uno de dos tipos:

  • Sesion Failover. Este modo recreará las conexiones perdidas y las sesiones.
  • Select Failover. Este modo volvera a ejecutar los queries que estaban en progreso.

Que a su vez puede usar uno de dos métodos:

  • Basic. Establece la conexión al momento de llevar a cabo el 'failover'. Esta opción casi no requiere trabajo extra en el lado del servidor hasta que ocurre el 'failover'.
  • Preconnect. Provee un 'failover' mucho más rápido pero requiere que la(s) instancia(s) de respaldo tengan de antemando la sesión creada, por lo que se requieren más recursos para soportar todas las conexiones.

Habilitar TAF implica llevar a cabo ciertos pasos de configuración manual, ya sea a nivel cliente al configurar la cadena de conexión, o bien a nivel servidor configurando ciertos atributos. Si ambas opciones de configuración son utilizadas, la configuración del servidor supersede a la del cliente.

A continuación se muestra un ejemplo de la cadena de conexión para configurar TAF en el cliente, cabe aclarar que existen otros parámetros o valores que pueden ser utilizados:

RAC10G =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = srvrac1vip.oratest.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = srvrac2vip.oratest.com)(PORT = 1521))
(LOAD_BALANCE=yes)
(FAILOVER=yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac10g.oratest.com)
(FAILOVER_MODE=
(TYPE=select)
(METHOD=basic)
)
)
)


La siguiente sentencia SQL nos permite ver el resultado de utilizar la cadena de conexión anterior:

SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
FROM V$SESSION
GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;

y obtendríamos el siguiente resultado similar al siguiente antes de realizar el 'failover':

MACHINE FAILOVER_TYPE FAILOVER_METH FAILED_OVER COUNT(*)
--------------- ----------------------- ---------------------------- -------------------- --------
srvrac2 NONE NONE NO 29
JUANJO-LAP SELECT BASIC NO 1


la salida después de llevarse a cabo el 'failover', sería algo parecido a lo siguiente:


MACHINE FAILOVER_TYPE FAILOVER_METH FAILED_OVER COUNT(*)
-------------- ----------------------- ---------------------------- -------------------- ---------
JUANJO-LAP SELECT BASIC YES 1
srvrac1 NONE NONE NO 29

Referencias
=========

  • Oracle® Database Net Services Administrator’s Guide

Pruebas
======

Ahora bien, describo las pruebas que realice:

  1. Se tiene una base de datos Oracle(10.2.0.1.0) en RAC con dos nodos.
  2. La arquitectura de ambos servidores es similar, la única diferencia es que el nodo 1 tiene 2GB RAM y el nodo 2 solamente cuenta con 1GB RAM.
  3. Se relizaron pruebas simulando dos tipos de eventos: perdida de conectivadad por problemas de red (se desconecto el cable de red del nodo activo) y colapso de una instancia (ejecutando un shutdown abort en la instancia activa)
  4. Se probaron las diferentes combinaciones entre tipos y metodos de TAF.
  5. El cliente utilizado fue sqlplus(10.1.0.2.0)

Los resultados son los siguientes:

PRUEBA DE FAILOVER CON DESCONEXIÓN CABLE DE RED

  • TYPE=SELECT Y METHOD=BASIC

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g2

SQL> set timing on

En este momento se desconecto el cable de red del nodo 2

SQL> select instance_name from v$instance;
select instance_name from v$instance;
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Elapsed: 00:00:18.92

Como se puede observar le casi 19 segundos darse cuenta de que la conexión ya no existía y mandar el error, sin embargo la sesión no se perdió ya que al volver a ejecutar la sentencia se obtuvo el siguiente resultado:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1
Elapsed: 00:00:00.00

Otro punto interesante a comentar es que el comportamiento esperado con la opción TYPE=SELECT no ocurrió, ya que la sentencia ejecutada mostró un error (ORA-03113) y no el resultado de la misma. Debido a esto se decidió intentarlo nuevamente, reconectando el cable de red del nodo 2 y desconectando el cable de red del nodo 1, en el que actualmente nos encontrabamos. El resultado fue el siguiente:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1
Elapsed: 00:01:04.12

Como se puede observar, ahora le tomó mucho más tiempo en regresar el resultado, sin embargo no mostró error alguno.

  • TYPE=SELECT Y METHOD=PRECONNECT

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1

SQL> set timing on

En este momento se desconecto el cable de red del nodo 1.

SQL> select instance_name from v$instance;
select instance_name from v$instance;
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Elapsed: 00:00:19.04

Como se puede observar le tomo poco más de 19 segundos darse cuenta de que la conexión ya no existía y mandar el error, sin embargo la sesión no se perdió ya que al volver a ejecutar la sentencia se obtuvo el siguiente resultado:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g2
Elapsed: 00:00:00.01

Nuevamente se puede observar que el comportamiento esperado con TYPE=SELECT no ocurrió y el tiempo transcurrido para recibir el ORA-03113 fue similiar a la primer prueba realizada anteriormente. Debido a esto no pude encontrar una diferencia palpable entre los metodos BASIC y PRECONNECT así como, en primera instancia observé un comportamiento inestable en el tipo SELECT.

Cabe aclarar que estos resultados pueden deberse a la naturaleza de las pruebas que se realizaron (Desconectar cables de red), aunque no pude probarlo, por lo que decidí cambiar el tipo de evento...

PRUEBA DE FAILOVER CON SHUTDOWN ABORT

  • TYPE=SESSION Y METHOD=BASIC

Averiguamos a que instancia estamos conectados:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1

SQL> set timing on

Este es el momento en el que se envía el 'shutdown abort' a la instancia rac10g1, justo al mismo tiempo que ejecutamos la siguiente sentencia SQL:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g2
Elapsed: 00:05:12.85

Como se puede observar, toma un poco mas de 5 segundos para que la sentencia regrese el resultado, el cual nos indica que nos encontramos en una instancia diferente a la original. En este caso, cabe aclarar que, aunque el tipo de failover es SESSION, el resultado se genera, en vez de el error (ORA-03113) que sería esperado, ya que probablemente primero ocurrio el ABORT y despues el SELECT una vez realizado el failover de la sesión. Sin embargo, lo interesante es obtener el tiempo que toma llevar a cabo el failover.

  • TYPE=SELECT Y METHOD=BASIC

Averiguamos a que instancia estamos conectados:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1

SQL> set timing on

Este es el momento en el que se envía el 'shutdown abort' a la instancia rac10g1, justo al mismo tiempo que ejecutamos la siguiente sentencia SQL:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g2
Elapsed: 00:00:04.43

Como se puede observar, toma 4.43 segundos para que la sentencia regrese el resultado, el cual nos indica que nos encontramos en una instancia diferente a la original. Aqui el resultado es muy similar a la prueba anterior, lo cual nos indica que practicamente no existe impacto en el tiempo del failover si el tipo elegido es SELECT o SESSION.

  • TYPE=SELECT Y METHOD=PRECONNECT

Averiguamos a que instancia estamos conectados:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g1

SQL> set timing on;

Este es el momento en el que se envía el 'shutdown abort' a la instancia rac10g1, justo al mismo tiempo que ejecutamos la siguiente sentencia SQL:

SQL> select instance_name from v$instance;
INSTANCE_NAME
----------------
rac10g2
Elapsed: 00:00:03.51

Como se puede observar, toma 3.51 segundos para que la sentencia regrese el resultado, el cual nos indica que nos encontramos en una instancia diferente a la original. El tiempo obtenido como resultado demuestra que el método PRECONNECT es alrededor de 1 segundo más rápido (En una red local 100Mbps con poco tráfico) que el método BASIC para efectuar el failover de la conexión pero requiere de una conexión existente desde el inicio a cada una de las instancias, por lo que el costo beneficio debe ser evaluado cuidadosamente.

Conclusiones
==========

  • Al llevar a cabo una implementación de cualquier aplicación que se conecte a un ambiente de base de datos Oracle RAC, o bien, decidir migrar una instancia "standalone" a RAC, es necesario evaluar los requerimientos de negocio que la aplicación tendra que soportar, a fin de seleccionar los tipos y metodos de failover adecuados para cada aplicación.
  • El método PRECONNECT es solo un poco más rápido que el método BASIC y tiene un costo mayor de recursos al requerir sesiones preexistentes en cada una de los nodos que conforman el RAC.

No hay comentarios:

Publicar un comentario en la entrada