Do you really understand the "Cache" it

I. Introduction

Caching can open very slowly so that the original page can become "seconds to open." APP usually visit the site almost all involve the use of cache.

So, in addition to the cache can speed up data access, as well as what effect?

In addition, everything has two sides, how can we be making the most of the advantages of caching, while avoiding its drawbacks it?

This article will give share with you how to understand the cache, as well as its use of ideas, we hope to inspire.

Second, what the cache can do?

As previously mentioned, we are most common understanding is that when we come across a page opens very slow time, think of the introduction of the cache, the page opens so fast. In fact, the fast and slow is relative, from a technical point of view, the cache fast because the cache memory is to establish the basis, and the memory read and write speeds many times faster than hard disks, so use memory instead of disk reads and writes as natural media can greatly improve the speed of access to data.

This process is generally such that when the data for subsequent access has been accessed in memory storage used in order to achieve the effect of speed.

In fact, in addition, there are two other important cache use way: pre-reading and writing delayed.

Third, pre-reading

Prefetch is pre-loaded data to be read, can be referred to as "pre-stored" in the system which is the first portion of the hard drive is loaded into memory, and then provide services.

Why do you do that? Because some systems would face tens of thousands of requests come in, if these requests directly hit the database, the database may be very large pressure surge, pocketing directly under, unable to respond to normal once started.

To alleviate this problem, we need to "pre-reading" to solve.

Maybe you will play, even with the cache or could not carry it? That is to do load balancing scale and the time, the contents of which are not discussed in this article, there is a special opportunity to share it.

If the "pre-reading" in the "Data export" added a front buffer, then say the following "delayed write" is after "data entry" added a rear buffer.

Fourth, write delay

As you probably know, the database write speed is slower than reading speed, because when there is written the accuracy of a series of mechanisms to ensure data. So, if you want to improve writing speed, then either do sub-library sub-table, or is carried out through a buffer cache, then a one-time batch written to disk in order to speed up.

Since the sub-library sub-table great for cross-table operation condition combination inquiry and many side effects, so the introduction of its complexity is greater than the introduction of the cache, we should give priority to introducing caching scheme.

那么,通过缓存机制来加速“写”的过程就可以称作“延迟写”,它是预先将需要写入磁盘或数据库的数据,暂时写入到内存,然后返回成功,再定时将内存中的数据批量写入到磁盘。

可能你会想,写到内存就认为成功,万一中途出现意外、断电、停机等导致程序异常终止的情况,数据不就丢失了吗?

是的,所以“延迟写”一般仅用于对数据完整性要求不是那么苛刻的场景,比如点赞数、参与用户数等等,可以大大缓解对数据库频繁修改所带来的压力。

其实在我们熟知的分布式缓存Redis中,其默认运用的持久化机制---RDB,也是这样的思路。

在一个成熟的系统中,能够运用到缓存的地方其实并不是一处。下面就来梳理一下我们在那些地方可以加“缓存”。

五、哪里可以加缓存?

在说哪里可以加缓存之前我们先搞清楚一个事情,我们要缓存什么?也就是符合什么特点的数据才需要加缓存?毕竟加缓存是一个额外的成本投入,得物有所值。

一般来说你可以用两个标准来衡量:

热点数据:被高频访问,如几十次/秒以上。

静态数据:很少变化,读大于写。

接下来就可以替他们找到合适的地方加缓存了。

缓存的本质是一个“防御性”的机制,而系统之间的数据流转是一个有序的过程,所以,选择在哪里加缓存就相当于选择在一条马路的哪个位置设路障。在这个路障之后的道路都能受到保护,不被车流碾压。

那么在以终端用户为起点,系统所用的数据库为终点的这条道路上可以作为缓存设立点的位置大致有以下这些:

每个设立点可以挡掉一些流量,最终形成一个漏斗状的拦截效果,以此保护最后面的系统以及最终的数据库。

下面简要描述一下每个运用场景以及需要注意的点。

六、缓存类别

1、浏览器缓存

这是离用户最近的可以作为缓存的地方,而且借助的是用户的“资源”(缓存的数据在用户的终端设备上),性价比可谓最好,让用户帮你分担压力。

当你打开浏览器的开发者工具,看到 from cache 或者 from memory cache、from disk cache 的时候,就意味着这些数据已经被缓存在了用户的终端设备上了,没网的时候也能访问到一部分内容就是这个原因。

这个过程是浏览器替我们完成的,一般用于缓存图片、js 与 css 这些资源,我们可以通过 Http 消息头中的 Cache-Control 来控制它,具体细节这里就不展开了。此外,js 里的全局变量、cookie 等运用也属于该范畴。

浏览器缓存是在用户侧的缓存点,所以我们对它的掌控力比较差,在没有发起新请求的情况下,你无法主动去更新数据。

2、CDN缓存

提供CDN服务的服务商,在全国甚至是全球部署着大量的服务器节点(可以叫做“边缘服务器”)。那么将数据分发到这些遍布各地服务器上作为缓存,让用户访问就近的服务器上的缓存数据,就可以起到压力分摊和加速效果。这在TOC类型的系统上运用,效果格外显著。

但是需要注意的是,由于节点众多,更新缓存数据比较缓慢,一般至少是分钟级别,所以一般仅适用于不经常变动的静态数据。

解决方式也是有的,就是在 url 后面带个自增数或者唯一标示,如 ?v=1001。因为不同的 url 会被视作“新”的数据和文件,被重新 create 出来。

3、网关(代理)缓存

很多时候我们在源站前面加一层网关,为的是做一些安全机制或者作为统一分流策略的入口。

同时这里也是做缓存的一个好场所,毕竟网关是“业务无关”的,它能够拦下来请求,对背后的源站也有很大的受益,减少了大量的CPU运算。

常用的网关缓存有Varnish、Squid与Ngnix。一般情况下,简单的缓存运用场景,用Ngnix即可,因为大部分时候我们会用它做负载均衡,能少引入一个技术就少一分复杂度。如果是大量的小文件可以使用Varnish,而 Squid 则相对大而全,运用成本也更高一些。

3、进程内缓存

可能我们大多数程序员第一次刻意使用缓存的场景就是这个时候。

一个请求能走到这里说明它是“业务相关”的,需要经过业务逻辑的运算。

也正因如此,从这里开始对缓存的引入成本比前面3种大大增加,因为对缓存与数据库之间的“数据一致性”要求更高了。

4、进程外缓存

这个大家也熟悉,就是 Redis 与 Memcached 之类,甚至也可以自己单独写一个程序来专门存放缓存数据,供其它程序远程调用。

这里先多说几句关于 Redis 和 Memcached 该怎么选择的思路。

对资源(CPU、内存等)利用率格外重视的话可以使用Memcached ,但程序在使用的时候需要容忍可能发生的数据丢失,因为纯内存的机制。如果无法容忍这单,并对资源利用率也比较豪放的话就可以使用Redis。而且Redis的数据库结构更多, Memcached 只有 key-value,更像是一个 NoSQL 存储。

5、数据库缓存

数据库本身是自带缓存模块的,否者也不会叫它内存杀手,基本上你给多少内存它就能吃多少内存。数据库缓存是数据库的内部机制,一般都会给出设置缓存空间大小的配置来让你进行干预。

最后,其实磁盘本身也有缓存。所以你会发现,为了让数据能够平稳地写到物理磁盘中真的是一波三折。

七、缓存是银弹吗?

可能你会想缓存那么好,那么应该多多益善,只要慢就上缓存来解决?

一个事物看上去再好,也有它负面的一面,缓存也有一系列的副作用需要考虑。除了前面提到的“缓存更新”和“缓存与数据的一致性”问题,还有诸如下边的这些问题:

1、缓存雪崩

大量的请求并发进入时,由于某些原因未起到预期的缓冲效果,哪怕只是很短的一段时间,导致请求全部转到数据库,造成数据库压力过重。解决它可以通过“加锁排队”或者“缓存时间增加随机值”。

2、缓存穿透

和缓存雪崩类似,区别是这会持续更长的时间,因为每次“cache miss”后依然无法从数据源加载数据到缓存,导致持续产生“cache miss”。解决它可以通过“布隆过滤器”或者“缓存空对象”。

3、缓存并发

一个缓存key下的数据被同时set,怎么保证业务的准确性?再加上数据库的话?进程内缓存、进程外缓存与数据库三者皆用的情况下呢?用一句话来概括建议的方案是:使用“先DB再缓存”的方式,并且缓存操作用delete而不是set。

4、缓存无底洞

虽然分布式缓存是可以无限横向扩展的,但是,集群下的节点真的是越多越好吗?当然不是,缓存也是符合“边际效用递减”规律的。

5、缓存淘汰

内存总是有限的,如果数据量很大,那么根据具体的场景定制合理的淘汰策略是必不可少的, 如 LRU、LFU 与 FIFO 等等。

八、总结

本文介绍了运用缓存的三种思路,然后梳理了在一个完整的系统中可以设立缓存的几个位置,并且分享了关于浏览器、CDN与网关(代理)等缓存的一些实用经验,没有具体展开来讲细节,只是希望我们对缓存有一个更加体系化的认识,希望能让我们变得更加全面。

 

每一篇博客都是一种经历,程序猿生涯的痕迹,知识改变命运,命运要由自己掌控,愿你游历半生,归来仍是少年。

欲速则不达,欲达则欲速!

更多精彩内容,首发公众号【素小暖】,欢迎关注。

发布了121 篇原创文章 · 获赞 12 · 访问量 8217

Guess you like

Origin blog.csdn.net/guorui_java/article/details/104557984