Acerca del rendimiento de las bases de datos de subprocesos individuales o subprocesos múltiples

58

H2 es una base de datos de un solo subproceso con una buena reputación en cuanto al rendimiento. Otras bases de datos son multiproceso.

Mi pregunta es: ¿cuándo una base de datos de múltiples hilos se vuelve más interesante que una base de datos de un solo hilo? Cuantos usuarios Cuantos procesos ¿Cuál es el disparador? ¿Alguien tiene experiencia para compartir?

Resumen

  • El cuello de botella habitual es el acceso al disco.
  • Los SSD son rápidos, pero frágiles (el procedimiento de falla es obligatorio)
  • Una consulta larga en un sistema de un solo hilo bloqueará todos los demás
  • Configurar el sistema de subprocesos múltiples puede ser complicado
  • Las bases de datos multiproceso son beneficiosas incluso en sistemas de un solo núcleo
Jérôme Verstrynge
fuente
Subproceso significa "subproceso o proceso" para el propósito de esta pregunta, por lo que puedo decir, por ejemplo, postgres no es multiproceso, pero la pregunta no está tratando de comparar (H2, postgres) contra (Oracle, SQL Server, etc.)
Jack Douglas

Respuestas:

31

Aquí está mi opinión:

Por lo general, el cuello de botella (o la parte más lenta) de un sistema de base de datos es el disco. La CPU solo se dispara durante las operaciones aritméticas, el procesamiento o cualquier otra tarea que realice la CPU. Con una arquitectura adecuada, el subprocesamiento múltiple puede ayudar a compensar la carga de una consulta en la CPU en lugar de realizar lecturas / escrituras lentas en el disco. Hay casos en los que es más rápido calcular un valor utilizando los ciclos de la CPU en lugar de crear una columna calculada (que se guardó previamente en el disco) y leer esta columna desde el disco.

En algunos RDBMS hay una base de datos temporal (tempdb) que utilizan todas las bases de datos en esa instancia para ordenar, trocear, variables temporales, etc. El subprocesamiento múltiple y la división de estos archivos tempdb se pueden usar para mejorar el rendimiento de tempdb , mejorando así el rendimiento general del servidor.

Mediante el uso de subprocesos múltiples (paralelismo), el conjunto de resultados de una consulta puede dividirse para procesarse en los diferentes núcleos del servidor, en lugar de utilizar un solo núcleo. Esta característica no siempre mejora el rendimiento, pero hay casos en que lo hace, y por lo tanto, la característica está disponible.

Los subprocesos disponibles para la base de datos se utilizan para muchos propósitos: lectura / escritura en el disco, conexiones de usuario, trabajos en segundo plano, bloqueo / enclavamiento, IO de red, etc. gestionado mediante esperas y colas. Si la CPU puede procesar estos subprocesos bastante rápido, los tiempos de espera serán bajos. Una base de datos de subprocesos múltiples será más rápida que una base de datos de subprocesos simples, ya que en una base de datos de subprocesos simples habrá la sobrecarga de reciclar solo un hilo en lugar de tener otras bandas de rodadura fácilmente disponibles.

La escalabilidad también se convierte en un problema, ya que se necesitarán más subprocesos para administrar y ejecutar el sistema de base de datos escalado.

StanleyJohns
fuente
Gracias por la perspicacia. Escucho personas alabando las unidades de estado sólido. Supongo que invertir en ellos es probablemente la mejor opción después de asegurarse de que las consultas estén bien escritas y de que la aplicación esté razonablemente paralela.
Jérôme Verstrynge
@Stan: creo que multithreadeden este contexto significa algo diferente , es decir, que todas las transacciones se serializan como Luke menciona en su respuesta.
Jack Douglas
@JVerstry ~ No, en realidad no. Ve a leer los pensamientos de Jeff Atwood sobre los SSD ... tienen una alta tasa de fallas. Lo mejor que puede hacer es indexar adecuadamente los datos y tener consultas bien escritas.
jcolebrand
@jcolebrand Ok, parece abogar por la velocidad solo con un fuerte sistema de respaldo para cuando fallan
Jérôme Verstrynge
2
@Jverstry ~ Sí, y si comprende ese concepto, y está de acuerdo con él, y no le importa reconstruir todo su entorno de producción (o esperar a que se active una conmutación por error automática y luego reconstruirla en algún momento en un futuro cercano) adelante, harán las cosas aún más rápido, sí.
jcolebrand
47

Si hay algo que puedo decir sobre MySQL es que InnoDB, su motor de almacenamiento transaccional (compatible con ACID), es de hecho multiproceso. ¡Sin embargo, es tan multiproceso como lo CONFIGURAS! Incluso "listo para usar", InnoDB funciona muy bien en un solo entorno de CPU, dada su configuración predeterminada. Para aprovechar las capacidades de subprocesamiento múltiple de InnoDB, debe recordar activar muchas opciones.

innodb_thread_concurrency establece el límite superior en el número de hilos concurrentes que InnoDB puede mantener abiertos. El mejor número de ronda para establecer es (2 X Número de CPU) + Número de discos. ACTUALIZACIÓN : Como aprendí de primera mano de la Conferencia de Percona NYC, debe establecer esto en 0 para alertar a InnoDB Storage Engine para que encuentre la mejor cantidad de subprocesos para el entorno en el que se está ejecutando.

innodb_concurrency_tickets establece el número de subprocesos que pueden evitar la comprobación de concurrencia con impunidad. Una vez alcanzado ese límite, la comprobación de concurrencia de subprocesos vuelve a ser la norma.

innodb_commit_concurrency establece el número de transacciones concurrentes que pueden confirmarse. Dado que el valor predeterminado es 0, no establecer esto permite que cualquier número de transacciones se confirme simultáneamente.

innodb_thread_sleep_delay establece el número de milisegundos que un subproceso InnoDB puede estar inactivo antes de volver a ingresar en la cola InnoDB. El valor predeterminado es 10000 (10 segundos).

innodb_read_io_threads e innodb_write_io_threads (ambos desde MySQL 5.1.38) asignan el número especificado de hilos para lecturas y escrituras. El valor predeterminado es 4 y el máximo es 64.

innodb_replication_delay impone un retraso de subproceso en un esclavo si se alcanza innodb_thread_concurrency.

innodb_read_ahead_threshold permite lecturas lineales del número establecido de extensiones (64 páginas [página = 16K]) antes de cambiar a lectura asíncrona.

El tiempo se me escaparía si nombrara más opciones. Puede leer sobre ellos en la documentación de MySQL .

La mayoría de las personas desconocen estas características y están bastante satisfechas con InnoDB simplemente haciendo transacciones que cumplen con ACID. Si modifica cualquiera de estas opciones, lo hace bajo su propio riesgo.

He jugado con MySQL 5.5 Multiple Buffer Pool Instances (162GB en 9 instancias de agrupaciones de búfer) y he intentado que los datos se particionen automáticamente en la memoria de esta manera. Algunos expertos dicen que esto debería brindarle una mejora del rendimiento del 50%. Lo que obtuve fue una tonelada de bloqueo de hilo que realmente hizo que InnoDB se arrastrara. Cambié a 1 búfer (162 GB) y todo volvió a estar bien en el mundo. Supongo que necesita expertos de Percona a su disposición para configurar esto. Mañana estaré en la Conferencia Percona MySQL en Nueva York y preguntaré sobre esto si se me brinda la oportunidad.

En conclusión, InnoDB se comporta bien ahora en un servidor de CPU múltiple dada su configuración predeterminada para operaciones multiproceso. Ajustarlos tiene mucho cuidado, gran paciencia, excelente documentación y excelente café (o Red Bull, Jolt, etc.).

¡Buenos días, buenas noches y buenas noches!

ACTUALIZACIÓN 2011-05-27 20:11

Regresé de la Conferencia Percona MySQL en Nueva York el jueves. Que conferencia. Aprendí mucho, pero obtuve una respuesta que investigaré sobre InnoDB. Ronald Bradford me informó que establecer innodb_thread_concurrency en 0 permitirá que InnoDB decida el mejor curso de acción internamente con concurrencia de hilos. Voy a experimentar más con esto en MySQL 5.5.

ACTUALIZACIÓN 2011-06-01 11:20

En lo que respecta a una consulta larga, InnoDB es compatible con ACID y funciona muy bien usando el Control de concurrencia de MultiVersion . Las transacciones deben poder llevar niveles de aislamiento (lecturas repetibles por defecto) que eviten que otros bloqueen el acceso a los datos.

En cuanto a los sistemas multinúcleo, InnoDB ha recorrido un largo camino. En el pasado, InnoDB no podía funcionar bien en un entorno multinúcleo. Recuerdo tener que ejecutar varias instancias de mysql en un solo servidor para obtener los múltiples núcleos para distribuir los múltiples procesos de mysqld entre las CPU. Esto ya no es necesario, gracias a Percona, y más tarde a MySQL (eh, Oracle, diciendo que todavía me da asco), ya que han desarrollado InnoDB en un motor de almacenamiento más maduro que puede acceder a los núcleos con simplicidad sin demasiados ajustes. La instancia actual de InnoDB hoy puede funcionar bien en un único servidor central.

RolandoMySQLDBA
fuente
11

Tan pronto como tenga múltiples usuarios o procesos concurrentes, o incluso un solo proceso con acceso a bases de datos multiproceso, tener una base de datos que admita subprocesos será potencialmente interesante.

H2 es seguro para subprocesos, pero serializa todas las solicitudes a la base de datos, lo que puede convertirse en un posible problema de rendimiento en un escenario de carga pesada. Si este es realmente el caso para un proyecto en particular depende de una combinación de sus requisitos de rendimiento, el número de subprocesos / usuarios / procesos que acceden a la base de datos, la frecuencia de consultas ejecutadas por estos subprocesos y el rendimiento promedio y el peor de los casos consultas

Por ejemplo, si sus requisitos de rendimiento deben tener una respuesta en un segundo, no tiene más de 10 usuarios concurrentes que ejecutan una sola consulta que demora 0.05 segundos en ejecutarse, una base de datos de un solo subproceso aún le permitiría alcanzar esos objetivos (aunque multiproceso) probablemente ya daría un notable aumento de rendimiento). Sin embargo, dado el mismo escenario con una sola consulta potencial con un rendimiento en el peor de los casos de medio segundo, serializar el acceso a su base de datos ya no le permitirá cumplir sus objetivos de rendimiento.

Si actualmente está utilizando H2 en su proyecto, le aconsejaría que ejecute un generador de perfiles contra su base de código en un escenario de carga (simplemente inicie un número x de hilos que golpean su código simultáneamente usando algunos casos de uso típicos). Esto le dará métricas reales sobre el rendimiento y los cuellos de botella en su base de código, en lugar de solo teorizar. Si esto muestra que sus solicitudes pasan un gran porcentaje de su tiempo esperando acceder a la base de datos, es hora de pasar a una base de datos enhebrada.

Luke Hutteman
fuente
¿H2 serializa todas las solicitudes, o solo DML?
Jack Douglas
8

Por lo que puedo decir, "un solo hilo" es un nombre poco apropiado para H2. El punto es que serializa todas las transacciones (es decir, las realiza de una en una).

La pregunta crucial sobre si eso está "bien" o no para su aplicación no es "¿Cuántos usuarios?" o incluso "¿Cuántos procesos?", pero "¿Cuánto tiempo tomarán mis transacciones?"

Si todas sus transacciones son inferiores a un segundo, eso puede estar bien, si algunas tardan varias horas en completarse, eso puede no estar bien, ya que todas las demás transacciones pendientes estarán esperando a que finalicen. La decisión sobre si eso está "bien" o no dependerá de sus propios requisitos de rendimiento, es decir, cuánto tiempo es una espera aceptable para que mis usuarios accedan a la base de datos con transacciones.

--EDITAR

Parece que H2 realmente no serializa las transacciones, solo DML. En otras palabras, muchas actualizaciones cortas dentro de una sola transacción larga no bloquearán otras actualizaciones . Sin embargo, a menos que esté utilizando la función experimental MVCC , el bloqueo de la tabla significa que esto tiene un efecto similar en la práctica. También hay una característica experimental "multi_threaded" pero no se puede usar al mismo tiempo que MVCC

Jack Douglas
fuente
5

Citando partes y piezas del sitio PostgreSQL ... Tenga en cuenta que no tengo ni idea de los méritos de estos argumentos, simplemente no cabían en un comentario.

De las Preguntas frecuentes del desarrollador ("Por qué no se usan hilos ..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

Los subprocesos no se utilizan actualmente en lugar de múltiples procesos para backends porque: (...)

  • Un error en un backend puede corromper otros backends si son hilos en un solo proceso
  • Las mejoras de velocidad con subprocesos son pequeñas en comparación con el tiempo de inicio del backend restante.
  • Compartir asignaciones ejecutables de solo lectura y el uso de shared_buffers significa que los procesos, como los subprocesos, son muy eficientes en memoria
  • La creación y destrucción regular de procesos ayuda a proteger contra la fragmentación de la memoria, que puede ser difícil de administrar en procesos de larga duración

De la lista Todo ("Características que no queremos"):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Todos los backends se ejecutan como subprocesos en un solo proceso (no deseado)

Esto elimina la protección del proceso que obtenemos de la configuración actual. La creación de subprocesos suele ser la misma sobrecarga que la creación de procesos en los sistemas modernos, por lo que parece imprudente utilizar un modelo de subprocesos puro, y MySQL y DB2 han demostrado que los subprocesos introducen tantos problemas como resuelven. (...)

Entonces, de nuevo ... No tengo ni idea de los méritos de lo anterior. Fue simplemente demasiado largo para caber en un comentario.

Denis de Bernardy
fuente
-3

Una base de datos multiproceso solo lo beneficiará cuando tenga más de 1 consulta paralela en la base de datos. Depende de la cantidad de usuarios que tenga. Si tiene más de diez usuarios trabajando en la aplicación al mismo tiempo, lo más probable es que produzcan más de una consulta en la base de datos al mismo tiempo.

Además, una base de datos multiproceso solo puede beneficiarse cuando hay varios núcleos en la CPU. Si hay un solo núcleo, la base de datos de múltiples subprocesos debe poner en cola el trabajo y ejecutarlos secuencialmente en el único núcleo. Cuando hay varios núcleos, cada núcleo puede ejecutar un subproceso en paralelo. Por lo tanto, un mejor rendimiento.

¿Responde esto a su consulta?

oazabir
fuente
77
Las bases de datos multiproceso son beneficiosas incluso en sistemas de un solo núcleo. Se evita una sola consulta de larga ejecución de bloquear todas las demás bases de datos de acceso, además de que podría tener varios hilos esperando en el disco o en la red de E / S, mientras que otro hilo está analizando activamente consultas, procesamiento de datos, etc. precapturados
Un usuario podría estar usando un programa que paraleliza algunas operaciones. Este programa probablemente se beneficiaría si la base de datos también tiene capacidades de multiprocesamiento / multiprocesamiento.
joanolo