Saját CDN-szerver felépítése: egyszer lehozni, ezerszer kiszolgálni
A CDN-szerver minden fájlt egyszer hoz le a forrásról, és onnantól ezerszer maga szolgálja ki. A forrásszerver már csak a kérések töredékét látja, a látogatók pedig rövid betöltési időt kapnak. Így épít fel egyet.
Minden fájlt, amelyet egy látogató letölt az oldaláról, a forrásszerver (origin) kikeres a fájlrendszerből, becsomagol egy válaszba, és elküld. Napi tíz látogatónál ezt senki nem érzi meg. Tízezer egyidejű látogatónál viszont pontosan ez az oka annak, hogy az oldal lassú lesz, miközben a tulajdonképpeni alkalmazásnak semmi dolga sincs.
A CDN-szerver ez elé áll. Minden fájlt egyszer hoz le a forrásról, és onnantól maga szolgálja ki, ahányszor csak kell. A forrás ezért már csak a kérések töredékét látja, a látogatók pedig olyan szervertől kapják a fájljaikat, amely semmi mást nem csinál, csak kiszolgál. Ez a cikk bemutatja, mennyit hoz ez valójában, hogyan állít fel egy ilyen szervert nginxszel, és min dől el a forgalom és a helyszín kérdése.
Mit tesz valójában egy CDN-szerver
A működés három mondatban elbeszélhető:
- Egy látogató fájlt kér a CDN-szervertől.
- Ha az már ott van, azonnal kimegy. Ez egy találat.
- Ha nincs ott, a CDN-szerver lehozza a forrásról, eltárolja és kiszolgálja. Ez egy tévesztés, és fájlonként csak egyszer történik meg érvényességi időszakonként.
Az elv ugyanaz, mint a streamszerver esetében: egyszer lehozni, sokszor kiszolgálni. A különbség csak annyi, hogy a streamszerver futó adatfolyamot oszt szét, a CDN-szerver pedig kész fájlokat.
A számítás: mennyit vesz le egy gyorsítótár
A döntő a találati arány, vagyis azoknak a kéréseknek a hányada, amelyeket a gyorsítótár maga válaszol meg. Napi egymillió kérésnél a tehercsökkenés így alakul:
| Találati arány | Kérések a forráson | Tehercsökkenés |
|---|---|---|
| 50% | 500 000 | kétszeres |
| 80% | 200 000 | ötszörös |
| 95% | 50 000 | hússzoros |
| 99% | 10 000 | százszoros |
Statikus fájloknál 95 százalék és annál több a normális eset, mert képek, szkriptek és betűtípusok ritkán változnak. A 95-ről 99 százalékra tett lépés közben értékesebb, mint amit a számok sejtetnek: a maradék terhelést még egyszer ötödére csökkenti.
Ezzel egy időben áthelyeződik a forgalom. A forrás már alig visz át valamit, a CDN-szerver annál többet. Napi 500 000 képletöltésnél, egyenként 400 KB-tal ez naponta 200 GB, vagyis havonta körülbelül 6 TB, csak a képekre. Egy CDN-csomópontnál ezért nem a processzor a fontos szám, hanem a hálózati kapcsolat és a mennyiség.
Mikor érdemes saját CDN-szerver
A kereskedelmi CDN-szolgáltatók átvitt gigabájtonként számláznak. Ez kényelmes, és kis mennyiségnél kedvező. Egy bizonyos mennyiség felett viszont megfordul az arány:
| Eset | Saját CDN-szerver | Gigabájtonkénti számlázás |
|---|---|---|
| Néhány GB havonta | alig érdemes | kedvezőbb |
| Sok TB havonta | fix havi díj | lineárisan nő vele |
| Nagy letöltések, videóarchívumok | világosan előnyben | hamar drága lesz |
| Teljes kontroll a szabályok és a protokollok felett | teljes | korlátozott |
Jön ehhez egy pont, amelyet nehéz számmal kifejezni: saját csomópontnál Ön dönti el, mi kerül gyorsítótárba, meddig, és mikor tűnik el. Nem köti idegen szolgáltató szabályrendszere, és olyan dolgokat is kiszolgálhat, amelyek nem illenek idegen sémákba.
Felépítés nginxszel mint gyorsítótárral
Telepítés
apt update
apt install -y nginx
Ennél több nem kell, a gyorsítótár be van építve az nginxbe. Hozza létre a könyvtárat, amelyben a fájlok lesznek:
mkdir -p /var/cache/cdn
chown www-data:www-data /var/cache/cdn
Beállítás
A gyorsítótárat egyszer kell leírni a http blokkban, és utána az egyes location blokkokban használni:
proxy_cache_path /var/cache/cdn
levels=1:2
keys_zone=cdn:100m
max_size=200g
inactive=30d
use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
Az értékek külön-külön: a keys_zone=cdn:100m körülbelül 800 000 bejegyzésre elég, a max_size korlátozza a lemezen elfoglalt helyet, az inactive=30d eldobja azokat a fájlokat, amelyeket 30 napig senki nem kért, a use_temp_path=off pedig elkerüli a könyvtárak közötti fölösleges mozgatást.
Ez alatt jön a tulajdonképpeni szerver:
server {
listen 443 ssl;
http2 on;
server_name cdn.example.com;
ssl_certificate /etc/letsencrypt/live/cdn.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cdn.example.com/privkey.pem;
location / {
proxy_pass https://origin.example.com;
proxy_set_header Host origin.example.com;
proxy_http_version 1.1;
proxy_cache cdn;
proxy_cache_valid 200 301 302 24h;
proxy_cache_valid 404 1m;
# több egyidejű tévesztés összevonása egyetlen kérésbe
proxy_cache_lock on;
proxy_cache_lock_timeout 10s;
# kiszolgálás folytatása, ha a forráson gond van
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
# a munkamenet-sütik nem boríthatják fel a gyorsítótárat
proxy_ignore_headers Set-Cookie;
proxy_hide_header Set-Cookie;
add_header X-Cache-Status $upstream_cache_status always;
}
}
Ebből három sor külön figyelmet érdemel. A proxy_cache_lock gondoskodik arról, hogy egy új fájl esetén ne száz látogató kérdezze meg egyszerre a forrást, hanem csak egy, a többi pedig várjon. A proxy_cache_use_stale fenntartja a kiszolgálást, amíg a forrás újraindul vagy lassan válaszol. A Set-Cookie elrejtése pedig megakadályozza, hogy egyetlen munkamenet-sütit hordozó válasz használhatatlanná tegye az egész gyorsítótárat.
Ellenőrzés, hogy működik-e
nginx -t && systemctl reload nginx
curl -sI https://cdn.example.com/bild.jpg | grep -i x-cache-status
curl -sI https://cdn.example.com/bild.jpg | grep -i x-cache-status
Az első hívásnál MISS áll ott, a másodiknál HIT. Ha másodszorra is MISS van, az szinte mindig a három szokásos gyanúsított egyikén múlik: egy Set-Cookie a válaszban, egy Cache-Control: no-store a forrástól, vagy egy hiányzó hosszmegadás.
Mi kerül gyorsítótárba és mi nem
A tiszta megoldás az, hogy a forrás maga mondja meg. Ő ismeri a tartalmait, a gyorsítótár nem. Ehhez megfelelő fejléceket állít be:
| Tartalom | Fejléc a forráson |
|---|---|
| Fájl ellenőrzőösszeggel a nevében | Cache-Control: public, max-age=31536000, immutable |
| Kép vagy letöltés verziózás nélkül | Cache-Control: public, max-age=86400 |
| Nyilvános oldal HTML-je | Cache-Control: public, max-age=300 |
| Bejelentkezett terület, kosár | Cache-Control: private, no-store |
Ha magában a gyorsítótárban akar dönteni, az fájltípusonként külön location blokkokkal lehetséges:
location ~* \.(jpg|jpeg|png|gif|webp|avif|svg|ico|css|js|woff2|mp4|zip)$ {
proxy_pass https://origin.example.com;
proxy_cache cdn;
proxy_cache_valid 200 7d;
add_header Cache-Control "public, max-age=604800";
add_header X-Cache-Status $upstream_cache_status always;
}
Tartalmak célzott eltávolítása
A legegyszerűbb út az, ha egyáltalán nem kell törölni: aki minden megváltozott képnek új fájlnevet ad, például logo.a1b2c3.png, annak nincs ilyen gondja. A régi fájl valamikor magától kiesik a gyorsítótárból.
Ha ez nem megy, az nginxnél segít a szabad ngx_cache_purge modul. Kiegészítő modul nélkül az elérési út kiszámolható a gyorsítótárkulcsból, mert az nginx annak MD5-összegét használja fájlnévként:
KEY="httpsGETcdn.example.com/bild.jpg"
H=$(printf '%s' "$KEY" | md5sum | cut -d' ' -f1)
rm -f "/var/cache/cdn/${H: -1}/${H: -3:2}/$H"
A napi üzemhez általában elég egy kis szkript, amely ezeket a sorokat egy elérési utakból álló listára futtatja le.
Nagy fájlok és videók
Néhány száz megabájt felett a fájlokat blokkokra kell bontani, különben a gyorsítótár a videóban tett minden ugrásnál újra letölti az egész fájlt:
location /video/ {
proxy_pass https://origin.example.com;
proxy_cache cdn;
proxy_cache_valid 200 206 7d;
slice 1m;
proxy_set_header Range $slice_range;
proxy_cache_key "$uri$slice_range";
}
Ezzel az nginx csak azokat a blokkokat hozza le, amelyeket valóban kérnek. Ha egy néző egy film közepére ugrik, néhány megabájt megy át a vonalon több gigabájt helyett.
TLS, HTTP/2 és HTTP/3
Egy CDN-csomópont sok kis fájlt szolgál ki sok kapcsolaton, és pontosan itt térülnek meg az újabb protokollok. A HTTP/2 a http2 on; sorral elintézett. A HTTP/3 főleg mobilhálózaton hoz hasznot, mert hálózatváltáskor nem szakad meg a kapcsolat:
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
add_header Alt-Svc 'h3=":443"; ma=86400';
Ne felejtse el közben megnyitni az UDP 443-at a tűzfalban. Ez a leggyakoribb oka annak, hogy a HTTP/3 be van állítva, és mégsem használja senki.
Több helyszín
Egyetlen csomópont már a nyereség legnagyobb részét meghozza, vagyis a forrás tehermentesítését. A második nyereség, a látogatóhoz vezető rövid út, csak több helyszínnel jön el.
A szétosztás DNS-en keresztül megy: ugyanaz a név a látogató származási helye szerint más csomópontra mutat. Ehhez földrajzi hozzárendelést támogató DNS-szolgáltató kell. Minden csomópont ugyanazt a beállítást és ugyanazt a forrást kapja, egymásról nem tudnak semmit, és pontosan ez teszi a felépítést ilyen szívóssá: ha egy csomópont kiesik, kiveszi a DNS-ből, a többi pedig átveszi a munkát.
A KernelHost németországi, az Egyesült Államok nyugati partján és keleti partján lévő, valamint szingapúri és dél-koreai helyszíneket kínál. Késleltetésekkel együtt készült áttekintést a szerverhelyszínek oldalon talál. Ökölszabály: egy csomópont minden olyan kontinensre, amelyen a közönségének említésre érdemes része van.
Mérés találgatás helyett
Írja a gyorsítótár állapotát a naplóba, akkor bármikor kiszámolhatja a találati arányt:
log_format cdn '$remote_addr $status $body_bytes_sent '
'$upstream_cache_status "$request"';
access_log /var/log/nginx/cdn.log cdn;
Kiértékelni egy egysorossal lehet:
awk '{print $4}' /var/log/nginx/cdn.log | sort | uniq -c | sort -rn
Ha a HIT aránya statikus fájloknál 90 százalék alatt van, szinte mindig megéri a hiba okát keresni: általában sütik vannak a válaszokban, túl rövidek az érvényességek, vagy a cím végén változó paraméterekkel jönnek a kérések, amelyek a gyorsítótár számára minden alkalommal új fájlnak látszanak.
Melyik szerver a megfelelő
A CDN-csomópont kiszolgálógép. A fontos jellemzők sorrendje ezért másképp alakul, mint egy alkalmazásszervernél:
- Forgalom és hálózati kapcsolat. Itt keletkezik a teljes terhelés. Egy csomópont üzem közben rendszeresen több terabájtot visz át havonta.
- Lemez. Az NVMe jelentős előnyben van, mert a gyorsítótár sok kis, véletlenszerű hozzáférésből áll. A méret ahhoz igazodik, hogy a készletéből mennyi forró, nem ahhoz, hogy a készlet összességében mekkora.
- Memória. Az operációs rendszer a szabad memóriát második gyorsítótárként használja a lemez előtt. Több memória itt közvetlenül több tempót jelent.
- Processzor. A legkevésbé kritikus, csak a TLS-hez kell, és azt a modern processzorok mellékesen elvégzik.
Pontosan erre az esetre készültek a korlátlan forgalmú root szervereink: valódi 2 × 1 Gbit/s szerverenként sávszélesség-korlátozás nélkül, korlátlan mennyiség fix havi díjon, adatközponti NVMe RAID-ben és gyárilag 3,2 Tbps floodvédelem. Az üzembe állítás 30 másodperc alatt megvan, teljes root hozzáféréssel, IPv4-címmel és egy /64-es IPv6-hálózattal. Mivel a számlázás PrePaid alapú és havonta felmondható, kezdheti egyetlen csomóponttal, és bármikor hozzávehet egy második helyszínt, ha a közönsége szétszóródik.
Gyakori kérdések
Mit tesz pontosan egy CDN-szerver?
Mennyire csökkenti ez valóban a terhelést?
Kell ehhez kereskedelmi szolgáltató?
Mely fájlokat tegyem gyorsítótárba és melyeket ne?
Meddig tartsa meg a gyorsítótár a fájlokat?
Hogyan törlök egy fájlt a gyorsítótárból?
Mi történik, ha a forrásszerver kiesik?
Működik ez nagy videófájlokkal is?
Hány helyszínre van szükségem?
Miből látom, hogy a gyorsítótár működik?
2026 KernelHost GmbH. Minden jog fenntartva. Ez az útmutató szerzői jogi védelem alatt áll. Más webhelyeken való közzététele, akár csak részleteiben vagy szerkesztett formában, írásos hozzájárulásunk nélkül nem engedélyezett. A forrás megjelölésével és hivatkozással történő idézést kifejezetten szívesen látjuk.

