9

Otrzymujemy równoległe wywołania zwrotne do naszej aplikacji internetowej od dostawcy i podejrzewamy, że powoduje to utratę aktualizacji, ponieważ są one przetwarzane w tym samym czasie na różnych komputerach.Jak mogę przetwarzać większość zadań równolegle, ale serializować podzbiór?

Musimy serializować przetwarzanie tych wywołań wtedy i tylko wtedy, gdy mają one wpływ na ten sam rekord użytkownika.

Mój kolega zaproponował strumień AWS Kinesis, w którym używamy ID użytkownika jako klucza partycji. Chodzi o to, że ten sam klucz partycji umieszcza rekord w tym samym fragmencie. Każdy fragment jest przetwarzany przez tylko jednego pracownika i nie będzie problemów z współbieżnością. Z założenia zagwarantujemy, że rekordy należące do tego samego użytkownika nie będą przetwarzane równolegle. To rozwiązanie skaluje i rozwiązuje problem, ale przywróci nam przynajmniej sprint.

Staramy się znaleźć rozwiązanie, które możemy wdrożyć szybciej.

Inne rozwiązania Omówiliśmy dotąd:

  1. Wystarczy opóźnić przetwarzanie wywołań zwrotnych, potencjalnie przez losową ilość czasu. W tym scenariuszu nadal jest (choć mniej prawdopodobne), że kilku pracowników przetwarza zadania dla tego samego użytkownika w tym samym czasie.
  2. Dowolny system kolejkowania ma wadę, że jesteśmy albo ograniczeni do jednego pracownika, albo do przetwarzania równoległego ryzyka, albo takiego samego, jak opisano w (1).

Jesteśmy na stosie Rails z MySQL i preferujemy AWS dla naszych rozwiązań.

Czy istnieje rozwiązanie tego problemu, które przyniesie szybsze wyniki niż przejście na Kinesis?

Odpowiedz

0

Po prostu szukasz nazwanych blokad rozproszonych, aby można było wymusić przetwarzanie szeregowe.

Jeśli korzystasz z AWS, możesz przesłać rekord do DynamoDB z każdym identyfikatorem klienta.

Za każdym razem, gdy otrzymasz rekord do przetworzenia, wykonaj spójny odczyt (patrz sekcja współbieżności tutaj: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/APISummary.html).

Jeśli zapis jest obecny, dodaj do niego swoją wiadomość (spójny zapis). Czy przetwarzany proces wykonuje odczyt po jego zakończeniu, a jeśli istnieją komunikaty dołączone do rekordu dynamo, przetwarzaj je szeregowo. Na koniec usuń rekord.

Możliwe jest, że dostaniesz warunki wyścigu, więc będziesz musiał zrobić back-off i spróbować ponownie. Nie wiem, jaka jest twoja objętość, ale Dynamo jest dość szybkie, więc szanse na trafienie tego więcej niż kilka razy są niewielkie. Jeśli nie powiedzie się zbyt wiele razy, może być konieczne zrzucenie rzeczy do kolejki błędów w celu oczyszczenia, ale jest to mało prawdopodobne. Zwłaszcza jeśli twój wolumen pozwala ci na rozważenie rozwiązań takich jak dowolne opóźnienie w przetwarzaniu wiadomości.

0

Tylko niektóre wejście teoretyczna:

Jeśli masz wywołania zwrotne, które są technicznie niezależny potrzebujesz semantycznej identyfikator, który oznacza je jako zależne lub niezależne i identyfikatorem sekwencji, który zapewnia kolejność wykonywania. Identyfikator użytkownika jest niewystarczający. Jak zapewnić prawidłową kolejność wykonywania baz danych dla równoległych żądań internetowych jednego użytkownika?

Jeśli masz unikatowe identyfikatory transakcji, możesz zastosować poziomy izolacji, takie jak serializacja. Ale w tym przypadku nie jesteś odporny na "twoje" utracone aktualizacje. Zdarzą się również podczas korzystania z serializacji, chyba że nie masz numeru porządkowego (wersji) i mechanizmu blokującego.

Pamiętaj, aby mówić o "nadpisywaniu niezatwierdzonych danych", jeśli masz na myśli "utracone aktualizacje", aby uniknąć nieporozumień. Będzie to obsługiwane przy co najmniej poziomie izolacji "odczyt powtarzalny".

Powiązane problemy