大数据轻松入门:玩Flink创建湖仓和集成架构-威加海内兮归故乡
用CDN一定比不用快吗?
大数据轻松入门:玩Flink创建湖仓和集成架构
download:https://www.51xuebc.com/thread-521-1-1.html
对于开发生来说,CDN这个词既熟悉又陌生。
从事开发的你很少需要接触这个,但总能听到别人提起。
我们都听说过它可以加快速度,我们可能知道为什么,但我们更深入。
用CDN一定比不用快吗?
我觉得有点傻。不过没关系。今天,我们从另一个角度来认识一下CDN。
什么是CDN?
用于数字和文本数据,如与姓名和电话号码相关的信息。我们需要一个地方来存放它。
我们一般用mysql数据库来存储。
当我们需要检索这些数据时,我们需要读取mysql数据库。
但是由于mysql的数据存在于磁盘上,单个实例的读取性能几乎是5kqps,相当不错了。
看起来还行,但是对于稍微大一点的系统来说,就有点着急了。
为了提高性能,我们在mysql之前再加一层内存作为缓存层,比如常说的redis。在读取数据时,优先选择在内存中读取,只有在无法读取时,才能在mysql中读取,大大减少了读取mysql的次数。有了这个组合拳,阅读性能轻松到几万qp。
好了,到目前为止,我们说的都是平时容易接触到的开发场景。
但是现在我要处理的不再是上面提到的文字数据,而是图片数据。
比如我有一张很帅的照片。就下面这个。
每次听到有人翻唱蔡健雅的《放手》,就忍不住想发这张图。
用小品《我还是忘不了》。
那么问题来了。
这个图片数据应该存在哪里?我应该在哪里读呢?
再回到mysql和redis的场景,无非是存储层加缓存层。
对于图片等文件对象,在存储层不太可能再使用mysql,应该改用专业的对象存储,比如亚马逊的s3(注意有三个以S开头的字,所以叫S3)或者阿里云的oss(对象存储服务)。下面的内容,我们就用常见的oss来解释。
而缓存层,不能继续使用redis,需要改用CDN(内容交付网络)。
CDN可以简单理解为对象存储对应的缓存层。
现在你可以回答上面的问题了。对于用户来说,这些图像数据存在于对象存储中,当需要时,将从CDN中读取。
CDN的工作原理
对于CDN和对象存储,现在让我们看看它们是如何工作的。
我们平时看到的图片,可以右键复制查看其网址。
你会发现图片的网址是这样的。
https://cdn.xiaobaidebug.top/1667106197000.png
复制代码
前面的CDN.xiaobaidebug.top是CDN的域名,后面的1667106197000.png是图片的路径名。
当我们在浏览器中输入这个URL时,我们将发起一个HTTP GET请求,然后经历下面的过程。
第一阶段:你的电脑首先会通过DNS协议获取域名cdn.xiaobaidebug.top对应的IP。
步骤1和步骤2:首先检查浏览器缓存,然后查看操作系统中的/etc/hosts缓存。如果没有,你会问最近的DNS服务器(比如你房间的家用路由器)。最近的DNS服务器上有相应的缓存吗?如果有,就退回去。
第三步:如果最近的DNS服务器上没有对应的缓存,则查询根域、一级域、二级域和三级域服务器。
第四步:然后,最近的DNS服务器会得到域名cdn.xiaobaidebug.top的别名(CNAME),比如cdn.xiaobaidebug.top.w.kunlunaq.com。
Kunlunaq.com是阿里CDN专用的DNS调度系统。
第5步到第7步:此时,最近的DNS服务器将请求这个kunlunaq.com,然后返回最近的IP地址给你。
第二阶段:对应上图中的step8。浏览器带着这个IP访问cdn节点,然后cdn节点返回数据。
在上面的第一阶段过程中,提到了许多新术语,如CNAME、根域名、一级域名等。它们在之前的《DNS中有哪些优秀的设计值得学习?不知道的可以看看。
我们知道DNS的目的是通过域名获取IP地址。
但这只是它众多功能中的一个。
DNS报文有很多种类型,其中A类是用域名来查域名对应的IP地址。CNAME类型使用域名来检查该域名的别名。
对于常见的域名,DNS解析后一般可以直接获得域名对应的IP地址(也叫A类记录,A指地址)。
例如,我使用dig命令发出DNS请求并打印进程数据。
$ dig +trace小白debug.top
;;回答部分:
小白汉堡. top . 600 47.102.221.141
复制代码
可以看到xiaobaidebug.top直接解析得到对应的IP地址47.102.221.141。
但对于cdn域名,经过一波查询,第一条记录是xx.kunlunaq.com的一个CNAME,然后再深挖一下,这个xx.kunlunaq.com,就可以得到相应的IP地址。
$ dig +trace cdn.xiaobaidebug.top
名为cdn.xiaobaidebug.top.w.kunlunaq.com。
$挖掘+追踪cdn.xiaobaidebug.top.w.kunlunaq.com
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.243
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.241
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.244
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.249
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.248
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.242
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.250
cdn.xiaobaidebug.top.w.kunlunaq.com。300英镑一辆122.228.7.251
复制代码
看到这里,问题又来了。
为什么加个CNAME这么麻烦?
CNAME所指的其实是CDN专用的DNS域名服务器。对于整个DNS系统来说,它只是小型DNS域名服务器中的一个,看起来和其他域名服务器没什么两样,平平淡淡。DNS请求也将正常进入此服务器。
但是,当请求真正击中它的时候,它的特殊性就体现出来了。当查询请求进入域名服务器时,普通DNS域名服务器返回域名对应的部分IP就足够了,但是CDN专用的DNS域名服务器会要求返回离调用者“最近”的服务器的IP。
怎么知道哪个服务器IP有最近的调用者?
可以看到“最近”这个词实际上是用双引号括起来的。
CDN的专用DNS域名服务器实际上是由CDN提供商提供的。比如阿里云当然知道自己有哪些CDN节点,以及这些CDN服务器当前的负载情况、响应延迟甚至权重,也能知道调用者的IP地址是什么。它可以通过来电者的IP知道自己所属的运营商及其大概位置,根据条件选择最合适的CDN服务器,也就是所谓的“最近”。
比如说。假设地理位置最近的CDN机房流量较多,响应较慢,但地理位置较远的服务器可以更好地响应当前请求,按理说可能会选择地理位置较远的CDN服务器。
也就是说,选择的服务器不一定是地理上最近的,但一定是目前最合适的服务器。
背后的源头是什么?
上面的图片网址是https://cdn域名/图片address.png的形式。
也就是说这张图是通过访问CDN获得的。
那么,直接访问对象存储可以得到图片数据并显示出来吗?
像下面这样。
https://OSS域名/图像address.png
复制代码
这就好比问你能不能不用redis直接从mysql读取和显示文本数据。
当然可以。
我之前放在博客里的图片就是这么做的。
但是成本较高。这里的成本可以指性能成本,也可以指通话成本。看下图。
可见直接请求oss的成本几乎是通过cdn请求oss的两倍。考虑到我家境贫寒,也为了让博客更快的获取图片,我连上了CDN。
但是看到这里,问题又来了。
在上面的截图中,红框里有一个词叫“回到源头”。
来源是什么?
当我们访问https://cdn域名/图片address.png时,请求会打到cdn服务器。
但是cdn服务器本质上是一层缓存,不是数据源,对象存储才是数据源。
当你第一次访问cdn获取某张图片时,很大概率cdn中没有这张图片的数据,所以你需要回到数据源获取这张图片数据。然后放到cdn上。下次访问cdn,只要缓存没有过期,就可以直接命中缓存返回,不需要回到源头。
所以参观的过程就变成了如下。
那么回到源头还会发生什么?
除了上面提到的cdn,如果你拿不到数据,它会返回源站,如果cdn上的缓存过期,它也会返回源站。
另外,即使有缓存,而且缓存没有过期,也可以通过cdn提供的开放接口来触发,但是我们很少有机会接触到这个。
另外,回到源头这件事,其实用户是察觉不到的,因为用户在看图片的时候,只能知道自己有没有看过。
也是读取,细分为是直接从cdn读取,还是从源读取对象存储后由cdn返回。
那么,我们有什么办法来判断是否发生了倒源呢?
是的。我们继续往下看。
如何判断是否发生货源回流?
以我们的云对象存储和CDN为例。
假设我要请求下图https://cdn . xiaobaidebug . top/image/image-20220404094549469 . png。
为了更方便的查看响应数据的http头,我们可以使用postman。
通过GET方法请求图像数据。
然后通过下面的标签开关查看响应头信息。
此时响应头下X-Cache的值为MISS TCP_MISS。意思是缓存未命中导致CDN回源检查oss,拿到数据后再返回。
那么这个时候CDN里肯定有这张图的缓存。我们可以尝试再次执行GET方法来获取图片。
X-Cache的值变成HIT TCP_MEM_HIT,也就是命中缓存。
这是某云的做法,其他的,比如腾某云,都是大相径庭。几乎都可以从响应头中找到相关信息。
用CDN一定比不用更快吗?
这里可以回答文章开头的问题。
如果不接入CDN,直接接入源站。过程如下。
但是,如果访问CDN,并且CDN上没有缓存的数据,则会触发回源。
相当于在原有流程上增加了一层CDN调用流程。
也就是使用CDN的时候会比不使用的时候慢,因为CDN缓存丢失,返回源。
如果缓存丢失,可能是cdn中根本没有这样的数据,也可能是有这样的数据但后来过期了。
这两种情况都很正常,大部分时候都不需要治疗。
但是对于极少数场景,我们可能需要做一些优化。比如你的源站数据有大版本更新,就像换了cdn域名什么的。然后在上线的那一刻,用户都是用新的cdn域名请求图片什么的,新的CDN节点基本上100%触发回源。在严重的情况下,它甚至可能会拖累对象存储。这时候你可能需要提前筛选出热数据,用工具提前请求一波,让CDN加载热数据缓存。比如云上的CDN就有这样的“刷新预热”功能。
当然,也可以通过灰度发布的模式,让少部分用户体验新功能,让这些用户“热起来”cdn,然后逐步释放流量。
就是曾经有过这个数据,后来过期了。对于热点数据,可以适当增加cdn数据的缓存时间。
什么情况下不应该使用CDN?
从上面的描述来看,CDN最大的优势是对于来自世界各地的用户来说,可以就近分配CDN节点获取数据,在重复获取相同文件数据时可以加速缓存。
非常适合这种网页图片的场景。因为底层使用的是对象存储,也就是说只要是文件对象,比如视频什么的,都可以用这个进程访问cdn进行加速。比如某音某手的短视频一般就是这么做的。
然后反过来想,问题就来了。
什么情况下不应该使用CDN?
如果你有公司内网服务,服务请求的图片等文件不太可能被重复调用,这个时候其实没必要用CDN。
注意上面两个加粗的要点。
内网服务是为了保证你知道服务请求的来源,还可以获得对象存储的读取权限。而且如果你的对象存储也是公司内部的,很有可能已经和你的服务在同一个机房了,非常近。接入CDN享受不到“就近分布CDN节点”的好处。
图片或其他文件不太可能多次重复使用。如果访问CDN,每次访问CDN获取图片,都有很大概率CDN节点没有你想要的数据,相当于每次都要回去对象库获取一个。那么接入CDN就相当于给自己加了一层代理。多了一层代理,就又多了一层时间。
关于上面第二点,如果你需要一个明确的指标来说服自己,那么我可以给你一个。从上面的介绍我们知道,可以通过cdn响应的http头中的X-Cache字段来看一个请求是否触发了对源的返回,统计次数,然后除以请求总数,得到对源的返回比例。比如,如果回归本源比例高达90%,那我们为什么还要接cdn?
摘要
对于文本数据,我们习惯用mysql做存储,redis做缓存。但如果属于文件数据,比如视频图片,就需要用oss做对象存储,cdn做缓存。
如果使用CDN,实际上会比不使用时慢。
CDN最大的优势在于,对于来自世界各地的用户,可以就近分配CDN节点获取数据,当多次重复获取同一文件数据时,具有缓存加速的功能。如果你的服务和对象存储都在内网,文件数据不太可能被重用,实际上就没有必要访问cdn。
本文系作者 @河马 原创发布在河马博客站点。未经许可,禁止转载。
暂无评论数据