Multihilo multi-CPU de Ruby

Hola, como he mencionado en publicaciones anteriores, estoy realizando pruebas de mi migración de Drupal a Discourse para tener todas las soluciones listas antes de desmantelar el sitio antiguo y migrar los datos de producción con sus ~2 millones de publicaciones. Lo que he aprendido es que en un VPS bastante rápido con 3 núcleos de vCPU, el proceso de importación lleva una eternidad, alrededor de 48 horas. Y luego, probablemente tendré que hacer más limpieza con tareas de rake y/o rails c, y para cualquier cosa que requiera un rake posts:rebake tomará otras 20 horas aproximadamente.

Realmente no entiendo los fundamentos de la cadena de herramientas de Ruby. Pero si le doy más núcleos de CPU al trabajo, ¿reducirá significativamente la cantidad de tiempo que cualquiera de estos procesos requiere para completarse? Por ejemplo, ¿un comando bundle o un comando rake podrá dividir su trabajo entre las CPU disponibles, o los núcleos adicionales son principalmente útiles para ejecutar procesos concurrentes cuando varios usuarios acceden al sitio web?

1 me gusta

Estoy fuera de tema, pero cuando estaba trabajando en una migración de foro con la misma cantidad de publicaciones, modifiqué el script de importación para importar solo 1/100 o 1/1000 temas y publicaciones.

Es una forma más rápida de ver si tu importación es confiable y si se necesitan ajustes o depuración.

3 Me gusta

@Canapin En realidad, muchas gracias por mencionarlo, me gustaría mucho saber cómo lo hiciste. He querido hacer lo mismo, pero deseché la idea porque asumí que me encontraría con inconsistencias en la base de datos con una importación parcial. Así que terminé creando un foro de prueba de Drupal esqueleto para probar. Pero preferiría probar una copia de la base de datos de producción.

Me preocupa principalmente la migración final de producción, tendré que desconectar el foro antiguo o al menos hacerlo de solo lectura, y parece que serán al menos 48 horas de inactividad en el mejor de los casos, ¿a menos que duplicar los núcleos de CPU reduzca el tiempo a la mitad?

1 me gusta

Las tareas que tardan mucho en restaurarse son, de hecho, multihilo. Una advertencia es que 2x las CPUs casi nunca es 2x el rendimiento.

Otro punto es que, por lo general, las tareas para rake posts:rebake y el trabajo pesado del foro en sí para recuperar y optimizar el contenido pueden ocurrir con el foro en vivo. Lo que podría reducir el tiempo que necesitas tener el foro fuera de línea o de solo lectura y poder ofrecer una experiencia algo degradada.

Mi recomendación sería: primero, prueba. Haz la migración, mira cuánto tiempo lleva y cómo se ve el foro sin todos los rebakes implementados. Si es suficiente, programa la migración para que termine alrededor de la hora de menor tráfico de tu foro, de esa manera ganas unas 4-10 horas de migración sin que mucha gente se queje.

3 Me gusta

Excelente, gracias por confirmarlo, también me preguntaba sobre esta opción.

Desafortunadamente, no lo he anotado y lo olvidé… Pero si sabes programar, no debería ser muy difícil.
Quizás ajusté los valores de BATCH_SIZE y offset entre otras cosas para alterar el bucle y hacer que salte lotes de publicaciones o algo así…

No puedo volver a intentarlo ahora porque no tengo ningún foro para importar en este momento, pero haré un tutorial rápido la próxima vez porque creo que es bastante útil.

1 me gusta

Quiero mencionar dos cosas.

  • Sí, las CPU importan, así que simplemente obtén un VPS más grande y ejecuta múltiples instancias de sidekiq para volver a hornear y procesar imágenes, irá más rápido.
  • Cuando tu importación se complete totalmente, siempre es una buena idea hacer una copia de seguridad/restauración, te dará un mejor rendimiento de la base de datos.

Estas dos juntas: obtén un VPS grande para la importación y cuando hayas terminado, muévelo a un VPS de producción más pequeño (usando copia de seguridad y restauración).

En general, una importación no requerirá que vuelvas a hornear las publicaciones después.

3 Me gusta

Muchas gracias Richard por la respuesta. Entonces, ¿cuál(es) de estos?

  • UNICORN_WORKERS
  • UNICORN_SIDEKIQS
  • DISCOURSE_SIDEKIQ_WORKERS

Interesante, no había visto esta recomendación antes. ¿Eso reduce la fragmentación o algo así?

Sí, inicialmente iba a intentar solucionar algunos problemas de [QUOTE] y la conversión de Textile a Markdown con regexp_replace() en la consola de Postgres y luego volver a hornear todas las publicaciones, porque los comandos rake posts:remap eran demasiado lentos. Pero entonces descubrí que el sabor de regexp que usa Postgres no es compatible con PCRE, y hay demasiadas anomalías inesperadas para confiar en él. Así que voy a intentar ejecutar las publicaciones a través de Pandoc durante el proceso de importación, lo que me permitirá tener el sitio importado en funcionamiento en un estado presentable y luego solucionar cosas más pequeñas como palabras clave de emoji con rake posts:remap.

  • UNICORN_SIDEKIQS –\u003e número de procesos (predeterminado 1)
  • DISCOURSE_SIDEKIQ_WORKERS –\u003e número de hilos dentro de un proceso (predeterminado 5)

Reduce la fragmentación y soluciona el hecho de que las estadísticas de Postgres puedan verse sesgadas debido a la importación.

2 Me gusta

:+1:

Yo tampoco había visto este consejo. Si esto es “siempre una buena idea”, ¿quizás debería añadirse a Pre-launch checklist after migrating from another platform?

Creo que fue Sam o Jeff quienes me dieron este consejo hace muchos años. Ya no lo encuentro. Quizás deberíamos comprobar si sigue siendo una buena idea y/o vale la pena el esfuerzo :wink:

1 me gusta

¿Alguien podría compartir conmigo consejos sobre la forma más rápida de volver a ejecutar un script de importación y hacer que reimporte los datos? Estoy intentando ajustar algunas sustituciones de texto en el script del importador y, cuando no lo hago bien, tengo que eliminar la base de datos de Discourse y ejecutar ./launcher rebuild import, lo que lleva bastante tiempo. Me gustaría hacer cambios en mi script de importación y que comience de nuevo desde el principio (estoy usando una pequeña base de datos de maqueta esquelética de mi sitio en este momento, por lo que es muy rápido ejecutar el importador).

Hmmm. Estoy probando otra importación de los datos de mi foro de producción, esta vez en un VPS bastante potente con 8 núcleos virtuales y 16 GB de RAM. He configurado:
UNICORN_SIDEKIQS=4
DISCOURSE_SIDEKIQ_WORKERS=20
UNICORN_WORKERS=16

Con esto, no parece estar aprovechando todos los núcleos durante la etapa de import_topics:

Aunque es interesante que el gráfico de CPU estuviera al máximo, por encima del 600% (es decir, ~6 de 8 núcleos utilizados al 100%) durante la etapa de user_import.

También noté esta variable de entorno: RUBY_GLOBAL_METHOD_CACHE_SIZE=131072, ¿sería demasiado pequeña?

Creo que durante el estado de creación de usuarios hay más acciones que son manejadas de forma asíncrona por Sidekiq.
Una gran parte de la importación, desafortunadamente, no se beneficiará de la paralelización; deberías optimizar para la velocidad de CPU de un solo núcleo.

Teóricamente, podrías ejecutar diferentes fragmentos de la importación de temas en paralelo, pero requeriría bastante refactorización del importador y asegurarse de que todo se procese en orden. No vale la pena para una tarea única con algunas iteraciones.

2 Me gusta

Seguí una combinación de estas dos guías [1] [2] para importar con acceso a otro contenedor Docker que ejecuta una copia de la base de datos del foro de origen en MySQL. Pero se me ocurrió que en lugar de crear un contenedor import separado, puedo usar un solo contenedor app y agregarle el mysql-dep.tempate:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

Esto me permite tener una instancia de Discourse funcionando mientras se ejecuta el script importador. ¿Hay alguna desventaja en abrir el foro al público tan pronto como se importen todos los usuarios y categorías, y simplemente informar a los usuarios con un banner de que tardará unos días hasta que esté completamente poblado? Estoy pensando que, como mínimo, podría abrirlo después de que se importen todos los temas y publicaciones, pero antes de que se importen los mensajes privados, ya que la importación de los mensajes privados por sí sola llevará unas 24 horas.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.