From 9a2bc75646a67492b85e48c4547376186931b3da Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Thu, 19 Jan 2023 18:54:30 +0400 Subject: [PATCH] Add caching strategies --- .../105-caching-strategies/100-cache-aside.md | 21 ++++++++++++---- .../101-write-through.md | 25 +++++++++++++++++-- .../102-write-behind.md | 4 ++- .../103-refresh-ahead.md | 8 ++++-- .../105-caching-strategies/index.md | 7 ++++++ 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/100-cache-aside.md b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/100-cache-aside.md index f5904afa2..a871f9bfc 100644 --- a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/100-cache-aside.md +++ b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/100-cache-aside.md @@ -1,6 +1,5 @@ # 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 entry in cache, resulting in a cache miss @@ -8,9 +7,21 @@ The application is responsible for reading and writing from storage. The cache d - Add entry to cache - Return entry -Memcached is generally used in this manner. 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. +```python +def get_user(self, user_id): + user = cache.get("user.{0}", user_id) + if user is None: + user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id) + if user is not None: + key = "user.{0}".format(user_id) + cache.set(key, json.dumps(user)) + return user +``` + +[Memcached](https://memcached.org/) is generally used in this manner. 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. + +![Cache Aside](https://i.imgur.com/Ujf0awN.png) -Learn more from the following links: +To learn more, have a look at the following resources: -- [Getting started with Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside) -- [What is Memcached?](https://memcached.org/) \ No newline at end of file +- [From cache to in-memory data grid](https://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast) \ No newline at end of file diff --git a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/101-write-through.md b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/101-write-through.md index 81d77b2ef..ecbdeedbb 100644 --- a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/101-write-through.md +++ b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/101-write-through.md @@ -6,8 +6,29 @@ The application uses the cache as the main data store, reading and writing data - Cache synchronously writes entry to data store - Return +Application code: + +```python +set_user(12345, {"foo":"bar"}) +``` + +Cache code: + +```python +def set_user(user_id, values): + user = db.query("UPDATE Users WHERE id = {0}", user_id, values) + cache.set(user_id, user) +``` + 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. -To learn more, visit the following links: +## 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 through](https://i.imgur.com/Ujf0awN.png) + +Have a look at the following resources to learn more: -- [Getting started with Write-through](https://github.com/donnemartin/system-design-primer#Write-through) \ No newline at end of file +- [Scalability, availability, stability, patterns](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) \ No newline at end of file diff --git a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/102-write-behind.md b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/102-write-behind.md index e2164a5f4..44d7832d7 100644 --- a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/102-write-behind.md +++ b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/102-write-behind.md @@ -10,6 +10,8 @@ In write-behind, the application does the following: - 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. +![Scalability, availability, stability, patterns](https://i.imgur.com/XDsb7RS.png) + To learn more, visit the following links: -- [Getting started with Write-behind](https://github.com/donnemartin/system-design-primer#Write-behind) \ No newline at end of file +- [Scalability, availability, stability, patterns](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) \ No newline at end of file diff --git a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/103-refresh-ahead.md b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/103-refresh-ahead.md index c53f9063d..836b9e154 100644 --- a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/103-refresh-ahead.md +++ b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/103-refresh-ahead.md @@ -1,10 +1,14 @@ # 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. +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. ## Disadvantage of refresh-ahead: - Not accurately predicting which items are likely to be needed in the future can result in reduced performance than without refresh-ahead. +![](https://i.imgur.com/sBXb7lb.png) + To learn more, visit the following links: -- [Getting started with Refresh-ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead) \ No newline at end of file +- [From cache to in-memory data grid](http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast) \ No newline at end of file diff --git a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/index.md b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/index.md index 4471b7b81..d13eae628 100644 --- a/src/roadmaps/system-design/content/112-caching/105-caching-strategies/index.md +++ b/src/roadmaps/system-design/content/112-caching/105-caching-strategies/index.md @@ -1 +1,8 @@ # Caching Strategies + +Since you can only store a limited amount of data in cache, you'll need to determine which cache update strategy works best for your use case. Here is the list of cache update strategies: + +- Cache-aside +- Write-through +- Write-behind +- Refresh-ahead \ No newline at end of file