1.浏览器缓存过期机制
1.1 最后修改时间 last-modified
浏览器缓存机制是优化网页加载速度和减少服务器负载的重要手段。以下是关于浏览器缓存过期机制、
Last-Modified
和ETag
的详细讲解:一、
Last-Modified
头部
定义:
Last-Modified
表示服务器上资源的最后修改时间。作用:用于资源的条件请求,帮助浏览器判断缓存的资源是否是最新的。
工作流程:
浏览器第一次请求资源时,服务器返回资源内容和
Last-Modified
时间。下次请求同一资源时,浏览器发送
If-Modified-Since
头部,值为之前的Last-Modified
时间。服务器比较资源的当前修改时间与
If-Modified-Since
的值:
- 如果资源未修改,返回
304 Not Modified
,浏览器继续使用缓存。- 如果资源已修改,返回新的资源内容和更新后的
Last-Modified
时间。示例:
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
二、
ETag
头部
定义:
ETag
(Entity Tag)是服务器为资源生成的唯一标识符,通常是资源内容的哈希值或版本号。作用:比
Last-Modified
更加精确,用于验证资源是否变化。工作流程:
浏览器第一次请求资源时,服务器返回资源内容和
ETag
值。下次请求同一资源时,浏览器发送
If-None-Match
头部,值为之前的ETag
。服务器比较当前资源的
ETag
与If-None-Match
的值:
- 如果
ETag
未变化,返回304 Not Modified
,浏览器继续使用缓存。
- 如果
ETag
变化,返回新的资源内容和新的ETag
值。示例:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
五、
Last-Modified
vsETag
- 精确度:
Last-Modified
仅记录最后修改时间,可能无法检测到在同一秒内的多次修改。ETag
通常基于内容的哈希值,能够更精确地检测到任何变化。- 性能:
- 生成
ETag
可能需要更多的计算资源,尤其是在大规模资源或高频请求的情况下。Last-Modified
相对简单,性能开销较小。- 使用场景:
- 对于静态资源,
ETag
更加适用。- 对于动态资源,可以结合
Last-Modified
和其他缓存策略使用。六、最佳实践
- 合理设置缓存策略:
- 对于不经常变化的静态资源,设置较长的
max-age
以充分利用缓存。- 对于经常变化的资源,使用较短的
max-age
或结合验证机制。- 使用
ETag
和Last-Modified
:
- 同时使用两者可以提供更可靠的缓存验证,但需注意服务器的性能开销。
- 如果服务器性能有限,可以选择只使用其中一个。
- 版本化资源:
- 通过在资源URL中包含版本号(如
style.v1.css
),可以在资源更新时强制浏览器下载新版本,避免缓存问题。七、总结
浏览器缓存机制通过多种HTTP头部字段控制资源的缓存和过期,
Last-Modified
和ETag
是其中重要的验证手段。合理配置这些头部字段,可以显著提升网页性能,优化用户体验,同时有效管理服务器资源。
第一次访问
第二次访问
1.2 Etag 标记
但是如果访问的时间一样的,怎么办?If-Modefied精确到的是秒,要知道的是,计算机一秒中可以干好多事的,比如一秒中修改上千次的图片
# 使用 touch 模拟访问时间是一样的(移走1.jpeg,在重新上传一张图片,重命名为1.jpeg)
[root@Rocky9.4 html]#touch -t 202407020931.48 1.jpeg
第一次访问
第一次访问是由于我将时间设置成一样了,但是因为服务器返回的Etag是新的,而浏览器保存的还是旧的,所以Etag不一致,所以返回状态码是200
第二次访问
第二次访问,Etag也统一了,所以返回了状态码304
1.3 过期时间 expires 和 Cache-Control
一、浏览器缓存机制概述
浏览器缓存通过在本地存储网页资源(如HTML、CSS、JavaScript、图片等),避免每次访问网页时都从服务器重新下载这些资源,从而加快页面加载速度,提高用户体验,同时减少服务器带宽的使用。
明白了,你希望更详细地了解浏览器缓存中的
Expires
和Cache-Control
头部,以及它们之间的关系和具体应用。以下是更深入的讲解:二、
Expires
头部1. 定义与作用
Expires
是一个HTTP响应头,用于指定资源的绝对过期时间。它告诉浏览器在指定的时间之前,可以直接从缓存中使用该资源,而无需向服务器重新请求。2. 格式
Expires
的值是一个绝对的HTTP日期和时间,格式为:Wdy, DD Mon YYYY HH:MM:SS GMT
。示例:
Expires: Wed, 21 Oct 2025 07:28:00 GMT
3. 使用场景
- 适用于静态资源,如图片、CSS、JavaScript文件,这些资源不经常变化。
- 适合设置较长的缓存时间,减少浏览器对服务器的请求频率,提升加载速度。
4. 缺点
- 使用绝对时间,可能受客户端和服务器时间不同步的影响。
- 当资源更新时,若不改变
Expires
,可能导致浏览器继续使用过期的缓存,出现内容不一致的问题。三、
Cache-Control
头部1. 定义与作用
Cache-Control
是一个更为灵活和强大的HTTP响应头,用于控制缓存策略。它可以替代或补充Expires
头部,提供更精确的缓存控制。2. 常用指令
max-age=秒数
:指定资源在多少秒内被认为是新鲜的。max-age
的优先级高于Expires
。示例:
Cache-Control: max-age=3600
no-cache
:资源必须在使用前重新验证(即使资源没有过期)。示例:
Cache-Control: no-cache
no-store
:禁止任何形式的缓存,既不存储请求信息,也不存储响应信息。示例:
Cache-Control: no-store
public
:响应可被任何缓存区缓存,包括浏览器和中间缓存(如CDN)。示例:
Cache-Control: public
private
:响应仅为单个用户缓存,不能被共享缓存(如CDN)缓存。示例:
Cache-Control: private
must-revalidate
:一旦资源过期,必须向服务器验证其有效性。示例:
Cache-Control: must-revalidate
proxy-revalidate
:与must-revalidate
类似,但仅适用于共享缓存。示例:
Cache-Control: proxy-revalidate
3. 使用场景
- 动态资源:可以灵活设置缓存策略,如需要频繁更新但又希望利用缓存提升性能的资源。
- 细粒度控制:通过组合多个指令,实现更复杂的缓存策略。
4. 与
Expires
的关系
- 优先级:当同时存在
Cache-Control: max-age
和Expires
时,Cache-Control
优先级更高。- 推荐使用:现代浏览器和服务器更推荐使用
Cache-Control
,因为它更灵活且不依赖绝对时间。四、
Expires
与Cache-Control
的对比
特性 Expires
Cache-Control
类型 绝对时间 相对时间及其他缓存指令 格式 HTTP日期格式 指令列表 优先级 低于 Cache-Control
高于 Expires
灵活性 较低,只有一个绝对过期时间 高,可以组合多种指令控制缓存行为 推荐使用场景 主要用于向后兼容旧浏览器 现代Web应用的首选缓存控制方式 五、实际应用示例
1. 设置长时间缓存(适用于不经常变化的静态资源)
Cache-Control: public, max-age=31536000 Expires: Wed, 21 Oct 2025 07:28:00 GMT
- 解释:资源可以被公共缓存(如CDN)缓存,且在1年内(31536000秒)不需要重新验证。
2. 设置短时间缓存,需重新验证(适用于可能会频繁更新的资源)
Cache-Control: no-cache
- 解释:浏览器每次使用缓存前必须向服务器验证资源是否有更新。
3. 禁止缓存(适用于敏感数据)
Cache-Control: no-store
- 解释:禁止任何形式的缓存,确保每次请求都从服务器获取最新数据。
六、结合
ETag
和Last-Modified
使用缓存验证即使设置了
Cache-Control
或Expires
,浏览器在某些情况下仍可能需要验证缓存资源的有效性。此时,ETag
和Last-Modified
提供了有效的验证机制:
ETag
:提供资源的唯一标识符,确保缓存的资源与服务器上的一致。Last-Modified
:记录资源的最后修改时间,供浏览器进行条件请求。示例:
Cache-Control: max-age=3600, must-revalidate ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
七、最佳实践
- 优先使用
Cache-Control
:
- 由于其灵活性和优先级,现代Web开发中应优先配置
Cache-Control
头部。
- 合理设置
max-age
:
- 根据资源的更新频率,合理设置缓存时间。静态资源可以设置较长时间,动态资源设置较短时间或不缓存。
- 结合使用
ETag
和Last-Modified
:
- 提供双重验证机制,确保缓存的资源始终是最新的。
- 版本化静态资源:
- 通过在资源URL中添加版本号(如
style.v1.css
),确保资源更新时浏览器能够获取到最新版本,避免缓存问题。
- 使用CDN:
- 配合缓存头部,利用内容分发网络(CDN)提升全球范围内的资源加载速度,并有效管理缓存策略。
八、总结
Expires
和Cache-Control
都用于控制资源的缓存和过期,但Cache-Control
提供了更高的灵活性和优先级。ETag
和Last-Modified
是用于缓存验证的强大工具,确保浏览器使用最新的资源。- 最佳实践 是结合使用这些HTTP头部,合理设置缓存策略,提升Web应用的性能和用户体验。
1.4 CDN
CDN(内容分发网络,Content Delivery Network)是一种通过将内容复制并缓存到全球多个地理位置的服务器上,从而加速用户访问速度的技术。它主要的目的是提高网站或应用的性能、稳定性、可扩展性,同时减少服务器负载和带宽消耗。
一、CDN的工作原理
CDN的核心思想是将网站的静态资源(如HTML文件、CSS文件、JavaScript、图片、视频等)缓存到分布在全球的边缘服务器(Edge Servers)上。当用户请求访问某个资源时,CDN会根据用户的地理位置,选择距离用户最近的服务器提供资源,从而减少加载时间和提高访问速度。
1. 资源分发与缓存
- 资源分发:当你将资源上传到CDN服务时,CDN提供商会将这些内容分发到位于世界各地的数据中心。
- 缓存:CDN的服务器会将常用的静态内容缓存到本地存储中,当有新的请求时,如果内容已经存在并且没有过期,则直接返回缓存的内容。
2. 边缘服务器与原始服务器
- 边缘服务器(Edge Server):这些是部署在全球各地的服务器,负责将资源提供给终端用户。用户访问时,通常会被路由到离他们最近的边缘服务器,以减少延迟。
- 原始服务器(Origin Server):原始服务器是网站的源服务器,存储网站的所有内容。如果CDN的边缘服务器没有缓存某个请求的内容,它会从原始服务器获取并返回给用户。
3. 缓存策略
CDN通常会使用一些缓存策略来决定哪些内容需要缓存,以及缓存多久。常见的缓存策略包括:
- 缓存时间(TTL,Time to Live):决定缓存的有效期。例如,静态资源如图片、CSS文件可能会缓存较长时间,而动态内容可能缓存较短时间。
- 缓存控制(Cache-Control):通过设置HTTP头来控制缓存行为(如
max-age
、no-cache
)。- 动态内容缓存:CDN一般针对动态内容(如用户特定数据、实时信息)使用不同的缓存策略,可能会使用“按需缓存”或“低过期时间”的方式进行处理。
4. 智能路由与负载均衡
CDN通常会根据多个因素(如地理位置、网络负载、带宽等)选择最优的边缘服务器来响应用户请求。这一过程称为智能路由或负载均衡。通过此方式,CDN能够确保用户始终通过最快的路径获取到资源。
二、CDN的优势
- 提高加载速度
- 减少延迟:通过将内容分发到全球多个节点,用户总是能够从离自己最近的节点获取资源,从而大幅减少延迟,提高加载速度。
- 更高的可用性:通过分布式缓存,用户能够在多个服务器之间获取资源,即使某个服务器出现故障,也不会影响服务的可用性。
- 减轻原始服务器负载
- CDN缓存了大量静态内容,减少了原始服务器的直接负担,降低了带宽使用和处理请求的压力。
- 提升网站的可扩展性
- CDN帮助网站应对流量激增,能够在不同地区和时段自动调整资源的分配和流量管理,提供更好的扩展性。
- 增强网站的安全性
- DDoS防护:许多CDN提供DDoS攻击防护,能够通过分布式架构分担攻击流量,从而减轻原始服务器的压力。
- SSL加密:CDN服务提供SSL证书支持,帮助加密数据传输,提升安全性。
- 节省带宽成本
- 通过减少从原始服务器到客户端的流量,CDN有助于降低带宽费用,尤其是对于全球性网站。
- 高可用性和容错性
- CDN通过将资源缓存到多个节点,提升了资源的冗余度。在某个节点出现故障时,流量可以被自动引导到其他正常工作的节点,保证网站的高可用性。
三、CDN的类型
- 静态内容CDN
- 主要缓存静态内容,如图片、JavaScript文件、CSS文件等。通过将这些内容缓存到多个位置,能够加速资源加载速度。
- 动态内容CDN
- 动态内容指的是根据用户请求生成的内容,比如数据库查询结果或用户个性化信息。动态内容通常不缓存,但现代CDN提供商提供了对动态内容的优化方案,通过智能缓存策略加速动态内容的加载。
- 直播和视频流CDN
- 专门用于视频流、直播视频内容的传输,优化了大带宽视频数据的分发和传输。常见的技术包括流媒体协议如 HLS(HTTP Live Streaming)和 DASH(Dynamic Adaptive Streaming over HTTP)。
- 边缘计算CDN
- 这种类型的CDN不仅提供缓存功能,还支持在边缘服务器上执行计算任务。它能够在靠近用户的地方处理请求,提高性能和降低延迟。
四、CDN的工作流程
- 资源上传到CDN:
- 将网站的静态资源上传到CDN供应商的服务器。资源可能会分发到多个全球节点进行缓存。
- 用户请求访问资源:
- 用户访问网页时,浏览器向CDN发起请求。CDN会根据用户的地理位置,智能选择离用户最近的服务器响应请求。
- 缓存命中与未命中:
- 如果边缘服务器已缓存该资源(缓存命中),CDN直接返回缓存的内容。
- 如果缓存过期或没有缓存该资源(缓存未命中),CDN会向原始服务器请求资源,并将返回的资源缓存起来供后续用户使用。
- 返回资源给用户:
- 一旦缓存的资源通过CDN的边缘节点返回给用户,用户的浏览器会在本地缓存该资源,下次访问时,直接从浏览器本地获取。
五、CDN的服务提供商
目前,全球有多个主要的CDN服务提供商,最知名的包括:
- Cloudflare
- 提供免费和收费的CDN服务,支持全球分布的边缘节点,提供DDoS防护和Web应用防火墙(WAF)。
- Akamai
- 全球领先的CDN供应商,服务覆盖范围广,适用于大规模企业和高流量网站,提供强大的内容加速和安全功能。
- Amazon CloudFront
- AWS提供的CDN服务,能够与AWS的其他服务(如S3、EC2等)无缝集成,提供高可扩展性和灵活性。
- Fastly
- 以高性能为特点,支持即时缓存清除和高效的动态内容传输,适用于对延迟要求极高的应用。
- KeyCDN
- 提供较为简单和成本效益高的CDN解决方案,适用于中小型网站。
六、CDN的优化策略
- 合理设置缓存过期时间:
- 根据内容的更新频率,合理设置缓存过期时间(TTL),避免缓存过期导致频繁访问原始服务器。
- 使用分布式缓存:
- 利用CDN的全球节点分布,将内容缓存到多个节点,从而提供更好的负载均衡和冗余。
- 压缩和优化内容:
- 对资源进行压缩(如图片、CSS、JavaScript等),减少传输的数据量,提高加载速度。
- 结合HTTPS加密:
- 使用CDN的SSL证书加密功能,为网站提供HTTPS支持,提升数据传输的安全性。
七、总结
CDN是一种通过将网站内容分发到全球多个节点,减少延迟、提高加载速度、减轻服务器负载的技术。它不仅能加速资源的交付,还能提高网站的安全性、可用性和可扩展性。随着互联网应用的增长,CDN已成为优化网站性能和提供全球用户良好体验的重要工具。
1.4.1 用户请求CDN流程
用户请求CDN资源的流程可以分为几个步骤。这个流程涉及到用户如何向CDN发起请求,CDN如何决定从哪个服务器提供资源,以及缓存如何影响响应时间。以下是详细的用户请求CD能资源的流程:
一、请求流程概述
- 用户发起请求:用户的浏览器或应用程序向服务器请求某个资源(如图片、CSS、JavaScript文件等)。
- DNS解析:请求首先通过DNS解析,将资源的域名解析为CDN的IP地址。
- 路由到CDN边缘节点:用户的请求被路由到距离用户最近的CDN边缘节点。
- 边缘节点缓存检查:CDN的边缘节点检查缓存中是否已有该资源。
- 缓存命中或未命中:根据缓存的情况,决定是直接返回缓存的内容,还是从源服务器获取最新的资源。
- 返回资源给用户:资源通过边缘节点传输给用户,用户的浏览器接收并展示。
二、详细步骤
1. 用户发起请求
用户在浏览器中输入网址或点击链接时,浏览器会发起HTTP请求来请求某个资源。这些资源通常是静态文件,如HTML、CSS、JavaScript文件,或者图片、视频等媒体文件。
例如,用户请求资源:
https://www.example.com/images/logo.png
。2. DNS解析
用户请求的域名(如
www.example.com
)会通过DNS解析,转化为一个IP地址。通常,这个域名已经指向CDN提供商的域名解析系统。
- 传统方式:直接访问原始服务器的IP。
- CDN方式:DNS解析返回的是CDN边缘服务器的IP,而不是源服务器的IP。
CDN提供商通常会在多个地理位置部署多个边缘节点(edge node),当请求发起时,DNS会返回离用户最近的CDN边缘节点的IP地址,确保请求被路由到最近的服务器。
3. 请求被路由到CDN边缘节点
DNS解析完成后,浏览器向CDN的边缘节点发送请求。CDN边缘节点是部署在全球各地的服务器,它们缓存了资源内容,能够快速响应用户请求。
CDN边缘节点的选择通常由以下因素决定:
- 地理位置:用户的IP地址与边缘节点的地理位置之间的距离,尽可能选择距离用户最近的节点。
- 网络负载:当前边缘节点的负载情况。如果某个节点过载,CDN会选择其他负载较低的节点。
4. 边缘节点缓存检查
边缘节点收到请求后,会检查缓存中是否已有该资源。这一步称为缓存命中检查。
- 缓存命中:如果边缘节点缓存中已经存在该资源,并且资源没有过期,则直接从缓存中读取并返回给用户。
- 缓存未命中:如果缓存中没有该资源,或者资源已经过期,则会将请求转发给源服务器(origin server)。
5. 缓存命中或未命中
缓存命中:如果资源已经存在并且有效,CDN会直接将缓存的资源返回给用户。这是加速访问的关键步骤,因为用户不需要访问源服务器,节省了时间和带宽。
例如,若用户请求
https://www.example.com/images/logo.png
,CDN的边缘节点可能已经缓存了这个文件,且TTL(过期时间)没有到期,此时CDN直接返回文件。缓存未命中:如果缓存中没有该资源,或者缓存的资源已经过期,CDN会向源服务器发起请求以获取资源。
6. 从源服务器获取资源
当缓存未命中时,CDN边缘节点会向原始服务器(origin server)请求该资源。此时,源服务器会根据请求返回最新的资源,并且将该资源缓存到边缘节点,以供下次请求使用。
- 资源返回后,CDN会缓存到边缘节点并设置适当的缓存过期时间(TTL)。这意味着下一次请求时,边缘节点可以直接返回缓存的内容,而不需要再访问源服务器。
7. 返回资源给用户
无论是缓存命中还是从源服务器获取资源,最终,CDN的边缘节点会把响应数据返回给用户的浏览器。用户的浏览器从CDN边缘节点接收到资源,并进行展示。
8. 浏览器缓存
在资源返回给浏览器后,浏览器也会根据响应头(如
Cache-Control
、Expires
等)进行本地缓存,以便在下一次访问时直接从本地缓存中获取资源,而不再发送请求到CDN或源服务器。三、缓存策略与内容更新
CDN中的缓存策略非常关键,它决定了缓存内容的过期时间、更新方式以及缓存策略的灵活性。
- TTL(Time to Live,生存时间)
- 每个缓存的资源都会设置一个TTL,TTL指定了该资源在CDN边缘节点缓存的有效期。TTL过期后,缓存的内容会被认为是过期的,需要重新向源服务器请求内容。
- 缓存清除
- 主动清除:CDN提供商允许通过管理控制台或API来主动清除缓存中的某些资源。这对于资源更新频繁或紧急更新的情况非常重要。
- 自动清除:当资源的TTL到期时,CDN会自动清除缓存并向源服务器请求新的内容。
- 缓存验证
- 使用
ETag
和Last-Modified
等HTTP头部字段,CDN可以验证缓存是否有效。即使TTL未到期,CDN也可以通过向源服务器发送条件请求(If-None-Match
或If-Modified-Since
)来判断缓存是否需要更新。四、CDN的优势
- 减少延迟:用户总是能从离自己最近的边缘服务器获取资源,减少了传输延迟。
- 提高可用性:即使源服务器宕机,CDN仍可以从其他节点提供缓存的内容,保持服务可用。
- 减轻源服务器负担:通过缓存大量请求,CDN能够减轻源服务器的负载,减少带宽消耗。
- 提高网站性能:加速资源加载,提升用户体验,尤其是对于全球用户。
五、CDN请求流程示意图
用户请求 --> DNS解析 --> CDN边缘节点 --> 缓存检查 --> | | | 缓存命中 缓存未命中 | | | | 返回缓存的资源 从源服务器请求资源 | | | | 返回给用户的资源 缓存资源并返回给用户 |
六、总结
- CDN工作流程:CDN通过将资源分发到多个边缘节点,利用智能路由、缓存和负载均衡技术,将资源快速交付给用户,减少延迟,提高网站性能。
- 缓存命中与未命中:CDN根据缓存策略决定是否直接返回缓存的内容,或者向源服务器请求更新内容。
- 浏览器与CDN缓存:浏览器本地缓存和CDN的缓存共同工作,确保资源加载更快,减少重复请求。
CDN在提高网站性能、增强网站可用性、降低带宽消耗等方面发挥了重要作用,是现代Web应用不可或缺的组成部分。
1.4.2 CDN分层缓存
CDN(Content Delivery Network,内容分发网络)的分层缓存(Layered Caching)是指通过多级缓存架构有效提升内容分发效率的一种策略。在CDN中,请求的内容通常会经过多个层级的缓存节点,以实现更佳的性能和资源利用率。整个流程通常可以分为以下几个层次:
- L1 边缘节点缓存(Edge Cache):
这是离用户最近的一层缓存节点。当用户向CDN请求内容时,边缘节点首先检查本地缓存是否已存有该内容。若存在并未过期,便直接从该节点返回内容给用户,降低传输延迟,提高用户体验;若缓存中无此内容或内容已过期,则向上层的缓存节点或源站请求。- L2 区域或中间层缓存(Mid-Tier/Regional Cache):
当边缘节点未能在本地拿到所需内容时,会将请求向上层的区域缓存节点发出。区域缓存通常位于更靠近源站的核心网络,储存那些在一定时间窗口内被多个边缘节点重复请求的内容。通过在此层进行缓存,CDN减少了向源站多次重复请求同一内容的频率。这一层有助于将热门内容在更广的地理范围内进行共享,降低源站负载,并减少跨区域的回源请求延迟。- 源站(Origin Server):
当所有中间层缓存与边缘缓存均无请求内容时,才会到达最终的源站。源站是内容的原始出处,CDN会从这里获取最新版本的内容,然后将其分发给请求用户,并在适当的层级缓存节点中储存副本,以便满足未来类似请求。分层缓存的工作原理
以下是一个典型的用户请求过程:
- 用户访问网站,请求某个资源(例如一张图片)。
- 用户的DNS解析请求将用户导向离他最近的L1边缘节点。
- L1节点检查自身是否缓存了该资源。
- 如果有,则直接将资源返回给用户,请求结束。这称为“缓存命中”。
- 如果没有,则L1节点向其上层的L2区域节点发起请求。
- L2节点执行相同的检查,查看自身是否缓存了该资源。
- 如果有,则将资源返回给L1节点,L1节点再将其返回给用户。同时,L1节点也会缓存该资源,以便下次相同的请求可以直接命中。
- 如果没有,则L2节点继续向上,向源站发起请求。
- 源站将资源返回给L2节点,L2节点再返回给L1节点,L1节点最终返回给用户。L1和L2节点都会缓存该资源。
分层缓存的优势
- 减轻源站压力: 通过多层缓存,大部分用户请求都可以在L1或L2节点得到满足,大大减少了回源站的请求数量,从而减轻了源站的负载。
- 提高缓存命中率: 分层结构使得更常用的内容可以缓存在更靠近用户的L1节点上,从而提高整体的缓存命中率,减少用户访问延迟。
- 降低网络拥塞: 由于大量请求在CDN内部完成,减少了跨区域和跨运营商的网络传输,有助于缓解网络拥塞。
- 更好的可扩展性: 分层结构使得CDN系统更容易扩展,可以通过增加L1和L2节点来应对不断增长的用户访问量。
分片缓存(Chunked Caching)
在某些情况下,CDN还会使用分片缓存技术,将大文件(例如视频文件)分割成多个小片段(chunks),然后分别缓存这些片段。当用户请求文件时,CDN只需传输用户需要的片段,而不是整个文件。这对于提高大文件传输效率和支持流媒体播放非常有用。
总结
CDN分层缓存是一种有效的提高网站性能和用户体验的技术。通过合理地组织和管理多层缓存节点,CDN可以更好地分配资源,提高缓存命中率,并减轻源站的压力。
2.Redis 安装及连接
Redis简介:
Redis(Remote Dictionary Server)是一个开源的内存数据结构存储系统,可以用作数据库、缓存和消息队列中间件。它以Key-Value形式存储数据,提供多种数据结构和丰富的功能特性。Redis的核心价值在于高速访问、简单的数据操作模型以及丰富的数据结构支持,使其在需要快速读写、实时计算和高并发的场景中表现突出。Redis的主要特性:
内存存储:
Redis将数据存储在内存中,从而达到非常高的访问速度(读写操作通常在微秒级别)。这使其在对实时性要求高的场景(如会话存储、实时排行、实时计数器等)表现优异。多种数据结构支持:
相较于传统的Key-Value存储仅支持字符串,Redis支持多种丰富的数据结构类型,这些数据结构以简单命令即可操作:
- String(字符串):最基础的数据结构,可存储普通字符串、数字、二进制数据。
- Hash(哈希):类似于Key-Value映射的集合,可方便存储对象属性并对属性进行增删改操作。
- List(列表):双端链表实现,支持从头尾插入、弹出元素,可用来实现消息队列、任务列表等功能。
- Set(集合):无序集合结构,支持求交集、并集和差集等集合运算,常用于去重、标签管理。
- Sorted Set(有序集合):每个元素会关联一个分数(score),Redis会根据分数对元素进行排序,可用于排行榜、延时队列等场景。
- Bitmap(位图)、HyperLogLog、Geo(地理位置)等特殊数据类型:满足统计计数、地理位置查询等特殊需求。
持久化能力:
虽然Redis是内存数据库,但它并非易失性存储。Redis提供两种持久化机制,让数据在断电后仍能恢复:
- RDB(Redis Database Backup):定时生成内存快照并持久化到磁盘,恢复速度快,数据略有延迟。
- AOF(Append Only File):将每次写操作以日志的形式追加到文件中,数据恢复更为完整,可根据策略对AOF文件进行定期重写压缩。
可以根据业务需求选择合适的持久化方案,或同时开启RDB和AOF实现数据安全与高效率的折中。
高可用与分布式:
Redis提供主从复制(Master-Slave Replication)实现数据的多份冗余,主节点负责写操作,从节点同步主节点的数据,提供读取分流和故障切换。当主节点出现故障时,可手动或借助Redis Sentinel(哨兵)实现自动故障转移。
对于更大规模的数据集与访问压力,Redis Cluster可以将数据分片至多个节点,提升整体存储能力和吞吐性能。事务支持:
Redis提供简单的事务机制(MULTI/EXEC命令),可以将一组操作打包,保证这些操作的顺序性和原子性。虽然不支持复杂的回滚功能,但事务可以确保一组命令要么都执行要么都不执行。Lua脚本扩展:
Redis内置了Lua解释器,用户可以在Redis内原子执行Lua脚本,对数据进行复杂操作,而无需在客户端与Redis之间多次往返,提高复杂操作的性能和一致性。丰富的使用场景:
凭借高性能和多数据结构支持,Redis可广泛应用于各种场景:
- 缓存热点数据(例如:热门商品信息、用户会话数据、应用程序配置)
- 消息队列与任务调度(利用List或Stream)
- 实时统计(计数器、排行榜、实时分析)
- 分布式锁(利用SetNx命令实现简单的分布式锁机制)
简单易用的命令行与客户端支持:
Redis提供简洁直观的命令行客户端和与主流编程语言(如Java、Python、Go、C#等)兼容的客户端库,降低学习成本与集成难度。
总结:
Redis作为一个内存数据存储系统,具有高性能、丰富的数据类型、灵活的持久化策略以及高可用性架构支持。它在高并发、低延迟与实时处理场景中得到广泛应用,已成为构建现代互联网应用的重要基础组件。
2.1 dnf 安装 Redis
# Rocky 9.4 由系统源提供
[root@redis1.xyy.org ~]#dnf info redis
Name : redis
Version : 6.2.7
Release : 1.el9
Architecture : x86_64
Size : 1.3 M
Source : redis-6.2.7-1.el9.src.rpm
Repository : appstream
Summary : A persistent key-value database
URL : https://redis.io
License : BSD and MIT
Description : Redis is an advanced key-value store. It is often referred to as a data
: structure server since keys can contain strings, hashes, lists, sets and
: sorted sets.
:
: You can run atomic operations on these types, like appending to a string;
: incrementing the value in a hash; pushing to a list; computing set
: intersection, union and difference; or getting the member with highest
: ranking in a sorted set.
:
: In order to achieve its outstanding performance, Redis works with an
: in-memory dataset. Depending on your use case, you can persist it either
: by dumping the dataset to disk every once in a while, or by appending
: each command to a log.
:
: Redis also supports trivial-to-setup master-slave replication, with very
: fast non-blocking first synchronization, auto-reconnection on net split
: and so forth.
:
: Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
: limited time-to-live, and configuration settings to make Redis behave like
: a cache.
:
: You can use Redis from most programming languages also.
[root@Rocky9.4 ~]#
# CentOS 7由 epel 源提供
[root@CentOS7 ~]#yum info redis
Name : redis
Arch : x86_64
Version : 3.2.12
Release : 2.el7
Size : 1.4 M
Repo : installed
From repo : epel
Summary : A persistent key-value database
URL : http://redis.io
License : BSD
[root@redis1.xyy.org ~]#dnf install redis
[root@redis1.xyy.org ~]#systemctl enable --now redis
[root@redis1.xyy.org ~]#pstree -p | grep redis
|-redis-server(4237)-+-{redis-server}(4238)
| |-{redis-server}(4239)
| |-{redis-server}(4240)
| `-{redis-server}(4241)
[root@redis1.xyy.org ~]#
[root@redis1.xyy.org ~]#redis-cl
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> INFO Server
# Server
redis_version:6.2.7
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:ec192bdd77ecd321
redis_mode:standalone
os:Linux 5.14.0-427.13.1.el9_4.x86_64 x86_64
arch_bits:64
monotonic_clock:POSIX clock_gettime
multiplexing_api:epoll
atomicvar_api:c11-builtin
gcc_version:11.3.1
process_id:4237
process_supervised:systemd
run_id:37144e0c3a2930dac6148605d26afae8ee4d38ba
tcp_port:6379
server_time_usec:1734486571682241
uptime_in_seconds:37314
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:6433323
executable:/usr/bin/redis-server
config_file:/etc/redis/redis.conf
io_threads_active:0
127.0.0.1:6379>
2.2 编译安装 Redis
从 Redis 官方下载地址 获取稳定版压缩包,如 redis-7.4.0.tar.gz
。
# 1.创建 Redis 用户(不需要登录权限,只是用于运行 Redis 服务以提高安全性)
useradd -r -s /sbin/nologin redis
# 2.获取源码包
wget https://download.redis.io/releases/redis-7.4.0.tar.gz
# 3.解压并进入源码目录
tar xf redis-7.4.0.tar.gz
cd redis-7.4.0
# 4.开始编译(在某些发行版下可开启 USE_SYSTEMD=yes 选项,以生成可与 systemd 交互的可执行文件。)
make -j $(nproc) USE_SYSTEMD=yes
# 5.安装到指定位置
make PREFIX=/apps/redis install
# 6.建立软链接(方便在命令行中使用redis-server、redis-cli)
ln -s /apps/redis/bin/redis-* /usr/bin/
# 7.创建所需目录
mkdir -p /apps/redis/{etc,log,data,run}
# 8.拷贝源码目录中自带redis.conf,拷贝到配置目录:
cp redis.conf /apps/redis/etc/
# 9.redis.conf:修改关键配置
#bind:改为 0.0.0.0 或保留默认看实际需要;
#requirepass:设置 Redis 密码,如 requirepass 123456;
#dir:RDB/快照文件存放目录,一般设为 /apps/redis/data;
#logfile:日志文件路径,如 /apps/redis/log/redis-6379.log;
#pidfile:pid 文件路径,如 /apps/redis/run/redis-6379.pid;
sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' \
-e "/# requirepass/a requirepass 123456" \
-e "/^dir .*/c dir /apps/redis/data/" \
-e "/^logfile .*/c logfile /apps/redis/log/redis-6379.log" \
-e "/^pidfile .*/c pidfile /apps/redis/run/redis-6379.pid" \
/apps/redis/etc/redis.conf
# 10.设置文件权限
chown -R redis:redis /apps/redis
# 11.内核与系统参数优化(不优化会有告警)
# 11.1 调整内核参数
vim /etc/sysctl.conf
net.core.somaxconn = 1024
vm.overcommit_memory = 1
sysctl -p
# 11.2 禁用透明大页(THP)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 可以写入启动脚本(如 /etc/rc.local 或 /etc/rc.d/rc.local)以在重启后继续生效。
# 12.创建Systemd服务并启动
# CentOS/Rocky:/usr/lib/systemd/system/redis.service
# Ubuntu:/lib/systemd/system/redis.service(或 /etc/systemd/system/redis.service)
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
# 启动notify一定要编译了 USE_SYSTEMD=yes,否则启动服务有问题
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
# 13.刷新并启动服务
systemctl daemon-reload
systemctl enable --now redis
systemctl status redis
# 14.查看Redis版本或者信息
redis-server -v
# 查看服务信息
redis-cli -a 123456 INFO Server
# 测试插入和查询数据
redis-cli -a 123456 set mykey "Hello World"
redis-cli -a 123456 get mykey
#! /bin/bash
#-----------------------------------------------------
#Author: XingYuyu
#Date: 2024-08-12
#Blog: http://8.141.4.74
#Filename: install_redis.sh
#Description: [Online Install Redis for Rocky Linux ,Ubuntu,CentOS ]
#-----------------------------------------------------
VERSION=redis-7.4.0
PASSWORD=123456
INSTALL_DIR=/apps/redis
os_type() {
awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release
}
color() {
RES_COL=80
MOVE_TO_COL="echo -en \e[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \e[1;32m"
SETCOLOR_FAILURE="echo -en \e[1;31m"
SETCOLOR_WARNING="echo -en \e[1;33m"
SETCOLOR_NORMAL="echo -en \e[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ]; then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ]; then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n $"]"
echo
}
install_redis() {
wget https://download.redis.io/releases/${VERSION}.tar.gz || {
color "Redis 源码下载失败" 1
exit
}
tar xf ${VERSION}.tar.