martes, marzo 18, 2008

RAID for dummies

Bueno... tras leer sobre RAID (debido al NAS que me he pillado) ahí van unas notas breves:
  • Del RAID 2 y 3 nos podemos olvidar.
  • RAID 0. Los datos se reparten en varios discos. Acceso más rapido tanto en lectura como escritura. No hay redundancia.
    • JBOD: No es realmente RAID 0, pero es parecido. Sirve para ver varios discos como uno solo.
  • Con RAID 1 (data mirroing) tenemos un disco espejo. Con lo cual es la redundancia más cara. No ganamos velocidad en lectura pero si en escritura (normalmente).
  • RAID 4: división por bloques on un disco dedicado a la paridad.
  • RAID 5: se usa mucho, porque se obtiene redundancia a bajo coste. Es mas lento en escritura, ya que hay que calcular los bloques de paridad, que se van escribiendo (es importante estudiar el tipo de acceso de escritura para saber si nos va a liminar). Son necesarios 3 discos. Puede recuperarse ante el fallo de un disco. Pero no ya de un fallo de un segundo disco.
Estos son los clásicos. Pero hay mas:
  • RAID 6: protege ante fallo de dos discos.
  • RAID 5E y 6E
  • RAIDs anidados.
  • .../...

miércoles, marzo 05, 2008

Compartiendo un fichero entre procesos

Imaginaros que se os da la situación en la cual necesitais compartir un archivo entre procesos.
Vamos a ver que opciones tenemos:

[1] Usar como lock un archivo que creamos. Se puede usar la llamada os.open() para crear un archivo en exclusiva. El proceso que lo pueda crear tiene via libre para usar ya el fichero que nos interesa. Hay que tener cuidado con proporcionar los mecanismos para no dejar el lock por ahí.

[2] Usar los mecanismos que nos proporciona el OS para bloquear ficheros. Llamada fcntl.lockf().

A continuación voy a copiar dos scripts que demuestran su uso. Ejecutar en primer lugar uno.py e inmediatamente dos.py en otro terminal.
En estos scripts se hace un open() se bloquea el archivo y despues un close().
Una alternativa seria el tener siempre el open() hecho y simplemente hacer el lockf(). Supongo que esto funcionaría pero no lo he probado.

Ya para acabar, comentar la importancia de hacer el seek() en el segundo script para poder escribir en lugar adecaudo del fichero.

uno.py

import os
import fcntl
import time

#--- Creamos el fichero
h = open("kk.txt","w")
h.write("hello\n")
h.close()

#--- Ahora lo abrimos bloquendolo

h = open("kk.txt","a")
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"
time.sleep(15)
print "escribimos"
h.write("hello\n")
print "Tam: ", h.tell()
#h.flush() -> He procado sin el flush y funciona correctamente,
# pero con el, podría ser mas seguro.
# Adicionalmente está la llamada os.fsync().
# Si queremos mas control en el modo de apertura de los
# ficheros tenemos que usar la llamada os.open().
# Por ejemplo si los queremos crear en exclusiva.
print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()

dos.py

import os
import fcntl
import time



#--- Abrimos
#
# Nota: Si usamos LOCK_NB en lockf al adquirirlo y no podemos,
# nos da un error.

h = open("kk.txt","a")
#fcntl.lockf(h.fileno(),fcntl.LOCK_EX|fcntl.LOCK_NB)
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"

#--- Lo usamos
h.seek(0,2)
print "Tam: ", h.tell()

#--- Cerramos

print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()