Cómo priorizar la escritura () sobre las actualizaciones de mmap (o retrasar el vaciado de caché de la página de mmap)

Estoy ejecutando un demonio DB especializado en un debian-64 con 64G de RAM y mucho espacio en disco. Utiliza una tabla hash en disco (mapeada) y escribe los datos reales en un archivo con llamadas regulares a write(). Cuando se realizan muchas actualizaciones, una gran parte del mmap se ensucia y la memoria caché de la página intenta vaciarlo en el disco, lo que produce muchas escrituras aleatorias que, a su vez, ralentizan el rendimiento de las escrituras regulares (secuenciales) en el archivo de datos. .

Si fuera posible retrasar el vaciado de la memoria caché de la página del área mmaped, el rendimiento mejoraría (supongo), ya que varios (o todos) los cambios en la página sucia se escribirían a la vez en lugar de una vez para cada actualización (en el peor de los casos, en realidad por supuesto, agrega muchos cambios de todos modos).

Entonces, mi pregunta: ¿es posible retrasar el vaciado de caché de página para un área asignada en memoria? ¿O es posible priorizar la escritura regular? ¿O alguien tiene alguna otra idea? madvise y posix_fadvise no parecen hacer ninguna diferencia...

preguntado el 12 de junio de 12 a las 16:06

2 Respuestas

Podrías jugar con los sintonizables en /proc/sys/vm. Por ejemplo, aumente el valor en dirty_writeback_centisecs para hacer que pdflush se despierte con menos frecuencia, aumente dirty_expire_centiseconds por lo que se permite que los datos permanezcan sucios durante más tiempo hasta que deban escribirse y aumentar dirty_background_ratio para permitir que más páginas sucias permanezcan en la RAM antes de que se deba hacer algo.
Vea aquí para obtener una descripción algo completa de lo que hacen todos los valores.

Tenga en cuenta que esto afectará cada proceso en su máquina, pero viendo cómo está ejecutando un enorme servidor de base de datos, es probable que esto no sea un problema ya que no desea que nada más se ejecute en la misma máquina de todos modos.

Ahora, por supuesto, esto retrasa las escrituras, pero aún no resuelve completamente el problema de las reescrituras de páginas sucias que compiten con write (aunque probablemente colapsará algunas escrituras si hay muchas actualizaciones).
Pero: Usted puede utilizar el sync_file_range syscall para forzar la escritura inicial de páginas en un rango determinado en su descriptor de archivo de "escritura" (SYNC_FILE_RANGE_WRITE). Por lo tanto, mientras que las páginas sucias se reescribirán en un momento desconocido más tarde (y con períodos de gracia mayores), usted inicia manualmente la reescritura en las que le interesan.
Esto no da ninguna garantía, pero debemos solo trabajo.

Asegúrese de leer absolutamente positivamente la documentación, mejor léala dos veces. sync_file_range puede corromper o perder datos muy fácilmente si lo usa incorrectamente. En particular, debe asegurarse de que los metadatos estén actualizados y vaciados si los agregó a un archivo, o los datos que se "escribieron con éxito" simplemente "desaparecerán" en caso de un bloqueo.

Respondido el 13 de junio de 12 a las 23:06

eso suena razonable (aunque creo que también tengo que aumentar la relación sucia), lo intentaré durante las próximas semanas y les haré saber los resultados. ¡Gracias! - Hugo Walter

lo intentaré mlock. Si tu mlock el rango de memoria relevante, puede evitar que ocurra el vaciado. Tú podrías munlock cuando termines.

Respondido el 12 de junio de 12 a las 16:06

Aunque mlock probablemente funcionará, no es evitando el lavado. Es porque la memoria física se adherirá al rango de direcciones, por lo que las páginas no pueden ser robadas. después de están vaciados (y no han sido referenciados durante mucho tiempo) El problema exacto, por supuesto, es que el acceso a la tabla hash será muy escaso y falso: existe la posibilidad de que alguna página no sea referenciada durante mucho tiempo. (y será eliminado del núcleo por la LRU). Mlock probablemente funcionará (si la memoria no es demasiado apretada) - salvaje

el problema no es que necesite volver a cargar partes relevantes de la tabla hash desde el disco (la tabla hash no es tan escasa ni tan grande, probé un escenario donde todo cabe en la ram, incluidos los datos), el problema es que las operaciones de escritura reales del vaciado de la página provocan una E/S de disco significativa (porque se ensucian con tanta frecuencia) lo que ralentiza las escrituras en el archivo de datos (por supuesto, esto es inevitable, pero la pregunta es si podría mitigarse) - Hugo Walter

El problema es que en (buenas) tablas hash, los patrones de acceso siempre están dispersos. Emitir N actualizaciones en una tabla hash que cubre N páginas, afectará aproximadamente (2/3) *N páginas. Solo aprox. N/3 páginas serán no ser golpeado. La única forma de evitar esto es no usar mmap (o un mapeo anónimo/privado) e inventar alguna otra forma de aplicar las actualizaciones al archivo del disco. - salvaje

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.