2010-11-21 16 views
11

Después de hablar con un amigo mío de Google, me gustaría implementar algún tipo de modelo de trabajo/trabajador para actualizar mi conjunto de datos.¿Debo aprender/usar MapReduce, o algún otro tipo de paralelización para esta tarea?

Este conjunto de datos refleja los datos de un servicio de terceros, por lo tanto, para hacer la actualización, debo hacer varias llamadas remotas a su API. Creo que se pasará mucho tiempo esperando respuestas de este servicio de terceros. Me gustaría acelerar las cosas, y hacer un mejor uso de mis horas de cómputo, paralelizando estas solicitudes y manteniendo muchas de ellas abiertas a la vez, mientras esperan sus respuestas individuales.

Antes de explicar mi conjunto de datos específico y entrar en el problema, me gustaría aclarar qué respuestas Busco:

  1. Es este un flujo que se adapta bien a la paralelización con MapReduce?
  2. Si , ¿sería rentable ejecutar en el módulo mapreduce de Amazon, que factura por hora, y redondea la hora cuando el trabajo está completo? (No estoy seguro de qué es exactamente como un "Trabajo", así que no sé exactamente cómo se me cobrará)
  3. Si no, ¿Hay algún otro sistema/patrón que deba usar? y ¿Hay alguna biblioteca que me ayude a hacer esto en python (en AWS, use EC2 + EBS)?
  4. ¿Hay algún problema que vea con la forma en que diseñé este flujo de trabajo?

Ok, ahora en los detalles:

El conjunto de datos consta de los usuarios que tienen los elementos favoritos y que siguen a otros usuarios. El objetivo es poder actualizar la cola de cada usuario: la lista de elementos que el usuario verá cuando carguen la página, en función de los elementos favoritos de los usuarios que ella sigue. Pero, antes de poder analizar los datos y actualizar la cola de un usuario, necesito asegurarme de tener la información más actualizada, que es donde entran las llamadas API.

Hay dos llamadas que puedo hacer :

  • conseguir que los usuarios seguido - que devuelve todos los usuarios que están siendo seguidos por el usuario solicita, y
  • obtener los elementos favoritos - que devuelve todos los elementos favoritos del usuario solicitado.

Después llamo get seguido usuarios para el usuario se actualiza, es necesario que actualice los elementos favoritos de cada usuario está siguiendo. Solo cuando se devuelven todos los favoritos para todos los usuarios que se están siguiendo puedo comenzar a procesar la cola para ese usuario original. Este flujo se parece a:

Updating UserX's Queue

Trabajo en este flujo incluyen:

  • iniciar la actualización de cola para el usuario - arranca el proceso por ir a buscar los usuarios, seguido por el usuario se actualiza constantemente, almacenándolos, y luego creando Obtiene trabajos de Favoritos para cada usuario.
  • Obtener Favoritos para el usuario - Solicita, y almacena, una lista de favoritos para el usuario especificado, del servicio de terceros.
  • Calcular nueva cola para el usuario - Procesa una nueva cola, ahora que se han recuperado todos los datos, y luego almacena los resultados en una memoria caché utilizada por la capa de aplicación.

Así, de nuevo, mis preguntas son:

  1. Es este un flujo que se adapta bien a la paralelización con MapReduce? No sé si me permitiría comenzar el proceso para UserX, buscar todos los datos relacionados y volver al procesamiento de la cola de UserX solo cuando todo haya terminado.
  2. Si , ¿sería rentable ejecutar en el módulo mapreduce de Amazon, que factura por hora, y redondea la hora cuando el trabajo está completo? ¿Hay un límite en la cantidad de "hilos" que puedo esperar para las solicitudes API abiertas si utilizo su módulo?
  3. Si no, ¿Hay algún otro sistema/patrón que deba usar? y ¿Hay alguna biblioteca que me ayude a hacer esto en python (en AWS, use EC2 + EBS?)?
  4. ¿Hay algún problema que vea con la forma en que diseñé este flujo de trabajo?

Gracias por leer, espero poder hablar con todos ustedes.

Editar, en respuesta a JimR:

Gracias por una respuesta sólida. En mis lecturas desde que escribí la pregunta original, me he alejado de usar MapReduce. Todavía no he decidido con certeza cómo quiero construir esto, pero estoy empezando a sentir que MapReduce es mejor para distribuir/paralelizar la carga de cómputo cuando realmente estoy buscando paralelizar las solicitudes HTTP.

Lo que habría sido mi tarea de "reducir", la parte que toma todos los datos obtenidos y los comprime en resultados, no es tan intensivo desde el punto de vista informático. Estoy bastante seguro de que terminará siendo una gran consulta SQL que se ejecuta por uno o dos segundos por usuario.

Por lo tanto, lo que yo estoy inclinando hacia es:

  • Un no-MapReduce de empleo/trabajador modelo, escrito en Python . Un amigo mío en Google me enseñó a aprender Python para esto, ya que es muy bajo y se escala bien.
  • Uso de Amazon EC2 como capa de cálculo. Creo que esto significa que también necesito un segmento de EBS para almacenar mi base de datos.
  • Posiblemente utilizando la cola de mensajes simple de Amazon thingy. Parece que este tercer widget de amazon está diseñado para realizar un seguimiento de las colas de trabajos, mover los resultados de una tarea a las entradas de otra y gestionar con elegancia las tareas fallidas. Es muy barato. Puede valer la pena implementarlo en lugar de un sistema personalizado de cola de trabajos.
+0

He utilizado el motor de aplicaciones de Google para solicitudes altamente paralelas y manejo casi en tiempo real de este tipo de problema. MapReduce tuvo una sobrecarga de ciclo de trabajo y arranque mucho mayor de lo que yo estaba buscando. – kevpie

+0

Interesante. Sé que el motor de aplicaciones puede usar Python, que es lo que he estado buscando para escribir estos trabajos, pero no tengo claro de qué otra manera usaría GAE para esto. No estoy familiarizado con el funcionamiento de GAE, ni con cómo expresar este problema, así que no puedo encontrar mis respuestas. ¿Tienes algún otro recurso que debería investigar aquí? ¡Gracias por el consejo! –

+0

De hecho, escribí un proceso de python que utilizaba los hilos y las colas para hacer solicitudes web paralelas y el procesamiento de datos. Funcionó bien, pero no estaba "completamente versado" en la programación o subprocesos de python, para hacerlo realmente confiable o funcionar bien. Después de mucho googlear, algo de frustración y otras tareas que necesitaban prioridad, abandoné el trabajo. Podría recogerlo de nuevo. Llegué a conclusiones similares sobre el trabajo con MapReduce, ya que no estaría aprovechando nada más que el paralelismo incorporado en hadoop. De todos modos, si quieres chatear más sobre enfoques y soluciones, lmk! –

Respuesta

1

Parece que vamos con Node.js y la biblioteca de control de flujo Seq. Fue muy fácil pasar de mi mapa/diagrama de flujo del proceso a una parte del código, y ahora solo es cuestión de completar el código para enlazar con las API correctas.

Gracias por las respuestas, fueron de gran ayuda para encontrar la solución que estaba buscando.

0

Estoy trabajando con un problema similar que necesito resolver. También estaba mirando MapReduce y usando el servicio Elastic MapReduce de Amazon.

Estoy bastante convencido de que MapReduce funcionará para este problema. La implementación es donde me cuelgo, porque no estoy seguro de que mi reductor necesite hacer algo.

Responderé a sus preguntas ya que entiendo su (y mi) problema, y ​​espero que ayude.

  1. Sí, creo que va bien. Podría ver cómo aprovechar la opción de pasos múltiples del servicio Elastic MapReduce. Podría usar 1 Paso para buscar a las personas que un usuario está siguiendo, y otro paso para compilar una lista de pistas para cada uno de esos seguidores, y el reductor para ese 2do paso probablemente sea el que construya el caché.

  2. Depende de qué tan grande es su conjunto de datos y con qué frecuencia lo ejecutará. Es difícil de decir sin saber qué tan grande es el conjunto de datos (o va a obtener) si será rentable o no. Inicialmente, probablemente sea bastante rentable, ya que no tendrá que administrar su propio clúster hadoop, ni tendrá que pagar las instancias de EC2 (suponiendo que sea eso lo que usa) para estar activo todo el tiempo. Una vez que llegue al punto en el que realmente está procesando estos datos durante un período prolongado de tiempo, es probable que tenga menos sentido usar el servicio MapReduce de Amazon, ya que constantemente tendrá nodos en línea todo el tiempo.

Un trabajo es básicamente su tarea de MapReduce. Puede consistir en varios pasos (cada tarea de MapReduce es un paso). Una vez que se hayan procesado sus datos y se hayan completado todos los pasos, su trabajo habrá finalizado. Así que efectivamente está pagando por el tiempo de CPU para cada nodo en el clúster de Hadoop. por lo tanto, T * n donde T es el tiempo (en horas) que lleva procesar sus datos, y n es la cantidad de nodos que le indica a Amazon que active.

Espero que esto ayude, buena suerte. Me gustaría saber cómo terminas implementando tus Mappers y Reductores, ya que estoy resolviendo un problema muy similar y no estoy seguro de que mi enfoque sea realmente el mejor.

+0

Buena respuesta. Publiqué una respuesta en el artículo principal que explica a qué me inclino y por qué. ¡Espero que ayude y buena suerte! –

5

El trabajo que describe probablemente sea adecuado para una cola o una combinación de una cola y un servidor de trabajos. Sin duda, podría funcionar como un conjunto de pasos de MapReduce.

Para un servidor de trabajo, recomiendo mirar a Gearman. La documentación no es impresionante, pero las presentaciones hacen un excelente trabajo al documentarla, y el módulo de Python también se explica por sí mismo.

Básicamente, usted crea funciones en el servidor de trabajos, y los clientes llaman a estas funciones a través de una API. Las funciones se pueden llamar de forma sincrónica o asíncrona. En su ejemplo, es probable que desee agregar asíncronamente el trabajo "Iniciar actualización". Eso hará todas las tareas preparatorias, y luego llamará asincrónicamente al trabajo "Obtener usuarios seguidos". Ese trabajo buscará a los usuarios y luego llamará al trabajo "Actualizar usuarios seguidos". Esto enviará todos los trabajos "Obtener favoritos para usuarios A" y amigos juntos de una sola vez, y esperará de forma sincrónica el resultado de todos ellos. Cuando todos hayan regresado, invocará el trabajo "Calcular nueva cola".

Este enfoque de solo trabajo-servidor inicialmente será un poco menos robusto, ya que garantizar que maneje los errores y cualquier servidor inactivo y persistencia correctamente será divertido.

Para una cola, SQS es una elección obvia. Es sólido como una roca, y tiene un acceso muy rápido desde EC2, y es económico. Y es mucho más fácil de configurar y mantener que otras colas cuando recién comienza.

Básicamente, colocará un mensaje en la cola, al igual que enviaría un trabajo al servidor de trabajos anterior, excepto que probablemente no haga nada de forma síncrona.En lugar de hacer que los "Obtener favoritos para el usuario A", etc., se llamen de forma síncrona, los hará de forma asíncrona y luego aparecerá un mensaje que le indicará si todos ellos han finalizado. Necesitará algún tipo de persistencia (una base de datos SQL con la que esté familiarizado, o SimpleDB de Amazon si quiere usar AWS por completo) para rastrear si el trabajo está terminado: no puede verificar el progreso de un trabajo en SQS (aunque puedes en otras colas). El mensaje que verifica si están todos terminados hará la comprobación; si no están completos, no haga nada, y luego el mensaje se reintentará en unos minutos (en función de visibility_timeout). De lo contrario, puede poner el siguiente mensaje en la cola.

Este enfoque solo de cola debe ser robusto, suponiendo que no consuma mensajes de cola por error sin hacer el trabajo. Cometer un error así es difícil de hacer con SQS; realmente tienes que intentarlo. No utilice colas o protocolos que consuman automáticamente: si se produce un error, es posible que no pueda garantizar que vuelva a colocar un mensaje de reemplazo en la cola.

Una combinación de cola y servidor de trabajos puede ser útil en este caso. Puede salirse con la suya sin tener una tienda de persistencia para verificar el progreso del trabajo: el servidor de trabajos le permitirá seguir el progreso del trabajo. Su mensaje "obtener favoritos para los usuarios" podría colocar todos los trabajos "obtener favoritos para usuario/B/C" en el servidor de trabajo. A continuación, coloque el mensaje "compruebe que todos los favoritos están llegando" en la cola con una lista de tareas que deben completarse (y suficiente información para reiniciar cualquier trabajo que desaparezca misteriosamente).

de puntos de bonificación:

Hacer esto como MapReduce debería ser bastante fácil.

La entrada de su primer trabajo será una lista de todos sus usuarios. El mapa se llevará a cada usuario, obtener los usuarios seguidos, y las líneas de salida para cada usuario y su usuario seguido:

"UserX" "UserA" 
"UserX" "UserB" 
"UserX" "UserC" 

Una identidad reducen paso será dejar este inalterada. Esto formará la entrada del segundo trabajo. El mapa para el segundo trabajo obtendrá los favoritos para cada línea (puede usar memcached para evitar la búsqueda de favoritos para UserX/UserA combo y UserY/UserA a través de la API) y generar una línea para cada favorito:

"UserX" "UserA" "Favourite1" 
"UserX" "UserA" "Favourite2" 
"UserX" "UserA" "Favourite3" 
"UserX" "UserB" "Favourite4" 

La reducir el paso para este trabajo va a convertir esto en:

"UserX" [("UserA", "Favourite1"), ("UserA", "Favourite2"), ("UserA", "Favourite3"), ("UserB", "Favourite4")] 

en este punto, es posible que tenga otro trabajo MapReduce para actualizar su base de datos para cada usuario con estos valores, o es posible que pueda utilizar algunos de las herramientas relacionadas con Hadoop como Pig, Hive y HBase para administrar su base de datos por usted.

Recomendaría usar Cloudera's Distribution para los comandos de gestión ec2 de Hadoop para crear y desmontar su clúster Hadoop en EC2 (sus AMI tienen Python configurado en ellos), y usar algo como Dumbo (en PyPI) para crear su MapReduce trabajos, ya que le permite probar sus trabajos de MapReduce en su máquina local/dev sin acceso a Hadoop.

¡Buena suerte!

+1

Gracias por una respuesta muy completa. Voy a tener que sentarme y pasar por esto correctamente. –

Cuestiones relacionadas