Cache etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Cache etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

23 Eylül 2026 Çarşamba

Cache Stratejileri - Cache Stampede

Giriş
Açıklamalar çoğunlukla buradan.

1. No protection
Every caller discovers the miss and independently loads the value.

This is the classic cache stampede / thundering herd.

The dangerous part is that the application may be completely correct. The database is simply receiving an unexpected burst.

2. Local singleflight
Here, each application instance says:

"If another thread on this same machine is already loading this key, I'll wait for its result."

Burada halen pod sayısı kadar hit gelebilir.

3. Fleet refresh lease
Only the pod that acquires the lease is allowed to refresh. Burada A uyandı ancak işi bitiremedi, sonra B uyandı işi bitirdi ve daha sonra A uyandı o da işi bitirdi ancak eski veriyi yazdı problemi var. Yani optimistic lock koymak lazım

4. Stale-while-revalidate
you distinguish:
- fresh
- stale-but-usable
- too-old / unavailable

Stale iken de veriyi sunar

The TTL jitter
Hepsi için kullanılabilir. Açıklaması şöyle
Bad jitter
If you do:
TTL = maxTTL + random()

then everything is already guaranteed to live at least maxTTL.

You're spreading the expiration times, but you're also violating the intended freshness boundary.

Subtractive jitter
Instead:
TTL = maxTTL - random()

gives:
maxTTL-0
maxTTL-3
maxTTL-17
maxTTL-42
...

So everything expires at or before the maximum freshness deadline.

The important concept isn't really the exact formula.

It's:

Randomize expiration without extending the maximum allowed lifetime.







3 Nisan 2023 Pazartesi

Cache Stratejileri - Cache Access Patterns Refresh-ahead - Implemented by Cache Provider

Giriş
Şeklen şöyle


Açıklaması şöyle
.. it refreshes the cache data before its expiration time,it is done for hot-data, the data we expect to be requested in the near future.

Approach
1. Supposed the cached data’s expiration time is 60 seconds and the refresh-ahead factor is 0.5.
2. If the cached object is accessed after 60 seconds, Coherence will perform a synchronous read from the cache store to refresh its value.
3. If the cached data is accessed after 30 seconds, said 35th second, the cache returns the data and asynchronously refreshes the data.

20 Mart 2023 Pazartesi

Cache Stratejileri - Cache Access Patterns Write-Around

Giriş
Veri tabanı güncellenir ancak cache güncellenmez. Cache verisi bayatlayınca veri tabanından son durumu okur.

Açıklaması şöyle
This strategy populates the underlying store but not the cache itself. In other words, the write bypasses the cache and writes to the underlying store only.
Açıklaması şöyle
Write request goes around the cache straight to DB and acknowledge is sent back, data is not sent to cache. Data is written to the cache when there is the first cache miss.
Açıklaması şöyle
In this design, cache entry only expires when exceeds the pre-set TTL. There is no cache invalidation nor cache update in the write path. The advantage is that the implementation is very simple, but at the cost of even more cache staleness — as long as the TTL window.
Dezavantajı
Açıklaması şöyle
Written data won't immediately be read back from cache
Ne Zaman Kullanılır
Açıklaması şöyle
This is often used when write volumes are large but read volumes are significantly lower.
Write-Around vs Cache-Aside
Açıklaması şöyle
The difference is that with Cache-Aside, the focus is on the reads and lazy loading — only populating the data into the cache when it is first read from the datastore. Whereas with Write-Around caching, the focus is on write performance instead. This technique is often used to avoid cache pollution when data is being written often but is infrequently read.




Cache Stratejileri - Cache Access Patterns Write-Behind veya Write Back

Giriş
Şeklen şöyle

Aslında Write-Through ile aynıdır. Tek fark veri tabanı güncellemesi senkron değil asenkron yapılır
Açıklaması şöyle
Write-behind approach is very much similar to write-through, just that the database write calls are asynchronous in fashion.
Açıklaması şöyle. 
In a write-behind cache, a write request only updates the cache. Then another background process asynchronously updates the DB with the new entries in the cache. The asynchronous DB update can be implemented as periodic batch update, and the workload can be scheduled to run during mid-night, i.e. when the DB load is low.
Açıklaması şöyle
first write into database and then into cache.
Avantajı
Açıklaması şöyle
In write-heavy environments where slight data loss is tolerable


Cache Stratejileri - Cache Access Patterns Write-Through - Implemented by Cache Provider

Açıklaması şöyle. Yani önce cache güncellenir, sonra veri tabanı güncellenir,
1. The application writes the data directly to the cache.
2. The cache updates the data in the main database. When the write is complete, both the cache and the database have the same value and the cache always remains consistent.
MapWriter kullanılır. Açıklaması şöyle
whenever any “write” request comes, it will come through the cache to the DB. Write is considered successful only if data is written successfully in the cache and in DB.
Eğer Spring ile bunu taklit etmek istersek şöyle yaparız
// With Spring you can mimic it
// Both DB + cache updated synchronously.
@CachePut(value = "users", key = "#user.id")
public User saveUser(User user) {
    return userRepository.save(user);
}


Cache Stratejileri - Cache Access Patterns Read-Through

Giriş
MapLoader kullanılır. Açıklaması şöyle. Uygulama sadece Cache'e erişir. Cache gerekiyorsa, veri tabanından sorgulama yapar.
1. The App never interacts with DB directly but always via Cache.
2. On a cache miss, the cache will read from DB and enrich the cache storage.
3. On a cache hit, data is served from the cache.

You can see, the DB is reached very infrequently and the response is fast since the caches are mostly in-memory (Redis/ Memcached). 
Avantajı
Açıklaması şöyle
Keeps cache consistently populated by handling misses automatically

Read-Through ve Request Collapsing Kavramı
Bir nesne için aynı anda çok fazla istek gelirse, Cache veri tabanına çok fazla sayıda istek gönderir. Bu isteklerin birleştirilmesine Request Collapsing deniliyor.

Cache-aside Okuma vs Read-Through
Şeklen şöyle

18 Ocak 2023 Çarşamba

Cache Stratejileri - Cache Access Patterns Cache-aside

Giriş
Okuma ve yazma işlemlerini kendimiz kodla yapıyoruz

1. Okuma
Okuma şeklen şöyle
Açıklaması şöyle. Aslında bu işlemi cache alt yapısına yaptırırsak Read-Through elde ederiz.
1. Whenever a requests comes to the application, it firsts checks the requested data in the cache.
2. If yes, the cache returns the data.
3. Otherwise, the application queries the data from the database, updates the cache on the way back and then returns the data.
Kod olarak şöyle
String cacheKey = "hello world";
String cacheValue = redisCache.get(cacheKey);
// got cache
if (cacheValue != null) {
    return cacheValue;
} else {
    //no cache, read from database
    cacheValue = getDataFromDB();
    // write date to cache
    redisCache.put(cacheValue);
}
2. Yazma
Yazma ise şöyle. Burada bir çok seçenek var. Önce veri tabanı güncellenebilir, veya cache güncellenebilir, cache silinebilir. Bunlar şöyle
1. Update the cache first, then update the database.
2. Update the database first, then update the cache.
3. Delete the cache first, then update the database.
4 Update the database first, then delete the cache.
Hangisi kullanılırsa kullanılsın, iki tane işlem olduğu için birisinin başarısız olma veya tutarsız sonuç dönme ihtimali var. Bu yüzden cache nesnelerine genellikle zaman aşımı ve bayatlama süresi konuluyor. Böylece bir müddet sonra eventual consistency elde ediliyor. 

Çözümler ve Etkileri
1. Update the database first, then delete the cache
Açıklaması şöyle
After updating the database, the corresponding records of the cache should be cleared immediately. When the same request comes in next time, it will be taken from the database first and the latest result will be written back to the cache.
Problemler
1. Eventual Consistency
Şeklen şöyle. Burada A işlemi bitirinceye kadar B halen eski veriyi okuyor


2. Uygulama veri tabanını günceller ancak cache güncellemesi yapmadan önce ölür. 
Açıklaması şöyle
..  when A wants to update the data, A is killed after finishing the database update, probably due to bugs or application upgrade and so on. Then the data in the cache will remain inconsistent for a long time, until the next update or timeout.
3. Lost Update
Şeklen şöyle
Bu aslında Lost Update problemi ile aynı. A eski veriyi okuyor ve ve Cache'e bunu yazıyor

4. Double Delete
Tutarlılığı artıran bir çözüm de şöyle. Buna double delete deniliyor
Delete the cache first.
Write database.
Sleep for 500 milliseconds, then delete the cache.


9 Aralık 2022 Cuma

Cache Stratejileri - Cache Access Patterns

Giriş
Yöntemler şöyle. Her bir yöntemin kendine göre consistency (tutarlılık) getirisi ve götürüsü var

Çoğu uygulamada %80 Cache-Aside + Eviction yeterli. Ölçeklenmesi gereken sistemlerde şu örüntülere de gerek var.
1. Stampede protection
2. Two-level cache
3. Event invalidation
4. Read-Repair
5. Refresh-Ahead

Spring şunları destekliyor:
1. Cache-Aside (natively)
2. Partial Write-Through
3. Eviction patterns
4. Negative Caching Control 

Eğer daha gelişmiş yöntemleri gerekiyorsa, mecburen cache sağlayıcının API'lerini kullanmak gerekiyor.

Okuma Ağırlıklı Yöntemler
App checks cache first.
If missing, fetch DB and update cache.
Best for: read-heavy systems.

2. Read-Through : Implemented by Cache Provider
App reads from cache.
Cache itself loads from DB if missing.
Best for: simpler app logic.

3. Refresh-ahead : Implemented by Cache Provider

Yazma Ağırlıklı Yöntemler
1. Write-Through : Implemented by Cache Provider
Write goes to cache and DB together.
Best for: strong consistency needs.

2. Write-Behind aka Write Back : Implemented by Cache Provider
Write to cache first, DB later.
Best for: high write throughput.
Risk: data loss if not handled well.

3. Write-Around : Implemented by App





















19 Kasım 2012 Pazartesi

Hibernate ve İkincil Önbellek

İkincil Önbellek
 
İkincil önbellek ile ilgili data detaylı bilgiyi burada bulabilirsiniz.
İkinci önbellek aslında 4 kısımdan oluşuyor. Bunlar entity, collection, query ve timestamp kısımları. Hibernate ikincil öbelleği kullanmak üzere ayarlanırsa bu alanları otomatik olarak oluşturuyor ancak bu alanlara ne kadar bellek ayırılacağı vs. gibi ince detaylar önbellek kütüphanesinin konfigürasyon dosyasında yapılıyor. Örneği burada görebilirsiniz.

İkincil Önbellek Hibernate Sessionları Arasında Ortak Kullanılır

Aşağıdaki şekli buradan aldım ve farklı Hibernate sessionları arasında önbelleğin ortak kullanıldığını görmek mümkün.


Hemen hemen aynı şeyi gösteren bir başka şekil ise buradan geldi.

İkincil Önbelleği Etkinleştirme Ayarları
İkincil önbelleği konfigüre etmek için gereken ayarları gösteren kısmı buradan aldım.

<property name="hibernate.cache.use_second_level_cache">
true</property>
<property name="hibernate.cache.use_query_cache">
true</property>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider</property> 
 
1. Entity Önbellek Ayarları

En kolay yöntem annotation kullanmak. Hibernate annotationları kullanılmak istenirse @Cache kullanılıyor. Eğer JPA annotation kullanılmak istenirse @Cacheable kullanılıyor.

Not : Entity Önbellekte entity'nin primary key değeri arama anahtarı olarak kullanılıyor

Eğer entity'ler InheritanceType.TABLE_PER_CLASS stratejisini kullanıyorsa @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) tag'ini en alttaki sınıfa eklemek gerekiyor.
Yoksa aşağıdaki şekilde de görüldüğü gibi Hibernate accessStrategy sınıfını bulamıyor ve entity ikincil önbelleği kullanamıyor





İkincil Önbellek Stratejileri
Bu konuyla ilgili fazla bilgi bulamadım. Kullanılabilecek stratejiler aşağıda.
NONE :

READ_ONLY : Eğer nesneler hiç değişmiyorsa, değeri hep sabit ise kullanılır

NONSTRICT_READ_WRITE : Çok nadiren değişen nesneler için kullanılır. Eşzamanlı güncellemeler için önbellekte lock mekanizması kullanmaz. Dolayısıyla önbellekten dönen sonucun her zaman en son güncellenen değer olduğunu garanti etmez!

READ_WRITE : En çok kullanılan yöntem.

TRANSACTIONAL : Sadece XA transaction yöneticisi varsa bu seçenek kullanılabilir

İkincil Önbellek Boşaltma Yöntemleri

İkincil önbellek boşaltılması ile ilgili kurallar aşağıda.

sessionFactory.close() –> Destroys the session factory object and releases level 2 cache.
sessionFactory.evict(arga …) –> Removes pojo class object from session factory.
sessionFactory.evictQueries(args…) –> Cleans queries related data from cache.

Evict örneklerini gösteren bir kodu buradan aldım.


İkinci kademe önbellekte entitiy kısmında arama yapılmasını anlatan örneği buradan aldım.


2. Sorgu Önbellek Ayarları
Sorgu önbelleğinin neden aslında zararlı olabileceği ise burada anlatılıyor. Sorgu önbelleği çalışma akışı ise aşağıda.


Not : Sorgu Önbellekte anahtar olarak sorgunun kendisi ve sorguya verilen parametreler arama anahtarı kullanılıyor

Sorgu Önbelleği Tabloların Değişip Değişmediğini Nasıl Anlıyor?
Buradaki soruda da anlatıldığı gibi sorgu çalıştırılmadan önce sorguyu ilgilendiren tabloların UpdateTimestampsCache önbelleğindeki en son güncellenme zamanına bakılıyor. Eğer tablolar önbellekteki sorgu sonucundan sonra güncellenmişse, sorgu tekrar çalıştırılıyor.

26 Temmuz 2012 Perşembe

Hibernate Birincil Önbellek

Birincil Önbellek
Birincil önbellek session ile ilişkilendirilir ve session kapatılınca yok olur. İkincil önbellek ise SessionFactory ile ilişkilendirilir ve SessionFactory kapatılınca yok olur.

Birincil önbelleğin Session ile ilişkili olduğunu gösteren şekli buradan aldım.

Bir diğer şekli ise buradan aldım.

Birincil önbellek bir nesneye arka arkaya birkaç güncelleme gelirse her seferinde veritabanına gitmeden SQL cümlelerini mümkün olduğunca geciktirebilmeye yarar. Eğer session kapatılırsa önbellek te beraberinde kapatılır. Birincil önbellek ile ilgili kurallar aşağıda.

Session.flush() –>  Flushes level one cache content to db software
Session.evict() –> Remove the content of level 1 cache
Session.close() –> closes level 1 cache, before that it calls session.flush()

Batch Processing
Birincil önbellek batch işlemlerde bazen OutOfMemoryException problemine sebep olabilyor. Bunun sebebi ve nasıl çözüleceği "Batch Processing" sayfasında anlatılmış. Ben de aşağıya bazı notlarımı ekliyorum.

Batch Update
Aşağıdaki kod parçasında da görüldüğü gibi openSession() metodu ile elde edilen Session nesnesi, birincil önbellek ile ilişkili ve bu nesne ile yapılan save(),update() vs. gibi işlemlerde parametre olarak geçilen nesne önbelleğe dahil ediliyor. Ancak çok fazla sayıda işlem yapılırsa önbellek şiştiği için OutofMemoryError hatası alabiliyoruz.


Bu durumdan kurtulmak için iki yol var. Birinci yöntemde önbellek ara sıra temizleniyor. Aşağıdaki kodda önbellek her 20 döngüde bir temizleniyor.
İkinci yöntemde ise önbellek hiç kullanılmıyor. Birinci koddan farklı olarak bu sefer openStatelessSession() metodunun çağırıldığına dikkat !
Batch Select
Batch select için örnek Managing the caches başlığı altında verilmiş.
Birincil Önbellek ve load
When does Hibernate Session.load() throw an exception sorusunda load() metodunun bir nesnenin veritabanında olup olmadığını kontrol etmek için kullanılmaması gerektiği açıklanmış.