.NET Core’da cache kullanımları #1 InMemory Cache

Gökten Karadağ
3 min readApr 4, 2020

--

Cache(önbellek), gelecek taleplerin daha hızlı sunulabilmesi için verileri depolayan yapılardır. Verilere tekrar erişilmek istendiğinde, uygulamalar verileri orijinal kaynaktan almak yerine cacheden alabilir bu sayede istenen bilgiyi sağlamak için gerekli eforu azaltır. Bu sayede daha ölçeklenebilir, daha hızlı, performansı yüksek uygulamalar geliştirmeyi sağlar.

Cache ile ilgili daha çok bilgi almak ve .NET Core’daki diğer cache kullanımlarını incelemek için, serinin diğer yazılarına aşağıdaki linklerden ulaşabilirsiniz.

  1. .NET Core’da cache kullanımları #1 InMemory Cache
  2. .NET Core’da cache kullanımları #2 Distributed Cache
  3. .NET Core’da cache kullanımları #3 Response Cache

Yazılım dünyasındaki çoğu problemde olduğu gibi hangi bilgilerin ne kadar sürede cacheleneceği, nasıl cacheleneceği gibi konular uygulamadan uygulamaya değişkenlik gösterebilir. Bu yüzden problemi doğru anlayıp olası sorunlardan kaçınarak tasarımı yapmakta fayda var. Sayfalarınızda dinamik alanlar ile statik alanları olabildiğince ayırarak sisteminizi daha doğru kurmanıza olanak sağlayabilir, cache mekanizmanızın çalışmaması gibi durumlar için uygulamanızı cacheden gelen veriye bağlı kalmayacak şekilde yapılandırmak daha doğru bir çözüm olabilir.

Örneğin, blog yazılarını anlık olarak veritabanından getirdiğimiz bir blog sitemiz olsun. Çoğu senaryoda bu kullanım bir sorun yaratmaz ama yoğun kullanımlı sitelerde veritabanına giden her istek bir yük getirebilir. Bu yapı yerine blog yazılarını belirli bir süreliğine cachede tutabilirsiniz. Artık yeni gelen istekler için veritabanına gidip blog yazılarını sorgulamak yerine istediğimiz veriyi uygulamanın belleğinden getirerek uygulamanızın performansını iyileştirebilirsiniz.

ASP.NET Core için cache tiplerini genel olarak data caching ve page caching (output caching) olarak ayırabiliriz.

Data caching, bir veri kaynağından (webservices,db,file vb) veriyi önbelleğe alma anlamına gelir. Önbellek süresi dolmadığı sürece, önbellekten veri talebi yerine getirilir. Önbellek süresi dolduğunda, veri kaynağı tarafından yeni veriler alınır ve önbellek yeniden doldurulur.

NET Core’da data cachingi In-memory (In-process) ve Distributed(Out-process) olarak ikiye ayırabiliriz.

InMemoryCache

.NET Core ile built-in bu cache tipi adı üstünde verileri uygulamanın belleğinde tutar. Microsoft.Extensions.Caching.Memory kütüphanesindeki IMemoryCache’in sağladığı interface ile ekleme silme gibi işlemleri yapabilmeyi sağlar.

Bazı zamanlarda cachedeki verileri geçersiz kılmak gerekebilir. Bazen de bu veriler büyüdükçe fazla bellek tüketerek sunucularınızı,uygulamalarınızı çalışmaz hale getirebilir. Bu gibi problemleri aşabilmek için cache frameworkleri bazı seçenekler sunar.

InMemoryCachede MemoryCacheEntryOptions ile kullanılabilen ayarlar şu şekildedir;

Absolute expiration : Belirli süre sonunda cachedeki verinin expire olmasını sağlar.

Sliding expiration: Belirli bir süre boyunca işlem yapılmazsa cachedeki veri expire olur, eğer işlem yapılırsa süre tekrar uzar.
Örnek olarak Sliding Expiration süresi 10 dakika olarak verdiğimizi düşünelim. 10 dakika dolmadan önce cachedeki veri tekrar istenirse cachein expire olma süresi yapılan son istekten 10 dakika sonrasına ertelenir.

Priority: CacheItemPriority enum değerine göre (NeverRemove, High, Normal, Low) bellekte yer açmak için verilerin hangi sırayla silineceğini belirler.

Size: Ayırabileceğiniz maximum belleği ayarlar.

PostEvictionCallbacks: Bir öğe cacheden kaldırıldığında bir callback metotu çalıştırmayı sağlar.

Şimdi örnek proje üzerinde InMemoryCache’in nasıl kullanıldığına bakalım.

İlk olarak Startup.cs sınıfındaki ConfigureServices metotunda Memorycache’i etkinleştirelim.

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddMemoryCache();

}

Ardından ilgili controllerın constructorında IMemoryCache’i inject edelim.

private IMemoryCache cache;
public InMemoryController(IMemoryCache cache)
{
this.cache = cache;
}

Artık uygulamamızda InMemoryCache’i kullanabilir durumdayız.

Şimdi de yazının giriş kısmında bahsettiğim gibi bir blog sitesi blog yazılarını veritabanından getirmek yerine cacheden tuttuğumuz bir yapının örneğini yapalım.

İlk if bloğumuzda TryGetValue metotu ile blog yazıları cachede var mı diye sorguluyoruz varsa direk bu bilgiyi dönüyoruz. Eğer veri cachede yoksa veritabanından sorguluyoruz. Sonrasında yeni bir 30 dakikalık absoluteexpire süresi tanımlayıp veritabanından gelen listeyi önbelleğe ekliyoruz. Artık projemizi çalıştırdığımızda sadece ilk istek için veritabanına gittiğimizi görebiliriz. InMemoryCache’i daha detaylı incelemek isterseniz Microsoft’un bu konudaki yazısını inceleyebilirsiniz

İlk kez oluşacak bir cache nesnesini birden çok thread isterse, istekler ilkinin tamamlanmasını beklemez ve cachedeki nesne birçok kez oluşturulur. Bu neden oluşması uzun süren veya maliyeti yüksek bir işlem varsa bu sırada gelen tüm cache istekleri verinin orjinal kaynağına tekrar gideceği için performans problemlerine neden olabilir. Bu problemi daha detaylı incelemek ve alternatif çözümleri görmek için Scott Hanselman’ın bu konudaki yazısını ve bu probleme çözüm sunan LazyCache kütüphanesini inceleyebilirsiniz.

Basit olarak cache nedir ve InMemoryCache nasıl kullanılır anlatmaya çalıştım. Anlatımda bir hata olduğunu düşünüyorsanız lütfen yorum yapmaktan çekinmeyin. Bir sonraki yazıda .NET Core’daki diğer cache yöntemlerini inceleyeceğiz. Görüşmek üzere..

Github : https://github.com/gktnkrdg/CacheExample-NetCore

Kaynaklar

[1]https://docs.microsoft.com/tr-tr/aspnet/core/performance/caching/memory?view=aspnetcore-3.1

[2]https://michaelscodingspot.com/cache-implementations-in-csharp-net/

[3]http://www.binaryintellect.net/articles/a7d9edfd-1f86-45f8-a668-64cc86d8e248.aspx

[4]https://www.devtrends.co.uk/blog/a-guide-to-caching-in-asp.net-core

--

--