Cache
Caching is a technique to speed up data lookups (data reading). Instead of reading the data directly from its source, which could be a database or another remote system, the data is read directly from a cache on the computer that needs the data. Caching improves page load times and can reduce the load on your servers and databases.
Databases often benefit from a uniform distribution of reads and writes across its partitions. Fetching most popular items repeatedly can add skew to this uniform distribution, causing bottlenecks. Adding a cache layer in front of a database can help to avoid this uneven loads and spikes in application traffic.
Given this, you'll need to determine which cache update strategy works best for your use case. Below are the four different ways to update your cache.
Cache Aside
The application is responsible for reading and writing from storage. The cache does not interact with storage directly. The application does the following:
- Look for an entry in the cache, resulting in a cache miss
- Load entry from the database
- Add entry to the cache
- Return entry
Subsequent reads of data added to cache are fast. Cache-aside is also referred to as lazy loading. Only requested data is cached, which avoids filling up the cache with data that isn't requested.
Disadvantages:
- Each cache miss results in three trips, which can cause a noticeable delay.
- Data can become stale if it is updated in the database. This issue is mitigated by setting a time-to-live (TTL) which forces an update of the cache entry, or by using write-through.
- When a node fails, it is replaced by a new, empty node, increasing latency.
Write Through
The application uses the cache as the main data store, reading and writing data to it, while the cache is responsible for reading and writing to the database:
- Application adds/updates an entry in the cache
- Cache synchronously writes an entry to the datastore
- Return
Write-through is a slow overall operation due to the write operation, but subsequent reads of just written data are fast. Users are generally more tolerant of latency when updating data than reading data. Data in the cache is not stale.
Disadvantages:
- When a new node is created due to failure or scaling, the new node will not cache entries until the entry is updated in the database. Cache-aside in conjunction with write-through can mitigate this issue.
- Most data written might never be read, which can be minimized with a TTL.
Write Behind
In write-behind, the application does the following:
- Add/update entry in the cache
- Asynchronously write an entry to the data store, improving write performance
Disadvantages:
- There could be data loss if the cache goes down prior to its contents hitting the data store.
- It is more complex to implement write-behind than it is to implement cache-aside or write-through.
Refresh Ahead
You can configure the cache to automatically refresh any recently accessed cache entry prior to its expiration.
Refresh-ahead can result in reduced latency vs read-through if the cache can accurately predict which items are likely to be needed in the future.
Disadvantages:
- Not accurately predicting which items are likely to be needed in the future can result in reduced performance than without refresh-ahead.
References :
- Images Source: From cache to in-memory data grid
- Images Source: Scalability, availability, stability, patterns
- Images Source: Cache Miss
Top comments (5)
For small applications with a few thousands users, I prefer to use the cache aside technique because it's less complicated to implement. The way I implement it is by populating the cache with data during the first read operation then any subsequent read operation will get the data from the cache.
The cache is then updated only when the data store is updated. And also kicking out data from the cache only when the corresponding data in the data store is removed.
That way the user only queries the data store and update the cache during the first read operation after updating the store data.
Really like these approaches.
Do you happen to know of any examples implementing refresh ahead? Is this something you get out of the box with some caches/databases out there?
'Refresh Ahead' approach is rarely used in real-time production applications. No cache/database provide out of the box solutions. I think max they provide ecosystem with plugins/tools to synchronize between two data sources like to sync data between redis/mysql kind of plugins. But, most of the developers prefer to have their own implementation to keep it simple based on their use case.
What does it mean: 'when a node fails' ?
What the term 'node' here refers to?
A node is a physical or virtual machine running an instance of your server inside a cluster for "horizental scaling" to cope with new demands (requests) to your server.