
隆重推出 Valkey Glide Go 客户端:现已公开发布预览版!
Valkey-Glide 很高兴宣布 GLIDE (企业通用语言独立驱动程序) Go 客户端的公开发布预览版。此版本为 Go 开发人员带来了 Valkey 的强大功能和可靠性,其 API 专为性能和开发人员生产力设计。
Valkey GLIDE 是 Valkey 的一个多语言客户端,旨在实现卓越运营并结合了多年经验积累的最佳实践。GLIDE 确保了跨应用程序的一致且统一的客户端体验,无论使用何种编程语言。
目前,GLIDE 支持 Java、Node.js 和 Python。本次发布引入了 Valkey GLIDE 对 Go 的支持,将支持扩展到 Go 开发人员,并为 Valkey 服务器(包括独立部署和集群部署)提供了新的连接方式。
为何您应该感到兴奋
Go 客户端将 Valkey GLIDE 扩展到 Go 社区,提供了一个基于经过实战检验的 Rust 核心构建的强大客户端。该客户端库为需要可靠、高性能数据访问的 Go 开发人员提供了精心设计的体验。
主要特性
高级集群拓扑管理
以最少的配置连接到您的 Valkey 集群。客户端会自动检测整个集群拓扑,并根据行业最佳实践配置连接管理。
config := api.NewGlideClusterClientConfiguration().
WithAddress(&api.NodeAddress{Host: "localhost", Port: 6379})
client, err := api.NewGlideClusterClient(config)
Go 客户端提供高级拓扑管理功能,例如:
自动拓扑发现
GLIDE 可以从单个种子节点自动发现所有集群节点,无需手动配置每个节点地址。节点地址可以是 IP 地址、主机名或完全限定域名 (FQDN)。
动态拓扑维护
随着节点的添加、移除或槽所有权的变化,集群拓扑可能会随时间而改变。GLIDE 实现了多种机制来维护准确的集群视图:
- 主动拓扑监控:GLIDE 执行定期的后台检查以发现集群拓扑变化。这种方法确保了全面且最新的集群视图,提高了可用性并减少了尾部延迟。
- 基于共识的解析:GLIDE 查询多个节点的拓扑视图,并选择一致性最高的一个,从而降低陈旧或不正确映射的风险,并确保更准确、更新的集群视图,提高集群的整体可用性。
- 高效资源管理:GLIDE 采用高效算法来比较节点视图并动态限制客户端管理请求,以防止 Valkey 服务器过载,确保在维护最新拓扑图和优化资源利用之间取得平衡。
增强的连接管理
分布式系统中的连接管理带来了影响性能、可靠性和资源利用率的独特挑战。Go 客户端通过可靠的解决方案解决了这些挑战:
主动重连
GLIDE 实现了连接状态的后台监控系统。通过检测断开连接并主动启动重新连接,客户端消除了请求发现连接中断时通常会遇到的重新连接延迟。
连接风暴预防
当发生网络事件时,连接风暴可能导致服务器因同时进行的重新连接尝试而过载。GLIDE 通过带有抖动(jitter)的指数退避算法来减轻这种风险,该算法将重新连接尝试分散在一段时间内,从而保护服务器免受突然的连接激增。
强大的连接处理能力与自动重新连接策略相结合,确保您的应用程序即使在网络不稳定期间也能保持弹性。
// Configure a custom reconnection strategy with exponential backoff
config := api.NewGlideClientConfiguration().
WithAddress(&api.NodeAddress{Host: "localhost", Port: 6379}).
WithReconnectStrategy(api.NewBackoffStrategy(
5, // Initial delay in milliseconds
10, // Maximum attempts
50 // Maximum delay in milliseconds
))
多路复用连接
GLIDE 不维护连接池,而是为每个集群节点建立一个多路复用连接。这种架构选择
- 最小化到服务器的 TCP 连接总数
- 减少系统调用开销
- 通过高效的连接流水线保持高吞吐量
- 降低服务器端连接管理负担
为性能而生
Go 客户端在设计之初就考虑了性能,同时保持易用性。Go 客户端提供了同步 API,以简化使用并兼容现有的 Go 键值存储客户端。虽然每个单独的命令都是阻塞的(遵循生态系统中常见的模式),但客户端是完全线程安全的,并专为并发使用而设计。
// Example of concurrent execution using goroutines
func performConcurrentOperations(client *api.GlideClient) {
var wg sync.WaitGroup
// Launch 10 concurrent operations
for i := 0; i < 10; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
key := fmt.Sprintf("key:%d", idx)
value := fmt.Sprintf("value:%d", idx)
// Each command blocks within its goroutine, but all 10 run concurrently
_, err := client.Set(key, value)
if err != nil {
fmt.Printf("Error setting %s: %v\n", key, err)
return
}
result, err := client.Get(key)
if err != nil {
fmt.Printf("Error getting %s: %v\n", key, err)
return
}
fmt.Printf("Result for %s: %s\n", key, result)
}(i)
}
wg.Wait()
}
在底层,客户端通过以下方式高效处理这些并发请求:
- 为每个节点使用单个多路复用连接来流水线化并发命令,最小化套接字开销和系统资源
- 实现线程安全的命令执行
- 高效地将并发命令路由到适当的服务器节点
尽管当前的 API 是同步的,但其实现通过 Go 原生的 goroutines 专门针对并发使用进行了优化。我们希望收到关于未来版本是否添加异步/基于通道的 API 的反馈。
快速入门
您可以通过以下两个命令将 Valkey GLIDE 添加到您的项目中:
go get github.com/valkey-io/valkey-glide/go
go mod tidy
然后,您可以使用以下示例应用程序开始连接到本地运行在 6379 端口的 Valkey 独立服务器:
package main
import (
"fmt"
"github.com/valkey-io/valkey-glide/go/api"
)
func main() {
// Connect to a standalone Valkey server
config := api.NewGlideClientConfiguration().
WithAddress(&api.NodeAddress{Host: "localhost", Port: 6379})
client, err := api.NewGlideClient(config)
if err != nil {
fmt.Println("Error:", err)
return
}
defer client.Close()
// Test the connection
result, err := client.Ping()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(result) // PONG
// Store and retrieve a value
client.Set("hello", "valkey")
value, _ := client.Get("hello")
fmt.Println(value) // valkey
}
集群模式连接设置
需要使用 Valkey 集群吗?
同样简单!Go 客户端可以从单个种子节点自动发现您的整个集群拓扑。以下示例展示了如何通过本地运行在 7001 端口的节点连接到 Valkey 集群:
package main
import (
"fmt"
"github.com/valkey-io/valkey-glide/go/api"
)
func main() {
// Specify the address of any single node in your cluster
// This example connects to a local cluster node on port 7001
host := "localhost"
port := 7001
// Connect to a Valkey cluster through any node
config := api.NewGlideClusterClientConfiguration().
WithAddress(&api.NodeAddress{Host: host, Port: port})
client, err := api.NewGlideClusterClient(config)
if err != nil {
fmt.Println("There was an error: ", err)
return
}
res, err := client.Ping()
if err != nil {
fmt.Println("There was an error: ", err)
return
}
fmt.Println(res) // PONG
client.Close()
}
高级配置选项
用于优化性能的读取策略
通过灵活的读取策略平衡一致性和吞吐量
// Configure to prefer replicas for read operations
config := api.NewGlideClusterClientConfiguration().
WithAddress(&api.NodeAddress{Host: "cluster.example.com", Port: 6379}).
WithReadFrom(api.PreferReplica)
client, err := api.NewGlideClusterClient(config)
// Write to primary
client.Set("key1", "value1")
// Automatically reads from a replica (round-robin)
result, err := client.Get("key1")
可用策略
- PRIMARY (主节点):始终从主节点读取以获取最新数据
- PREFER_REPLICA (优先副本):以轮询方式在副本之间分发读取,必要时回退到主节点
计划在未来版本中发布
- AZ_AFFINITY (可用区亲和性):(即将推出) 优先选择与客户端位于同一可用区内的副本
身份验证和 TLS
通过内置的身份验证和 TLS 支持保护您的连接
// Configure with authentication
config := api.NewGlideClientConfiguration().
WithAddress(&api.NodeAddress{Host: "localhost", Port: 6379}).
WithCredentials(api.NewServerCredentials("username", "password")).
WithUseTLS(true) // Enable TLS for encrypted connections
请求超时和处理
为不同工作负载精细调整超时设置
// Set a longer timeout for operations that may take more time
config := api.NewGlideClientConfiguration().
WithAddress(&api.NodeAddress{Host: "localhost", Port: 6379}).
WithRequestTimeout(500) // 500ms timeout
幕后:技术架构
Valkey GLIDE Go 客户端建立在 Valkey GLIDE 核心之上。核心框架用 Rust (lib.rs) 编写,暴露公共函数。这些函数使用 Cbindgen 转换为 C 头文件。然后 Go 客户端使用 CGO 调用这些 C 函数,为 Go 开发人员提供了惯用的接口,同时利用了 Rust 的性能优势。这种架构确保了所有 Valkey GLIDE 语言实现(Java、Python、Node.js 和 Go)的一致行为,同时保持了性能和可靠性。
组件详情
+------------+ +------+ +------------+ +------------+ +------------+
| | | | | | | | | |
| Go |----->| |----->| C Header |----->| Rust |----->| Valkey |
| Client | | CGO | | cbindgen | | Core | | Server |
| |<-----| |<-----| |<-----| |<-----| |
| | | | | | | | | |
+------------+ +------+ +------------+ +------------+ +------------+
- Go 客户端:Go 开发人员的特定语言接口
- CGO:允许 Go 代码调用 C 函数
- Cbindgen:自动化从 Rust 公共 API 生成 C 头文件
- Rust 核心:连接并与 Valkey 服务器通信的高性能框架
- Rust FFI 库:实现 Rust 和其他语言之间的跨语言函数调用
加入旅程
本次公测仅仅是个开始。我们正在积极开发和增强 Go 封装器,并期待您的反馈和贡献。请在您的项目中试用,分享您的经验,并帮助我们做得更好!您可以通过以下方式加入我们的开发旅程:
- 在我们的 GitHub Issues 页面上提交问题或功能请求
- 在我们的 GitHub Discussions 论坛中参与讨论
展望未来
随着我们迈向正式发布,我们将扩展命令支持、提升性能并添加更多功能,使 Valkey GLIDE Go 客户端成为 Go 开发人员的绝佳选择。
请查看我们的 Valkey GLIDE Go 客户端 获取源代码。有关实现示例,请参阅 Go 示例的 README 文件,以获取运行独立和集群示例的说明。
有关所有可用命令及其参数的完整参考,请查阅 pkg.go.dev 上的 Go API 文档,其中提供了关于方法签名、参数和返回类型的详细信息。
贡献者
非常感谢所有使之成为可能的贡献者——你们的奉献和专业知识为 Go 社区创造了真正特别的东西。
Janhavi Gupta (Google Cloud Platform)
Niharika Bhavaraju (Google Cloud Platform)
Edric Cuartero (Google Cloud Platform)
Omkar Mestry (Google Cloud Platform)
Yury Fridlyand (Improving)
Prateek Kumar (Improving)
感谢 Aaron Congo 为客户端奠定了基础 🚀,以及 Umit Unal、Michael 的贡献!