2012-05-21 24 views
15

Esta pregunta ya ha sido publicado en los foros de AWS, pero aún sigue sin respuesta https://forums.aws.amazon.com/thread.jspa?threadID=94589escrituras ridículamente lento a Amazon DynamoDB (API PHP)

Estoy tratando de llevar a cabo un proceso de carga inicial de una larga lista de artículos cortos (aproximadamente 120 millones de ellos), para recuperarlos más tarde mediante una clave única, y parece ser un caso perfecto para DynamoDb.

Sin embargo, mi velocidad de escritura corriente es muy lenta (aproximadamente 8-9 segundos por cada 100 escrituras) que hace que la carga inicial casi imposible (que tomaría cerca de 3 meses con el ritmo actual).

He leído foros de AWS en busca de una respuesta y ya probado las siguientes cosas:

  1. Cambié de sencillo "put_item" llama a las escrituras de lotes de 25 artículos (de tamaño recomendado de escritura por lotes max), y cada uno de mis artículos es más pequeño que 1Kb (que también se recomienda). Es muy típico incluso que 25 de mis artículos tengan menos de 1 KB también, pero no está garantizado (y no debe importar de todos modos, ya que entiendo que solo el tamaño de un solo elemento es importante para DynamoDB).

  2. Utilizo la región de la UE recientemente introducida (estoy en el Reino Unido) especificando su punto de entrada directamente llamando a set_region ('dynamodb.eu-west-1.amazonaws.com') ya que aparentemente no hay otra manera para hacer eso en PHP API. La consola de AWS muestra que la tabla está en una región adecuada, por lo que funciona.

  3. tengo SSL desactivado llamando disable_ssl() (ganando 1 segundo por 100 registros).

Aún así, un conjunto de prueba de 100 elementos (4 llamadas de escritura por lotes para 25 elementos) nunca lleva menos de 8 segundos para indexar. Cada solicitud de escritura por lotes tarda unos 2 segundos, por lo que no es como si la primera fuera instantánea y las solicitudes consiguientes son lentas.

Mi mesa rendimiento es aprovisionado 100 de escritura y 100 unidades de lectura que debería ser suficiente hasta el momento (tratado de límites más altos, así por si acaso, sin efecto).

También sé que hay algunos gastos en la serialización de solicitudes así que probablemente pueda usar la cola para "acumular" mis solicitudes, pero ¿eso realmente importa tanto para batch_writes? Y no creo que ese sea el problema porque incluso una sola solicitud lleva demasiado tiempo.

Descubrí que algunas personas modifican los encabezados de cURL ("Esperar:" particularmente) en la API para acelerar las solicitudes, pero no creo que sea una manera adecuada, y también la API se ha actualizado desde ese momento. consejo fue publicado.

El servidor en el que se ejecuta mi aplicación también está bien - He leído que a veces la carga de la CPU se dispara, pero en mi caso todo está bien, es solo la solicitud de la red lo que lleva demasiado tiempo.

estoy atascado ahora - ¿hay algo más que pueda probar? Por favor, siéntase libre de pedir más información si no he proporcionado suficiente.

Hay otros temas recientes, al parecer por el mismo problema, here (sin respuesta hasta el momento sin embargo).

Este servicio se supone que es ultra-rápido, así que estoy muy desconcertado por ese problema en el principio.

+0

Parece que necesita una base de datos relacional como SQL Server. Simplemente 'SqlBulkCopy' los datos en. SQL Server es escala web, si lo estás preguntando. –

+0

No necesito DB relacional aquí (es un índice plano sin relaciones reales) pero sí, estoy pensando en retirarme a mySQL o Solr si no tengo otras opciones. Sin embargo, por el momento sigo interesado en entender qué pasa con ese enfoque. – Yuriy

+0

Su publicación en el foro ha sido respondida a: https://forums.aws.amazon.com/thread.jspa?messageID=365597#365597 –

Respuesta

10

Si está cargando desde su máquina local, la velocidad se verá afectada por todo tipo de tráfico/firewall, etc. entre usted y los servidores. Si llamo a DynamoDB, cada solicitud toma 0.3 de segundo simplemente por el tiempo de viajar a/desde Australia.

Mi sugerencia sería crear usted mismo una instancia EC2 (servidor) con PHP, cargue el script y todos los archivos en el servidor EC2 como un bloque y luego realice el volcado desde allí. El servidor EC2 shuold tiene la velocidad impresionante del servidor DynamoDB.

Si no está seguro de configurar EC2 con LAMP usted mismo, entonces tienen un nuevo servicio "Elastic Beanstalk" que puede hacerlo todo por usted. Cuando haya completado la carga, simplemente queme el servidor y esperemos que pueda hacer todo eso dentro de su estructura de precios "gratuita" :)

No resuelve problemas de conectividad a largo plazo, pero reducirá los tres meses ¡subir!

+0

Gracias por su respuesta. No probé Beanstalk, pero estaba tratando de usar Elastic MapReduce en su lugar - todavía hay un problema aquí. He creado otra pregunta para: http://stackoverflow.com/questions/10683136/amazon-elastic-mapreduce-mass-insert- from-s3-to-dynamodb-is-incredible-slow – Yuriy

+0

Como mencionas incluso desde Australia, todavía está por debajo de 0.5 segundos, así que no pueden ser 2 segundos para mí de Londres a Irlanda. Nuestra conexión es muy buena, hasta ahora lo descarto. – Yuriy

+0

2 segundos es increíblemente lento, pero puede ser simple como un firewall en el servidor haciendo algunas "comprobaciones", o un firewall en el enrutador haciendo otras "comprobaciones". (O, siendo cínico, una forma de que Amzon te empuje a lo largo de EC2, ¿no?) Como dije, no es una solución a largo plazo, solo algo para hacer la carga. Si quieres mantenerlo localmente, ¿por qué no miras a Cassandra o Mongo? Pero si usa Amazon y paga, solo cambie el servidor allí; los mantendrá contentos :) – Robbie

1

Intentaría una carga multiproceso para aumentar el rendimiento. Tal vez agregue subprocesos de uno en uno y vea si el rendimiento aumenta linealmente. Como prueba, puede ejecutar dos de sus cargadores actuales al mismo tiempo y ver si ambos funcionan a la velocidad que está observando ahora.

0

Tuve un gran éxito utilizando el php sdk utilizando el método por lotes en la clase AmazonDynamoDB. Pude ejecutar aproximadamente 50 elementos por segundo desde una instancia de EC2. El método funciona haciendo cola de solicitudes hasta que se llame al método de envío, momento en el que ejecuta múltiples solicitudes simultáneas utilizando Curl. Aquí hay algunas buenas referencias:

http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/LoadData_PHP.html

http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/LowLevelPHPItemOperationsExample.html

creo que también se puede utilizar COLMENA sql usando elástico MapReduce para carga masiva de datos desde un archivo CSV. EMR puede usar múltiples máquinas para repartir la carga de trabajo y lograr una alta concurrencia.

+1

Gracias, Jonathan, pero he vuelto a escribir la funcionalidad para use un índice local. Respecto a HIVE, también hay un problema cuando se trata de DynamoDB que ha sido confirmado por Amazon (vea mi otra pregunta y mi respuesta auto-publicada): http://stackoverflow.com/questions/10683136/amazon-elástico-mapreduce-mass-insert-from-s3-to-dynamodb-is-increíblemente lento – Yuriy