sql >> Base de Datos >  >> RDS >> Mysql

La mejor manera de manejar los problemas de concurrencia

La respuesta de Donnie (sondeo) es probablemente su mejor opción:simple y funciona. Cubrirá casi todos los casos (es poco probable que una simple búsqueda de PK perjudique el rendimiento, incluso en un sitio muy popular).

Para completar, y si desea evitar el sondeo, puede usar un push-model . Hay varias formas descritas en el artículo de Wikipedia. Si puede mantener un caché de escritura simultánea (cada vez que actualiza el registro, actualiza el caché), entonces puede eliminar casi por completo la carga de la base de datos.

Sin embargo, no use una columna de marca de tiempo "last_updated". Las ediciones en el mismo segundo no son desconocidas. Puede salirse con la suya si agrega información adicional (servidor que realizó la actualización, dirección remota, puerto, etc.) para asegurarse de que, si llegan dos solicitudes en el mismo segundo, al mismo servidor, podría detectar la diferencia. Sin embargo, si necesita esa precisión, también puede usar un campo de revisión único (no necesariamente tiene que ser un número entero incremental, solo único dentro de la vida útil de ese registro).

Alguien mencionó conexiones persistentes:esto reduciría el costo de configuración de las consultas de sondeo (cada conexión consume recursos en la base de datos y la máquina host, naturalmente). Mantendría una sola conexión (o la menor cantidad posible) abierta todo el tiempo (o el mayor tiempo posible) y la usaría (en combinación con el almacenamiento en caché y la memorización, si lo desea).

Finalmente, hay declaraciones SQL que le permiten agregar una condición en ACTUALIZAR o INSERTAR. Mi SQl está realmente oxidado, pero creo que es algo así como UPDATE ... WHERE ... . Para igualar este nivel de protección, tendría que hacer su propio bloqueo de filas antes de enviar la actualización (y todo el manejo de errores y la limpieza que podría implicar). Es poco probable que necesites esto; Solo lo menciono para que esté completo.

Editar:

Su solución suena bien (marcas de tiempo de caché, solicitudes de sondeo de proxy a otro servidor). El único cambio que haría es actualizar las marcas de tiempo en caché en cada guardado. Esto mantendrá el caché más fresco. También verificaría la marca de tiempo directamente desde la base de datos al guardar para evitar que se guarde a escondidas debido a datos de caché obsoletos.

Si usa APC para el almacenamiento en caché, entonces un segundo servidor HTTP no tiene sentido; tendría que ejecutarlo en la misma máquina (APC usa memoria compartida). La misma máquina física estaría haciendo el trabajo, pero con la sobrecarga adicional de un segundo servidor HTTP. Si desea descargar las solicitudes de sondeo a un segundo servidor (lighttpd, en su caso), entonces sería mejor configurar lightttpd frente a Apache en una segunda máquina física y usar un servidor de almacenamiento en caché compartido (memcache) para que el El servidor lighttpd puede leer las marcas de tiempo en caché y Apache puede actualizar las marcas de tiempo en caché. La razón para poner lighttpd delante de Apache es, si la mayoría de las solicitudes son solicitudes de sondeo, para evitar el uso pesado del proceso de Apache.

Probablemente no necesites un segundo servidor, en realidad. Apache debería poder manejar las solicitudes adicionales. Si no puede, entonces revisaría su configuración (específicamente las directivas que controlan cuántos procesos de trabajo ejecuta y cuántas solicitudes pueden manejar antes de ser eliminados).