Microsoft AZ-204: Azure 缓存、CDN 与性能 — 学习指南
属于 Microsoft Azure Developer Associate AZ-204 — 学习指南. 使用经过验证的答案练习: Microsoft 考试中心, 或参加限时模拟考试: ExamRoll.io.
概述
在 Azure 中,要实现快速、可靠的用户体验,依赖于将内容和状态置于靠近用户的位置、最大限度地减少源站负载以及优雅地处理故障。Azure Cache for Redis、Azure CDN 和 Azure Front Door 共同提供了内存加速、边缘缓存以及带安全性的全局任播路由。掌握 Redis 数据结构和连接模式、CDN 配置文件和缓存语义,以及 Front Door 路由和健康探测,能让你设计出低延迟、高弹性的应用程序。
Azure Cache for Redis:层、数据结构、驱逐策略和模式
Azure Cache for Redis 是一种托管的 Redis 服务,提供亚毫秒级的数据访问,支持常见的 Redis 数据结构,并在更高级别的层中提供高级功能。
层级:
- Basic:单节点缓存,无 SLA,无数据复制。适用于开发/测试和非关键工作负载。无数据持久化、无集群、无 VNet 集成。
- Standard:双节点主/从结构,带自动故障转移和 SLA。适用于生产环境。支持以最小中断进行纵向扩缩容,但无集群或持久化功能。
- Premium:更高的性能和吞吐量,更大的缓存容量,Redis 持久化 (RDB 和 AOF),集群(分片)以实现横向扩展,虚拟网络集成,区域冗余(在支持的区域),以及用于灾难恢复 (DR) 的异地复制。还支持计划内修补时段和高级安全功能。
数据结构及其适用场景:
- Strings:基本的键/值、计数器、JSON Blob;用于速率限制和计数器的原子性 INCR/DECR 操作。
- Hashes:将对象字段(例如,用户个人资料)存储为带有字段-值对的单个键,以实现部分更新和空间效率。
- Lists:队列或堆栈,按插入顺序排序;与 LPUSH/BRPOP 结合使用,实现简单的工作队列。
- Sets:唯一集合;用于标签、成员资格检查、交集运算。
- Sorted Sets:带分数的排名;非常适合排行榜和按时间排序的事件。
- Bitmaps/Bitfields:紧凑地跟踪跨位置的布尔标志和计数器。
- HyperLogLog:以固定的内存估算基数(唯一计数)。
- Geospatial:存储和查询经纬度坐标,进行半径搜索。
- Streams:用于事件注入和消费者组的仅追加日志。
驱逐策略(当达到 maxmemory 时应用):
- volatile-lru:驱逐最近最少使用的且带有过期时间的键(Azure Cache for Redis 上的默认策略)。
- allkeys-lru:驱逐最近最少使用的键,无论其是否有过期时间。
- volatile-ttl:驱逐最快要过期的键。
- volatile-random / allkeys-random:随机驱逐键,范围限定为带过期时间的键或所有键。
- noeviction:不驱逐;会增加内存的写入命令将失败并返回错误。
- volatile-lfu / allkeys-lfu:最不常用驱逐策略的变体(适用于较新版本的 Redis)。
根据数据关键性和访问模式选择驱逐策略。对于缓存,allkeys-lru 或 allkeys-lfu 提供最佳命中率。对于精心设置了过期时间的混合存储,volatile-ttl 或 volatile-lru 可以尊重您设置的 TTL。
常见用例:
- 会话缓存:通过 IDistributedCache 或会话中间件存储用户会话状态。保持键短小,使用与会话超时一致的 TTL,如果需要,在边缘启用会话亲和性。
- 输出缓存:缓存按路由和用户分段作为键的已渲染页面片段或完整响应。在内容更改时,使用键版本控制或显式 DEL 命令使其失效。
- 发布/订阅:用于通知或缓存失效扇出的近实时消息传递。使用通道向多个订阅者广播更改。
- 排行榜:使用带分数的有序集合进行排名;使用 ZADD/ZREVRANGE 更新和读取前 N 名;使用辅助有序集合实现时间窗口排名。
连接到 Azure Redis:连接字符串、StackExchange.Redis 和弹性
连接终结点和密钥在 Azure 门户的“访问密钥”下提供。主连接字符串包括主机、端口、TLS 和密码(例如,contoso.redis.cache.windows.net:6380,password=…;ssl=True;abortConnect=False)。在生产环境中,始终在 6380 端口上使用 TLS。
StackExchange.Redis 最佳实践:
- 每个进程使用一个单一的、长生命周期的 ConnectionMultiplexer。它是线程安全的,并且能高效地复用请求。创建一次,将其存储在静态变量或 DI 容器中,然后重用。
- 配置选项:设置 AbortOnConnectFail=false 以容忍云环境的故障转移;为瞬时问题设置 ConnectRetry 和 ConnectTimeout;根据工作负载调整 SyncTimeout;使用 KeepAlive 维持 NAT 穿透。文本形式的示例选项:ssl=True, abortConnect=False, connectRetry=5, connectTimeout=5000。
- 使用异步方法以避免在高负载下线程池耗尽。IDatabase 方法(StringGetAsync、HashSetAsync、SortedSetAddAsync)是非阻塞的。
- 处理弹性事件:订阅 ConnectionFailed、ConnectionRestored 和 ConfigurationChanged 事件,以记录和观察拓扑变化及故障转移。StackExchange.Redis 在故障转移时会自动重新解析主节点。
- 避免长时间运行的 Lua 脚本和繁重的事务;优先选择小型的原子命令。通过多路复用器自然地实现管道化;不要过度批处理以至于超时。
- 超时和重试:不要盲目重试非幂等命令。对关键写入操作使用幂等模式或直写队列。
- 序列化:存储紧凑的有效负载(例如 MessagePack),以最大限度地减少网络流量和内存占用。避免巨大的值;优先使用支持字段级访问的哈希。
- 键命名:按应用/环境(例如 prod:session:{userId})添加前缀,以避免冲突并简化批量操作和清除。
- 安全性:轮换访问密钥,通过 VNet(Premium 层)进行限制,并考虑使用 Private Link 进行私有访问。在生产环境中,不要将“仅允许通过 SSL 访问”设置为 false。
Azure CDN:配置文件、终结点、源站、优化和内容新鲜度
Azure CDN 在边缘 POP 缓存静态内容,以减少延迟和源站负载。一个 CDN 配置文件对终结点和定价层/提供商进行分组;一个终结点定义了边缘主机名,并连接到一个或多个源站。
配置文件和终结点:
- 在一个配置文件下,为每个应用程序或环境创建一个或多个终结点。每个终结点都有自己的边缘主机名(例如 app.azureedge.net),您可以将其通过 TLS 映射到自定义域。
- 如果需要隔离计费或应用不同的提供商/功能,请使用不同的配置文件。
源站类型:
- Azure Blob Storage:静态网站和大型媒体的理想选择。启用“静态网站”功能或映射到某个容器;确保设置正确的 MIME 类型和缓存标头。
- App Service:用于动态内容或 REST API,其中选定的响应可以被缓存。将源主机标头配置为您的应用的主机名,并确保使用 HTTPS。
- 自定义源:任何可通过公共 IP 或反向代理访问的 HTTP(S) 终结点,包括本地部署的终结点。
优化类型(在创建终结点时应用):
- 常规 Web 交付:针对大量中小型资产(HTML、CSS、JS、图片)进行平衡优化,具有广泛的 POP 覆盖范围。
- 大文件下载:针对大文件进行优化,具有范围请求调整、连接管理和面向吞吐量的设置。
- 视频流式处理:针对渐进式下载或 HLS/DASH 段交付进行优化,保持段缓存的高效性并支持字节范围请求。
缓存规则和清除:
- 全局和自定义缓存规则允许您根据路径、文件扩展名、请求方法和查询字符串行为来控制 TTL。在标准层上,在终结点的缓存设置中配置规则;高级版层增加了高级规则引擎。
- 通过门户、CLI 或 REST API,使用带通配符的路径(例如 /images/*)来清除无效内容。清除操作会传播到所有 POP;使用有针对性的清除以最小化影响范围。高级版层支持通过预加载来预热缓存。
内容新鲜度控制:
- TTL:默认情况下,CDN 会遵循源站的
Cache-Control和Expires标头。您可以使用规则覆盖或设置最小/最大 TTL。对于不可变资产,提供Cache-Control: public,max-age=31536000,immutable标头以最大化缓存命中率。 Cache-Control指令:no-store和private不会被 CDN 缓存;must-revalidate和s-maxage允许进行细粒度的共享缓存控制。优先使用s-maxage来设置 CDN 特定的 TTL,同时为浏览器保留一个较为保守的max-age值。- 查询字符串缓存行为:选择忽略查询字符串(每个路径只缓存一个对象)、缓存每个唯一 URL(每个查询字符串组合都单独缓存)或当存在查询字符串时绕过缓存。对于版本化资产(例如 app.css?v=hash),应选择“缓存每个唯一 URL”。对于分析参数(如 utm_),应选择“忽略查询字符串”以提高命中率。
- Vary 和压缩:在进行压缩时,确保设置了
Vary: Accept-Encoding;CDN 将根据每个Vary键缓存不同的变体。为文本资产启用 CDN 压缩以减少带宽消耗。
Azure Front Door:全局路由、健康状况、安全性和亲和性
Azure Front Door 提供基于任播(anycast)的第 7 层全局负载均衡、动态站点加速和集成的 WAF。它通过路由和保护动态流量来补充 CDN,同时可在 Standard/Premium 层级中选择性地缓存静态内容。
路由规则:
- 匹配传入的主机名和路径模式,并路由到源组(后端池)。可按规则应用路径重写、标头转换、重定向和协议设置。
- 当您希望在应用程序边缘进行更精细的控制时,可在路由级别(Standard/Premium)配置缓存,以实现静态或半静态资产的边缘缓存。
- 在多个源之间使用基于优先级的故障转移和加权负载均衡,并可选择性地使用地理筛选(geo-filtering)进行特定区域的路由。
健康探测和后端健康状况:
- 定义探测路径、协议、间隔和预期的 HTTP 状态码。探测从多个边缘站点运行,以确定源的健康状况。
- Front Door 使用健康状况将流量引导至延迟低且健康的源。调整超时和样本大小以避免状态抖动;确保探测端点是轻量级且未被缓存的。
WAF 集成:
- 将 WAF 策略附加到您的 Front Door,以强制执行针对常见 Web 漏洞的托管规则集,并添加用于 IP 限制、地理封锁或请求大小限制的自定义规则。
- 使用机器人防护和速率限制在边缘吸收滥用流量,从而保留源的容量。
会话亲和性:
- 当您的应用程序要求连续的请求命中同一个后端时(例如,非分布式会话状态),请启用会话亲和性。Front Door 会注入一个亲和性 Cookie,并将同一会话中的后续请求路由到路由规则内选定的后端。
- 尽可能优先选择无状态设计或由 Redis 支持的会话状态以避免使用亲和性;如果必须使用,请谨慎界定亲和性的范围,并设置适当的 Cookie TTL。
与 CDN 的协同工作:
- CDN 应用于提供具有长 TTL 的静态资产(图像、脚本、媒体);Front Door 则通过 WAF、TLS 终止和基于路径的路由来处理动态请求。这种分离可以最大化缓存命中率并最小化动态延迟。
- 对于无法缓存的 API 或页面,保持较低的 TTL 或绕过缓存;对于半静态 HTML,可以考虑使用较短的 TTL 并配合“变更时清除”的工作流。
实践问题场景
Mozilla 正在为一个用于附加组件发现的全球微型站点做发布准备,该站点在发布期间会有很高的流量峰值。他们需要快速的静态资产交付、有弹性的动态 API,以及全球范围内安全、低延迟的用户交互。
- 使用 Front Door 实现全局入口和安全性
- 创建一个带有自定义域和托管 TLS 的 Front Door Standard 配置文件。定义路由规则:/api/* 路由到 App Service API 源组,/* 路由到 CDN 端点主机名。
- 原因:任播路由将用户带到最近的边缘节点;Front Door 上的 WAF 在流量到达源之前拦截恶意模式;基于路径的路由清晰地分离了动态和静态流量。
- WAF 策略和速率限制
- 附加一个启用了托管规则集的 WAF 策略,并添加一条自定义规则来限制对 /api/search 的过多 POST 请求。
- 原因:保护 API 免受 OWASP 级别的攻击和滥用型客户端的侵害,在流量高峰期间保留源容量。
- 健康探测和源组
- 配置 API 源组,使其包含位于不同区域的两个 App Service 实例。在 /healthz 上使用健康探测,预期状态码为 200,间隔为 10 秒。将一个区域的优先级设置为 1,另一个设置为 2,以实现故障转移。
- 原因:确保在主区域性能下降时能自动进行区域性故障转移;探测可以独立于缓存响应来检测健康状况。
- 由 Redis 支持的会话和输出缓存
- 部署 Azure Cache for Redis Standard,并将 API 与 IDistributedCache 集成,以存储最少的会话状态和生命周期较短的输出片段(用于常见 API 响应,如热门附加组件列表),TTL 设置为 60-300 秒。
- 原因:在将状态移出 Web 层 的同时,减少了 API 延迟和数据库负载;较短的 TTL 无需手动失效即可保持数据新鲜度。
- 使用 Redis 数据结构实现排行榜
- 每个类别使用一个 Redis 排序集(sorted set)(例如,addons:top:{category})来维护基于下载量的排名。通过队列消费者异步更新分数,并提供读取前 N 个条目的只读 API。
- 原因:排序集提供 O(log n) 的更新速度和快速的范围读取,非常适合具有高读取并发性的实时排名。
- 使用 StackExchange.Redis 实现连接弹性
- 初始化一个单例的 ConnectionMultiplexer,设置 ssl=True、abortConnect=False、connectRetry=5 以及合理的超时时间。处理 ConnectionFailed/Restored 事件以实现可观察性,并在使用异步 API 的同时将 SyncTimeout 设置得足够高以应对突发流量。
- 原因:确保无缝的故障转移处理,并避免在瞬时网络事件或 Redis 故障转移期间发生进程范围的中断。
- 对静态资产使用 CDN 并进行积极缓存
- 创建一个 Azure CDN 配置文件和端点,针对“常规 Web 交付”进行优化,源为存储帐户的静态网站。配置缓存规则以遵循源标头,但对 /static/* 路径覆盖为 7 天的 TTL,并启用压缩。将查询字符串缓存设置为“缓存每个唯一 URL”,并为资产添加指纹(例如 app.css?v=hash)。
- 原因:边缘缓存可在全球范围内快速交付资产;资产指纹允许使用长 TTL,同时在部署时能即时更新;压缩减少了传输大小。
- CI/CD 中的清除过程
- 添加一个部署步骤,在发布时清除 HTML 和 JSON 清单文件的 CDN 路径(例如 /index.html, /manifest/*.json),并在支持的层级中为关键页面预热缓存。
- 原因:确保用户能快速获取最新的 HTML,同时保持不可变资产的缓存;预加载可以减少部署后的冷启动延迟。
- 仅在需要时使用 Front Door 会话亲和性
- 保持 API 无状态,并依赖 Redis 进行会话状态管理;为 /api/* 路由禁用 Front Door 会话亲和性。对于需要亲和性的旧版管理工具,在 /admin/* 路径上启用它,并设置较短的 TTL。
- 原因:为大多数用户最大化负载分配和可缓存性,同时将亲和性限制在所需的最小范围内。
该架构使用 Front Door 实现安全、智能的边缘路由和 WAF,使用 Azure CDN 实现高命中率的静态内容交付和精确的新鲜度控制,并使用 Azure Cache for Redis 来分流热点读取、维护低延迟的会话和排行榜数据,并平稳地吸收流量峰值。
← Azure 基于事件和消息的解决方案 · 所有领域 · Azure 监视、诊断与 DevOps 集成 →
练习这些题目 → · 在 ExamRoll.io 上限时练习 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通过考试 →