
通过设置客户端库降低应用程序延迟并减少云账单
调整客户端库如何帮助您降低云成本并改善延迟?
在本文中,我们将深入探讨可用区 (AZ) 亲和性路由机制,展示它如何使用 Valkey GLIDE (企业通用语言无关驱动程序) 优化您的应用程序性能和成本。我们还将指导您如何配置 GLIDE 以受益于其他关键功能。
GLIDE 是 Valkey 官方的开源客户端库。GLIDE 旨在为 Valkey 和基于 Redis 的应用程序提供可靠性、优化性能和高可用性。GLIDE 是一个多语言客户端,支持 Java、Python 和 Node.js,并有更多语言正在开发中。GLIDE 最近增加了对一项关键功能——AZ 亲和性路由的支持,它使基于 Valkey 的应用程序能够将调用专门定向到与客户端位于同一 AZ 的服务器节点。这最大限度地减少了跨 AZ 流量,降低了延迟,并降低了云费用。
在探讨 AZ 亲和性路由之前,让我们了解什么是可用区,不同的读取策略如何工作以及它们如何影响您的应用程序。
为您的应用程序选择正确的读取策略
分布式应用程序依赖于可伸缩性和弹性,这通常通过缓存、分片和高可用性等技术实现。Valkey 通过充当强大的缓存层来增强这些系统,减少数据库负载并加速读取操作。它的分片功能将数据分布到多个节点,确保高效的存储和访问模式,而其高可用性功能通过在主节点和副本节点之间复制数据来保障正常运行时间。这种组合使分布式应用程序能够处理高流量并从故障中快速恢复,确保一致的性能。
在基于 Valkey 的应用程序中,选择正确的读取策略对于优化性能和成本至关重要。读取策略决定了只读命令的路由方式,平衡了数据新鲜度、延迟和吞吐量等因素。理解支持这些策略的基础设施是有效利用它们的关键。
可用区是云区域内提供冗余和容错的隔离位置。它们物理上相互分离,但通过低延迟网络连接。主要的云提供商如 AWS、Oracle 和 GCP 都实现了可用区 (AZ) 的概念。然而,跨不同可用区使用资源可能会导致延迟和成本增加。GLIDE 利用这种基础设施,通过将读取操作路由到同一可用区内的副本节点,从而实现更快的响应并改善用户体验。这对于优先考虑读取吞吐量并能容忍轻微过期数据的应用程序特别有利。例如,具有个性化推荐引擎的网站依赖于快速向用户显示内容,而不是确保每次更新都完美同步。此外,缓存最常见的用例之一是存储数据库查询结果,允许应用程序用牺牲绝对新鲜度来换取更好的性能、可伸缩性和成本效益。从副本读取的策略引入了最小的额外过期时间,使其成为此类场景的有效选择。GLIDE 提供了根据您的应用程序需求量身定制的灵活选项
PRIMARY
:始终从主节点读取,以确保数据的新鲜度。PREFER_REPLICA
:以轮询方式在所有副本之间分发请求。如果没有可用的副本,则回退到主节点。AZ_AFFINITY
:优先选择与客户端位于同一 AZ 的副本。如果该区域没有可用的副本,则回退到其他副本,或在需要时回退到主节点。AZ_AFFINITY_REPLICAS_AND_PRIMARY
:优先选择与客户端位于同一 AZ 的副本。如果该区域没有可用的副本,则回退到同一 AZ 中的主节点。如果两者都不可用,则回退到其他区域的副本或主节点。
在 Valkey 8 中,引入了 availability-zone
配置,允许客户端为每个 Valkey 服务器指定 AZ。GLIDE 利用这一新配置,使其用户能够使用 AZ 亲和性路由。在撰写本文时,GLIDE 是唯一支持 AZ 亲和性策略的 Valkey 客户端库,提供了独特的优势。
AZ 亲和性路由优势
-
降低数据传输成本 跨区域数据传输在云环境中通常会产生额外费用。通过确保操作指向同一 AZ 内的节点,您可以最大限度地减少或消除这些成本。
示例: 在 AWS 中,一个 Valkey 集群包含 2 个分片,每个分片有 1 个主节点和 2 个副本,实例类型为 m7g.xlarge。该集群每秒处理 250MB 数据,为简化示例,100% 的流量是读取操作。其中 50% 的流量跨越 AZ,成本为每 GB $0.01,每月跨 AZ 数据传输成本约为 $3,285。此外,集群的成本为每个节点每小时 $0.252。总计每月 $1,088。通过实施 AZ 亲和性路由,您可以将总成本从 $4,373 降低到 $1,088,因为所有流量都保留在同一 AZ 内。
-
最小化延迟 同一区域内可用区之间的距离——例如,在 AWS 中通常高达 60 英里(100 公里)——会增加额外的往返延迟,通常在 500µs 到 1000µs 之间。通过确保请求保留在同一 AZ 内,您可以降低延迟并提高应用程序的响应速度。
示例 1: 考虑一个包含三个节点的集群,一个主节点和两个副本。每个节点都位于不同的可用区。客户端位于 az-2,与 replica-1 在一起。
使用
PREFER_REPLICA
策略:在这种情况下,客户端将从任何可用的副本读取命令。它可能位于不同的 AZ 中,如下图所示,平均延迟例如为 800 微秒。使用
AZ_AFFINITY
策略:在这种情况下,客户端将从与客户端位于同一 AZ 的副本读取命令,平均延迟例如约为 300 微秒。示例 2: 考虑一个包含三个节点的集群,一个主节点和两个副本。每个节点都位于不同的可用区。客户端位于 az-2,与主节点在一起。副本位于 az-1 和 az-3。
使用
AZ_AFFINITY
策略:在这种情况下,客户端尝试从同一 AZ 中的副本读取。由于 az-2 中没有可用的副本,它会回退到另一个 AZ 中的副本,例如 az-1 或 az-3。
平均延迟例如约为 800 微秒。使用
AZ_AFFINITY_REPLICAS_AND_PRIMARY
策略:
在这种情况下,客户端首先尝试从同一 AZ 中的副本读取。由于没有本地副本,它会从位于 az-2 的主节点读取。平均延迟例如约为 300 微秒。
使用 GLIDE 配置 AZ 亲和性连接
在 GLIDE 中设置 AZ 亲和性路由非常简单,只需几个配置步骤即可充分发挥其潜力。让我们详细介绍如何在应用程序中启用此功能。
在 GLIDE 中设置 AZ 亲和性路由的步骤
-
配置 Valkey 节点的可用区 - 根据每个 Valkey 节点在云提供商区域内的物理或虚拟位置,将其分配给特定的 AZ。初始配置必须在节点初始化时使用单独的管理客户端完成,因为客户端在首次重新连接时会从副本获取信息。在某些托管服务(如 Amazon ElastiCache)中,此映射是自动配置的,因此不需要此步骤。
对于每个节点,运行以下命令并根据需要更改 AZ 和路由地址
Python
client.config_set({"availability-zone": az}, route=ByAddressRoute(host="address.example.com", port=6379))
Java
client.configSet(Map.of("availability-zone", az), new ByAddressRoute("address.example.com", 6379))
Node.js
client.configSet({"availability-zone": az}, { route: {type: "routeByAddress", host:"address.example.com", port:6379}})
-
使用特定 AZ 定位配置 GLIDE - 这里提供了 Python、Java 和 Node.js 示例,展示了如何设置 AZ 亲和性客户端,将调用定向到与客户端位于同一 AZ 的节点。
Python
from glide import ( GlideClient, GlideClientConfiguration, NodeAddress, ReadFrom ) # Determine the client's AZ (this could be fetched from the cloud provider's metadata service) client_az = 'us-east-1a' # Initialize Valkey client with preference for the client's AZ addresses = [NodeAddress(host="address.example.com", port=6379)] client_config = GlideClusterClientConfiguration(addresses, read_from=ReadFrom.AZ_AFFINITY, client_az=client_az) client = await GlideClusterClient.create(client_config) # Write operation (route to the primary's slot owner) client.set("key1", "val1") # Get will read from one of the replicas in the same client's availability zone if one exits. value = client.get("key1")
Java
// Initialize Valkey client with preference for the client's AZ GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder() .host("address.example.com") .port(6379) .build()) .readFrom(ReadFrom.AZ_AFFINITY) .clientAZ("us-east-1a") .build() GlideClusterClient client = GlideClusterClient.createClient(config).get(); // Write operation (route to the primary's slot owner) client.set("key1", "val1").get(); // Get will read from one of the replicas in the same client's availability zone if one exits. client.get("key1").get();
Node.js
import GlideClusterClient from "@valkey/valkey-glide"; const addresses = [ { host: "address.example.com", port: 6379 } ]; // Initialize Valkey client with preference for the client's AZ const client = await GlideClusterClient.createClient({ addresses: addresses, readFrom: "AZAffinity" as ReadFrom, clientAz: "us-east-1a", }); // Write operation (route to the primary's slot owner) await client.set("key1", "val1"); // Get will read from one of the replicas in the same client's availability zone if one exits. await client.get("key1");
结论
通过在 Valkey 中实施 AZ 亲和性路由并使用 GLIDE,您可以通过将请求路由到与客户端位于同一 AZ 的副本,从而实现更低的延迟和成本节约。
2025 年 5 月更新,涵盖 AZ_AFFINITY_REPLICAS_AND_PRIMARY
策略及相应示例。