14

Estoy estudiando las mejores estructuras de datos para implementar una base de datos temporal de objetos de código abierto simple, y actualmente estoy muy encariñado con el uso de árboles rojo-negros persistentes para hacer eso.Árboles rojos-negros persistentes (puramente funcionales) en el rendimiento del disco

Mi principal razón para utilizar estructuras de datos persistentes es ante todo para minimizar el uso de bloqueos, por lo que la base de datos puede ser lo más paralela posible. También será más fácil implementar transacciones ACID e incluso ser capaz de abstraer la base de datos para trabajar en paralelo en un clúster de algún tipo. Lo bueno de este enfoque es que hace posible la implementación de bases de datos temporales casi de forma gratuita. Y esto es algo bastante agradable de tener, especialmente para la web y para el análisis de datos (por ejemplo, tendencias).

Todo esto es genial, pero sospecho un poco sobre el rendimiento general del uso de una estructura de datos persistente en el disco. A pesar de que hay algunos discos muy rápidos disponibles hoy en día, y todas las escrituras se pueden realizar de forma asíncrona, por lo que una respuesta es siempre inmediata, no quiero construir todas las aplicaciones bajo una premisa falsa, solo darme cuenta de que no es realmente una buena forma de hacerlo

Esta es mi línea de pensamiento: - Dado que todas las escrituras se realizan de forma asincrónica, y utilizando una estructura de datos persistente no invalidará la estructura anterior - y actualmente válida -, el tiempo de escritura no es realmente un cuello de botella. - Hay literatura sobre estructuras como this que son exactamente para el uso del disco. Pero me parece que estas técnicas agregarán más sobrecarga de lectura para lograr escrituras más rápidas. Pero creo que exactamente lo opuesto es preferible. También muchas de estas técnicas realmente terminan con árboles de múltiples versiones, pero no son estrictamente inmutables, lo cual es algo muy crucial para justificar la sobrecarga persistente. - Sé que todavía habrá algún tipo de bloqueo al agregar valores a la base de datos, y también sé que debería haber una buena lógica de recolección de basura si no se mantienen todas las versiones (de lo contrario, el tamaño del archivo seguramente aumentará drásticamente)) También podría pensarse en un sistema de compresión delta. - De todas las estructuras de árboles de búsqueda, realmente creo que los Red-Blacks son los más cercanos a lo que necesito, ya que ofrecen el menor número de rotaciones.

Pero hay algunas posibles dificultades en el camino: - Las escrituras asincrónicas pueden afectar a las aplicaciones que necesitan los datos en tiempo real. Pero no creo que ese sea el caso con las aplicaciones web, la mayoría de las veces. Además, cuando se necesitan datos en tiempo real, se podrían idear otras soluciones, como un sistema de check-in/check-out de datos específicos que deberán trabajarse de una manera más en tiempo real. - También podrían provocar algunos conflictos de compromiso, aunque no puedo pensar en un buen ejemplo de cuándo podría suceder. También pueden ocurrir conflictos de compromiso en RDBMS normal, si dos hilos funcionan con los mismos datos, ¿no? - La sobrecarga de tener una interfaz inmutable como esta crecerá exponencialmente y todo está destinado a fallar pronto, por lo que todo esto es una mala idea.

¿Alguna idea?

Gracias!

edición: Parece que hay un malentendido de lo que una estructura de datos persistente es: http://en.wikipedia.org/wiki/Persistent_data_structure

+1

Me estás matando Smalls. –

+1

¿Puedes explicar por qué "Mis razones principales para usar estructuras de datos persistentes es antes que nada para minimizar el uso de bloqueos" ??? Persistente o no, aún necesitas bloqueos ... –

+1

Bueno, tienes razón. Todavía existe la necesidad de utilizar bloqueos, pero se reduce al mínimo a un mínimo absoluto. Por ejemplo, en mi caso, los únicos lugares donde necesitaremos candados son referencias "débiles", como la cabeza del árbol rojo-negro. Después de agregar todos los cambios de árbol al archivo, debemos bloquearlo solo para cambiar el puntero (solo un int) al encabezado del árbol. No hay posibilidad de que un lector que no se está moviendo atrape el árbol en un estado incoherente, y el bloqueo debería funcionar realmente rápido. También para escribir, la única vez que se necesita un bloqueo es cambiar el tamaño del archivo (agregando datos) – Waneck

Respuesta

3

Si observa que tiene un cuello de botella en el tiempo de escritura, o que su garantía de durabilidad no tiene sentido sin escrituras sincrónicas (hmm ...), debe hacer lo que hacen la mayoría de las otras bases de datos: implementar un Write-Ahead Log (WAL) o un redo-log.

Los discos son muy buenos para escribir secuencialmente, o al menos eso es lo que hacen mejor. Son escrituras aleatorias (como las de un árbol) que son terriblemente lentas. Incluso las unidades de memoria flash, que se libran al máximo de discos para escrituras aleatorias, son aún significativamente mejores en las escrituras secuenciales. De hecho, incluso la mayor parte de la RAM es mejor en las escrituras secuenciales porque hay menos señales de control involucradas.

Mediante el uso de un registro de escritura anticipada, usted no tiene que preocuparse:

  • escrituras rasgados (que escribió la mitad de un árbol antes de que el gato se comió su fuente de alimentación)
  • Pérdida de información (En realidad, no llegó a persistir en el árbol, pero Joe cree que lo hizo)
  • Enorme rendimiento de las E/S de disco síncronas aleatorias.
+0

¡Oye! ¡Gracias por el consejo! Esto es realmente imprescindible, ya que la memoria utilizada puede llenarse fácilmente.Pero en un caso donde la base de datos es completamente temporal (todos los datos modificados se registran), ¡en realidad podría convertirse en un solo archivo! La recolección de basura es una de las desaceleraciones más grandes (pero necesarias), en este sentido. – Waneck

+0

¿Podría explicar por qué usar un WAL significa que no tiene que preocuparse por "Grandes resultados de rendimiento de E/S de disco síncronas al azar"? –

+0

Un registro de escritura anticipada lee con poca frecuencia/escribe datos al azar; siempre se adjunta, que es rápido en un disco duro tradicional. Sí, habrá otras escrituras aleatorias en el sistema, pero para algo que se usa básicamente en cada actualización de registro, la eficiencia será importante. –

1

Mi pensamiento es que usted tiene una gran idea. Ahora ve a construir la maldita cosa. De todo lo que has escrito, parece que estás sufriendo de un caso agudo de analysis paralysis.

+0

¡Hola! ¡Estoy muy contento de que pienses así! Ya lo estoy codificando, pero ya que esta es la primera vez que estoy codificando un DBMS, ¡pensé que quizás podría estar tomando la dirección equivocada en alguna parte! Gracias! – Waneck

+0

¿Algún progreso en esto? – clintm

1

Sé que esta pregunta es un poco antigua, pero he estado implementando casi lo mismo y lo que he encontrado es que, ser un árbol binario significa que el rendimiento es terrible (debido al número de búsquedas). Probablemente sea una idea mucho mejor tratar de crear un árbol persistente mucho más amplio a pesar del espacio adicional sobrecargado.

+0

Tiene toda la razón. De hecho, hay una buena implementación que cuidar: ¡el b-tree inmutable de couchdb! Pero ahora he cambiado la dirección de este proyecto, y abandoné la necesidad de estructuras de datos puramente funcionales en el disco, ya que no son realmente ajustadas en este caso. Para estructuras sin bloqueo, es mejor implementar una operación CAS en un archivo mapeado en memoria. – Waneck

+0

@Waneck, sí, había visto el b-tree de couchdb (aunque no he profundizado en la implementación). ¿Te importaría explicar tu segundo comentario sobre estructuras sin cerrojo? No estoy seguro de entender. –

+0

, consulte http://stackoverflow.com/questions/2846190/cross-platform-and-cross-process-atomic-int-writes-on-file! Después de descubrir que puede hacer operaciones de comparación e intercambio en archivos mapeados en memoria, me pareció que las estructuras de datos persistentes no son una solución muy buena para las bases de datos. Agregar solo significa que no hay lugar, y el uso deficiente del disco (rendimiento) después de todo. – Waneck

1

Interesante con alguien con mentalidad similar :-) De hecho, he implementado una base de datos que utiliza una estructura de datos persistente como su modelo de datos. Un tipo de árbol B2 persistente, supongo que uno podría llamarlo. Almacenamiento solo en el disco y en la recolección de basura: no es necesario guardar todo el historial para siempre. Se puede establecer un período de retención finito para permitir que la base de datos se olvide de la historia temprana.

Ver http://bergdb.com/

Cuestiones relacionadas