2012-05-21 7 views
15

Kwestia ta została już wysłana na forach AWS, ale jeszcze pozostaje bez odpowiedzi https://forums.aws.amazon.com/thread.jspa?threadID=94589Śmiesznie powolne zapisy do Amazon DynamoDB (PHP API)

Próbuję wykonać wstępną przesyłanie długiej listy krótkich pozycji (około 120 milionów z nich), aby pobrać je później za pomocą unikalnego klucza, i wydaje się, że jest to doskonały przypadek dla DynamoDb.

Jednak moja aktualna szybkość zapisu jest bardzo powolna (około 8-9 sekund na 100 zapisów), co sprawia, że ​​początkowe przesłanie jest prawie niemożliwe (zajęłoby to około 3 miesięcy z bieżącym tempem).

Czytałem fora AWS wyglądające na odpowiedź i już wypróbowany następujące rzeczy:

  1. przeszedłem z singlem „put_item” Połączenia do zapisu partii o 25 pozycji (zalecana maksymalna wielkość partii zapisu), a każdy z moich przedmiotów jest mniejszy niż 1Kb (który jest również zalecany). To bardzo typowe, nawet w przypadku 25 moich produktów, które również mają mniej niż 1Kb, ale nie jest to gwarantowane (i nie powinno to mieć znaczenia, ponieważ rozumiem, że dla DynamoDB ważna jest tylko wielkość pojedynczego elementu).

  2. Używam ostatnio wprowadzonego regionu UE (jestem w Wielkiej Brytanii), określając punkt wejścia bezpośrednio przez wywołanie set_region ("dynamodb.eu-west-1.amazonaws.com"), ponieważ najwyraźniej nie ma innego sposobu zrobić to w PHP API. Konsola AWS pokazuje, że tabela w odpowiednim regionie, tak że działa.

  3. Wyłączyłem SSL, wywołując funkcję disable_ssl() (uzyskując 1 sekundę na 100 rekordów).

Mimo to zestaw testowy zawierający 100 pozycji (4 zadania zapisu partii na 25 pozycji) indeksowanie nie trwa nigdy dłużej niż 8 sekund. Każde żądanie zapisu wsadowego trwa około 2 sekund, więc nie jest tak, że pierwsze jest natychmiastowe, a następnie żądania są powolne.

Moją tabelą wydajności jest 100 zapisów i 100 odczytów jednostek, które powinny wystarczyć do tej pory (wypróbowane wyższe limity, a także na wszelki wypadek, bez efektu).

Wiem również, że są pewne wydatki na serializację żądania, więc prawdopodobnie mogę użyć kolejki do "akumulacji" moich żądań, ale czy to naprawdę ma znaczenie dla skryptów wsadowych? I nie sądzę, że to jest problem, ponieważ nawet jedna prośba trwa zbyt długo.

Zauważyłem, że niektórzy ludzie modyfikują nagłówki cURL ("Expect:" w szczególności) w API, aby przyspieszyć żądania, ale nie sądzę, że to jest właściwy sposób, a także API zostało zaktualizowane od tego czasu porady zostały zamieszczone.

Serwer, na którym działa moja aplikacja, jest również w porządku - czytałem, że czasami obciążenie procesora przechodzi przez dach, ale w moim przypadku wszystko jest w porządku, to tylko żądanie sieciowe trwa zbyt długo.

Utknąłem teraz - czy jest coś jeszcze, co mogę spróbować? Jeśli nie dostarczyłem wystarczającej ilości informacji, poproś o więcej informacji.

Istnieją inne ostatnie wątki, podobno na ten sam problem, here (brak odpowiedzi na razie).

Ta usługa ma być bardzo szybka, więc jestem bardzo zaskoczony tym problemem na samym początku.

+0

Wygląda na to, że potrzebujesz relacyjnej bazy danych, takiej jak SQL Server. Po prostu 'SqlBulkCopy' dane. SQL Server jest skalowalna, jeśli pytasz. –

+0

Nie potrzebuję tutaj relacyjnej bazy danych (jest to płaski indeks bez rzeczywistych relacji), ale tak, myślę o wycofaniu się do mySQL lub Solr, jeśli nie mam innych opcji. Jednak na razie wciąż chcę zrozumieć, co jest nie tak z tym podejściem. – Yuriy

+0

Twój wpis na forum został odpowiedział na: https://forums.aws.amazon.com/thread.jspa?messageID=365597#365597 –

Odpowiedz

10

Jeśli przesyłasz z lokalnego komputera, na szybkość będą wpływać różnego rodzaju ruch/zapora sieciowa itp. Między Tobą a serwerami. Jeśli zadzwonię do DynamoDB, każde żądanie zajmuje 0,3 sekundy po prostu ze względu na czas podróży do/z Australii.

Moja sugestia to stworzenie sobie instancji EC2 (serwera) z PHP, przesłanie skryptu i wszystkich plików do serwera EC2 jako bloku, a następnie zrób zrzut z tego miejsca. Serwer serwera EC2 ma niesamowitą prędkość na serwerze DynamoDB.

Jeśli nie masz pewności, jak skonfigurować EC2 z lampą LAMPA, to otrzymasz nową usługę "Elastic Beanstalk", która może zrobić wszystko za Ciebie. Po zakończeniu przesyłania wystarczy spalić serwer - i miejmy nadzieję, że możesz to wszystko zrobić w ramach struktury cenowej "wolnej warstwy" :)

Nie rozwiązuje długoterminowych problemów z łącznością, ale zmniejszy trzy miesiące Przekazać plik!

+0

Dzięki za odpowiedź. Nie próbowałem Beanstalk, ale zamiast tego próbowałem użyć Elastic MapReduce - nadal jest tu problem. Stworzyłem kolejne pytanie: http://stackoverflow.com/questions/10683136/amazon-elastic-mapreduce-mass-insert- od-s3-do-dynamodb-jest-niewiarygodnie powolny – Yuriy

+0

Tak jak wspomniałeś nawet z Australii, wciąż jest ci mniej niż 0,5 s, więc nie mogę być 2 sekundy dla mnie z Londynu do Irlandii. Nasze połączenie jest bardzo dobre, jak na razie to wykluczam. – Yuriy

+0

2 sekundy jest niesamowicie powolne, ale może to być proste, jak zapora ogniowa na serwerze, wykonująca pewne "kontrole" lub zapora ogniowa routera wykonująca inne "kontrole". (Czy może być cynicznym sposobem na to, żeby Amzon popchnął Cię na drugą stronę EC2 ?!) Jak już powiedziałem - to nie jest długoterminowe rozwiązanie, po prostu coś, co trzeba zrobić, aby przesłać. Jeśli chcesz zachować ją lokalnie, dlaczego nie spojrzeć na Cassandrę lub Mongo? Ale jeśli korzystasz z Amazon i płacisz, po prostu przenieś tam serwer - to będzie je zadowolić :) – Robbie

1

Chciałbym spróbować przesłać wielowątkowe, aby zwiększyć przepustowość. Może dodawać wątki po jednym na raz i sprawdzać, czy przepustowość rośnie liniowo. Jako test możesz po prostu uruchomić dwa z obecnych ładowarek w tym samym czasie i sprawdzić, czy obaj poruszają się z prędkością, którą obserwujesz teraz.

0

Osiągnąłem dobry sukces, używając php sdk przy użyciu metody wsadowej w klasie AmazonDynamoDB. Byłem w stanie uruchomić około 50 przedmiotów na sekundę z instancji EC2. Metoda polega na kolejkowaniu żądań do czasu wywołania metody wysyłania, w którym to momencie wykonuje wiele jednoczesnych żądań za pomocą Curl. Oto kilka dobrych odniesienia:

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

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

myślę, że można także użyć ula SQL przy użyciu Elastic mapę Zmniejsz do masowych ładowanie danych z pliku CSV. EMR może wykorzystywać wiele maszyn do rozłożenia obciążenia pracą i osiągnięcia wysokiej współbieżności.

+1

Dzięki, Jonathan, ale napisałem od nowa funkcje do użyj lokalnego indeksu. Jeśli chodzi o HIVE, istnieje również problem, jeśli chodzi o DynamoDB, który został potwierdzony przez Amazon (zobacz moje inne pytanie i moją własną odpowiedź): http://stackoverflow.com/questions/10683136/amazon-elastic-mapreduce-mass-insert-from-s3-to-dynamodb-is-incredibly-slow – Yuriy