2009-01-10 19 views
7

Estoy trabajando en el diseño de una aplicación de múltiples niveles en Perl y me pregunto cuáles son los pros y los contras de los diversos mecanismos de IPC disponibles para mí. Estoy tratando de manejar datos de tamaño moderado, típicamente unas pocas docenas de kilobytes pero hasta un par de megabytes, y la carga es bastante ligera, a lo sumo un par de cientos de solicitudes por minuto.¿Cuál es el mejor mecanismo de IPC para datos de tamaño mediano en Perl?

Mi principal preocupación es el mantenimiento y el rendimiento (en ese orden). No creo que tenga que escalar a más de un servidor, o puerto fuera de nuestra plataforma principal (RHEL), pero supongo que es algo a considerar.

puedo pensar en las siguientes opciones:

  • archivos temporales - simplista, probablemente la peor opción en términos de requisitos de velocidad y almacenamiento
  • sockets de dominio UNIX - No es portátil, no escalable
  • internet sockets - portátiles, escalables
  • Tubos - (?) portátil, no escalable

Considérant Creo que necesito aprender más acerca de la escalabilidad y la portabilidad. ¿Cuál es la mejor opción y por qué? Por favor comente si necesita información adicional.


EDIT: Voy a tratar de dar más detalle en respuesta a ysth's questions(advertencia, muro de texto a continuación):

  • son lectores/escritores en una relación uno a uno, o algo más complicado?
  • ¿Qué le quiere pasar al escritor si el lector ya no está allí o no está ocupado?
  • ¿Y viceversa?
  • ¿Qué otra información tiene sobre su uso deseado?

En este punto, estoy contemplando un enfoque de tres niveles, pero no estoy seguro de cuántos procesos tendré en cada nivel. Creo que necesita tener más procesos hacia el lado izquierdo y menos hacia la derecha, pero tal vez debería tener el mismo número en todos los ámbitos:

 
.---------.   .----------.  .-------. 
| Request | -----> | Business | -----> | Data | 
| Manager | <----- | Logic | <----- | Layer | 
`---------'   `----------'  `-------' 

Estos nombres siguen siendo genéricos y probablemente no lo hará en la implementación en estas formas.

El administrador de solicitud es responsable de escuchar solicitudes de diferentes interfaces, por ejemplo, solicitudes web y CLI (donde el tiempo de respuesta es importante) y correo electrónico (donde el tiempo de respuesta es menos importante). Realiza el registro y gestiona las respuestas a las solicitudes (que se procesan en un formato apropiado para el tipo de solicitud).

envía datos acerca de la solicitud a la lógica de negocio que realiza el registro, autorización, dependiendo de las reglas de negocio, etc.

la lógica de negocio (si es necesario) solicita a continuación datos de la capa de datos , que puede hablar con (la mayoría de las veces) la base de datos MySQL interna o alguna otra fuente de datos fuera del control de nuestro equipo (por ejemplo, los servidores LDAP principales de nuestra organización o nuestra base de datos de información de empleados de DB2, etc.). En su mayoría, se trata simplemente de un contenedor que formatea los datos de manera uniforme para que se pueda manejar con mayor facilidad en la lógica comercial.

La información vuelve al gestor de solicitudes para su presentación.

Si, cuando los datos fluyen hacia la derecha, el lector está ocupado, para las solicitudes interactivas me gustaría simplemente esperar un período de tiempo adecuado, y devolver un error de tiempo de espera si no obtengo acceso en ese cantidad de tiempo (por ejemplo, "Intente de nuevo más tarde"). Para las solicitudes no interactivas (por ejemplo, correo electrónico), el sistema de sondeo simplemente puede salir e intentar nuevamente en la siguiente invocación (que probablemente será una vez cada 1-3 minutos).

Cuando los datos fluyen en la otra dirección, no debe haber ninguna situación de espera. Si uno de los procesos ha muerto al intentar regresar a la izquierda, todo lo que puedo hacer es iniciar sesión y salir.

De todos modos, eso fue bastante detallado, y como todavía estoy en el diseño inicial, probablemente aún tenga algunas ideas confusas. Algo de lo que he mencionado probablemente sea tangencial al problema de cuyo sistema IPC usar. Estoy abierto a otras sugerencias sobre el diseño, pero estaba tratando de mantener la pregunta limitada en su alcance (Por ejemplo, tal vez debería considerar el colapso en dos niveles, que es mucho más simple para IPC). ¿Cuáles son tus pensamientos?

Respuesta

4

Los archivos temporales (y cosas relacionadas, como una región de memoria compartida), son probablemente una mala apuesta. Si alguna vez desea ejecutar su servidor en una máquina y sus clientes en otra, tendrá que volver a escribir su aplicación. Si elige alguna de las otras opciones, al menos la semántica es esencialmente la misma, si necesita cambiar entre ellas en una fecha posterior.

Mi único consejo real, sin embargo, es no escribir esto usted mismo. En el lado del servidor, debe usar POE (o Coro, etc.), en lugar de hacerlo en el socket select. Además, si su interfaz va a ser RPC-ish, use algo como JSON-RPC-Common/ del CPAN.

Finalmente, existe IPC :: PubSub, que podría funcionar para usted.

+0

Muchas gracias! Estaba ho ping para conectarse con algunos recursos útiles de Perl. –

4

Los archivos temporales tienen otros problemas además de eso. Creo que los calcetines de Internet son realmente la mejor opción. Están bien documentados y, como dices, son escalables y portátiles. Incluso si ese no es un requisito básico, lo obtiene casi gratis. Los enchufes son bastante fáciles de manejar, una vez más hay una gran cantidad de documentación. Puede construir su mecanismo y protocolo de intercambio de datos en una biblioteca y nunca más tener que volver a mirarlo.

3

Los sockets de dominio de UNIX son portátiles en todos los equipos. No es menos portátil que las tuberías. También es más eficiente que los enchufes IP.

De todos modos, te perdiste algunas opciones, memoria compartida, por ejemplo. Algunos agregarían bases de datos a esa lista, pero diría que es una solución bastante pesada.

Las colas de mensajes también serían una posibilidad, aunque tendría que cambiar una opción de kernel para manejar mensajes tan grandes.De lo contrario, tienen una interfaz ideal para muchas cosas, y en mi humilde opinión están muy infrautilizadas.

En general, estoy de acuerdo en que utilizar una solución existente es mejor que construir algunas cosas propias. No sé los detalles de su problema, pero le sugiero que consulte la sección IPC de CPAN

+0

Gracias! Tienes razón, la memoria compartida y las colas de mensajes ni siquiera se me ocurrieron. –

6

Si no está seguro de sus requisitos exactos en este momento, intente pensar en una interfaz simple que puede codificar, que cualquier implementación de IPC (ya sean archivos temporales, TCP/IP o lo que sea) debe ser compatible. A continuación, puede elegir un sabor IPC en particular (comenzaría con lo que sea más fácil y/o más fácil de depurar, probablemente archivos temporales) e implementar la interfaz con eso. Si eso resulta demasiado lento, implemente la interfaz usando, p. TCP/IP. En realidad, la implementación de la interfaz no requiere mucho trabajo ya que básicamente solo reenviarás las llamadas a alguna biblioteca existente.

El punto es que tiene una tarea de alto nivel para realizar ("transmitir datos del programa A al programa B") que es más o menos independiente de los detalles de cómo se realiza. Al establecer una interfaz y codificarlo, usted aísla el programa principal de los cambios en caso de que necesite cambiar la implementación.

Tenga en cuenta que no necesita utilizar ningún mecanismo de lenguaje Perl pesado para capitalizar la idea de tener una interfaz. Simplemente podría tener, por ejemplo, 3 paquetes diferentes (para archivos temporales, TCP/IP, sockets de dominio Unix), cada uno de los cuales exporta el mismo conjunto de métodos. Elegir qué implementación desea usar en su programa principal equivale a elegir qué módulo va al use.

2

Hay tantas opciones diferentes porque la mayoría de ellas son mejores para algunos casos en particular, pero realmente no ha dado ninguna información que identifique su caso.

¿Los lectores/escritores están en una relación uno a uno, o algo más complicado? ¿Qué le quiere pasar al escritor si el lector ya no está allí o ocupado? ¿Y viceversa? ¿Qué otra información tiene sobre su uso deseado?

+0

Gracias por responder, he agregado más detalles a la pregunta. –

2

Para solicitudes "interactivas" (mantener la conexión abierta mientras se espera una respuesta (asíncrona o no): HTTP + JSON. JSON::XS es increíblemente rápido. Todo el mundo puede hablar HTTP y es fácil cargar el saldo, depurar,. ..

Para solicitudes en cola ("por favor hacer esto, gracias!"):. Beanstalkd y Beanstalk::Client Serialice las peticiones en la cola planta de frijoles con JSON

Thrift también podría ser digno de mirar en función de su aplicación..

Cuestiones relacionadas