Cache PDF
Document Details
Uploaded by DecisiveGreatWallOfChina1467
Tags
Summary
This document discusses caching strategies in scalable systems. It covers various caching approaches, including client-side, CDN, web server, database, and application caching. It explores how caching can improve performance and reduce server load.
Full Transcript
Cache *[ Source: Scalable system design patterns ]()* Caching improves page load times and can reduce the load on your servers and == == ==...
Cache *[ Source: Scalable system design patterns ]()* Caching improves page load times and can reduce the load on your servers and == == == == == == == == == == == databases. In this model, the dispatcher will first lookup if the request has been == == == *** *** == == made before and try to find the previous result to return, in order to save the actual == == execution. (Otherwise the Dispatcher forwards the request to a worker ) == == Databases often benefit from a uniform distribution of reads and writes across its == == == partitions. Popular items can skew the distribution , causing bottlenecks. == == == == == == == — Putting a cache in front of a database can help absorb uneven loads and spikes == == == == == == == == in traffic. == == == Client caching == Caches can be located on the client side ( OS or browser ), server side, or in a == == == == == == [ ]() *** *** == distinct cache layer. == == CDN caching == [ CDNs are considered a type of cache. ]() == Web server caching == [ == Reverse proxies and caches such as Varnish can serve static and dynamic content == ]() [ == == ]() == == == == directly. Web servers can also cache requests , returning responses without having to == == == == contact application servers. == == == Database caching == Your database usually includes some level of caching in a default configuration , == == optimized for a generic use case. Tweaking these settings for specific usage patterns == == can further boost performance. == Application caching == In-memory caches such as Memcached and Redis are key-value stores between == == == == == == your application and your data storage. Since the data is held in RAM , it is much == == == == == == == faster than typical databases where data is stored on disk. RAM is more limited than == == == == disk , so cache invalidation algorithms such as least recently used (LRU) can help == [ == == ]() [ == == ]() invalidate 'cold' entries and keep 'hot' data in RAM. == == == == == Redis has the following additional features: == == Persistence option == == Built-in data structures such as sorted sets and lists == == == == == ⠀ There are multiple levels you can cache that fall into two general categories: == == ** == database queries and objects : == ** ** == == ** == Row level == == Query-level == Fully-formed serializable objects == == == Fully-rendered HTML == ⠀ *** Generally, you should try to avoid file-based caching , as it makes cloning and auto- *** *** *** == == == == == scaling more difficult. == Why does file based caching make cloning and auto-scaling more difficult? File-based caching makes cloning and auto-scaling more difficult due to the ** ** ** ** following key reasons: ** 1. Lack of Shared State Across Instances ** ** File-based caches are stored locally on the filesystem of a single server ** instance. In a distributed system: When new instances are cloned or added during auto-scaling, they do not have access to the cached data stored on other instances. Each instance ends up with its own isolated cache, leading to cache ** fragmentation. ** ** 2. Cache Inconsistency ** Since the cache is stored locally: Different instances might have different versions of cached data. ** ** This leads to cache inconsistency, where requests handled by ** ** different instances may yield inconsistent results. Synchronizing file-based caches across multiple instances is non-trivial and requires additional mechanisms, such as file replication or a shared storage solution. ** 3. Increased Latency for New Instances ** When new instances are cloned during auto-scaling: They start with an empty cache because the cached files are not ** ** shared. This results in a "cold start", where the new instances must fetch all ** ** data from the original source (e.g., database) again. This degrades performance until the cache warms up. ** ** ** 4. Storage Limitations ** In auto-scaling environments, the local disk space available for caching on ** ** each instance might become a bottleneck: If the cache grows too large, the system risks running out of disk space on some instances. This makes file-based caching harder to manage at scale. ** 5. Difficulty in Load Balancing ** In environments with multiple clones of an application: A load balancer directs requests to different instances. ** ** Since each instance has its own isolated file-based cache, there is no ** guarantee that a cache hit on one instance will be valid on another. ** This reduces the overall cache hit rate, increasing the load on the backend systems. ** 6. Challenges with Deployment and Consistency ** When deploying updates or scaling, maintaining the state of the cache ** ** across instances becomes a challenge: ** Cache invalidation becomes complex, as the file-based cache on all ** instances needs to be updated simultaneously. If not done correctly, this can lead to stale or inconsistent data being ** ** served. ** Solutions to Address These Challenges ** To mitigate these issues, distributed or centralized caching systems are preferred for environments that require cloning and auto-scaling. Examples include: 1. In-Memory Distributed Caching: ** ** Tools like Redis, Memcached, or Amazon ElastiCache store cache ** ** ** ** ** ** data in memory and share it across instances, ensuring consistency and availability. 2. Shared Network File Systems: ** ** Solutions like AWS EFS (Elastic File System) or Google Cloud ** ** ** Filestore allow multiple instances to access the same cached files. ** 3. Stateless Applications: ** ** Design the application to be stateless and rely on centralized caching ** ** instead of local file storage. ** Summary ** File-based caching is challenging in auto-scaling and cloning scenarios because it leads to isolated caches, inconsistent data, cold starts, and increased ** ** ** ** ** ** management complexity. To handle these environments effectively, use ** centralized or distributed caching systems that can scale dynamically and ** maintain shared state across instancess. Caching at the database query level == == Whenever you query the database, hash the query as a key and store the result to == == == == == == == == the cache. This approach suffers from expiration issues : == == == == Hard to delete a cached result with complex queries == == * If one piece of data changes such as a table cell, you need to delete all cached * == queries that might include the changed cell == Applications Needing Query-Level Caching: 1. E-commerce Websites: Product catalogs or pricing data that rarely changes, ** ** reducing database load for high-traffic queries. 2. Social Media Platforms: User profiles or feed data that doesn't update ** ** frequently, improving response times for repeated queries. Applications That May Not Need Query-Level Caching: 1. Banking Applications: Real-time account balances must always reflect up-to- ** ** date information to ensure accuracy. 2. Stock Trading Platforms: Live stock prices change rapidly, requiring real-time ** ** updates for precision. ℹ Caching at the object level == == See your data as an object , similar to what you do with your application code. Have == == your application assemble the dataset from the database into a class instance or a == == == data structure(s ): == * Remove the object from cache if its underlying data has changed * *** *** == == Allows for asynchronous processing : workers assemble objects by consuming == == == == the latest cached object == == ⠀ How is it possible to cache an activity stream? Caching an activity stream involves storing precomputed or partially computed ** ** streams of user activities (e.g., posts, comments, likes) to improve performance and scalability. Instead of relying on live, real-time connections like an event bus, activity streams are cached as individual objects (e.g., posts or events) or as preassembled streams, allowing for faster retrieval and reduced backend load. Updates to the stream trigger cache invalidation or incremental updates, * * * * ensuring freshness, while time-based expiration or event-driven invalidation keeps data consistent. This approach enhances scalability and user experience, particularly for systems like social media platforms or dashboards, by serving cached results efficiently without the need to recompute the entire stream on every request. " == When to update the cache == 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