Últimos Cambios |
||
Blog personal: El hilo del laberinto |
Última Actualización: 12 de Mayo de 2003 - Lunes
Este documento describe con detalle el sistema de persistencia para la base de Datos Distribuida de IRC-Hispano.
La BDD (Base de Datos Distribuida) se almacena en disco, pero se carga completamente en memoria cuando lanza el servidor. Los cambios subsiguientes se realizan simultaneamente tanto en disco duro como en memoria.
Este esquema permite que las búsquedas y las modificaciones sean muy rápidas, pero tiene dos problemas fundamentales:
Obviando el segundo punto, se ve claramente que el tiempo de arranque de un servidor de IRCD puede ser muy elevado, en función del número de registros en la BDD. En mi sistema de desarrollo, lento, cargar una BDD de unos 250.000 registros consume aproximadamente un minuto de CPU.
Esta situación no es tolerable, y lo será aún menos cuando el número de registros (en particular, modificaciones) crezca para acomodar las nuevas funcionalidades de registros distribuidos de canales.
Optimizar este proceso también reduce la necesidad y frecuencia de las compactaciones de la BDD, proceso lento y delicado.
La carga de la BDD en memoria se puede optimizar (por ejemplo, fusionando "malloc()"), pero siempre tendrá una dependencia O(n) del número de registros en la BDD. La alternativa evidente es utilizar una base de datos clave/registro clásica, como la BerkeleyDB, pero ello supone un mantenimiento extra (a nivel de BDD) que muchos administradores no tendrán conocimientos, tiempo o ganas de hacer.
Una solución más sencilla es utilizar tecnología de "persistencia".
Es decir, ya que cargamos la BDD en memoria al arrancar el servidor IRCD, y vamos siguiendo los cambios de la BDD en las estructuras en memoria, una solución sería que dicha memoria fuera "persistente" y mantuviese su valor entre "reinicios" del servidor IRCD (incluyendo reinicios de la propia máquina que soporta el IRCD). De esta forma podemos arrancar el servidor IRCD y encontrarnos con que ya tenemos toda la BDD en memoria, tal y como la dejamos al cerrar la instancia previa del programa. No necesitamos recrear ninguna estructura o releer las tablas en disco duro.
En un entorno así es imprescindible, no obstante, asegurarnos de que las estructuras que "persisten" no estén incompletas o corruptas, como ocurriría si el servidor IRCD "muere" en un momento inconveniente (bug) o hay un corte de suministro eléctrico. Es decir, el sistema de persistencia debe utilizar también un sistema de control de integridad y "frescura" de la información, para asegurarnos que las estructuras en memoria se corresponden, escrupulosamente con la última versión de la BDD.
El primer paso para implementar una BDD persistente es definir un mecanismo persistente para crear, borrar y modificar registros. El mecanismo ya existe, en forma de "malloc()". En vez de reescribir el sistema de BDD para emplear otro sistema, lo que hacemos es dividir los "malloc()" en dos tipos: "normales" y "persistentes".
Los "malloc()" "normales" son las funciones de toda la vida, que proporcionan memoria que se pierde cuando el programa muere.
Definimos un nuevo tipo de "malloc()", "persistente", cuyo contenido "persiste" incluso entre reinicios del sistema operativo. Esto se hace utilizando una nueva librería "malloc" y empleando un fichero en disco, mapeado en memoria, para realizar los "malloc()" y "free()" persistentes. Dicho fichero en disco existe siempre, independientemente de que se esté ejecutando el IRCD.
Cuando el IRCD arranca, mapea el fichero persistente en memoria. Este mapa proporciona, así, de forma automática, el contenido del fichero en memoria, sin tener que leerlo manualmente (esto lo hace el sistema automáticamente, bajo "demand paging"). Ese mapa contiene una implementación "malloc" completa, con todos los punteros y estructuras como estaban cuando se cerró el IRCD. Es decir, tenemos todos los datos disponibles automáticamente y podemos hacer "malloc()" y "free()" sobre esa memoria como si no hubiera habido un corte intermedio en la ejecución del programa.
Es así como se obtiene el sistema de persistencia.
Naturalmente hay que asegurarse de que el fichero es consistente, reciente y utilizable. Puede ser, por ejemplo, que hubiese habido un corte en el suministro eléctrico mientras había bloques de memoria "sucios", aún no enviados al disco duro. O puede ser que el IRCD corrompa memoria y que, al reiniciarse, se encuentre con la memoria corrompida en el sistema de persistencia y sea incapaz de recuperarse.
Así pues, el siguiente paso consiste en asegurarnos que el fichero en disco es correcto, antes de utilizarlo. Si detectamos cualquier problema simplemente recrearemos el fichero desde cero, recargando la BDD de disco, como si no hubiese persistencia. Ello soluciona el problema y, además, inicializa el sistema de persistencia para que pueda utilizarse en el siguiente reinicio.
El sistema de verificación de integridad y "frescura" del fichero persistente se basa en tres componentes:
Exceptuando la verificación criptográfica, el resto de operaciones son prácticamente instantaneas. La verificación criptográfica en sí tiene un tiempo de ejecución O(m) proporcional a la cantidad de memoria persistente utilizada, no al número de registros en la BDD. En general m<<n. Además, el coeficiente O(m) es mucho menor que el de O(n), por lo que el tiempo de inicialización será muy bajo. En el caso descrito más arriba, el tiempo necesario para inicializar el sistema de persistencia es de unos 2 o 3 segundos.
Un último detalle del sistema de persistencia es que algunos registros tienen efectos colaterales que debemos recrear. Por ejemplo, los canales persistentes. Para este caso concreto tenemos tres opciones:
Surge la duda también de dónde almacenar la información adicional de un canal, como su lista de usuarios, su "topic" o la la lista de "invites" o "baneos".
Toda esa información puede introducir una carga apreciable en el sistema de persistencia, pero probablemente sea el camino a seguir en el futuro.
Los programadores interesados en estudiar las interioridades del sistema de persistencia pueden curiosear los cambios en "s_bdd.c" y el nuevo fichero "persistent_malloc.c".
Más información sobre los OpenBadges
Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS