miércoles, 30 de julio de 2008

Conexiones en Windows vs. Linux

Recientemente queriendo hacer unas pruebas (sobre algo que no pude demostrar), me pregunté sobre las conexiones en windows vs. conexiones en Linux.

De forma arquitectónica ambas son diferentes, en windows, la arquitectura está basada en threads, los threads son objetos dentro de un proceso que ejecutan instrucciones, y permiten la ejecución "simultanea" de instrucciones dentro del proceso, para que código se ejecute en diversos procesadores. En teoría, las ventajas de este modelo son:

1.- Context Switches más rápidos.

2.- Implementación más sencilla de SGA (ya que no requiere un shared memory).

3.- Creación más rápida de conexiones (ya que crear un thread es más rápido que crear un proceso).

4.- Decremento en el uso de memoria. Esto es porque se pueden compartir más estructuras de memoria.

Estoy muy de acuerdo en la teoría con todo lo anterior, sin embargo, como diría Jonathan Lewis "Just because it's written, it doesn't mean it's true...".

Para hacer las pruebas, hice un pequeño código en Perl que abre "n" número de conexiones a la base de datos y mide el tiempo que tarda en realizar las conexiones.

el código es el siguiente:

conecta.pl


use DBI;
use Time::HiRes qw(gettimeofday tv_interval);
$cont = 100;
$t0=[gettimeofday];
for ($inicio=1;$inicio<=$cont;$inicio++){
$dbh[$inicio] = DBI->connect( 'dbi:Oracle:HECG',
'system',
'******',
{ RaiseError => 1, AutoCommit => 0 }
) || die "No se pudo conectar a la base de datos: $DBI::errstr";
#$sql = qq{select count(1) from v\$database};
#$dbh[$inicio]->do($sql);
}
$elapsed = tv_interval ($t0);
print "Las ".$cont." conexiones se realizaron en ";
print $elapsed ." segundos\n\n\n";
print "presiona cualquier tecla para terminar... ";
$dummy = < STDIN> ;
for ($fin=1;$fin<=$cont;$fin++){
$dbh[$fin]->disconnect;
}



¿Por qué lo hice en Perl?, por dos sencillas razones:

1.- No soy programador, y decidí no complicarme la vida.
2.- Porque quería ejecutar el mismo código en Linux que en Windows.

Antes de ejecutar mi script, mi proceso Oracle se encontraba de esta forma:



Ejecuté el código para 100 conexiones e windows, y los resultados son los siguientes


C:\oracle\product\10.2.0\NETWORK\ADMIN>%PH%\perl.exe conecta.pl
Las 100 conexiones se realizaron en 4.53125 segundos

presiona cualquier tecla para terminar...




Vemos que el proceso incrementó el número de threads en casi 100 (quizá en el inicio se tenían algunos jobs corriendo, y por eso subió de 23 a 122).

El consumo de memoria fue de 70 mb. por las 100 sesiones, lo cuál significa que cada sesión inicialmente ocupa 700k.

El tiempo que tardaron las 100 conexiones fue de 4.5 segundos.

Ahora el código del script se lanzó en Linux, y el resultado fue el siguiente:


$ perl conecta.pl
Las 100 conexiones se realizaron en 3.14312 segundos

presiona cualquier tecla para terminar...


Las conexiones se ejecutaron mucho más rapidas en Linux que en Windows. Intentamos con 200 y 400 conexiones.

Para 200 el tiempo fue lineal:


Windows - 9.02403 Segundos
Linux - 6.32876 Segundos


La sorpresa en 400 conexiones fue la siguiente:


Windows - 18.23311 Segundos
Linux - 32.75434 Segundos


El tiempo fue lineal para windows, pero para linux no, la razón...

En linux cada sesión ocupaba 1.8 mb de memoria aproximadamente (720 mb sólo en sesiones), más el tamaño del SGA ~200Mb, más la memoria ocupada por el sistema operativo... nos daban un total mayor a la memoria física del equipo, y por esta razón el equipo empezó a hacer uso de Swap.

Lo cual nos lleva a concluir lo siguiente:

1.- Efectivamente la arquitectura de Windows utiliza mejor los recursos de memoria, ya que usa threads en lugar de procesos.

2.- La creación de threads NO ES MÁS RÁPIDA que la creación de procesos.

¿Qué arquitectura recomiendo yo?, definitivamente depende de muchos factores, pero se deben de tener en cuenta todos los factores antes de decidir la arquitectura correcta.

En un sistema que no cuenta con mucha memoria física el servidor de base de datos y que va a recibir muchas conexiones dedicadas, podría decir que un windows sería algo bueno, sin embargo, si las conexiones no van a ser persistentes, esta arquitectura podría traer problemas con memoria "non paged pool".

Por el otro lado, si se usa un equipo Linux, el equipo podría quedarse muy rápido sin memoría física, y el sistema operativo se degradaría en cuanto a desempeño.

Sé que hay muchas cosas más que probar, quizás el uso de Bequeath en lugar de SQL*Net, el comportamiento a través de Shared Servers, etc., pero eso se queda para otro post.

2 comentarios:

Anónimo dijo...

hola buen día.

Resulta que estoy realizando un backup con la herramienta RMAN en oracle 10g. es modo archivelog

de la siguiente manera:
rman>connect target nombre_usuario/contraseña@Nombre_Base_Datos;
rman>configure controlfile autobackup on;
rman>backup database plus archivelog format '/u01/backup/rman/rman_full_11092008.dmp';

el comienza
Starting backup at 11-SEP-08
current log archived
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=2160 devtype=DISK
channel ORA_DISK_1: starting archive log backupset
channel ORA_DISK_1: specifying archive log(s) in backup set
input archive log thread=1 sequence=112 recid=6 stamp=647080675
input archive log thread=1 sequence=603 recid=497 stamp=661481668
channel ORA_DISK_1: starting piece 1 at 11-SEP-08
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of backup plus archivelog command at 09/11/2008 10:02:13
ORA-19504: fallo al crear el archivo "/u01/backup/rman/rman_full_tolima_1109
.dmp"
ORA-27038: el archivo creado ya existe
Additional information: 1

Soy nueva en le manejo de esta base de datos y poco se sobre el manejo del man.

Alguien por favor me puede colaborar con este error.

Agradezco su interés

Hugo E. Contreras Gamiño dijo...

Hola Anónimo, parece que tu problema va relacionado a que no pones un nombre de archivo correcto, te sugiero que uses un identificador de archivo:


backup database plus archivelog format '/u01/backup/rman/rman_full_11092008%U.dmp';


El %U se sustituye por un identificador único de archivo.

Espero y esto te sirva para solucionar tu problema.