@harrasteblogi JUURI NYT
--:--

Tilaa uutiskirje

Saat tuoreimmat 10 uusinta artikkelia kerran viikossa sähköpostiisi.

Tilaa uutiskirje

Miten rakentaa oma cache-layer WordPressiinWordPressissä monet suorituskykyongelmat johtuvat siitä, että sama data lasketaan tai haetaan tietokannasta yhä uudelleen jokaisella requestilla. Vaikka WordPress tarjoaa valmiita cache-mekanismeja kuten object cachen ja transientit, suuremmissa projekteissa tarvitaan usein oma cache-layer, joka hallitsee datan välimuistia keskitetysti ja ennustettavasti.

Tiivistelmä
Miksi oma cache-layer kannattaa rakentaa

Monissa WordPress-projekteissa cache-logiikka päätyy hajalleen:...

Cache-layerin perusrakenne

Yksinkertainen arkkitehtuuri:...

Redis cache-layerin pohjana

Paras tuotantoratkaisu:...

Dynamic cache keys

Esimerkki:...

Cache wrapper callback-mallilla

Moderni lähestymistapa:...

Query cache

Yksi tehokkaimmista käyttökohteista....

API cache

Ulkoiset API:t ovat hitaita ja epäluotettavia....

Fragment caching

Voit cachettaa HTML:n....

Cache invalidation

Vaikein osa cache-arkkitehtuuria....

Tag-pohjainen invalidointi

WordPress ei tue tätä natiivisti, mutta voit rakentaa itse....

Cache stampede ongelma

Jos cache vanhenee samaan aikaan:...

Locking-esimerkki

if (get_transient('cache_lock')) { return $stale_data; } Stale-while-revalidate malli Hyvä ratkaisu suurille sivustoille:...

Stale-while-revalidate malli

Hyvä ratkaisu suurille sivustoille:...

Multi-layer cache

Skaalautuva rakenne:...

Admin ja frontend cache erikseen

Älä cacheta kaikkea samalla tavalla....

Cache warming

Voit esigeneroida cachea:...

Yleisimmät virheet

Moderni WordPress cache-layer:...

Paras arkkitehtuuri

Moderni WordPress cache-layer:...

Yhteenveto

Oma cache-layer tekee WordPress-sovelluksesta huomattavasti nopeamman, vakaamman ja helpommin ylläpidettävän. Kun välimuistilogiikka keskitetään yhteen kerrokseen, suorituskykyoptimointi muuttuu hallittavaksi eikä cache-ratkaisu hajaannu ympäri projektia....

Hyvin rakennettu cache-layer voi:

  • vähentää database-kuormaa merkittävästi
  • nopeuttaa API-vastauksia
  • pienentää TTFB-aikaa
  • vähentää ulkoisia HTTP-kutsuja
  • parantaa skaalautuvuutta

Miksi oma cache-layer kannattaa rakentaa

Monissa WordPress-projekteissa cache-logiikka päätyy hajalleen:

get_transient(...)
set_transient(...)

satunnaisesti eri tiedostoihin.

Ongelmat:

  • cache invalidation unohtuu
  • key naming muuttuu sekavaksi
  • TTL-arvot vaihtelevat hallitsemattomasti
  • ei keskitettyä logiikkaa
  • vaikea debugata

Cache-layer ratkaisee tämän keskittämällä kaiken välimuistilogiikan yhteen järjestelmään.

Cache-layerin perusrakenne

Yksinkertainen arkkitehtuuri:

src/
├── Cache/
│   ├── Cache.php
│   ├── RedisCache.php
│   ├── NullCache.php
│   └── CacheKeys.php

Yksinkertainen cache-luokka

Esimerkki:

namespace MyPlugin\Cache;

class Cache {

    public function get($key) {

        return wp_cache_get($key);
    }

    public function set($key, $value, $ttl = 3600) {

        wp_cache_set($key, $value, '', $ttl);
    }

    public function delete($key) {

        wp_cache_delete($key);
    }
}

Tämä abstrahoi WordPressin object cachen.

Miksi käyttää wp_cache_* eikä aina transientteja

Transientit:

  • voivat tallentua tietokantaan
  • eivät ole optimaalisia high-frequency cachelle

Object cache:

  • toimii memory-pohjaisesti Redisillä/Memcachedilla
  • huomattavasti nopeampi

Redis cache-layerin pohjana

Paras tuotantoratkaisu:

  • Redis Object Cache
  • memory-pohjainen cache
  • erittäin nopea retrieval

Ilman Redisia cache-layerin hyöty jää paljon pienemmäksi.

Cache key naming strategy

Huono:

posts

Parempi:

myplugin:posts:featured

Hyvä naming strategy:

  • namespace
  • resource
  • identifier

Dynamic cache keys

Esimerkki:

$key = sprintf(
    'product:%d',
    $product_id
);

Cache wrapper callback-mallilla

Moderni lähestymistapa:

public function remember($key, $ttl, callable $callback) {

    $cached = $this->get($key);

    if ($cached !== false) {
        return $cached;
    }

    $value = $callback();

    $this->set($key, $value, $ttl);

    return $value;
}

Käyttö:

$data = $cache->remember(
    'latest_posts',
    3600,
    function() {

        return get_posts(...);
    }
);

Tämä tekee cachesta erittäin siistin käyttää.

Query cache

Yksi tehokkaimmista käyttökohteista.

$posts = $cache->remember(
    'homepage_posts',
    1800,
    function() {

        return new WP_Query([
            'post_type' => 'post'
        ]);
    }
);

API cache

Ulkoiset API:t ovat hitaita ja epäluotettavia.

$response = $cache->remember(
    'weather_api',
    HOUR_IN_SECONDS,
    function() {

        return wp_remote_get(...);
    }
);

Fragment caching

Voit cachettaa HTML:n.

$html = $cache->remember(
    'hero_html',
    3600,
    function() {

        ob_start();

        get_template_part('hero');

        return ob_get_clean();
    }
);

Cache invalidation

Vaikein osa cache-arkkitehtuuria.

Perussääntö:

cache pitää poistaa kun data muuttuu

Esimerkki:

add_action('save_post', function($post_id) use ($cache) {

    $cache->delete('homepage_posts');
});

Tag-pohjainen invalidointi

WordPress ei tue tätä natiivisti, mutta voit rakentaa itse.

Esimerkki:

posts
products
users

Kun post muuttuu:

invalidoi kaikki posts-tagged keyt

Cache stampede ongelma

Jos cache vanhenee samaan aikaan:

  • sadat requestit generoivat datan uudelleen

Ratkaisuja:

  • lock mekanismi
  • stale cache fallback
  • background regeneration

Locking-esimerkki

if (get_transient('cache_lock')) {
    return $stale_data;
}

Stale-while-revalidate malli

Hyvä ratkaisu suurille sivustoille:

  • vanha cache palautetaan heti
  • uusi generoidaan taustalla

Tämä vähentää piikkejä.

Multi-layer cache

Skaalautuva rakenne:

Browser Cache
↓
CDN Cache
↓
Page Cache
↓
Object Cache
↓
Database

Oma cache-layer toimii object cache -tasolla.

Admin ja frontend cache erikseen

Älä cacheta kaikkea samalla tavalla.

Frontend:

  • aggressiivinen cache

Admin:

  • lyhyempi TTL
  • enemmän realtime-dataa

Cache metrics ja monitorointi

Seuraa:

  • hit ratio
  • miss ratio
  • regeneration time
  • Redis memory usage

Työkalut:

  • Redis Insight
  • Query Monitor
  • New Relic

Cache warming

Voit esigeneroida cachea:

  • cronilla
  • deployn jälkeen
  • queue-workerilla

Näin käyttäjä ei triggeröi ensimmäistä hidasta requestia.

Yleisimmät virheet

  • cache invalidation puuttuu
  • kaikki cachetetaan samalla TTL:llä
  • liian isot payloadit
  • ei namespaceja
  • cache logic hajallaan
  • transientteja käytetään object cacheksi ilman Redisia

Paras arkkitehtuuri

Moderni WordPress cache-layer:

  • Redis Object Cache
  • wrapper-luokka
  • callback-pohjainen API
  • centralized key management
  • hook-pohjainen invalidointi
  • stale-while-revalidate
  • metrics ja monitorointi

Yhteenveto

Oma cache-layer tekee WordPress-sovelluksesta huomattavasti nopeamman, vakaamman ja helpommin ylläpidettävän. Kun välimuistilogiikka keskitetään yhteen kerrokseen, suorituskykyoptimointi muuttuu hallittavaksi eikä cache-ratkaisu hajaannu ympäri projektia.

Parhaat tulokset saavutetaan yhdistämällä oma cache abstraction Redis Object Cacheen, järkevään invalidointistrategiaan ja monitorointiin. Tällöin WordPress pystyy käsittelemään huomattavasti suurempaa liikennettä ja datamäärää tehokkaasti.

🍪