Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Kolejka w PHP,
Prph
post
Post #1





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Dawno mnie tu nie było (IMG:style_emoticons/default/smile.gif)

Forumowicze, problem z kolejką w PHP. System, który tworzę przetwarza dane co minutę (z CRONa). Niestety uruchomienie pojedynczego procesu np, przetwarzaj.php nie kończy się w 1 minucie, ponieważ przetwarzanie danych może trwać np. 2 mninuty dla pojedynczego rekordu bazy danych, a rekordów jest np. 20. Teoretycznie szeregowe uruchomienie przetwarzania zajmie więc 40 min. Każdy przetwarzaj.pho bierze z bazy zatem 1 rekord i tylko taki mieli.

Moje pytanie: w jaki sposób napisać kolejkę, która poprawnie przetworzy takie dane? Wywołać z crona 20x ten sam przetwarzaj.php? Zanim proces zacznie wykonywać swoją pracę, ustawia na rekordzie bazy, że jest on przetwarzany, więc inny proces weźmie kolejne dane.

Spotkaliście się z podobnym problemem, macie pomysły?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


To może inaczej, co jest powodem tak długiego przetwarzania pojedynczego rekordu? Bo jeżeli są to jakieś ciężkie operacje wykorzystujące procesor albo dysk, wykonanie równoległych przetwarzań wcale nie musi przyspieszyć ich ogólnego czasu wykonywania. Zaś jeżeli jest to spowodowane przykładowo oczekiwaniem na pobranie danych z sieci to już jak najbardziej miałoby to sens.

1. Zamiast odpalać co minutę zadanie w Cronie, utwórz sobie daemona(y) (System_Daemon).
2. Generalnie utworzenie w bazie danych kolumny status (awaiting, processing, processed) będzie niewystarczające. Dwa (lub nawet więcej) procesy mogłyby pobrać ten sam wiersz nim którykolwiek z nich zdąży zmienić jego status z awaiting na processing. Tutaj trzeba by było albo zablokować na chwilę tabelę dla odczytu:
  1. LOCK TABLE tbl_name READ;
  2. SELECT ... WHERE STATUS = 'awaiting' LIMIT 1;
  3. UPDATE ... SET STATUS = 'processing' WHERE id = ...;
  4. UNLOCK TABLE tbl_name;

3. Jeżeli masz możliwość nie pisz tego w PHP, tylko w czymś co wspiera współbieżność (ot, chociażby Java) - znacznie uprości Ci to życie.

EDIT:
Ewentualnie zamiast ręcznego bawienia się w blokowanie tabeli skorzystaj z transakcji, i tak zawsze trzeba, na odpowiednim poziomie izolacji - tutaj potrzebny byłby chyba aż poziom serializable.

Ten post edytował Crozin 23.05.2012, 07:38:35
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 4.10.2025 - 00:45