2010-07-21 20 views
6

Estoy tratando de implementar un mecanismo de almacenamiento de archivos que contiene una cantidad de registros de tamaño variable en un solo archivo con la garantía de que el conjunto de registros siempre será recuperable en un estado consistente, incluso si el sistema falló en un hardware nivel.¿Se garantiza que los datos en un archivo mapeado en memoria se descarguen secuencialmente?

Hasta ahora, cada esquema que he propuesto pivota al escribir datos secuencialmente. Se adjuntará algún dato al final de cada registro que confirma que la escritura tuvo éxito. Sin embargo, si los datos no se escriben necesariamente en el disco de forma secuencial cuando se vacían, es posible que los datos de confirmación se escriban antes de los datos de contenido.

Hay dos maneras obvias de todo esto, pero ambos son indeseables:

  1. a vaciar el contenido, a continuación, escribir la confirmación y tirar de la cadena. Agregar la descarga adicional puede degradar el rendimiento.
  2. Incluya una suma de comprobación en la confirmación (sería necesario leer el contenido para confirmar que es válido).

estoy usando C# en Windows (32 y 64 bits) y la memoria asignada la ejecución de archivos de .Net 4.0

+0

La segunda idea (verificar los datos , la marca de tiempo, el número de secuencia y la suma de comprobación) parece legítimo. Sin embargo, en general, debería buscar clusters de alta disponibilidad, con máquinas separadas en una red. Todos los registros o escrituras de diarios deben replicarse a través de la red en dos o más máquinas. No puede extraer ninguna garantía de una sola máquina, punto. – rwong

Respuesta

1

Este es el nivel demasiado bajo y el sistema operativo específico para C#. intente usar las API de Windows desde C, y lea cuidadosamente las especificaciones de API.

0

¿Ha intentado utilizar FileOptions.WriteThrough en la extensión de archivos subyacente? Eso podría ayudar, ya que desactiva el almacenamiento en búfer. Otras ideas serían mantener un archivo separado que contenga las confirmaciones como el último desplazamiento escrito, si no coincide con el tamaño del archivo (debido a un corte de energía por ejemplo) simplemente puede truncarlo hacer ese tamaño

+1

Esas son buenas ideas en términos de recuperación de fallas. Lamentablemente, no se aplican a los archivos mapeados en memoria. Los archivos MM siempre tienen WriteThrough deshabilitado porque usan el administrador de página subyacente del sistema operativo para manejar el almacenamiento en búfer. Mantener un registro de confirmación también es una buena idea, pero tiene otros problemas. Entonces requeriría dos descargas por operación de archivo (una para el archivo MM, una para el registro). Aún más problemático, con los archivos MM no se sabe cuando se completa una descarga. En el mejor de los casos, puede indicar al sistema operativo que inicie un color, pero no obtiene la confirmación una vez que se completa. Eso hace que un registro determinista sea un no-go –

+0

@Kennet Belenky: Lo que pasa con el enrojecimiento es extraño, compáralo con [Java] (http://docs.oracle.com/javase/1.4.2/docs/api/java/nio /MappedByteBuffer.html). ¿Tal vez podría usar un FileOutputStream normal para el registro (el registro es corto, por lo que no habrá mucha diferencia de velocidad)? IIUYC perder un registro no confirmado no es tan malo, por lo que podría vaciar el registro más raramente. – maaartinus

+0

@maaartinus La API de Java es definitivamente más fácil de razonar, pero tampoco es perfecta. Es bueno que brinde la garantía de que la descarga está completa a su regreso. Sin embargo, sería aún mejor si le proporcionara una notificación asíncrona para que pueda dedicarse a su negocio. El tiempo de búsqueda de 10 ms de una descarga de disco giratorio es mucho tiempo para permanecer inactivo. –

Cuestiones relacionadas