转载一篇介绍CDN的工作原理文章:CDN 是什么
CDN 是什么
对于数字和文本类型的数据,比方说名字和电话号码相关的信息。我们需要有个地方存起来,我们通常会用mysql数据库去存。
image.png
当我们需要重新将这一数据取出的时候,就需要去读mysql数据库。
但因为mysql的数据是存在磁盘上的,单台实例,读性能到差不多5kqps就已经很不错了。看起来还凑合,但对于稍微大一点的系统,就稍微有点捉急了。
为了提升点性能,我们在mysql之前再加一层内存做缓存层,比如常说的redis,读数据优先到内存里读,读不到才到mysql里读,大大减少了读mysql的次数。有了这套组合拳,读性能轻松上万qps。
好了,到这里,我们说的都是我们平时比较容易接触的开发场景。
但如果现在我要处理的,不再是上面提到的文本类数据,而是图片数据。
那么问题来了。
这张图片数据应该存在哪?,又该从哪里读?
我们回过头去看mysql和redis的场景,无非就是存储层加缓存层。
image.png
对于图片这样的文件对象,存储层不太可能再用mysql,应该改用专业的对象存储,比如亚马逊的S3(Amazon Simple Storage Service,注意后面是三个S开头的单词,所以叫s3),或者阿里云的oss(Object Storage Service)。下面的内容,我们就用比较常见的oss去做解释。
而缓存层,也不能继续用redis了,需要改成使用CDN(Content Delivery Network,内容分发网络)。可以将CDN简单理解为对象存储对应的缓存层。
image.png
现在就可以回答上面的提问,对用户来说,这张图片数据存在了对象存储那,当有需要的时候,会从CDN那被读出来。
CDN 的工作原理
有了CDN和对象存储之后,现在我们来看下他们之间是怎么工作的,我们平时看到的图片,可以右键复制查看它的URL。
image.png会发现图片的URL长这样。
https://cdn.xiaobaidebug.top/1667106197000.png
其中前面的cdn.xiaobaidebug.top就是CDN的域名,后面的1667106197000.png是图片的路径名。
当我们在浏览器输入这个URL就会发起HTTP GET请求,然后经历以下过程。(kunlunaq.com是阿里CDN专用的DNS调度系统)
image.png
回源是什么?
上面的图片URL,是https://cdn域名/图片地址.png的形式。也就是说这张图片是访问CDN拿到的。那么,直接访问对象存储能不能拿到图片数据并展示?
当然能。这就像问,不走redis,直接从mysql中能不能读取到文本数据并展示一样。
但这样成本更高,这里的成本,可以指性能成本,也可以指调用成本。看下下面这个图。
image.png
可以看到直接请求oss的费用差不多是通过cdn请求oss的两倍。
但看到这里,问题又又来了,上面的截图里,红框里有个词叫"回源",那么什么是回源?
当我们访问https://cdn域名/图片地址.png时,请求会打到cdn服务器上面。但cdn服务器本质上就是一层缓存,并不是数据源,对象存储才是数据源。
第一次访问cdn获取某张图片时,大概率在cdn里并没有这张图片的数据,因此需要回到数据源那去取出这份图片数据。然后再放到cdn上。下次再次访问cdn时,只要缓存不过期,就能命中缓存直接返回,这就不需要再回源。
于是访问的过程就变成了下面这样:
image.png
那还有哪些情况会发生回源呢?
除了上面提到的cdn上拿不到数据会回源站外,还有cdn上的缓存过期失效了也会导致回源站。
另外,就算有缓存,且缓存不过期,也可以通过cdn提供的开放接口来触发主动回源,但这个我们比较少机会能接触到。
怎么判断是否发生回源
我们以某里云的对象存储和CDN为例。
假设我要请求下面这张图https://cdn.xiaobaidebug.top/image/image-20220404094549469.png
为了更方便的查看响应数据的http header,我们可以用上postman。通过GET方法去请求图片数据。然后通过下面的tab切换查看response header信息。
image.png
此时查看response header下的X-Cache的值是 MISS TCP_MISS。意思是未命中缓存导致CDN回源查oss,拿到数据后再返回。
那此时CDN里肯定是有这张图片的缓存了。我们可以试着再执行一次 GET 方法获取图片。
image.png
X-Cache的值就变成了 HIT TCP_MEM_HIT,这就是命中缓存了。
这个是某里云的做法,其他比如腾某云啥的,也都大差不差,几乎都可以从response header里找到相关的信息。
网友评论