Laravel'de Cache (Önbellek) Kullanımı

Caching (önbellekleme) uygulamanızın çalışma hızı açısından çok büyük bir önem sarf ediyor. Laravel'de de caching modülünün kullanımı gayet basit. Ancak, birçok eğitici video ve makale bu kısmı atladığı için, kaçırmış olabilme ihtimaliniz çok fazla.

Nerede ve nasıl caching kullanmalısınız sorusunu cevaplayacak olursam, farz edin ki, elinizde bir uygulama var ve bu uygulamanızdaki veritabanı sorguları 1 milyon satırlık tablolar arasında birden fazla join sorgusundan oluşuyor, üstüne üstlük, tüm bu sorguların sonucu da bir gün içerisinde hiç değişmiyor. Eğer ki o gün uygulamanıza 1000 tane istek gelirse, caching kullanmazsanız, o 1000 istek de işlenecek ve her bir isteğin 2 saniye süreceğini düşünürseniz, sisteminizin bir gün içerisinde sadece 1 kere yapması gereken bu işlemi siz 1000 kere gereksiz yere işlediğiniz için sunucunuz 2000-2=1998 saniye, gereksiz yere veritabanı sorgusuna vakit ayırmak zorunda kalacak.

İşte bu ve bunun gibi durumlarda, Caching'in sizin için faydası çok büyük. Caching sonucunda istek bir kere işlendikten sonra sizin seçtiğiniz caching driver'ı ile, ki Laravel veritabanı, dosya ve birçok modern uygulamada kullanılan Memcached ile Redis'i destekliyor, gelen her bir aynı sorguda, önbelleğe alınmış sonucu geri döndürecek.

Cache driver'ınızı .env dosyanızdan CACHE_DRIVER değişkeni üzerinden değiştirebileceğiniz gibi, config/cache.php dosyanızdan da değiştirebilirsiniz. Eğer ki caching modülü olarak dosyayı seçerseniz, herhangi bir ekstra değişiklik yapmanıza gerek yok, sadece driver olarak file'ı belirtmeniz lazım, dilerseniz de oluşturulan caching dosyalarının da nerede tutulacağını config/cache.php dosyasındaki stores anahtarının file değeri içerisinde ayarlayabilirsiniz ki diğerleri için de yapacağını tüm değişiklikleri yine aynı yerden yapıyorsunuz.

Veritabanı (database) olarak seçmek isterseniz, driver'ı database olarak ayarlamanız gerek, aynı zamanda da alttaki artisan komutu ile cache tablosunu oluşturup, migrate etmeniz lazım.
$ php artisan cache:table && php artisan migrate
Memcached ve Redis için ekstra paket yüklemeniz lazım. Memcached için, PHP modülünü yüklemeniz lazım.

PHP7 için,
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
$ sudo apt-get install memcached php7.0 php7.0-common php-memcached
Eğer ki hala PHP5 kullanıyorsanız,
$ sudo apt-get install memcached php5-memcached
Sonrasında ekstra bir ayar yapmanıza gerek yok, ama eğer ki soket kullanmak ve de portu değiştirmek istiyorsanız, tekrardan config/cache.php içerisinde stores anahtarının memcached değerindeki değerleri değiştirebilirsiniz.

Redis içinse, predis/predis paketini yüklemeniz lazım. Bunun için de,
$ sudo apt-get install redis-server
$ composer require predis/predis
Memcached için geçerli olan kısım redis için de geçerli, bir ayar yapmanıza gerek yok ama yapmak isterseniz burada farklı olarak config/database.php içerisinde redis anahtarının içerisindeki değerleri değiştirebilirsiniz.

Artık Caching'i nasıl kullanabileceğize değinebiliriz. Temel olarak basit getter ve setter'ları kullanabileceğiniz gibi daha gelişmiş yöntemleri de kullanabilirsiniz. Temel yöntemlerde, get ile cache içerisindeki değeri getirebileceğiniz gibi, put ile de cache içerisinde tanımlama yapabilirsiniz.
Cache::put('anahtar', 'deger', $cacheIcerisindeTutulacagiDakika = 60);
$deger = Cache::get('anahtar', 'Bulunamazsa Dondurulecek Olan Atadiginiz Default Deger');
Yine aynı şekilde temel olarak cache içerisinde bir değerin bulunup bulunmadığını has yöntemi ile kontrol edebilirsiniz.
if (Cache::has('anahtar')) {
    // islemleriniz
}
Cache içerisindeki değeri ayrıca süresi bitmeden silmek için de, alttaki komutu kullanabilirsiniz.
Cache::forget('anahtar');
Cache'de tutulan tüm anahtarları, kısacası her şeyi silmek için de flush yöntemini kullanabilirsiniz.
Cache::flush();
Her ne kadar bu yöntemler en temelleri olsa da tüm bunların bir araya getirildiği yöntemleri kullanmak kodunuz açısından daha temiz olabilir.
return Cache::remember('users', $cacheIcerisindeTutulacagiDakika = 60, function () {
    return DB::table('users')->get();
});
Üstteki yöntem ile, eğer ki Cache içerisinde users anahtarında bir değer mevcutsa o döndürülecek, eğer ki değilse, veritabanı sorgusu ile tüm kullanıcılar döndürülecek, aynı zamanda da bu kullanıcılar users anahtarı içerisinde önbelleğe alınacak, böylece eğer ki 60 dakika içerisinde aynı istek tekrar gelirse, dönen cevap Cache aracılığıyla gerçeklenecek.

Ayrıca, kullanıcılarınız hiçbir zaman değişmiyorsa, bunu yine sonsuza kadar önbellekte tutabilirsiniz. Böylece, uygulamanız sağlıklı bir biçimde çalıştığı sürece sadece bir kez tüm kullanıcıları veritabanından çeken sorgu gerçeklenecek, kalan tüm zamanlarda tüm isteklere Cache modülü cevap verecek.
return Cache::rememberForever('users', function () {
    return DB::table('users')->get();
});
Son olarak da, sık yapılan bir hatadan bahsedip bu makaleyi sonlandıracağım. Eğer ki paginated edilen bir sorgunuz varsa ve bunu sayfa değerine dikkat etmeden önbelleğe alıyorsanız, her sayfada aynı sonuçla karşılaşırsınız. Bu yüzden sayfa numarasını cache anahtarınıza eklemeyi unutmayın. Alttaki örnekte bunu nasıl gerçekleyebileceğinizi inceleyebilirsiniz.
public function getArticles($pagination = 12)
{
    return Cache::remember(implode('_', ['articles', 'page', Request::input('page', '1')]), $cacheIcerisindeTutulacagiDakika = 120, function () use ($pagination) {
        return Article::orderBy('published_at', 'desc')->paginate($pagination);
    });
}
Kısacası uygulamalarınızın daha hızlı çalışması için Cache kullanmayı unutmayın.