{"id":3659,"date":"2021-01-08T17:01:12","date_gmt":"2021-01-08T16:01:12","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=3659"},"modified":"2021-01-08T17:36:56","modified_gmt":"2021-01-08T16:36:56","slug":"improving-repeated-access-with-cache-aside-pattern","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/improving-repeated-access-with-cache-aside-pattern\/","title":{"rendered":"Improving Repeated Access with Cache-Aside Pattern"},"content":{"rendered":"<p><\/p>\r\n<p>Temiz bir kod yazabilmenin yan\u0131 s\u0131ra, sorumlu bir developer olarak uygulamam\u0131z\u0131n performansl\u0131 bir \u015fekilde \u00e7al\u0131\u015fabilmesini sa\u011flamak da bir o kadar \u00f6nemlidir. Bildi\u011fimiz gibi kullan\u0131c\u0131lara daha iyi bir deneyim sa\u011flatabilmemiz i\u00e7in olabildi\u011fince h\u0131zl\u0131 sonu\u00e7lar d\u00f6n\u00fcyor olmal\u0131y\u0131z. Tahmin edebilece\u011fimiz gibi h\u0131zl\u0131ca uygulayabilece\u011fimiz en temel performans iyile\u015ftirmelerinden bir tanesi, tekrarlanan eri\u015fimler i\u00e7in bir cache implementasyonu.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Her ne kadar basit bir i\u015flem gibi g\u00f6z\u00fcksede, bir \u00e7ok durum kar\u015f\u0131s\u0131nda uygulamalar\u0131m\u0131za olduk\u00e7a bir performans art\u0131\u015f\u0131 kazand\u0131rmaktad\u0131r. Bunun yan\u0131 s\u0131ra kaynaklar\u0131m\u0131z\u0131 da daha efektif olarak kullanabilmemizi sa\u011flamaktad\u0131r.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Bu makale kapsam\u0131nda ise <strong>.NET<\/strong> i\u00e7erisinde <strong>Cache-Aside<\/strong> pattern&#8217;\u0131n\u0131 nas\u0131l kolay bir \u015fekilde implemente edebilece\u011fimizi g\u00f6stermeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<h2 class=\"wp-block-heading\">Tan\u0131yal\u0131m<\/h2>\r\n<p><\/p>\r\n<p><\/p>\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter\"><a href=\"\/wp-content\/uploads\/2020\/12\/cache-aside-pattern.jpg\"><img decoding=\"async\" width=\"941\" height=\"321\" class=\"wp-image-3664 lazyload\" data-src=\"\/wp-content\/uploads\/2020\/12\/cache-aside-pattern.jpg\" alt=\"\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/12\/cache-aside-pattern.jpg 941w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/12\/cache-aside-pattern-300x102.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2020\/12\/cache-aside-pattern-768x262.jpg 768w\" data-sizes=\"(max-width: 941px) 100vw, 941px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 941px; --smush-placeholder-aspect-ratio: 941\/321;\" \/><\/a><\/figure>\r\n<\/div>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Yukar\u0131daki diyagramdan da anlayabilece\u011fimiz \u00fczere, yakla\u015f\u0131m\u0131m\u0131z her zaman data&#8217;y\u0131 ilk olarak cache&#8217;den okuyabilmek.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>E\u011fer okumak istedi\u011fimiz data cache&#8217;de yoksa, data&#8217;y\u0131 ilgili data store&#8217;dan okuyup ard\u0131ndan cache&#8217;e ekleyerek response d\u00f6nmemiz gerekmektedir. B\u00f6ylece tekrarlanan eri\u015fimleri en aza indirerek kaynaklar\u0131m\u0131z\u0131 daha efektif kullanabilir ve kullan\u0131c\u0131lara daha iyi bir deneyim sa\u011flatabiliriz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<h3 class=\"wp-block-heading\">Consistency<\/h3>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Cache-aside pattern&#8217;\u0131 herhangi bir consistency garantisi vermemektedir. Bir ba\u015fka de\u011fi\u015fle, okumak istedi\u011fimiz bir data, farkl\u0131 bir i\u015flem taraf\u0131ndan de\u011fi\u015ftirilmi\u015f olabilir.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>E\u011fer distributed bir ortamda \u00e7al\u0131\u015f\u0131yorsak, <strong>pub\/sub<\/strong> yakla\u015f\u0131m\u0131 ile data&#8217;y\u0131 olabildi\u011fince g\u00fcncel tutmaya \u00e7al\u0131\u015fabiliriz. Tabi bu durumda eventual consistency&#8217;i de kabul ediyor olmal\u0131y\u0131z.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<h3 class=\"wp-block-heading\">Expiration Policy<\/h3>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Bir di\u011fer \u00f6nemli konu ise cache&#8217;lemek istedi\u011fimiz data&#8217;n\u0131n, bir expiration policy&#8217;e sahip olmas\u0131. Aksi halde cacheledi\u011fimiz data, bir s\u00fcre sonra ge\u00e7ersiz bir hale gelebilir.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Consistency&#8217;i sa\u011flayabilmek i\u00e7in expiration policy&#8217;i dikkatli bir \u015fekilde ayarlamam\u0131z gerekmektedir. E\u011fer bu expiration s\u00fcresini \u00e7ok fazla k\u0131sa tutarsak, bu sefer yine ilgili data soruce&#8217;a tekrar ve tekrar gidilece\u011fi i\u00e7in bu yakla\u015f\u0131mdan \u00e7ok da fazla bir fayda alamayaca\u011f\u0131z.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>\u00d6zetle, i\u00e7erisinde bulundu\u011fumuz domain&#8217;e g\u00f6re bu s\u00fcreyi dikkatli bir \u015fekilde ayarlamam\u0131z gerekmektedir.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<h2 class=\"wp-block-heading\">Implemente Edelim<\/h2>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Ben implementasyon i\u015flemleri i\u00e7in basit bir ASP.NET 5 Web API projesi olu\u015fturaca\u011f\u0131m. Burada amac\u0131m\u0131z, cache-aside pattern&#8217;\u0131n\u0131 implemente ederken minimum efor ile olabildi\u011fince esnek ve reusable bir cache yap\u0131s\u0131 kurabilmek olacak.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Bunun i\u00e7in \u00f6ncelikle a\u015fa\u011f\u0131daki gibi &#8220;<em>ICacheService<\/em>&#8221; ad\u0131nda bir interface olu\u015ftural\u0131m.<\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-code\"><code>using System;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace MyTodoAPI.Services\r\n{\r\n    public interface ICacheService\r\n    {\r\n        Task&lt;T&gt; GetOrSetAsync&lt;T&gt;(string cacheKey, int cacheDurationInMin, Func&lt;Task&lt;T&gt;&gt; func);\r\n        Task Remove(string cacheKey);\r\n    }\r\n}<\/code><\/pre>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>&#8220;<em>GetOrSetAsync<\/em>&#8221; method&#8217;u i\u00e7erisinde cache-aside pattern&#8217;\u0131n\u0131n implementasyonunu ger\u00e7ekle\u015ftirece\u011fiz. &#8220;<em>Remove<\/em>&#8221; method&#8217;u i\u00e7erisinde ise istedi\u011fimiz bir data&#8217;n\u0131n cache&#8217;ini invalide edebilmemiz i\u00e7in gerekli olan logic&#8217;i ekleyece\u011fiz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Cache service&#8217;i olarak ise, <strong>Redis&#8217;i<\/strong> implemente edece\u011fiz. Ben bu konuda <em>Azure Redis Cache<\/em> service&#8217;ini kullanaca\u011f\u0131m. <em>Azure Redis Cache<\/em> service&#8217;inin kurulumu ile ilgili ad\u0131mlara ise, <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-cache-for-redis\/quickstart-create-redis?WT.mc_id=DT-MVP-5003382\" target=\"_blank\" rel=\"noreferrer noopener\">buradan<\/a> ula\u015fabilirsiniz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Implementasyona ba\u015flamadan \u00f6nce, &#8220;<em>Microsoft.Extensions.Caching.StackExchangeRedis<\/em>&#8221; paketini projeye NuGet \u00fczerinden a\u015fa\u011f\u0131daki gibi dahil edelim.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-preformatted\">dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis --version 5.0.1<\/pre>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Ard\u0131ndan projeye &#8220;<em>RedisCacheService<\/em>&#8221; ad\u0131nda bir class olu\u015fturarak, &#8220;<em>ICacheService<\/em>&#8221; interface&#8217;inin implementasyonunu a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirelim.<\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-code\"><code>using System;\r\nusing System.Text.Json;\r\nusing System.Threading.Tasks;\r\nusing Microsoft.Extensions.Caching.Distributed;\r\n\r\nnamespace MyTodoAPI.Services\r\n{\r\n    public class RedisCacheService : ICacheService\r\n    {\r\n        private readonly IDistributedCache _distributedCache;\r\n\r\n        public RedisCacheService(IDistributedCache distributedCache)\r\n        {\r\n            _distributedCache = distributedCache;\r\n        }\r\n\r\n        public async Task&lt;T&gt; GetOrSetAsync&lt;T&gt;(string cacheKey, int cacheDurationInMin, Func&lt;Task&lt;T&gt;&gt; func)\r\n        {\r\n            string cachedItem = await _distributedCache.GetStringAsync(cacheKey);\r\n\r\n            if(!string.IsNullOrEmpty(cachedItem))\r\n            {\r\n                return JsonSerializer.Deserialize&lt;T&gt;(cachedItem);\r\n            }\r\n\r\n            var item = await func();\r\n\r\n            if (item != null)\r\n            {\r\n                var cacheEntryOptions = new DistributedCacheEntryOptions()\r\n                                        .SetSlidingExpiration(TimeSpan.FromMinutes(cacheDurationInMin));\r\n\r\n                string serializedItem = JsonSerializer.Serialize(item);\r\n\r\n                await _distributedCache.SetStringAsync(cacheKey, serializedItem, cacheEntryOptions);\r\n            }\r\n\r\n            return item;\r\n        }\r\n\r\n        public async Task Remove(string cacheKey)\r\n        {\r\n            await _distributedCache.RemoveAsync(cacheKey);\r\n        }\r\n    }\r\n}<\/code><\/pre>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Yukar\u0131daki kod blo\u011funa bakt\u0131\u011f\u0131m\u0131zda, caching i\u015flemleri i\u00e7in build-in olarak gelen &#8220;<em>IDistributedCache<\/em>&#8221; interface&#8217;ini kulland\u0131\u011f\u0131m\u0131z\u0131 g\u00f6rebiliriz. Adapt\u00f6r olarak redis&#8217;i ise, bir sonraki a\u015famada inject edece\u011fiz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>&#8220;<em>GetOrSetAsync<\/em>&#8221; method&#8217;u i\u00e7erisinde ise tekrar kullan\u0131labilir bir yap\u0131 elde edebilmek i\u00e7in func delegate&#8217;inden yararland\u0131k. Ayr\u0131ca method ak\u0131\u015f\u0131n\u0131n ise yukar\u0131da payla\u015ft\u0131\u011f\u0131m diyagram ile benzer oldu\u011funu da g\u00f6rebiliriz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Son olarak cache&#8217;lenmi\u015f data&#8217;n\u0131n invalidation i\u015flemleri i\u00e7in ise, &#8220;<em>Remove<\/em>&#8221; method&#8217;unu kullanaca\u011f\u0131z.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<h2 class=\"wp-block-heading\">\u00d6rnek Bir Kullan\u0131m<\/h2>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>\u00d6rnek ger\u00e7ekle\u015ftirebilmek i\u00e7in default template ile gelen &#8220;<em>WeatherForecast<\/em>&#8221; \u00fczerinden gidece\u011fim.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Bunun i\u00e7in &#8220;<em>IWeatherForecastService<\/em>&#8221; interface&#8217;ini ve &#8220;<em>WeatherForecastService<\/em>&#8221; class&#8217;\u0131n\u0131 a\u015fa\u011f\u0131daki gibi olu\u015ftural\u0131m ve cache service&#8217;ini implemente edelim.<\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-code\"><code>using System.Collections.Generic;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace MyTodoAPI.Services\r\n{\r\n    public interface IWeatherForecastService\r\n    {\r\n        Task&lt;List&lt;WeatherForecast&gt;&gt; GetWeatherForecasts();\r\n        Task AddNewWeatherSummary(string summary);\r\n    }\r\n}<\/code><\/pre>\r\n<p><\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-code\"><code>using System;\r\nusing System.Collections.Generic;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace MyTodoAPI.Services\r\n{\r\n    public class WeatherForecastService : IWeatherForecastService\r\n    {\r\n        private readonly ICacheService _cacheService;\r\n\r\n        private static List&lt;string&gt; Summaries = new()\r\n        {\r\n            \"Freezing\", \"Bracing\", \"Chilly\", \"Cool\", \"Mild\", \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\"\r\n        };\r\n\r\n        private const string GetWeatherForecastsCacheKey = \"GetWeatherForecasts\";\r\n        private const string GetWeatherForecastsCacheDurationInMin = 30;\r\n\r\n        public WeatherForecastService(ICacheService cacheService)\r\n        {\r\n            _cacheService = cacheService;\r\n        }\r\n\r\n        public async Task&lt;List&lt;WeatherForecast&gt;&gt; GetWeatherForecasts()\r\n        {\r\n            List&lt;WeatherForecast&gt; weatherForecasts = await _cacheService.GetOrSetAsync(cacheKey: GetWeatherForecastsCacheKey,\r\n                                                                                       cacheDurationInMin: GetWeatherForecastsCacheDurationInMin,\r\n                                                                                       func: () =&gt;\r\n            {\r\n                var rng = new Random();\r\n                var weatherForecasts = new List&lt;WeatherForecast&gt;();\r\n\r\n                foreach (var item in Summaries)\r\n                {\r\n                    weatherForecasts.Add(new WeatherForecast\r\n                    {\r\n                        Date = DateTime.Now,\r\n                        TemperatureC = rng.Next(-20, 55),\r\n                        Summary = item\r\n                    });\r\n                }\r\n\r\n                return Task.FromResult(weatherForecasts);\r\n            });\r\n\r\n            return weatherForecasts;\r\n        }\r\n\r\n        public Task AddNewWeatherSummary(string summary)\r\n        {\r\n            Summaries.Add(summary);\r\n\r\n            _cacheService.Remove(GetWeatherForecastsCacheKey);\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n    }\r\n}<\/code><\/pre>\r\n<p><\/p>\r\n<p>&#8220;<em>GetWeatherForecasts<\/em>&#8221; method&#8217;u i\u00e7erisinde &#8220;<em>ICacheService<\/em>&#8221; ini kullanarak basit bir logic implemente ettik. E\u011fer istedi\u011fimiz data daha \u00f6nce cache&#8217;e eklenmi\u015f ise, bu veriye h\u0131zl\u0131 bir \u015fekilde cache \u00fczerinden eri\u015febilece\u011fiz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Ayr\u0131ca yeni bir &#8220;summary&#8221; ekleme ihtiyac\u0131nda da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi ilgili cachi&#8217;i, &#8220;<em>Remove<\/em>&#8221; method&#8217;u ile invalidate edece\u011fiz.<\/p>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>Son olarak injection i\u015flemlerini ise &#8220;<em>Startup<\/em>&#8221; i\u00e7erisinde a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirelim.<\/p>\r\n<p><\/p>\r\n<pre class=\"wp-block-code\"><code>services.AddStackExchangeRedisCache(opt =&gt;\r\n{\r\n    opt.Configuration = Configuration.GetConnectionString(\"redis:connection_string\");\r\n});\r\n\r\nservices.AddSingleton&lt;ICacheService, RedisCacheService&gt;();\r\nservices.AddScoped&lt;IWeatherForecastService, WeatherForecastService&gt;();<\/code><\/pre>\r\n<p><\/p>\r\n<p><\/p>\r\n<h2 class=\"wp-block-heading\">Sonu\u00e7<\/h2>\r\n<p><\/p>\r\n<p><\/p>\r\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi cache-aside pattern&#8217;\u0131, implemente etmesi olduk\u00e7a kolay bir pattern. Uygulamalar\u0131n iste\u011fi \u00fczerine istenilen data&#8217;y\u0131 cache&#8217;e ekleyebilmemize ve cache&#8217;lenmi\u015f data&#8217;y\u0131 elde edebilmemize olanak sa\u011flamaktad\u0131r. B\u00f6ylelikle \u00f6ng\u00f6r\u00fclemeyen durumlarda da caching i\u015flemlerinden olabildi\u011fince faydalanabilmekteyiz.<\/p>\r\n<p><\/p>\r\n<h2>Referanslar<\/h2>\r\n<p><\/p>\r\n<p><\/p>\r\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/cache-aside?WT.mc_id=DT-MVP-5003382\" target=\"_blank\" rel=\"noreferrer noopener\">Cache-Aside pattern &#8211; Cloud Design Patterns | Microsoft Docs<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Temiz bir kod yazabilmenin yan\u0131 s\u0131ra, sorumlu bir developer olarak uygulamam\u0131z\u0131n performansl\u0131 bir \u015fekilde \u00e7al\u0131\u015fabilmesini sa\u011flamak da bir o kadar \u00f6nemlidir. Bildi\u011fimiz gibi kullan\u0131c\u0131lara daha iyi bir deneyim sa\u011flatabilmemiz i\u00e7in olabildi\u011fince h\u0131zl\u0131 sonu\u00e7lar d\u00f6n\u00fcyor olmal\u0131y\u0131z. Tahmin edebilece\u011fimiz gibi h\u0131zl\u0131ca uygulayabilece\u011fimiz en temel performans iyile\u015ftirmelerinden bir&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/improving-repeated-access-with-cache-aside-pattern\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">Improving Repeated Access with Cache-Aside Pattern<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":3699,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[505,68,418,457,47],"tags":[597,595,594,370],"class_list":["post-3659","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-architectural","category-azure","category-dotnet","category-tasarim-kaliplari-design-patterns","tag-net-5","tag-c-cache-aside","tag-cache-aside-pattern","tag-redis","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-08T16:01:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-08T16:36:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"Improving Repeated Access with Cache-Aside Pattern\",\"datePublished\":\"2021-01-08T16:01:12+00:00\",\"dateModified\":\"2021-01-08T16:36:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/\"},\"wordCount\":1542,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/cache-aside-wall.jpg\",\"keywords\":[\".net 5\",\"c# cache aside\",\"cache aside pattern\",\"redis\"],\"articleSection\":[\".NET Core\",\"Architectural\",\"Azure\",\"dotnet\",\"Tasar\u0131m Kal\u0131plar\u0131 (Design Patterns)\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/\",\"name\":\"Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/cache-aside-wall.jpg\",\"datePublished\":\"2021-01-08T16:01:12+00:00\",\"dateModified\":\"2021-01-08T16:36:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/cache-aside-wall.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/cache-aside-wall.jpg\",\"width\":1200,\"height\":675},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/improving-repeated-access-with-cache-aside-pattern\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Improving Repeated Access with Cache-Aside Pattern\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/","og_locale":"tr_TR","og_type":"article","og_title":"Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2021-01-08T16:01:12+00:00","article_modified_time":"2021-01-08T16:36:56+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"11 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"Improving Repeated Access with Cache-Aside Pattern","datePublished":"2021-01-08T16:01:12+00:00","dateModified":"2021-01-08T16:36:56+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/"},"wordCount":1542,"commentCount":3,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg","keywords":[".net 5","c# cache aside","cache aside pattern","redis"],"articleSection":[".NET Core","Architectural","Azure","dotnet","Tasar\u0131m Kal\u0131plar\u0131 (Design Patterns)"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/","url":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/","name":"Improving Repeated Access with Cache-Aside Pattern - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg","datePublished":"2021-01-08T16:01:12+00:00","dateModified":"2021-01-08T16:36:56+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2021\/01\/cache-aside-wall.jpg","width":1200,"height":675},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/improving-repeated-access-with-cache-aside-pattern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Improving Repeated Access with Cache-Aside Pattern"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3659","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=3659"}],"version-history":[{"count":5,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3659\/revisions"}],"predecessor-version":[{"id":3705,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/3659\/revisions\/3705"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/3699"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=3659"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=3659"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=3659"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}