• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Bazy danych, odczyt wierszy przez wiele procesów

Object Storage Arubacloud
0 głosów
256 wizyt
pytanie zadane 18 kwietnia 2023 w SQL, bazy danych przez Grzegorz123 Nowicjusz (150 p.)
zamknięte 20 kwietnia 2023 przez Grzegorz123

Hej. 

Jest sobie baza danych, w niej tabela z wieloma rekordami. Każdy z tych rekordów musi być przetworzony przez logikę biznesową (coś w rodzaju tasku do wykonania). Każdy wiersz ma status boolean o nazwie loaded, informujący czy został on już przetworzony (w postępujących iteracjach pobieramy w chunkach tylko te wiersze które mają status false).

Aby było szybciej, serwis przetwarzający dane odpalony jest w kilku instancjach. Czyli mamy kilka procesów pracujących na tej samej bazie danych. 

Oczywisty jest fakt, że nie chce by te same wiersze były przetwarzane jednocześnie przez kilka instancji. No więc stawiam transakcje, domyślna (REPEATABLE READ) wydaje się być ok.

Z tym, że sam odczyt wierszy nie sprawia, że są "dirty", i za nim po poprawnym wykonaniu logiki, status loaded zmienimy na true, to już inne instancje pobiorą te same wiersze... trzeba więc coś pozmieniać w pobranych danych na samym początku, myślę np. o dodaniu enuma o trzech wartościach (unloaded, pending, loaded). Wtedy w pętli będą pobierane tylko wiersze które nie zostały jeszcze przetworzone ani nie są w tej chwili przetwarzane.

Co sądzicie o tym? A może są jakieś jeszcze lepsze sposoby/wzorce na to? Używam jc. MySQL.

Dzięki i pozdrawiam

komentarz zamknięcia: Temat wyczerpany
1
komentarz 18 kwietnia 2023 przez tkz Nałogowiec (42,000 p.)
Osobiście zrobiłbym osobny serwis na zasadzie master i workers. Master dostaje dostęp do bazy, rozsyła do workerów zadania. Masz 100%, że nic się nie zdubluje bez żadnych vendor locków. Przy założeniu, ze dopisanie się opłaca, bo możliwość zawsze jest.

 Ewentualnie lecieć jak w przypadku wektoryzacji kontenerów. Pobierasz co X elementów z bazy, oczywiście tutaj też dochodzi system spójności.
komentarz 19 kwietnia 2023 przez Grzegorz123 Nowicjusz (150 p.)
Dzięki za myśl, chyba właśnie tego szukam. Faktycznie w moim przypadku lepiej to jakoś zorkiestrować, niż po prostu odpalać kilka niezależnych kopii.

1 odpowiedź

+1 głos
odpowiedź 18 kwietnia 2023 przez Wiciorny Ekspert (269,590 p.)
wybrane 20 kwietnia 2023 przez Grzegorz123
 
Najlepsza

Sugeruje ustawić różna logikę transakcji w zależności od operacji :
Aktualizacje powinny byc atomowe i  transakcja powinna przyjąć poziom SERIALIZABLE - wtedy masz gwarancje braku problemów, nieco kosztem wydajności ( z tym, że natura aktualizacji jest taka, że nie są one częste jak odczyty).
Odczyty i tu zależy: jeśli aktualizowany jest tylko 1 rekord po kluczu nie ma możliwości wystąpienia odczytu fantomowego, jeśli jednak jest ich wiele, to tak naprwadę odczyt fantomowy zwróci większą ilość danych rekordów dla tego samego zapytania, ale to zazwyczaj nie stanowi dużego problemu, nie zaburza to spójności takiej jak brudny odczyt, który zwraca dane niespójne, albo dane wycofane w dirty reads. 

Stąd odczyty mogłyby zostać repeatable_read, wtedy  pobrane dane są blokowane, więc kolejne odczyty zwracają te same dane, możliwe anomalie: phantoms

Jeśli odczyt ma zmienić "flagę w bazie i w twoich danych", to jest to duży problem w twojej aplikacji i to jest działanie niepoprawne, odczyty powinny być czysty i bez side effects.

Jeśli twoja aplikacji skupia się na strategii zorientowanej na wysoką współbieżność:
To propagacja transakcji powinna być zawsze REQUIRED_NEW i odpowiednio dobrany poziom izolacji z racji tego, ze będzie mógł się on zmieniać z wywołaniem nowej transakcji ,

Głównym założeniem tej strategii transakcji jest skrócenie zakresu transakcji, tak aby zminimalizować blokady w bazie danych przy zachowaniu atomowości dla danego żądania klienta

komentarz 19 kwietnia 2023 przez Grzegorz123 Nowicjusz (150 p.)

Dzięki za odpowiedź, trochę się dowiedziałem nowych rzeczy :)

Stąd odczyty mogłyby zostać repeatable_read, wtedy  pobrane dane są blokowane, więc kolejne odczyty zwracają te same dane

Mi akurat nie chodziło o to, żeby zwracać niezmienione dane. Chciałem podzielić przetwarzanie danych w tabeli na kilka wątków (lub osobnych procesów). Np. każdy wątek bierze sobie 10 losowych nieprzetworzonych wierszy, przetwarza je i ustawia status loaded na true. To samo robi to N innych wątków. Nie chcemy by pobierały te same rekordy, więc select nie powinien zwracać tych aktualnie przetwarzanych. By to osiągnąć myślałem właście o dodaniu tego enuma i wartości pending.

Ale jak teraz o tym myśle, to najlepiej chyba przenieść tą kontrole na stronę skryptów, i zrobić jak @tkz zasugerował.

1
komentarz 19 kwietnia 2023 przez Wiciorny Ekspert (269,590 p.)

. Np. każdy wątek bierze sobie 10 losowych nieprzetworzonych wierszy, przetwarza je i ustawia status loaded na true. To samo robi to N innych wątków. Nie chcemy by pobierały te same rekordy, więc select nie powinien zwracać tych aktualnie przetwarzanych.

to wszystko jasne, słuchaj to się sprowadza to problemu "Wzajemnego wykluczania" , aby np. dzielić partyjnie przetwarzanie na odpowiednie procesy bez duplikacji.

Np. mógłbyś definiować pule egzekutorów dla danego procesu i uruchamiać wszystkie kolejno w sekwencji albo równolegle indeksując od ilości egzekutorów w kolejce np 1-10,  11-20 itd. 
Bo takie coś realizuje Wzajemne Wykluczanie (w skrócie często nazywane mutex, z ang. mutual exclusion) są używane w przetwarzaniu współbieżnym w celu uniknięcia równoczesnego użycia wspólnego zasób.

Ustawiłbym aby procesy mogły działać np co 0... n, rekordów a każde kolejne n... n+m itd 
wtedy masz gwarancje, co i jak będzie przetwarzane. 
Dodatkowo jeśli dany proces nie bedzie musiał przetwarzać danych z racji flagi już ustawionej, to spokojnie nie bedzie nic blokował i zużywał cpu 

Podobne pytania

0 głosów
0 odpowiedzi 95 wizyt
pytanie zadane 1 listopada 2020 w SQL, bazy danych przez blowing_rocket Nowicjusz (170 p.)
0 głosów
0 odpowiedzi 424 wizyt
0 głosów
0 odpowiedzi 499 wizyt
pytanie zadane 22 listopada 2018 w SQL, bazy danych przez Maikel11 Początkujący (470 p.)

92,544 zapytań

141,387 odpowiedzi

319,503 komentarzy

61,930 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...