¿Usar un CDN es necesariamente más rápido que no usarlo?

Este artículo es el primer artículo contratado en la comunidad de los Nuggets. Está prohibida la reimpresión dentro de los 14 días. Está prohibida la reimpresión sin autorización después de los 14 días. ¡Se debe investigar la infracción!

Para los estudiantes de desarrollo, la palabra CDN es tanto familiar como desconocida.

Rara vez necesito tocar esto cuando hago desarrollo, pero siempre puedo escuchar a otros mencionarlo.

Todos hemos escuchado que puede acelerar, y probablemente sepamos la razón, pero preguntamos más profundamente.

¿Usar un CDN es necesariamente más rápido que no usarlo?

Me siento un poco confundido. Pero no importa, hoy volveremos a entender CDN desde otro ángulo.

¿Qué es un CDN?

Para datos numéricos y de tipo texto, como información relacionada con el nombre y el número de teléfono. Necesitamos un lugar para guardarlo.

Usualmente usamos la base de datos mysql para guardar.

El texto se almacena en mysql.

Cuando necesitemos recuperar estos datos nuevamente, necesitamos leer la base de datos mysql.

Pero debido a que los datos de mysql se almacenan en el disco, el rendimiento de lectura de una sola instancia es de casi 5kqps, lo que ya es muy bueno.

Parece estar bien, pero para un sistema un poco más grande, es un poco urgente.

Para mejorar el rendimiento, agregamos una capa de memoria antes de mysql como capa de caché, como redis, que se dice a menudo, y primero leemos los datos en la memoria, y luego leemos en mysql si no se puede leer, lo que reduce en gran medida el número de veces para leer mysql. Con este conjunto de punzones combinados, el rendimiento de lectura puede alcanzar fácilmente decenas de miles de qps.

mysql y redis

Ok, hasta ahora, estamos hablando de escenarios de desarrollo a los que generalmente tenemos acceso más fácilmente.

Pero si lo que quiero tratar ahora ya no son los datos de texto mencionados anteriormente, sino los datos de imagen .

Por ejemplo, tengo una foto guapa. Solo el de abajo.

Cada vez que deslizo un cierto sonido y escucho a alguien versionar " letting go" de Cai Tanya, no puedo evitar querer publicar esta imagen.

Y con el texto "Todavía no puedo olvidar".


Así que aquí viene el problema.

¿Dónde deberían existir estos datos de imagen? , y donde debo leerlo?

Miremos hacia atrás a los escenarios de mysql y redis, que no son más que la capa de almacenamiento más la capa de caché .

capa de almacenamiento y capa de almacenamiento en caché

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

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

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

CDN y OSS

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

CDN的工作原理

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

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

1667103075060

会发现图片的URL长这样。

https://cdn.xiaobaidebug.top/1667106197000.png
复制代码

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

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

Proceso de consulta de CDN

第一阶段: 你的电脑会先通过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。

El servidor de resolución DNS dedicado a CDN devolverá la IP del nodo CDN más cercano


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

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

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

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

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


回源是什么

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

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

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

比如像下面这样。

https://oss域名/图片地址.png
复制代码

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

当然能。

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

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

1667101182393

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

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

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

回源是什么?

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

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

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

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

1668605964836

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

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

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


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

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

La diferencia entre regresar directamente con caché y regresar a la fuente sin caché

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

有。我们接着往下看。


怎么判断是否发生回源

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

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

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

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

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

ver encabezado de respuesta

Volver a la fuente

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

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

1667095186020

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

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

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

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

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

Actualizar el acceso directo al sitio de origen

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

Después de que se haya ido la actualización, la CDN volverá a la fuente

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

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

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

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

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

precalentamiento de actualización de cdn

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

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

1667344813600

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

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

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

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

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

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

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

  • 内网服务,是为了保证你是了解服务的请求来源的,也能拿到对象存储的读权限,并且如果你的对象存储也是公司内部的,那大概率跟你的服务已经在同一个机房里,这已经很近了。接入CDN也享受不到"就近分配CDN节点"所带来的好处。
  • 图片或其他文件不太可能被多次重复使用,如果接入了CDN,那你每次去访问CDN获取图片的时候,CDN节点上大概率没有你要的数据,相当于每次都需要回源到对象存储去取一把。那接入CDN相当于给自己加了一层代理,多一层代理,就多一层耗时。

1668612494972

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

总结

  • 对于文本类数据我们习惯用mysql做存储,redis做缓存。但属于文件类数据,比如视频图片,则需要使用oss等做对象存储,cdn做缓存。
  • 用了CDN如果发生回源,那实际上会比不用的时候更慢一些。
  • CDN最大的优势在于,对于来自世界各地的用户,它可以就近分配CDN节点获取数据,并且多次重复获取同一个文件数据的时候,有缓存加速的作用。如果你的服务和对象存储都在内网,并且文件数据也不太会有重复使用的可能性,那其实没必要接入cdn。

最后

Recientemente, el volumen de lectura de las actualizaciones originales ha disminuido constantemente, y después de pensarlo, di vueltas y vueltas por la noche.

Tengo una solicitud inmadura.


Ha pasado mucho tiempo desde que me fui de Guangdong, y nadie me llamó Pretty Boy durante mucho tiempo.

¿Pueden todos llamarme chico guapo en el área de comentarios ?

¿Se puede cumplir mi amable y sencillo deseo?


Deja de hablar, ahoguémonos juntos en el océano del conocimiento.

Supongo que te gusta

Origin juejin.im/post/7166782260933296142
Recomendado
Clasificación