CDN是什么?用了CDN就一定比不用更快吗?

news2024/12/25 12:31:41

对于开发同学来说,CDN这个词,既熟悉又陌生。

平时搞开发的时候很少需要碰这个,但却总能听到别人提起。

我们都听说过它能加速,也大概知道个原因,但是往深了问。

用了CDN就一定比不用更快吗?

就感觉有些懵了。但没关系,今天我们换个角度重新认识下CDN。

CDN是什么

对于数字和文本类型的数据,比方说名字和电话号码相关的信息。我们需要有个地方存起来。

我们通常会用mysql数据库去存。

4d6f30b84b771e45296a15e5b96d382e.png

当我们需要重新将这一数据取出的时候,就需要去读mysql数据库。

但因为mysql的数据是存在磁盘上的,单台实例,读性能到差不多5kqps就已经很不错了。

看起来还凑合,但对于稍微大一点的系统,就稍微有点捉急了。

为了提升点性能,我们在mysql之前再加一层内存做缓存层,比如常说的redis,读数据优先到内存里读,读不到才到mysql里读,大大减少了读mysql的次数。有了这套组合拳,读性能轻松上万qps。

好了,到这里,我们说的都是我们平时比较容易接触的开发场景。

但如果现在我要处理的,不再是上面提到的文本类数据,而是图片数据

比如,我有一张帅气的照片。就下面这张。

每次刷某音听到有人翻唱蔡健雅的《letting go》的时候,我都忍不住想发这张图。

并配文"还是忘不了"。

那么问题来了。

这张图片数据应该存在哪?,又该从哪里读?

我们回过头去看mysql和redis的场景,无非就是存储层加缓存层

823d00d07f7da23f39bb519937107a95.png

对于图片这样的文件对象存储层不太可能再用mysql,应该改用专业的对象存储,比如亚马逊的S3(Amazon Simple Storage Service,注意后面是三个S开头的单词,所以叫s3),或者阿里云的oss(Object Storage Service)。下面的内容,我们就用比较常见的oss去做解释。

缓存层,也不能继续用redis了,需要改成使用CDNContent Delivery Network,内容分发网络)。

可以将CDN简单理解为对象存储对应的缓存层。

现在就可以回答上面的提问,对用户来说,这张图片数据存在了对象存储那,当有需要的时候,会从CDN那被读出来。

CDN的工作原理

有了CDN和对象存储之后,现在我们来看下他们之间是怎么工作的。

我们平时看到的图片,可以右键复制查看它的URL。

会发现图片的URL长这样。

https://cdn.xiaobaidebug.top/1667106197000.png

其中前面的cdn.xiaobaidebug.top就是CDN的域名,后面的1667106197000.png是图片的路径名。

当我们在浏览器输入这个URL就会发起HTTP GET请求,然后经历以下过程。

8fda943c34ca5242bef0d8b312e0f6bc.png

第一阶段: 你的电脑会先通过DNS协议获得cdn.xiaobaidebug.top这个域名对应的IP。

  • • step1和step2:先查看浏览器缓存,再看操作系统里的/etc/hosts缓存,如果都没有,就会去询问最近的DNS服务器(比如你房间里的家用路由器)。最近的DNS服务器上有没有对应的缓存,如果有则返回。

  • • step3:如果最近的DNS服务器上没有对应的缓存,就会去查询根域,一级域,二级域,三级域服务器。

  • • step4:然后,最近的DNS服务器会得到这个cdn.xiaobaidebug.top域名的别名(CNAME),比如cdn.xiaobaidebug.top.w.kunlunaq.com

  • • kunlunaq.com是阿里CDN专用的DNS调度系统

  • • step5到step7:此时最近的DNS服务器会去请求这个kunlunaq.com,然后返回一个离你最近的IP地址返回给你。

第二阶段: 对应上图里的step8。浏览器拿着这个IP去访问cdn节点,然后,cdn节点返回数据。

上面第一阶段流程里,提到了很多新的名词,比如CNAME,根域,一级域啥的,它们在之前写的 「DNS中有哪些值得学习的优秀设计」有很详细的描述,如果不了解的话可以去看下。

我们知道DNS的目的就是通过域名去获得IP地址

但这只是它的众多功能之一。

DNS消息有很多种类型,其中A类型,就是用域名去查域名对应的IP地址。而CNAME类型,则是用域名去查这个域名的别名

对于普通域名,DNS解析后一般就能直接得到域名对应的IP 地址(又叫A类型记录,A指Address)。

比如下面,我用dig命令发出DNS请求并打印过程数据。

$ dig +trace xiaobaidebug.top
;; ANSWER SECTION:
xiaobaidebug.top. 600 IN A 47.102.221.141

可以看到xiaobaidebug.top直接解析得到对应的IP地址47.102.221.141

但对于cdn域名,一波查询下来,先得到的却是一条CNAME的记录xx.kunlunaq.com,然后dig这个xx.kunlunaq.com才能得到对应的IP地址

$ dig +trace cdn.xiaobaidebug.top
cdn.xiaobaidebug.top. 600 IN CNAME cdn.xiaobaidebug.top.w.kunlunaq.com.

$ dig +trace cdn.xiaobaidebug.top.w.kunlunaq.com
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.243
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.241
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.244
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.249
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.248
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.242
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.250
cdn.xiaobaidebug.top.w.kunlunaq.com. 300 IN A 122.228.7.251

看到这里,问题就又来了。

为什么要加个CNAME那么麻烦?

CNAME里指向的,其实是CDN专用的DNS域名服务器,它对整个DNS体系来说,只是其中一台小小的DNS域名服务器,看起来就跟其他域名服务器一样,平平无奇。DNS请求也会正常打入这个服务器里。

但当请求真正打到它上面的时候,它的特别之处就体现出来了,当查询请求打入域名服务器时,普通的DNS域名服务器返回域名对应的部分IP就够了,但CDN专用的DNS域名服务器却会要求返回离调用方"最近的"服务器IP。

CDN专用的DNS解析服务器会返回就近的CDN节点IP

怎么知道哪个服务器IP里调用方最近?

可以看到"最近"这个词其实是加了双引号的。

CDN专用的DNS域名服务器其实是CDN提供商提供的,比如阿里云当然知道自己的的CDN节点有哪些,以及这些CDN服务器目前的负载情况和响应延时甚至权重啥的,并且也能知道调用方的IP地址是什么,可以通过调用方的IP知道它所属的运营商以及大概所在地,根据条件筛选出最合适的CDN服务器,这就是所谓的"最近"。

举个例子。假设地理位置最近的CDN机房流量较多,响应较慢,但地理位置远一些的服务器却能更好的响应当前请求,那按理说可能会选择地理位置远一些的那台CDN服务器。

也就是说,选出来的服务器不一定在地理位置最近,但一定是当前最合适的服务器。

回源是什么

上面的图片URL,是https://cdn域名/图片地址.png的形式。

也就是说这张图片是访问CDN拿到的。

那么,直接访问对象存储能不能拿到图片数据并展示?

比如像下面这样。

https://oss域名/图片地址.png

这就像问,不走redis,直接从mysql中能不能读取到文本数据并展示一样。

当然能。

我之前放在博客里的图片就是这么干的。

但这样成本更高,这里的成本,可以指性能成本,也可以指调用成本。看下下面这个图。

837d13be50173cf3cb58d9c684566423.png

可以看到直接请求oss的费用差不多是通过cdn请求oss的两倍,考虑到家境贫寒,同时也为了让博客获取图片的速度更快,我就接入了CDN。

但看到这里,问题又又来了。

上面的截图里,红框里有个词叫"回源"。

回源是什么?

当我们访问https://cdn域名/图片地址.png时,请求会打到cdn服务器上面。

但cdn服务器本质上就是一层缓存,并不是数据源,对象存储才是数据源

第一次访问cdn获取某张图片时,大概率在cdn里并没有这张图片的数据,因此需要到数据那去取出这份图片数据。然后再放到cdn上。下次再次访问cdn时,只要缓存不过期,就能命中缓存直接返回,这就不需要再回源。

于是访问的过程就变成了下面这样。

那还有哪些情况会发生回源呢?

除了上面提到的cdn上拿不到数据会回源站外,还有cdn上的缓存过期失效了也会导致回源站。

另外,就算有缓存,且缓存不过期,也可以通过cdn提供的开放接口来触发主动回源,但这个我们比较少机会能接触到。

另外,回源这个事情,其实用户是感知不到的,因为用户去读图片的时候,只能知道自己读到了还是读不到。

同样是读到了,还细分为是从cdn那直接读的,还是cdn回源读对象存储之后返回的

有缓存直接返回和没缓存回源的区别

那么,我们有办法判断是否发生过回源吗?

有。我们接着往下看。

怎么判断是否发生回源

我们以某里云的对象存储和CDN为例。

假设我要请求下面这张图https://cdn.xiaobaidebug.top/image/image-20220404094549469.png

为了更方便的查看响应数据的http header,我们可以用上postman

通过GET方法去请求图片数据。

然后通过下面的tab切换查看response header信息。

5dc5766114cd957d70a4482f175fe4d3.png

此时查看response header下的X-Cache的值是 MISS TCP_MISS。意思是未命中缓存导致CDN回源查oss,拿到数据后再返回。

那此时CDN里肯定是有这张图片的缓存了。我们可以试着再执行一次 GET 方法获取图片。

X-Cache的值就变成了 HIT TCP_MEM_HIT,这就是命中缓存了。

这个是某里云的做法,其他比如腾某云啥的,也都大差不差,几乎都可以从response header里找到相关的信息。

用了CDN一定比不用的更快吗?

看到这里我们就可以回答文章开头的问题了。

如果没有接入CDN,直接访问源站,流程是这样的。

09e939176e945e2f8d1f26abd7ff0a99.png

但如果接入了CDN,且CDN上没有缓存数据,那就会触发回源。

更新走了CDN还回源

相当于在原来的流程上还多了一层CDN的调用流程。

也就是,用了CDN时,未命中CDN缓存导致回源,就会比不用的时候更慢。

未命中缓存,可能是cdn里压根就没这一数据,也可能是曾经有这条数据但后来过期失效了

这两种情况都正常,大部分时候并不需要做任何处理。

但对于极个别场景,我们可能需要做些优化。比如你们源站数据有大版本更新,就像更换cdn域名啥的,那在上线的那一刻用户全用新cdn域名去请求图片啥的,新CDN节点基本上百分百触发回源,严重的时候甚至可能会拖垮对象存储。这时候你可能需要提前将热点数据筛选出来,利用工具预先请求一波,让CDN加载上热数据缓存。比如某里云上的CDN就有这样的"刷新预热"功能。

当然也可以通过灰度发布的模式,先让少量用户体验新功能,让这些用户把cdn"热"起来,然后再逐步放开流量。

还有就是曾经有这条数据但后来过期失效了,对于热点数据,可以适当提高一下cdn数据的缓存时间

d9dc655c5e2559508fc3b995d306325b.png

什么情况下不应该使用CDN?

从上面的描述看下来,CDN最大的优势在于,对于来自世界各地的用户,它可以就近分配CDN节点获取数据,并且多次重复获取同一个文件数据的时候,有缓存加速的作用。

这对于网页图片这样的场景,是再合适不过了。因为底层用的是对象存储,也就是说,只要是文件对象,比如视频啥的,都可以用这套流程接入cdn做加速。比如平时刷的某音某手短视频就是这么干的。

那反过来想想,问题就来了。

什么情况下不应该使用CDN?

如果你有一个公司内网的服务,并且服务请求的图片等文件不太可能被多次重复调用,这时候其实没必要使用CDN。

注意上面两个加粗了的关键点。

  • • 内网服务,是为了保证你是了解服务的请求来源的,也能拿到对象存储的读权限,并且如果你的对象存储也是公司内部的,那大概率跟你的服务已经在同一个机房里,这已经很近了。接入CDN也享受不到"就近分配CDN节点"所带来的好处。

  • • 图片或其他文件不太可能被多次重复使用,如果接入了CDN,那你每次去访问CDN获取图片的时候,CDN节点上大概率没有你要的数据,相当于每次都需要回源到对象存储去取一把。那接入CDN相当于给自己加了一层代理,多一层代理,就多一层耗时。

关于上面的第二点,如果你需要一个明确的指标去说服自己,那我可以给你一个。从上面的介绍内容,我们知道以通过cdn响应的http header中的X-Cache字段,看到一个请求是否触发过回源,统计次数,再除以总的请求数,就能得到回源的比例,比如回源比例高达90%,那还接啥cdn。

总结

  • • 对于文本类数据我们习惯用mysql做存储,redis做缓存。但属于文件类数据,比如视频图片,则需要使用oss等做对象存储,cdn做缓存。

  • • 用了CDN如果发生回源,那实际上会比不用的时候更慢一些。

  • • CDN最大的优势在于,对于来自世界各地的用户,它可以就近分配CDN节点获取数据,并且多次重复获取同一个文件数据的时候,有缓存加速的作用。如果你的服务和对象存储都在内网,并且文件数据也不太会有重复使用的可能性,那其实没必要接入cdn。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136239.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Node.js操作Dom ,轻松hold住简单爬虫

前言 前段时间,我发现一个开源题库,题目非常有意思。我想把它整成一个JSON文件做为数据储备,方便整活。 一共有一百五十多道题目,手动CV我肯定是不想干的。于是写了个脚本,在写脚本的过程中,我发现一个能…

Opencv(C++)笔记--利用分水岭算法实现图像分割

1--分水岭算法的原理详细原理讲解可参考:博客1和视频1;原理简述:分水岭算法的基本思想是把图像视为拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而两个集…

csrf漏洞原理及防御

攻击原理 从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤 1.登录受信任网站A,并在本地生成Cookie 2.在不登出A的情况下,访问危险网站B 防御原理 csrf能防御的本质是,黑客虽然携带了合法的cookie&a…

振弦采集模块的辅助功能寄存器

振弦采集模块辅助功能寄存器 1.频率值模拟量输出 VMXXX(仅 VM501、 VM511) 模块支持将当前实时频率值以模拟量形式从管脚输出,模拟量有电流和电压两种输出形式。为了使用此功能,需要将辅助功能寄存器 AUX.[0]设置为 1&#xff0…

<Linux开发> ubuntu开发工具-EasyConnect使用记录

<Linux开发> ubuntu开发工具-EasyConnect使用记录 1、安装EasyConnect 打开EasyConnect官网EasyConnect 根据当前电脑系统选择对应版本下载 作者这里是ubuntu 22.04版本 右击,选择 “软件安装” 即可安装完成;windows版本类似…

数据可视化:揭开“智慧校园”新篇章,助力新时代教育信息化

随着移动互联网、物联网等新一代信息技术的快速发展,建设智慧校园已经具备了成熟的技术条件。自从教育部启动教育信息化2.0计划后,建设智慧校园已成为我国教育信息化发展目标,无论是国家教育事业发展的十三五规划,还是十四五规划&…

Hadoop高手之路7-Hadoop的新特性

文章目录Hadoop高手之路7-Hadoop的新特性一、Hadoop2.0以上新特性二、Yarn资源管理框架1. yarn体系结构2. yarn的工作流程三、HDFS的高可用HA1. HDFS的高可用(HA)架构2. 搭建Hadoop高可用HA集群1) 规划集群节点2) 环境准备3) 配置HA集群(1) 修改core-sit…

【ROS】—— ROS通信机制——实践与练习(六)

文章目录前言1. 话题发布1.1 C方式实现1.2 python实现2. 话题订阅2.1 C实现2.2 python实现3. 服务调用3.1 C3.2 python4. 参数设置4.1 C4.2 python4.3 运行4.4 其他方式4.4.1 修改小乌龟节点的背景色(命令行实现)4.4.2 启动节点时,直接设置参数4.4.3 通过launch文件…

Java测试框架——JUnit详解(45)

文章目录前言何为JUnit?官方资料JUnit4常用注解和断言代码测试搭建一个JUnit测试环境生命周期忽略测试断言测试异常测试测试时间套件测试JUnit5JUnit5对比JUnit4的好处导包的改变注解的改变扩展JUnit新功能:参考文章JUnit是Java编程语言的单元测试框架&a…

list的介绍及模拟实现

🌈感谢阅读East-sunrise学习分享——list的介绍及模拟实现 博主水平有限,如有差错,欢迎斧正🙏感谢有你 码字不易,若有收获,期待你的点赞关注💙我们一起进步 今天想分享介绍一下STL的容器之一lis…

openharmony GPIO 驱动开发

openharmony GPIO 驱动开发GPIO 基础知识GPIO 基础知识——概念GPIO 基础知识——IO 复用GPIO 基础知识——GPIO 分组和编号GPIO 基础知识——用户态测试HDF 框架下 GPIO 驱动HDF 框架下的 GPIO 驱动——案例描述(以 HI3516DV300 平台为例,提供代码)HDF 框架下的 GP…

为什么jvm需要有栈协程?

旧有的servlet生态的线程模型 首先我们先要聊一聊现在我们用的最多的servlet的执行模型是什么: 这个dispatch其实就是一个EventLoop或者说是一个selector来检测注册到其上的链接状态发生的变化 以Tomcat为例子,当这个selector发现存在一个链接可读时&…

【node.js】fs\path\http模块的使用

🥳博 主:初映CY的前说(前端领域) 🌞个人信条:想要变成得到,中间还有做到! 🤘本文核心:Node.js的fs\path\http模块的使用,模块化开发概念 目录 一、node.js概念与作…

一个曾经分享动态(2021)的回顾和解释-2023-

虽然看过一些典故,里面有名言道: 解释永远是多余的,理解的人不需要,不理解的更不需要。 但是,误会还是需要沟通来消除的。 例如,曾经分享过: 如下都是误会 ↓↓↓↓↓↓↓↓↓ 有朋友联系我&a…

解决东方财富数据接口激活后仍显示reactive的问题

首先确保代码可以在python中导入这个包: from EmQuantAPI import c如果无法导入,就是python没有配置好东方财富的接口,可以参考: Mac版本:Mac使用Python接入东方财富量化接口Choice,调试与获取数据Window…

北京智和信通:信创运维自动化,全栈适配国产软硬件环境

近年来,新基建和信创产业政策东风席卷神州,国产CPU、操作系统、关键应用软件等核心技术步入发展快车道,一批优秀软硬件产品走进政府机关、国企事业单位。在国产软硬件核心技术崛起的过程中,如何迅速搭建起成熟的生态环境是行业面临…

LeetCode135之分发糖果(相关话题:数组,贪心思想)

题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求,给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果,计算并返回需…

【node.js】跨域的解决办法(CORS方法、同源策列的理解)

🥳博 主:初映CY的前说(前端领域) 🌞个人信条:想要变成得到,中间还有做到! 🤘本文核心:面对cors跨域、同源策略的处理 下图为本文的核心 目录 一、 跨域介绍 二、同源策略 三…

正态分布与numpy.random.normal函数

文章目录1. 正态分布2. numpy.random.normal函数3. 示例在Numpy中,有一个专门用于生成符合正态分布的随机数函数:numpy.random.normal,本文我们梳理一下它的使用方法,在梳理前,需要先了解一下什么是正态分布。 1. 正态…

黑马Hive+Spark离线数仓工业项目-任务流调度工具AirFlow(1)

任务流调度工具AirFlow 1. AirFlow介绍【了解】 - 功能、特点 - 架构角色、安装部署 2. **AirFlow使用【掌握】** - 核心:调度脚本【Python | Shell】 - 定时调度:Linux Crontab表达式 - 邮件告警:配置 3. 回顾Spark核心概念 - 存…