php database-design sqlite couchdb distributed

Anatomía de un sistema distribuido en PHP



database-design sqlite (7)

Creo que vas en la dirección correcta con un distribuidor de trabajo maestro y trabajadores. Me gustaría que se comunicaran a través de HTTP.

Elegiría C, C ++ o Java para ser clientes, ya que tienen capacidades para ejecutar scripts (execvp en C, System.Desktop.something en Java). Jobs podría ser el nombre de un script y argumentos para ese script. Puede hacer que los clientes devuelvan un estado en los trabajos. Si las tareas fallaron, podría volver a intentarlas. Puede hacer que los clientes busquen trabajos cada minuto (o cada x segundos y que el servidor resuelva los trabajos)

PHP funcionaría para el servidor.

MySQL funcionaría bien para la base de datos. Me gustaría hacer dos marcas de tiempo: comienzo y final. En el servidor, buscaría CUÁNDO SEGUNDOS == 0

Tengo un problema que me está dificultando tratar de encontrar la solución ideal y, para explicarlo mejor, voy a exponer mi escenario aquí.

Tengo un servidor que recibirá pedidos de varios clientes. Cada cliente enviará un conjunto de tareas recurrentes que se deben ejecutar a intervalos específicos, por ejemplo: el cliente A envía la tarea AA que debe ejecutarse cada minuto entre 2009-12-31 y 2010-12-31 ; entonces, si mi matemática es correcta, se trata de 525 600 operaciones en un año, dado más clientes y tareas, no sería factible dejar que el servidor procese todas estas tareas, así que se me ocurrió la idea de las máquinas de trabajo. El servidor se desarrollará en PHP.

Las máquinas de los trabajadores son simplemente computadoras baratas basadas en Windows que alojaré en mi casa o en mi lugar de trabajo, cada trabajador tendrá una conexión de Internet dedicada ( con direcciones IP dinámicas ) y un UPS para evitar cortes de energía. Cada trabajador también consultará el servidor cada 30 segundos más o menos a través de llamadas al servicio web, buscará el próximo trabajo pendiente y lo procesará. Una vez que se completa el trabajo, el trabajador enviará la salida al servidor y solicitará un nuevo trabajo, y así sucesivamente hasta el infinito. Si hay una necesidad de escalar el sistema, simplemente debería configurar un nuevo trabajador y todo debería funcionar a la perfección. El cliente trabajador se desarrollará en PHP o Python.

En cualquier momento, mis clientes deberían poder iniciar sesión en el servidor y verificar el estado de las tareas que ordenaron.

Ahora aquí es donde entra la parte difícil:

  • Debo ser capaz de reconstruir las tareas ya procesadas si por alguna razón el servidor deja de funcionar.
  • Los trabajadores no son específicos del cliente, un trabajador debe procesar trabajos para un número determinado de clientes.

Tengo algunas dudas con respecto al diseño general de la base de datos y qué tecnologías usar.

Originalmente pensé en usar varias bases de datos SQLite y unirlas en el servidor, pero no puedo entender cómo agruparé los clientes para generar los informes de trabajo .

En realidad, nunca he trabajado con ninguna de las siguientes tecnologías: memcached , CouchDB , Hadoop y todo lo demás, pero me gustaría saber si alguno de estos es adecuado para mi problema, y ​​si es así, lo que recomiendas para un novato es "computación distribuida" (¿o es esto paralelo?) como yo. Tenga en cuenta que los trabajadores tienen direcciones IP dinámicas.

Como dije antes, también estoy teniendo problemas con el diseño general de la base de datos, en parte porque todavía no he elegido ningún DBMS R (D) en particular, pero un problema que tengo y creo que es agnóstico para el DBMS que elijo está relacionado al sistema de colas ... ¿Debería precalcular todas las marcas de tiempo absolutas a un trabajo específico y tener un gran conjunto de marcas de tiempo , ejecutarlas y marcarlas como completadas en orden ascendente o debería tener un sistema más inteligente como " cuando el módulo de marca de tiempo 60 = = 0 -> ejecutar ". El problema con este sistema "inteligente" es que algunos trabajos no se ejecutarán para que así sea, porque algunos trabajadores podrían estar esperando sin hacer nada mientras otros están sobrecargados. ¿Que sugieres?

PD: No estoy seguro de si el título y las etiquetas de esta pregunta reflejan adecuadamente mi problema y lo que trato de hacer; si no, edite en consecuencia.

¡Gracias por tu contribución!

@timdev:

  1. La entrada será una cadena muy pequeña codificada en JSON, la salida también será una cadena contenida en JSON pero un poco más grande (del orden de 1-5 KB).
  2. La salida se computará utilizando varios recursos disponibles de la Web, por lo que el cuello de botella principal probablemente sea el ancho de banda. Las escrituras de la base de datos también pueden ser una, dependiendo del R (D) DBMS.

En lugar de reinventar la rueda de espera a través de SQL, puede usar un sistema de mensajería como RabbitMQ o ActiveMQ como núcleo de su sistema. Cada uno de estos sistemas proporciona el protocolo AMQP y tiene colas respaldadas en el disco duro. En el servidor tiene una aplicación que inserta trabajos nuevos en una cola de "trabajador" de acuerdo con su programa y otro que escribe los resultados de una cola de "resultado" en la base de datos (o actúa de otra manera).

Todos los trabajadores se conectan a RabbitMQ o ActiveMQ. Sacan el trabajo de la cola de trabajo, hacen el trabajo y colocan la respuesta en otra fila. Después de que hayan hecho eso, ACK la solicitud de trabajo original para decir "está hecho". Si un trabajador abandona su conexión, el trabajo se restaurará en la cola para que otro trabajador pueda hacerlo.

Todo lo que no sean las colas (descripciones de trabajo, detalles del cliente, trabajo completado) puede almacenarse en la base de datos. Pero cualquier cosa en tiempo real debería colocarse en otro lado. En mi propio trabajo estoy transmitiendo datos de uso de energía en vivo y tener a mucha gente golpeando la base de datos para sondear es una mala idea. He escrito sobre datos en vivo en mi sistema .


Evitaría sqlite para este tipo de tarea, aunque es una base de datos maravillosa para pequeñas aplicaciones, no maneja muy bien la concurrencia, tiene solo una estrategia de bloqueo que es bloquear toda la base de datos y mantenerla bloqueada hasta una transacción sincrónica Esta completo.

Considere Postgres, que tiene concurrencia de fuerza industrial y administración de bloqueos, y puede manejar múltiples transacciones simultáneas muy bien.

¡También esto suena como un trabajo para hacer cola! Si estuvieras en el mundo de Java, recomendaría una arquitectura basada en JMS para tu solución. Hay un proyecto ''dropr'' para hacer algo similar en php pero es bastante nuevo, por lo que podría no ser adecuado para su proyecto.

Cualquiera que sea la tecnología que use, debe optar por una solución de "mercado libre" donde los hilos de trabajo consuman "trabajos" disponibles tan rápido como puedan, en lugar de una "economía de comando" donde un proceso central asigna tareas a los trabajadores elegidos.


La configuración de un servidor maestro y varios trabajadores se ve bien en su caso.

En el servidor maestro , instalaría MySQL (la versión InnoDB de Percona es estable y rápida ) en la réplica master-master, por lo que no tendrá un solo punto de falla. El servidor maestro alojará una API que los trabajadores utilizarán cada N segundos. El maestro verificará si hay un trabajo disponible, si es así debe señalar que el trabajo ha sido asignado al trabajador X y devolver la entrada correspondiente al trabajador (todo esto a través de HTTP). Además, aquí puede almacenar todos los archivos de script de los trabajadores.

Sobre los trabajadores , le sugiero encarecidamente que instale una distribución de Linux. En Linux es más fácil configurar tareas programadas y, en general, creo que es más apropiado para el trabajo. Con Linux, incluso puede crear una imagen en vivo de cd o iso con un trabajador perfectamente configurado e instalarlo de manera rápida y sencilla en todas las máquinas que desee. Luego configure un trabajo cron que se sincronice con el servidor maestro para actualizar / modificar los scripts. De esta manera, usted cambiará los archivos en un solo lugar (el servidor maestro) y todos los trabajadores recibirán las actualizaciones.

En esta configuración, no le importan las IP ni la cantidad de trabajadores porque los trabajadores se están conectando al maestro, no viceversa.

El trabajo del trabajador es bastante fácil: solicite un trabajo a la API, hágalo, envíe el resultado por API. Enjuague y repita :-)


Parece que estás a punto de recrear a Gearman . Aquí está la introducción para Gearman:

Gearman proporciona un marco de aplicación genérico para extender el trabajo a otras máquinas o procesos que son más adecuados para hacer el trabajo. Le permite trabajar en paralelo, cargar el proceso de equilibrio y llamar funciones entre idiomas. Se puede usar en una variedad de aplicaciones, desde sitios web de alta disponibilidad hasta el transporte de eventos de replicación de bases de datos. En otras palabras, es el sistema nervioso el que comunica el procesamiento distribuido.

Puede escribir tanto su cliente como el código del empleado de back-end en PHP.

Responda su pregunta sobre un Servidor Gearman compilado para Windows: no creo que esté disponible en un paquete ordenado y preconstruido para Windows. Gearman sigue siendo un proyecto bastante joven y es posible que no hayan madurado hasta el punto de producir distribuciones listas para ejecutar para Windows.

Los empleados de Sun / MySQL Eric Day y Brian Aker dieron un tutorial para Gearman en OSCON en julio de 2009, pero sus diapositivas solo mencionan los paquetes de Linux.

Aquí hay un enlace al proyecto Perl CPAN Testers, que indica que Gearman-Server se puede construir en Win32 usando el compilador C de Microsoft ( cl.exe ), y pasa las pruebas: http://www.nntp.perl.org/group/perl.cpan.testers/2009/10/msg5521569.html Pero supongo que tienes que descargar el código fuente y compilarlo tú mismo.


Una solución más simple sería tener una única base de datos con múltiples nodos de php conectados. Si usa un RDBMS adecuado (MSql + InnoDB lo hará), puede hacer que una tabla actúe como una cola. Luego, cada trabajador retirará las tareas de eso para trabajar y lo volverá a escribir en la base de datos al finalizar, usando transacciones y bloqueos para sincronizar. Esto depende un poco del tamaño de los datos de entrada / salida. Si es grande, este puede no ser el mejor esquema.


Gearman parece ser el candidato perfecto para este escenario, es posible que desee virtualizar sus máquinas de Windows a varios nodos de trabajadores por máquina, dependiendo de la cantidad de potencia informática que necesite.

Además, el sistema de cola persistente en Gearman evita que los trabajos se pierdan cuando un trabajador o el servidor de engranaje se cuelga. Después de reiniciar el servicio, la cola simplemente continúa donde se quedó antes del bloqueo / reinicio, no tiene que encargarse de todo esto en su aplicación y eso es una gran ventaja y ahorra mucho tiempo / código.

Encontrar una solución personalizada podría funcionar, pero las ventajas de Gearman, especialmente la cola persistente, me parecen que esta podría ser la mejor solución para usted en este momento. Aunque no sé sobre un binario de Windows para Gearman, creo que debería ser posible.