2012-04-16 22 views
10

Tengo un databse KDB/Q que tiene alrededor de ~ 2M registros por día consumiendo aproximadamente ~ 2G de memoria. Al final del día ejecuta algunas tareas de informes haciendo combinaciones entre las tablas y generando resultados en archivos en el disco. Durante el cálculo, el uso de la memoria aumenta a ~ 15G. Mi problema es que una vez que esta operación finaliza, la memoria nunca se libera y hasta que se reinicie el DB, consume todos los 15G de memoria.Consumo de memoria KDB/Q

Me gustaría decirle a KDB que descargue algunas tablas de la memoria (aunque no las deje caer) pero no quiero reiniciar el DB ya que algunas otras aplicaciones todavía se están conectando a él.

¿Hay alguna manera de decirle a KDB que descargue algo de la memoria?

EDIT:

Si alguien le resulta interesante que sugerir a echar un vistazo a .Q.gc[] de KDB 2.5+, parece prometedor.

Respuesta

7

Aquí es la suma de mi investigación:

  • KDB antes de ver. 2.5 asigna 64 MB de fragmentos de memoria a la necesidad y nunca los libera. Sin embargo, es capaz de reutilizarlos.
  • recientes versiones KDB permiten .Q.gc[] llamada que está en la petición de llamada al recolector de basura (KDB utiliza ref. A contar por cierto.)
  • Esto es especialmente útil cuando se invoca algún cálculo intensivo de la memoria que asigna gran cantidad de memoria (en mi caso era ~ 20 gB) y desea liberar la memoria después de que termine el cálculo.
  • siempre se puede considerar la posibilidad de la secuencia de comandos intensivo de memoria en un proceso Q separada por lo que se libera la memoria una vez que termine el script
4

Esto puede ser obvio, pero además de comprobar los modos de recolección de basura para su versión de q, asegúrese de que realmente se haya deshecho de los datos en memoria que están usando la memoria. Si estás bien con la eliminación de toda la tabla (por ejemplo, se trata de una tabla temporal que participan en el cálculo), simplemente eliminarlo del espacio de nombres raíz

delete table from`. 

si no, puede borrar todos sus filas

delete from`table 
2

para cualquiera que trate esto en el futuro la forma más fácil habría sido para:

  1. iniciar un nuevo proceso de KDB.
  2. De esa consulta de proceso para seleccionar los subconjuntos de datos limitados más pequeños necesarios.
  3. Realice cualquier unión/cálculo/escritura en el archivo de ese proceso. (permitiendo que el original continúe las solicitudes de procesamiento)
  4. Cierre el proceso, liberando toda la memoria.

Como se menciona en los carteles anteriores, las versiones más nuevas de KDB liberan la memoria mejor pero no son perfectas.

Hay un buen artículo en nuestra página web que detalla KDB + Gestión de memoria: http://timestored.com/kdbGuides/memoryManagement

1

http://code.kx.com/q4m3/12_Workspace_Organization/#125-expunging-from-a-context

que utilizan algunos comandos diferentes. Siempre que su tabla esté almacenada en el disco antes de borrarla, debería estar bien.

Esta es la sesión antes de crear la tabla.

q).Q.w[] 
used| 290192 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

Este comando crea la tabla y luego la guarda en el disco.

q)t:([]10000?"ab"; 10000?5) 
q)save `t 
`:t 

La tabla se encuentra todavía en la memoria

q).Q.w[] 
used| 437808 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 629 
symw| 20704 

Vamos a borrar la variable de la memoria y recoger la basura.

q)delete t from `. 
`. 
q).Q.gc[] 
0 

Ahora la memoria `utilizada se ha reducido a una cantidad similar al inicio de la sesión.

q).Q.w[] 
used| 290208 
heap| 67108864 
peak| 67108864 
wmax| 0 
mmap| 0 
mphy| 8589934592 
syms| 630 
symw| 20730 
q)\v 
`symbol$() 
Cuestiones relacionadas