Przejdź do głównej treści

Odśmiecanie danych na stronie WWW: porównanie podejść

Odśmiecanie danych na stronie WWW: porównanie podejść

Strony internetowe w trakcie działania generują różnego rodzaju dane tymczasowe — cache, sesje, tymczasowe pliki, wpisy w bazie danych itd. Choć są one przydatne w kontekście wydajności i działania aplikacji, z czasem mogą urosnąć do niekontrolowanych rozmiarów. Odśmiecanie (ang. garbage collection) tego typu danych jest niezbędne, by utrzymać sprawność, szybkość i bezpieczeństwo aplikacji webowej.

W tym artykule porównamy dwa popularne podejścia do odśmiecania danych:

  • Losowe odśmiecanie przy okazji żądań użytkowników
  • Regularne zadania CRON

Co należy odśmiecać?

W zależności od systemu i aplikacji, typowe elementy do odśmiecania to:

  • Cache aplikacji (pliki lub dane w bazie)
  • Sesje użytkowników, które wygasły
  • Tymczasowe pliki (np. uploady, pliki robocze)
  • Logi starsze niż określony czas
  • Dane w bazie, np. stare tokeny, wygasłe linki, niepotwierdzone konta

Podejście 1: Losowe odśmiecanie na podstawie requestów

Jak to działa?

Mechanizm losowy polega na tym, że z pewnym prawdopodobieństwem (np. 1 na 100 requestów) serwer wykonuje odśmiecanie. Takie podejście często można spotkać np. w PHP (session.gc_probability i session.gc_divisor).

Zalety:

  • Brak potrzeby ustawiania dodatkowych zadań CRON
  • Zadziała automatycznie nawet na serwerach bez dostępu do CRON
  • Proste do implementacji

Wady:

  • Nierówna częstotliwość — zależna od ruchu na stronie
  • W mało ruchliwych serwisach odśmiecanie może być zbyt rzadkie
  • W czasie jednego requestu może dojść do opóźnienia użytkownika

Przykład ustawień:

Jeśli chcesz uruchamiać odśmiecanie średnio co 100 żądań:

define('GC_CHANCE', 100);
if (mt_rand(1, GC_CHANCE) === 1) {
    garbage_collect();
}

Dla większych serwisów o dużym ruchu warto zmniejszyć częstotliwość, np. 1 na 1000 requestów. Dla mniejszych — nawet 1 na 10.

Podejście 2: CRON — zadania cykliczne

Jak to działa?

CRON to systemowy harmonogram zadań, który może cyklicznie uruchamiać skrypt odśmiecania np. raz dziennie lub co godzinę.

Zalety:

  • Niezależne od ruchu — działa nawet przy zerowym ruchu
  • Stabilna, przewidywalna częstotliwość
  • Może wykonywać bardziej zasobożerne czyszczenie (np. indeksowanie, backupy)

Wady:

  • Wymaga dostępu do CRON lub narzędzia typu scheduler (np. Laravel Scheduler)
  • Może nie być dostępne na niektórych hostingach współdzielonych
  • Może wymagać dodatkowego monitoringu działania

Przykład wpisu w CRON (raz dziennie o 3:00):

0 3 * * * /usr/bin/php /var/www/html/artisan schedule:run >> /var/log/cron.log 2>&1

Co wybrać?

Kryterium Losowe requesty Zadanie CRON
Łatwość wdrożenia Bardzo proste Wymaga dostępu do CRON
Skuteczność Zależna od ruchu Zawsze regularna
Obciążenie serwera Może wpływać na usera Zależne od harmonogramu
Stabilność działania Niska przy małym ruchu Wysoka

Rekomendacje

  • Dla prostych stron, blogów, landing page’y – losowe czyszczenie może być wystarczające, np. 1 na 50–100 requestów.
  • Dla większych serwisów i aplikacji – lepszym wyborem będzie CRON, z częstotliwością:

    • Sesje, cache – co godzinę lub co 6 godzin
    • Logi, pliki tymczasowe, tokeny – raz dziennie
    • Backupy, indeksowanie – co tydzień

Emulacja zadań CRON

Aby emulować działanie zadania CRON, bazując na ruchu użytkowników, możesz stworzyć system, który uruchamia akcję odśmiecania mniej więcej co godzinę, bez użycia systemowego CRON-a.

Poniżej przedstawiam pełne rozwiązanie, które:

  • zapisuje ostatni czas wykonania odśmiecania,
  • sprawdza przy każdym żądaniu, czy minęła określona ilość czasu (np. godzina),
  • uruchamia czyszczenie tylko raz, bez względu na to, ilu użytkowników wejdzie w tym samym czasie.

Rozwiązanie: Emulacja CRON co godzinę z użyciem pliku blokady (lockfile)

Zalety:

  • Nie wymaga CRON-a
  • Działa przy umiarkowanym ruchu
  • Odśmiecanie wykonuje się tylko raz na określony czas
  • Bezpieczne w środowisku współdzielonym (np. shared hosting)

Przykład w PHP:

function emulate_cron($interval_seconds, callable $task, $lock_file = '/tmp/emulated_cron.lock') {
    $now = time();

    // Sprawdź czy plik istnieje
    if (file_exists($lock_file)) {
        $last_run = (int)file_get_contents($lock_file);

        // Jeśli nie minął jeszcze interwał – nie rób nic
        if (($now - $last_run) < $interval_seconds) {
            return;
        }
    }

    // Próbujemy zapisać nowy czas
    if (file_put_contents($lock_file, $now, LOCK_EX) !== false) {
        // Wykonaj zadanie
        $task();
    }
}

Użycie:

emulate_cron(3600, function() {
    // Wstaw tutaj logikę odśmiecania
    cleanup_sessions();
    cleanup_temp_files();
    cleanup_cache();
});

Uwagi techniczne:

  • LOCK_EX zapobiega konfliktom przy równoczesnym zapisie.
  • Domyślnie plik blokady jest zapisywany w /tmp, ale możesz go przenieść np. do katalogu projektu (__DIR__ . '/cron.lock').
  • Przy niskim ruchu (np. 1 użytkownik co 3 godziny), czyszczenie może uruchamiać się rzadziej — ale nadal z zachowaniem logiki CRON-a.
  • W środowisku z wieloma serwerami (np. load balancer), użyj bazy danych lub systemu wspólnego cache (Redis/Memcached) zamiast pliku.

Bonus: Dostosowanie do liczby użytkowników

Jeśli chcesz uwzględnić częstotliwość odwiedzin, możesz:

  • zwiększyć częstotliwość sprawdzania, np. co 10 minut (600 sekund)
  • lub ustawić odśmiecanie co N requestów i co określony czas:
define('GC_REQUEST_INTERVAL', 500);
define('GC_TIME_INTERVAL', 3600);

session_start();
if (!isset($_SESSION['gc_count'])) {
    $_SESSION['gc_count'] = 0;
}
$_SESSION['gc_count']++;

if ($_SESSION['gc_count'] >= GC_REQUEST_INTERVAL) {
    $_SESSION['gc_count'] = 0;
    emulate_cron(GC_TIME_INTERVAL, function() {
        cleanup_sessions();
    });
}

Jak dynamicznie ustalić optymalną częstotliwość odśmiecania?

Aby dobrać optymalną częstotliwość losowego odśmiecania (np. 1 na N requestów), możemy napisać skrypt w PHP, który:

  1. Zlicza liczbę wejść (żądań) w ciągu ostatniej godziny (lub innego przedziału czasu),
  2. Na tej podstawie wylicza, co ile requestów powinno losowo wywoływać czyszczenie, by zdarzało się to średnio raz na godzinę,
  3. Proponuje wartość N, którą można ustawić np. jako GC_CHANCE.

Wymagania:

  • Prosty zapis requestów do pliku lub bazy (dla trwałości)
  • Brak zewnętrznych bibliotek — czyste PHP

Koncepcja:

Zapisujemy timestamp każdego requestu (np. UNIX time) do pliku (można też użyć bazy danych). Na tej podstawie analizujemy, ile requestów było w ostatniej godzinie, i wyliczamy optymalny współczynnik odśmiecania.

Kod PHP – zapisywanie i analiza requestów

define('HISTORY_FILE', __DIR__ . '/request_log.txt');
define('GC_TARGET_INTERVAL', 3600); // docelowy czas między czyszczeniami (1h)

/**
 * Zarejestruj request
 */
function log_request() {
    $now = time();
    file_put_contents(HISTORY_FILE, $now . PHP_EOL, FILE_APPEND | LOCK_EX);
}

/**
 * Policz requesty z ostatniej godziny i zaproponuj interwał
 */
function get_optimal_gc_chance($target_interval = GC_TARGET_INTERVAL) {
    $now = time();
    $threshold = $now - $target_interval;

    $lines = @file(HISTORY_FILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (!$lines) return 100; // domyślnie

    // Odfiltruj tylko ostatnią godzinę
    $recent = array_filter($lines, function($ts) use ($threshold) {
        return is_numeric($ts) && (int)$ts >= $threshold;
    });

    $request_count = count($recent);
    if ($request_count === 0) return 1; // bardzo mały ruch

    // Chcemy, żeby czyszczenie odbywało się 1x na godzinę
    $chance = (int) ceil($request_count);

    return max($chance, 1);
}

Przykład użycia:

log_request(); // rejestrujemy request

$gc_chance = get_optimal_gc_chance(); // np. zwraca 80

if (mt_rand(1, $gc_chance) === 1) {
    garbage_collect(); // wykonujemy czyszczenie
}

Dodatek: Czyszczenie starego logu (co kilka dni)

Aby plik request_log.txt nie urósł za bardzo, warto co jakiś czas go oczyścić:

function cleanup_request_log($max_age_seconds = 7 * 86400) {
    $now = time();
    $threshold = $now - $max_age_seconds;

    $lines = @file(HISTORY_FILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (!$lines) return;

    $filtered = array_filter($lines, function($ts) use ($threshold) {
        return is_numeric($ts) && (int)$ts >= $threshold;
    });

    file_put_contents(HISTORY_FILE, implode(PHP_EOL, $filtered) . PHP_EOL, LOCK_EX);
}

Pzykład: Jak to działa w praktyce?

  • Jeśli w ciągu godziny było 150 requestów, losowe czyszczenie będzie uruchamiane średnio raz na 150 requestów, czyli raz na godzinę.
  • Jeśli strona ma tylko 10 requestów na godzinę, czyszczenie będzie uruchamiane średnio co 10 requestów, czyli raz na 1–2 dni.

Podsumowanie

Odśmiecanie danych to kluczowy element utrzymania zdrowia aplikacji webowej. Dla mniejszych stron prostsze podejście oparte na losowości może być wystarczające, jednak w przypadku serwisów o większym znaczeniu lub wymaganiach operacyjnych, CRON zapewnia stabilność i przewidywalność działania.

Najlepszym rozwiązaniem bywa często hybryda – podstawowe czyszczenie (np. sesji) za pomocą losowych requestów, a bardziej kompleksowe działania przez CRON.

Emulacja CRON-a przez plik z czasem ostatniego uruchomienia to efektywne rozwiązanie dla środowisk bez dostępu do systemowego CRON-a. Jest deterministyczne, odporne na powielanie i działa niezależnie od liczby requestów — tak długo, jak strona ma umiarkowany ruch.

Dynamiczna optymalizacja dopasowuje częstotliwość losowego czyszczenia do ruchu na stronie, osiągając docelowy interwał (np. godzinny). Działa na każdej stronie z umiarkowanym ruchem i nie wymaga CRON-a. W razie potrzeby możemy przenieść logi do bazy danych lub Redis dla większej skali.

19 maja 2025 5

Kategorie

Tagi

php

Ocena wpisu

Dziękujemy!
()

Powiązane wpisy


Używam plików cookie

Moja strona wykorzystuje niezbędne pliki cookie i local storage, które są konieczne do prawidłowego działania strony i świadczenia usług. Możesz dowiedzieć się więcej w mojej polityce prywatności.