mostrando nuestro Pangoloader / Sudo Null IT News

¡Hola Habr! Mi nombre es Dmitry Korolev, soy ingeniero de pruebas de carga. Pangolín Plataforma V – apuntar a DBMS en Sberbank y más. Escribí este artículo junto con mi colega Alexey Khorohorin @AlexeyHorohorin. Nuestro producto es una versión especial de PostgreSQL con mejoras (más de 30 importantes y más de 70 en total) en las áreas de seguridad, rendimiento y tolerancia a fallos.

Las condiciones para nosotros son las siguientes: probamos todo el producto, en diferentes versiones, en diferentes núcleos. Tenemos tres versiones ejecutándose en paralelo para ocho sistemas operativos diferentes, y necesitamos probar cuándo usamos y no usamos diferentes funciones. Ahora imagina cuántas integraciones hay…

Varias herramientas ayudan a automatizar la carga. Pero en ellos nos faltaba la automatización de la ejecución de escenarios de carga y la elaboración de un informe final al finalizar las pruebas. Por eso hemos creado y estamos desarrollando nuestro propio cargador: Pangoloader. En este artículo te contamos cómo funciona, qué puede hacer y cómo vamos a mejorarlo en el futuro.

Cómo funcionan las pruebas de carga de la próxima versión de Pangolin

Primero, probamos el TPS (transacciones por segundo) máximo, lo confirmamos con una prueba de dos horas. Hay pasos para probar el máximo: elevamos la carga a un nivel estable y corremos durante dos horas para asegurarnos de que sea exactamente el máximo. Luego una prueba de estabilidad de 24 horas: buscamos pérdidas de memoria y otros problemas que puedan ocurrir. Después de esto hay una prueba de conmutación por error. Si el maestro falla (se estropea), comprobamos con qué éxito y cuánto tiempo lleva reemplazarlo, y cómo la réplica se convierte en maestro (una réplica es como un paracaídas de reserva).

Anteriormente, hacíamos la carga de trabajo con scripts escritos por nosotros mismos en Bash. Este es un método simple y accesible, pero no nos permitió implementar un mecanismo universal para ejecutar simultáneamente múltiples escenarios de prueba. Más importante aún, dificulta la generación de un informe final al finalizar las pruebas. Pero recopilar un informe de este tipo manualmente lleva mucho tiempo y también es necesario recordar incluir toda la información…

Por eso, a finales de 2022, obtuvimos nuestra propia herramienta de carga.

¿Qué es nuestro Pangoloader?

Esta es una combinación de dos herramientas:

  • Benchbase es una herramienta de código abierto para realizar pruebas de carga para varios DBMS. Lo modificamos para adaptarlo a nuestros requisitos.

  • Pangoloader es una herramienta de Python. Le permite preparar y ejecutar herramientas de carga, como Benchbase, realizar un seguimiento de su estado de trabajo y recopilar un hermoso informe final en una página HTML, donde se cargan la configuración de DBMS, indicadores de compilación, gráficos durante las pruebas, métricas comerciales y métricas del sistema.

Este artículo está dedicado a Pangoloader, pero aquí responderemos brevemente posibles preguntas sobre Benchbase y la elección de la primera solución del paquete.

¿Qué otras herramientas podrías utilizar?

  • banco de pruebas contiene un escenario de carga básico, pero queríamos algo más complejo. Además, pgbench es un punto de referencia integrado para probar PostgreSQL; no sería posible comparar el rendimiento en el mismo escenario en diferentes DBMS;

  • Jmetro — no teníamos experiencia trabajando con él, y toda la lógica del escenario de carga y la generación de datos tendrían que implementarse en él, lo que llevaría bastante tiempo.

  • martillodb Puede cargar diferentes DBMS para comparar el rendimiento, pero solo tiene dos escenarios de carga.

Elegimos Benchbase porque:

  • puede cargar diferentes DBMS;

  • tiene muchos guiones preparados;

  • implementado en Java, tenemos experiencia en ello, puedes hacer tus propias mejoras;

  • una base preparada para crear sus propios escenarios de carga.

Volvamos a Pangoloader. Así es como funciona. Antes de iniciar la utilidad, prepare un archivo de configuración en formato YAML:

stand:
 stand_1:
   ssh_user: pprb_dev
   host: 65.32.1.29
   postgresql:
     port: 5433
   pgbouncer:
     port: 6544

benchmark:
 benchbase:
   host: 65.32.1.30
   config: /tmp/tpcc_config.xml
   command: java -jar /home/pprb_dev/benchbase-postgres/benchbase.jar
   scalefactor: 2500
   terminals: 250
   time_load: 300
   rate_load: 100
   test_port: 6544

Registramos los servidores en los que se encuentra el banco de pruebas con el DBMS y el host con la utilidad de carga:

ssh_user:
 pprb_dev:
   name: pprb_dev
   password: pprb_dev_pass
 postgres:
   name: postgres
   password: postgres_pass
sql_role:
 postgres:
   name: postgres
   password: P@ssword
 pangoloader:
   name: postgres
   password: P@ssword
 pgbouncer:
   name: pgbouncer
   password: pgbpass

Aquí está la sección para definir usuarios SSH y SQL. Participan en las pruebas:

grafana:
 host: 65.32.1.5
 port: 3000
 api_key: eyJrIjoiTTVhTHpSd...
 render_params:
   theme: light
   width: 1280
   height: 720
   var-interval: 2s
 render_processes: 4

prometheus:
 host: 65.32.1.4
 port: 9090

Luego especificamos los hosts para las utilidades de monitoreo Grafana y Prometheus. Seleccionamos algunos parámetros para representar imágenes con gráficos, que luego terminan en el informe final.

El principal requisito de la herramienta es la capacidad de guardar archivos de script preparados y ejecutarlos posteriormente.

El escenario de carga se ve así:

class tpcc_load(Scenario):

   dbname="First_db"
   time = 7200
   rate = 1260
   test_port="pgbouncer"
   test_generate_report = True

   Scenario.description = """Тест подтверждения максимальной нагрузки.
   Тест проводится на ступени нагрузки, предшествующей L0 (или на уровне нагрузки 90% от L0). Длительность стабильной нагрузки не менее 1 часа."""

Esta es una clase que representa un script de prueba. Los parámetros necesarios para esta prueba se declaran aquí. Por ejemplo:

  • dbname — nombre de la base de datos de prueba en el DBMS;

  • time — tiempo de carga;

  • rate — intensidad de carga;

  • test_port determina a qué puerto se conectarán los clientes de prueba;

  • test_generate_report determina si se debe generar un informe al finalizar el script de prueba;

  • Scenario.description – una descripción textual del escenario y de lo que sucede en él. Luego esta descripción se incluye en el informe.

La clase hereda de la clase. Scenario. Esta es una clase base abstracta y contiene tres métodos:

  • setup — sirve, por ejemplo, para la configuración preliminar del objeto probado. Configurar los parámetros correctos, reiniciar la base de datos, generar datos de prueba, etc.

  • execute — el guión de prueba en sí. Aquí es donde se inicia la carga, con la que necesitamos obtener resultados en forma de rendimiento final, métricas de recursos del sistema y otras cosas. El informe contendrá datos sólo durante el intervalo de funcionamiento de este método.

  • teardown – ejecutado al finalizar la carga. Restaura los parámetros a sus valores originales para devolver el objeto bajo prueba a su estado original.

Así es como se ve el método. execute Por ejemplo:

def execute(self):
       benchmark = utils.Benchmark()
       scalefactor = benchmark.scalefactor
       terminals = benchmark.terminals     

       if tpcc_load.test_port == 'postgres':
           conn_string = ','.join(f'{pg.get_host()}:{pg.get_port()}' for pg in config.postgresql_list())
       elif tpcc_load.test_port == 'pgbouncer':
           conn_string = ','.join(f'{pg.get_host()}:{pg.get_port()}' for pg in config.pgbouncer_list())

       bench_cfg = benchmark.read_config('/home/pprb_dev/benchbase-postgres/config/postgres/tpcc_load.xml')
       bench_cfg.find('url').text = f'jdbc:postgresql://{conn_string}/{tpcc_load.dbname}?ApplicationName=tpcc&reWriteBatchedInserts=true&prepareThreshold=0&targetServerType=primary'
       bench_cfg.find('username').text = config.SQLRole('pangoloader').name
       bench_cfg.find('password').text = config.SQLRole('pangoloader').password
       bench_cfg.find('scalefactor').text = f'{scalefactor}'
       bench_cfg.find('loaderThreads').text = f'{tpcc_load.loaderThreads}'
       bench_cfg.find('terminals').text = f'{terminals}'
       bench_cfg.find('works').find('work').find('time').text = f'{tpcc_load.time}'
       bench_cfg.find('works').find('work').find('rate').text = f'{tpcc_load.rate}'
       bench_cfg.find('works').find('work').find('weights').text = f'{tpcc_load.weights}'
       benchmark.write_config('/tmp/tpcc_config.xml', bench_cfg)
       benchmark.run(
               "--bench tpcc",
               "--config /tmp/tpcc_config.xml",
               "--create=false",
               "--clear=false",
               "--load=false",
               "--execute=true",
               with_log = True,
               )

En este ejemplo, ya tenemos una base de datos de prueba. Preparamos la configuración para la utilidad de carga con los parámetros necesarios y la ejecutamos con un comando:

pangoloader --config config.yaml --report-template template/base.j2 --log-file pangoloader.log tests.tpcc_load

Y luego especificamos el archivo de configuración, la plantilla para el informe, el archivo de registro y enumeramos los scripts que se ejecutarán en la prueba.

¿Qué pasó al final?

Pangoloader nos ha facilitado mucho el trabajo. Ahora podemos:

  • iniciar la carga con un botón;

  • configurar el monitoreo en máquinas virtuales;

  • cambiar la configuración del entorno donde estamos probando, la configuración de scripts;

  • ejecutar varios scripts seguidos;

  • recopile resultados para cada tipo de prueba y genere informes detallados y convenientes.

Pensamos en el contenido del informe final para poder repetir en cualquier momento el mismo escenario de prueba y analizar los resultados de la prueba en su totalidad.

Informe final

Informe final

Registramos el tiempo de prueba, la versión del objeto que se está probando y el hash de la confirmación a partir del cual se compiló. Aquí también se muestra una tabla con la configuración del banco de pruebas. Si hay varios hosts, se enumerarán en orden.

A continuación se muestra información sobre el escenario de carga: qué escenario de prueba se lanzó y con qué parámetros. Pruebe el diseño de la base de datos, el tamaño de las tablas y la cantidad de registros que contienen, los tamaños de los índices de las tablas.

Y aquí hay información con los resultados en forma de gráficos de monitoreo: aquí hay gráficos de métricas del sistema (CPU, RAM, disco), estadísticas de intensidad de carga (TPS, latencia). Toda esta información detallada está oculta debajo de enlaces y se abre en páginas separadas.

Planes: lo que queremos agregar a nuestro cargador

Vamos a desarrollar aún más Pangoloader. La característica más interesante y compleja que me gustaría agregar es el análisis automatizado de informes. Sería fantástico si, al abrir un informe, las áreas problemáticas se resaltaran automáticamente en rojo en la parte superior de la página. Esto se puede lograr, por ejemplo, comparando indicadores con valores de referencia y resaltando inconsistencias. O comparando los resultados con pruebas anteriores. Pero por ahora esto son sólo pensamientos, todavía no hemos probado la idea en la práctica. Empecemos a intentarlo; hablaremos un poco sobre ello en comunidad nuestro equipo, únete si estás interesado.

Y si tienes tanta experiencia en automatización de cargas, estaremos agradecidos por tus comentarios. ¡Gracias por su atención!

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *