Procesamiento de base de datos MySQL de programación de alta concurrencia multiproceso

Autor: Chen Jinjian
Blog personal: HTTPS: //jian1098.github.io
Blog de CSDN: https: //blog.csdn.net/c_jian
Libro de Jane: https: //www.jianshu.com/u/8ba9ac5706b6
Contacto: jian1098 @ qq.com

Resumen


Muchos lenguajes de programación convencionales ahora admiten el procesamiento de múltiples subprocesos o corrutinas, como los que, naturalmente, admiten corrutinas go语言, php+swooleetc. Pero el subproceso múltiple es diferente del subproceso único. Si el subproceso múltiple no procesa la base de datos, a veces el programa de un solo subproceso se ejecuta sin problemas, pero una vez que se activa el subproceso múltiple, se producirán una serie de problemas que no ocurrían antes. ocurrir en la base de datos.

Entonces, ¿qué se debe hacer para una base de datos de múltiples subprocesos y altamente concurrente? El siguiente es PHP+MySQLun ejemplo para ilustrar, otros lenguajes de programación son similares.

Procesamiento de bases de datos


Las condiciones mínimas para el procesamiento simultáneo de bases de datos deben cumplir con los primeros 6 elementos a continuación

asuntos

La transacción es uno de los pasos principales para garantizar la precisión y la coherencia de los datos en el procesamiento de múltiples subprocesos, pero la premisa es que el motor de almacenamiento de la base de datos MySQL debe ser InnoDB , porque MyISAM no admite transacciones, y cada lenguaje SQL para InnoDB es encapsulado como una transacción de forma predeterminada Envío automático, que afectará la velocidad, por lo que es mejor colocar varios lenguajes SQL entre comenzar y confirmar para formar una transacción;

Por ejemplo, transacciones en el marco php-laravel:

try {
    
    
    DB::beginTransaction();
    
    //业务逻辑和数据库操作
    
    DB::commit();
} catch (Exception $e) {
    
    
    DB::rollback();
    echo $e->getMessage();
}

Bloqueo de fila

Los bloqueos de fila son el segundo paso fundamental para garantizar la precisión y la coherencia de los datos en el procesamiento de subprocesos múltiples. Agregar bloqueos de fila puede garantizar que los datos de esta transacción no sean modificados por otros subprocesos para garantizar que los datos sean precisos. Cuando acceden otros subprocesos esta fila se bloqueará; debe tenerse en cuenta que el bloqueo de fila solo puede bloquear una fila. Si la base de datos donde la condición contiene varias filas de resultados, se informará un error

Por ejemplo, bloqueo de fila en la transacción del marco php-laravel:

try {
    
    
    DB::beginTransaction();
    
    //lockForUpdate()表示加行锁进行更新
    $user = User::where('id',1)->lockForUpdate()->first();		//可行
    $user = User::where('id','>',1)->lockForUpdate()->first();	//这是不行的,会报错
    $user->name = 'test';
    $user->save();
    
    DB::commit();
} catch (Exception $e) {
    
    
    DB::rollback();
    echo $e->getMessage();
}

índice

InnoDBEl bloqueo de fila se logra en el índice, en lugar de en un bloqueo de filas físico. El subtexto es que si el acceso no llega al índice, el bloqueo de fila no se puede usar y degenerará en un bloqueo de tabla.

Operación prohibida

Las siguientes operaciones no se pueden realizar en una transacción con bloqueos de fila

  • Aumentar y disminuir

    Muchos marcos de lenguaje de programación orm proporcionan operaciones continuas de autoincremento y autodecreción, pero no se permiten cosas en las transacciones de bloqueo de filas, como

    User::where(['id'=>1])->increment('stock');
    User::where(['id'=>1])->decrement('stock');
    
  • La declaración de consulta está fuera de la transacción.

    La ejecución de la consulta de datos debe ser posterior al inicio de la transacción, de lo contrario no funcionará

Orden de ejecución

Si las tablas de datos de la operación lockForUpdate en su transacción son tablas A, B y C en orden, entonces el orden en el que actualiza las tablas también debe actualizarse en el orden de las tablas A, B y C;

Si sus dos subprocesos concurrentes con la misma lógica necesitan bloquear la misma tabla de datos respectivamente, el orden de las tablas bloqueadas debe seguir siendo el mismo. Tome un caso inverso: los dos hilos están bloqueados en el orden de A, B, C y B, A, C. Cuando los dos hilos se ejecutan al mismo tiempo, cuando el hilo 1 bloquea la tabla A, necesita bloquear el B tabla, pero la tabla B se ha bloqueado en el subproceso 2; el subproceso 2 también está esperando que el subproceso 1 libere la lista A, por lo que dos subprocesos que se esperan el uno al otro causarán un punto muerto.

grupo de conexiones

En el caso de varios subprocesos, si la conexión de la base de datos usa la misma instancia de conexión, puede ocurrir un error. Esto depende del marco del lenguaje de programación. Algunos marcos ya se han ocupado de ello, pero la mayoría de ellos deben configurarse para tomar efecto. La aplicación del grupo de conexiones reduce en gran medida la ocupación de los recursos de conexión de la base de datos y la velocidad de acceso.

Separación de lectura y escritura (opcional)

Cuando aumenta la presión de escritura de la base de datos, la concentración de lectura y escritura en una base de datos abrumará la base de datos. La separación de lectura y escritura es el establecimiento de múltiples bases de datos distribuidas, que solo se escriben en el servidor de base de datos principal y solo se leen en el servidor de base de datos esclavo. Entre ellos, se pueden implementar varios servidores de base de datos esclavos para leer datos. Orm del lenguaje de programación general admite la configuración de separación de lectura y escritura.

Subbiblioteca y submesa (opcional)

Con el aumento en el acceso al sistema, el QPS es cada vez más alto y la capacidad del disco de la base de datos está aumentando. Generalmente, el QPS del servidor de la base de datos tiene el mejor rendimiento cuando es 800-1200. Cuando excede 2000, el SQL se volverá muy lento y muy lento. Es fácil que las solicitudes lo maten, y la gran cantidad de datos en una sola tabla también hará que la base de datos ejecute SQL muy lentamente. Para hacer frente a este escenario, la idea y la tecnología de sub -se creó la base de datos y la subtabla. Para MySQL, puede considerar el uso de middleware de tablas distribuidas, por ejemplo mycat. Además, si los datos de una sola tabla son demasiado grandes, la velocidad de consulta será muy lenta. Si no se requiere mucho tiempo, considere la posibilidad de crear una tabla de historial.

Usar caché (opcional)

Con el fin de reducir el acceso a la base de datos, la base de datos de caché se puede utilizar para los datos con poca puntualidad para mejorar la velocidad de acceso, como redis y memcacha.

Equilibrio de carga (opcional)

Equilibrio de carga, también conocido como servidor distribuido, si hay una gran cantidad de usuarios y un servidor no puede admitir el servicio, es necesario implementar varios servidores para equilibrar la carga. Por ejemplo, utilice el equilibrio de carga de Aliyun o cree un proxy inverso nginx usted mismo. Además, el servidor de caché también se puede construir de manera distribuida

Errores comunes

Mensaje de error:

ERROR : (2006, 'MySQL server has gone away')

Solución:

Hay un problema de bloqueo en espera en la transacción que hace que la base de datos se bloquee, verifique si hay alguna transacción en su transacción que no se haya confirmado y si se ha revertido antes de regresar, continuar o romper

Mensaje de error:

[ERROR] Uncaught exception 'Illuminate\Database\QueryException': [0]Packets out of order. Expected 15 received 1. Packet size=80

Solución:

Verifique si la declaración de bloqueo de fila en la transacción contiene varias filas, varias filas solo pueden bloquear una fila, es decir, el campo de su condición de consulta debe ser único;

O verifique si el grupo de conexiones de la base de datos está habilitado, este problema también ocurrirá cuando varios subprocesos usen la misma conexión de la base de datos

Mensaje de error:

ERROR 1305(42000) SAVEPOINT trans*** DOES NOT EXIST

Solución:

Algunas transacciones no se han comprometido o revertido, verifique si hay alguna transacción en su transacción que no se haya comprometido, si se ha revertido antes de devolver, continuar o interrumpir.

Supongo que te gusta

Origin blog.csdn.net/C_jian/article/details/107918598
Recomendado
Clasificación