我们有一个在高并发环境中运行的 Go 应用程序。我们通过生成多个 goroutine 来对每个请求进行多次 aerospike 读取。 目前,我们正面临这个问题,我们的客户端间歇性地超出连接队列大小限制。这是客户政策:
"ConnectionTimeoutMs": 1000,
"SocketTimeoutMs": 50,
"TimeoutMs": 100,
"ConnectionQueueSize": 150,
"LimitConnectionsToQueueSize": true
我们尝试使用默认值增加/减少connectionQueueSize,但结果相同。
最近我们进行了更改以使客户端成为单例。此外,我们尝试将 MaxRetries 设置为 0,以防尝试在多次尝试中池化连接。 将其设置为 0 后,我收到以下错误:
command execution timed out on client: Exceeded number of retries. See Policy.MaxRetries. why it says exceeded no of retries, when maxretries is set to 0
总而言之,这些都没有帮助。 任何指针表示赞赏。谢谢。
请注意:我们使用 Aerospike 社区版本。
为了完全理解这个问题,我们需要一些策略对象初始化和值设置的代码片段。第一的 确保您使用 init 函数,而不是使用
$...{}
声明对象,例如:
policy := aerospike.NewClientPolicy()
policy.ConnectionQueueSize = 150
如果问题仍然存在,最可能的原因是客户端应用程序试图以比实际速度更快的速度读取/写入。 Aerospike 将使用每个连接进行事务。因此,如果您同时进行 100 个事务,则需要 100 个连接。如果服务器负载太大,它处理事务的速度就会变慢,这意味着客户端处理每个事务的时间会更长一些。这意味着,要处理相同的负载,客户端需要打开更多连接。一般来说,如果增加
ConnectionQueueSize
不能解决问题,最可能的原因是规模调整 - 服务器达到某种速度限制 - 无论是网络还是磁盘瓶颈。
要解决此问题,您可以使用 Linux 标准工具,例如
atop, iotop, top, mpstat, iostat
或在 aerospike 中启用微基准测试:https://aerospike.com/docs/server/operations/monitor/latency
通过微基准测试,您可以使用
aerolab-agi
(例如:aerolab agi create --source-local /path/to/aerospike/logs
)等工具来检查 grafana 中的结果。
https://github.com/aerospike/aerolab
我也注意到你有
"LimitConnectionsToQueueSize": true
。这将导致连接被限制在队列大小 - 最多 150 个连接。将其设置为 false 将允许打开更多连接,但如果问题是服务器/网络/磁盘瓶颈,则将其设置为 false 可能会导致更多不利影响。
关于
maxretries
- 错误指出已达到 maxretries
的 0
(无需重试) - 意味着第一次也是唯一一次尝试失败。如果您在没有重试的情况下遇到这些超时,这进一步强化了上述瓶颈理论。