2012-04-28 7 views
7

Estoy construyendo una aplicación que implica un procesamiento de imágenes significativo. Lo estamos construyendo en una casa solar distribuida, con un número arbitrario de máquinas de procesamiento que reciben solicitudes para representar imágenes de un intercambio RabbitMQ.¿Está usando una columna mySQL de una manera sensata para lograr el bloqueo global?

Debido a que una solicitud de una imagen podría entrar mientras que una prestación ya está en proceso, y porque no quieren tener dos servidores render duplicar el trabajo, he creado una columna en la tabla de imágenes MySQL llamado is_rendering como un booleano .

Cuando un servidor de render recibe una solicitud de render se sigue una serie de pasos que se ve así:

  1. Seleccionar para una actualización de la fila de imagen
  2. Si is_rendering == true aborto render solicitud
  3. Establecer is_rendering == true y confirmar la transacción
  4. representar la imagen y guardar la imagen en miniatura en una tienda accesible globalmente
  5. Conjunto is_rendering == false y volver

definitivamente las obras, pero me preocupa que estas actualizaciones de bases de datos frecuentes parecen un poco tonta. Además, estoy considerando el caso límite en el que un servidor de renderización falla en el medio de un renderizado y deja is_rendering == true, lo que impide que esa imagen se represente. La solución que estoy considerando a este problema es cambiar la columna de la is_rendering de un tinyint (1) a un campo de fecha y hora, y el almacenamiento de la fecha de bloqueo como el valor "verdadero", y el valor nulo como "falsa". Una verificación de estado del servicio periódico podría seleccionar todas las filas con un valor de is_rendering más allá de un cierto período de tiempo y liberar el bloqueo en este caso.

Es éste un enfoque cuerdo a este problema, o existen otros enfoques más elegantes que debería considerar?

+0

He implementado el enfoque de bloqueo de campo de fecha y hora varias veces – ilanco

+0

No veo ninguna otra forma de bloqueo, salvo la introducción de dicha columna. Solo yo lo convertiría en un estado, como '0 = not_rendered, 1 = rendering, 2 = rendered'. Pero tal vez malentendí un poco tu flujo de trabajo. Y, por supuesto, el uso de las transacciones 'InnoDB' garantizará que solo una consulta simultánea pueda establecer una imagen en el estado de la representación. –

+0

Si el enfoque en sí es sensato, no lo sé, pero como alternativa a una columna, una tabla 1: 1 'is_render (int)' por separado me parece más manejable. Simplemente agregue/elimine registros y no tendrá que escanear todos los registros de imágenes en la verificación de estado. Sin embargo, si necesita la imagen al mismo tiempo, puede ser un trabajo extra. – mkjeldsen

Respuesta

0

que he ido por delante y cambió la implementación de usar una columna DATETIME.

Yo estaba muy curioso aquí si esto era un mal uso de MySQL en general. Por lo que he investigado, podría ir con algo como ZooKeeper de Hadoop: http://zookeeper.apache.org/doc/r3.1.2/recipes.html o algo así como el sistema Chubby interno de Google. Como esta es solo la primera iteración del servicio, me quedaré con mySQL.

Por lo que he leído aquí, y lo que he leído en línea utilizando mySQL como una forma de producir un bloqueo global no es una idea terrible, y cambiarla a una columna DATETIME, aunque un poco obtusa, es La mejor manera de implementar una política de caducidad para manejar el caso de borde extraño de una máquina que se apaga en el medio del procesamiento de un trabajo.

Conservar en un bloqueo de nivel de transacción sería otro enfoque, pero no tiene sentido cuando un servidor único está ejecutando muchos subprocesos con un pequeño grupo de conexión, ataría la conexión innecesariamente, aunque tiene una función -en caducidad cuando se pierde la conexión del cliente.

0

Estimado Como entiendo su problema, su primer enfoque también es correcto si está siguiendo la regla siguiente: 1) su tipo de tabla es innoDB. 2) Está utilizando transacción en su código. Porque se revertirá si se produce una ruptura durante la actualización.

Al final, el segundo enfoque es también mejor. si no está cumpliendo con mis puntos mencionados

+0

Estoy usando InnoDB. No creo que sea aconsejable conservar la transacción para todo el renderizado. La representación puede tardar más de 30 segundos en completarse y estoy usando la agrupación de conexiones. Aferrarse a la transacción significa que tengo que atar una conexión que podría usarse en otro lugar. – Andrew

Cuestiones relacionadas