Bir web sitesine girildiğinde server o sitenin kaynak kodlarını alır ve o request'i atan client'a kaynak kodlarını render eder. Bu, birkaç kişi için bir sorun olmayabilir, ancak birkaç binlik requestlerde bu çok büyük bir sorun olabiliyor. Bu sebeple, web cache teknolojisini kullanarak bir web sitesine 10 kişi aynı anda request atarsa, backend tarafında bulunan kaynakları o 10 kişi için ayrı ayrı render etmek yerine, bilgisayarlarımız o verileri cacheden çeker ve browserımızda işlenir. (Bu verilere örnek olarak HTML, CSS ve JS verilebilir.) Böylece, backend tarafındaki yük epey bir hafifletilmiş olur çünkü ilgili kaynaklar iki kere veya daha fazla request-response işlemi ile işlenmez; onun yerine, HTML, CSS gibi kaynaklar bilgisayarınızda tutulur.
Öncelikle, cache'lenebilir bir endpoint'e bir request atıldığında ne gibi durumlar oluyor, buna değinelim.
Önceden cache'lenmemiş bir endpoint'e request atıldığında, bir tür anahtar oluşturulur. Bu anahtar sayesinde, oluşturulan cache'in endpointine tekrar bir request atıldığında, verileri yeniden renderlamak yerine, request'in HTTP header'ına bakılır ve buna göre bir anahtar daha oluşturulur. Eğer o anahtar, cache'in db(memory)'sinde varsa, tekrar bir render işlemi gerçekleştirilmez, onun yerine, cache'lenmiş veri kullanıcıya cache'den return edilir.
Örnek bir HTTP Response'unda Cachelenebilir/Cachelenemez bilgisinin verildiği kısım:age: 15
cache-control: max-age=600
date: Tue, 21 Feb 2023 17:02:37 GMT
etag: W/"63f36903-194d"
expires: Tue, 21 Feb 2023 16:23:53 GMT
vary: Accept-Encoding
via: 1.1 varnish
x-cache: HIT
x-cache-hits: 1
x-fastly-request-id: 9e1ebe8397080d97590d076e0bf46a0e5f3020d5
x-served-by: cache-sof1510058-SOF
x-timer: S1676998958.524868,VS0,VE1
Dönen response'da yer alan cache-control ve expires başlıkları, response'un cache'lenip cache'lenemediğini belirler.
Cache-Control: max-age=600 header'ı, respons'un cach'de en fazla 600 saniye (10 dakika) tutulabileceğini belirtir. Bu süre sona erdikten sonra, cache'den alınan veriler, server'dan yeniden alınır.
Expires: Tue, 21 Feb 2023 16:23:53 GMT header'ı da benzer bir bilgi verir. Bu header, response'un cache'de en fazla bu tarihe kadar (21 Şubat 2023, 16:23:53) tutulabileceğini belirtir.
Bu başlıkların olmaması ya da sıfır değerleriyle ayarlanmış olmaları durumunda, yanıt önbelleğe alınamaz. "Vary", "ETag" ve "X-Cache" gibi diğer başlıklar, cache'in davranışını etkileyen diğer bilgileri sağlarlar.
Cache key'i, HTTP request'inin içerisinde bulunan çok temel verilere bakarak bir key oluşturur. Peki, bu temel veriler nelerdir? Bu veriler protokol, domain, path ve qs (Query String)'dir. Tabii, böyle olmak zorunda değil. Sonundaki qs parametresi olmasa da veri, cachelenilebilir bir şekilde ayarlanabilir. Örneğin, key create işlemi sadece protokol, domain ve path bilgisine göre oluşturulabilir.
Bir verinin neye bakarak caching yaptığımızdan bahsettik, peki neye bakarak caching yapmıyoruz? Backend tarafından gönderilen response içerisindeki header kısmında verinin cachlenebilir ya da cachlenemez bilgisini veriyor. Böylece gelen veri, server'ın bize söylemiş olduğu cachelenebilirlik durumuna göre cache'liyor ya da cachlemiyoruz.
Bazı verileri cache'lemememiz gerekiyor. Örnek olarak, değişkenlik gösteren bir veriyi cache'lersek, o sayfayı yenilesek bile, yine veriyi cacheden almaya çalıştığımız için hala daha güncellenmemiş halini görürüz. Buna örnek olarak profil fotoğrafları verilebilir. Eğer her gönderilen veri cache'lenebilseydi, yenilediğiniz profil fotoğrafınızı görebilmek için cachelerinizi silmeniz ve yeni bir request atmanız gerekirdi.
İlk örneğimize geri dönelim. Yukarıda, bir siteye ilk kez request atıldığında HTML, CSS ve JS gibi kaynakların bilgisayarlarımızda tutulmak üzere indirildiğinden bahsetmiştik. Şimdi ise ilk requestten sonra aynı endpoint'e 2. bir request atılırsa ne gibi durumların yaşanacağına değinelim.
Aynı endpoint'e ikinci kez request atıldığında, ilk attığımız request üzerinden oluşturulan key'e bakılır ve yeni atılan request'in key'i ile uyusup uyusmadığı testine sokulur. Ardından bu işlemin sonucu True ise backend tarafında cachelenen verinin aynısı bu client'a gönderilir ve ilgili kaynaklar browser tarafından işlenir.
Bu duruma aşağıda bir örnek verdim:
Atilan bir request sonucunda server tarafinda bir cache key'i nasil olusturulur?request = calculating_cash_key(http-response-parameters)
Böyle bir örnek düşünelim. Burada 'http-response-parameters' değişkeni içinde tutulan verinin 'HTTP 1.1/mertbingol0.github.io/index.html' olduğunu varsayalım. Key'in bu HTTP parametrelerine göre oluşturulduğundan söz etmiştim. Burada da aynı şekilde, eğer tekrar atılan request 'HTTP 1.1/mertbingol0.github.io/index.html' ise cache key hesaplanır ve hesaplanan key'in değeri, db(memory)'de var olup olmadığına bakılır. Eğer var ise, cache içerisinde bu endpoint için önceden cachelenmiş olan veriler return edilir.
from flask import Flask, request
from werkzeug.contrib.cache import SimpleCache
# Flask uygulamasını başlat
app = Flask(__name__)
# Bir cache nesnesi oluştur
cache = SimpleCache()
# Cache'lenecek endpoint için bir route belirle
@app.route('/cached-endpoint')
def cached_endpoint():
# Yanıtın cache'de olup olmadığını kontrol et
response = cache.get(request.path)
if response is not None:
# Yanıt cache'de ise, direkt olarak cache'den yanıtı döndür
return response
else:
# Yanıt cache'de yok ise, yanıtı üret ve cache'e kaydet
response = generate_response()
cache.set(request.path, response, timeout=60)
return response
# Bu fonksiyon cache'lenecek yanıtı üretir
def generate_response():
# Bu örnekte, sadece bir string döndürüyoruz
return "Bu cache'lenmiş bir veridir!"
if __name__ == '__main__':
app.run()
Flask ile yazdığım bu örnek cache uygulaması, HTTP isteklerine verilen yanıtların önbellekte (cache) saklanmasını sağlar. Bu şekilde, aynı isteği yapan birden fazla kullanıcı için, istek her seferinde yeniden işlenmeden önbellekten alınarak hızlı bir yanıt döndürülür.
Yazımı okuduğunuz için teşekkür ederim. İyi çalışmalar.