go - terabyte - tb to gb
¿Qué tan rápido es el go 1.5 gc con terabytes de RAM? (1)
Java no puede usar terabytes de RAM porque la pausa del GC es demasiado larga (minutos). Con la reciente actualización del Go GC, me pregunto si las pausas de su GC son lo suficientemente cortas como para usarlas con grandes cantidades de RAM, como un par de terabytes.
¿Hay algún punto de referencia de esto todavía? ¿Podemos usar un lenguaje recolectado con esta cantidad de RAM ahora?
tl; dr :
- No puedes usar TBs de RAM con un solo proceso Go en este momento. Max tiene 512 GB en Linux, y la mayoría de lo que he visto probado es de 240 GB.
- Con el GC de fondo actual, la carga de trabajo del GC tiende a ser más importante que las pausas del GC.
- Puede comprender la carga de trabajo del GC como punteros * tasa de asignación / RAM de reserva . De las aplicaciones que usan toneladas de RAM, solo aquellas con pocos punteros o poca asignación tendrán una carga de trabajo de GC baja.
Estoy de acuerdo con el comentario de inf de que vale la pena preguntar a otras personas acerca de (o pruebas). JimB señala que los montones de Go tienen un límite de 512 GB en este momento, y 18 240 GB es lo más que he visto probado.
Algunas cosas que sabemos sobre enormes montones, desde el documento de diseño y las diapositivas de GopherCon 2015 :
- El recolector 1.5 no pretende cortar el trabajo de GC, solo corta las pausas trabajando en segundo plano.
- Su código está en pausa mientras el GC escanea los punteros en la pila y en los globales.
El 1.5 GC tiene una breve pausa en un punto de referencia de GC con un montón de aproximadamente 18 GB , como lo muestra el punto amarillo más a la derecha en la parte inferior de este gráfico de la charla de GopherCon :
Las personas que ejecutan un par de aplicaciones de producción que inicialmente tenían aproximadamente ~4ms pausa informaron caídas de ~4ms y ~20ms . Otra aplicación informó que su tiempo de GC del percentil 95 pasó de 279 ms a ~ 10 ms .
Ir 1.6 añadió pulimento y empujó parte del trabajo restante al fondo . Como resultado, las pruebas con montones de hasta un poco más de 200 GB aún vieron un tiempo máximo de pausa de 20 ms, como se muestra en una diapositiva en una charla sobre el estado de Go de 2016:
La misma aplicación que tuvo 20 ms de tiempo de pausa por debajo de 1.5 tuvo 3-4 ms de pausa por debajo de 1.6, con un montón de 8 GB y 150 M de asignación por minuto .
Twitch, que utiliza Go para su servicio de chat, informó que los tiempos de pausa de Go 1.7 se habían reducido a 1 ms con un montón de goroutines en ejecución .
1.8 eliminó el escaneo de la pila de la fase de parada del mundo , lo que llevó a la mayoría de las pausas a menos de 1 ms, incluso en grandes montones. Los primeros números se ven bien . En ocasiones, las aplicaciones todavía tienen patrones de código que hacen que una goroutina sea difícil de pausar, alargando efectivamente la pausa para todos los demás subprocesos, pero en general es justo decir que el trabajo en segundo plano del GC ahora suele ser mucho más importante que las pausas del GC.
Algunas observaciones generales sobre la recolección de basura, no específicas para Go:
- La frecuencia de las recopilaciones depende de la rapidez con la que utilice la memoria RAM que está dispuesto a aportar al proceso.
- La cantidad de trabajo que realiza cada recopilación depende en parte de cuántos punteros se estén utilizando. (Eso incluye los punteros dentro de segmentos, valores de interfaz, cadenas, etc. )
Reformado, una aplicación que acceda a una gran cantidad de memoria podría no tener un problema de GC si solo tiene algunos indicadores (por ejemplo, maneja relativamente pocos búferes de []byte
grandes) y las recopilaciones ocurren con menos frecuencia si la tasa de asignación es baja (por ejemplo, porque aplicó sync.Pool
para reutilizar la memoria donde estaba masticando la memoria RAM más rápidamente).
Entonces, si estás viendo algo que involucra montones de cientos de GB que no son naturalmente compatibles con GC, te sugiero que consideres cualquiera de
- escribiendo en C o tal
- mover los datos voluminosos fuera del gráfico de objetos. Por ejemplo, puede administrar datos en una base de datos incrustada como un
bolt
, colocarlos en un servicio externo de base de datos o usar algo comogroupcache
o memcache si desea más caché que un DB. - ejecutar un conjunto de procesos de menor tamaño en lugar de uno grande
- Simplemente haga prototipos, pruebe y optimice para evitar problemas de memoria.