Web Caching This article covers one of the secrets of high scalability and performance. A that has more than brings us the following: . blog post about Flickr Architecture 5 billions photos Caching and RAM are the answer to everything A could store data for the purpose of speed up future requests on three different layers and environments: 1) Client, 2) , 3) Server, and 4) Application. Website Network Chapter 1. Client Caching Different pages of a Website commonly share the same assets. The user should reuse assets during navigation. , and could be cached for months and also the document page itself could be cached for minutes on the Client Browser. Images scripts, styles HTTP headers have the responsibility to define if a response . The following header example indicates that the response might be cached for 7 days. The Browser is going to request it again only if the cache expires or if the user : could be cached and for how long Cache-Control force refreshes the page Request and response that could be cached for 604800 seconds A response could also include a header or a header. These headers are used to verify if an expired response could be reused. The response status 304 indicates that the content didn't change and . Pay attention to the and the header pairs and the dates bellow: Last-Modified Etag doesn't need to be downloaded again Last-Modified If-Modified-Since Response with Last-Modified header and subsequent request using it The header is used with in a similar way to exchange codes to identify if a content changed or not. Etag If-None-Match A Website with the HTTP headers wisely defined will provide a better experience for the users. The Browser could save time and Network Bandwidth based on it. Chapter 2. Network Caching Wikipedia defines a Content Delivery Network (CDN) as a globally distributed network of proxy servers. CDNs are about caching — shared caching. The HTTP header directive allows different parts of the Network to cache a response. It is common to find assets with meaning that it last a year anywhere. Cache-control: public Cache-Control: public, max-age=31536000 You might know that there are others . There is also a to handle authenticated and other kinds of dynamic responses. header cache directives powerful header Chapter 3. Server Caching Finally, the control is all on your hand, developer! Aside setting the right response headers and handle the request headers correctly, there are many things you could improve on server and application side. The first approach to is setting up a cache server between the application and the client. faster responses and save resources Clients requesting the same content to a proxy server Tools like , , and might cache , and other contents that are shared by users. The following setup up a nginx server proxy that caches content relying only Varnish Squid nginx images scripts on the application HTTP headers: There is also a directive called that allows the proxy server to at a time for the application. If it is set on, the clients are going to receive the response when the first request returns. proxy_cache_lock delegate only the first of similar client requests Many clients requesting the same content at the same time It is a simple but powerful mechanism that , and many clients are requesting for it. avoids chaos on the application side when a content expires The server proxy could also deliver expired content for the subsequent similar requests using the directive . This faster the response time and reduces the number of clients waiting for a server response. proxy_cache_use_stale: updating; Last but not least, the . There are flags for the directive to deliver expired content when the application returns error statuses or when the communication between the server proxy and the application is not working as expected. proxy could improve the fault tolerance of the application proxy_cache_use_stale The article have more details and configuration options. A Guide to Caching with NGINX and NGINX Plus Chapter 4. Application Caching Application Caching reduces the time of specific operations. Complex computations, data requests to other services or common data shared across request are some examples. 4.1. Memoization The Ruby code above uses the simple . It stores the to avoid future calculations. In that case, it will store the data on an object instance, and it will only save resources during a request. technique memoization caching product price This technique could be applied anywhere in the code. But the use of it brings some concerns. It is important to mind that your data will not expire for example. A global code is going to last in-memory during all the application execution cycle. memoization 4.2. Smart In-Memory Caching The code above uses the to store and reuse the during one minute . The definition uses the to identify the data. This technique is used there to reduce the amount of request to the external Category Tax Service saving resources and time. Rails Caching API category tax across requests cache key category_id There are many libraries that provide this pattern. But it is important to mention that the application memory is a finite resource. The . It could be a problem if your application massively caches data consuming all the available memory. node-cache module, for example, doesn't manage the amount of memory consumed The by removing the least recently used entries. It allows to cache immutable data without defining expiration. Rails Memory Caching wisely prunes the cached data when it exceeds the allotted memory size 4.3. Cache Storages — Shared Caching Handle a growing amount of users and requests is an important subject of Web development. One of the ways to scale an application is through adding more application instances (scale horizontally). And as you might imagine, the simple in-memory cache can't be shared between instances. The Twelve-factor App, a methodology for building Software as a Service (SaaS), points that or job — with many processes of each type running, chances are high that a future request will be served by a different process. an application should never assume that anything cached in memory or on disk will be available on a future request A Key-value Storage like or could be used to share cache data between application instances. These tools have to prune the amount of cached data. Cache Storages might also be fault tolerable with and . It should have so different requirements that . Memcached Redis different policies replication persistence Netflix builds it own tool Another important aspect to consider on using Cache Storages is the that happens when different application instances fetch for a not cached data at the same time. have the to minimize this effect. race condition Rails Cache Fetch API race_condition_ttl It is difficult to completely eliminate cache updating race conditions issues with multiple application instances. A solution for that is to update the cache data outside the application flow and just consume cached data on the application. On a micro services architecture, it is also possible to protect the communication between application and service with a nginx proxy server as explained above. I hope this article helps you to understand and choose the best strategy for your application. . You should set up the others caching strategies when you fill some performance pain, keep in mind that “premature optimization is the root of all evil.” HTTP headers for caching is something easy that you should setup as soon as possible
Share Your Thoughts