500 个并发客户端的 firestore 查询问题

Posted

技术标签:

【中文标题】500 个并发客户端的 firestore 查询问题【英文标题】:firestore query issues with 500 concurrent clients 【发布时间】:2022-01-23 20:35:38 【问题描述】:

我正在对我的项目进行一些压力测试,需要您的帮助来理解行为。我有一个网络服务器,它接受来自用户的 json 数据并将其存储在 firestore 集合中。用户可以查询这些数据。文档 json 只有两个字段 id1 和 id2 并且都是字符串。现在,作为压力测试的一部分,我启动了 500 个线程来模拟 500 个客户端,这些客户端查询集合以向每个线程提供 id1 == thread_id 的文档,如下所示:

query := client.Collection("mycollection").Where("id1", ==, my_id)    
iter := query.Documents(ctx)                          
snapList, err = iter.GetAll()

我看到两个问题:

    其中一些查询需要长达 20 秒才能返回。 某些查询因连接错误/io 超时而失败。我正在使用 go sdk。

"message":"error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp x.x.x.x:443: i/o timeout""

根据 Firestore 文档,最多允许 100 万个并发客户端。那为什么我只有 500 个问题?即使在空集合上运行此测试,我也观察到相同的行为。我还缺少其他速率限制吗? 新的

【问题讨论】:

【参考方案1】:

向 Firestore 添加负载时,建议遵循 500/50/5 规则,如 ramping up traffic 上的文档中所述:

您应该逐渐增加新集合的流量或按字典顺序关闭文档,以便 Cloud Firestore 有足够的时间准备文档以应对增加的流量。我们建议从每秒最多 500 次操作开始到新集合,然后每 5 分钟将流量增加 50%。您可以类似地增加写入流量,但请记住Cloud Firestore Standard Limits。确保操作在整个键范围内相对均匀地分布。这称为“500/50/5”规则。

因此,您可能希望从较少的线程数开始,然后每 5 分钟增加 50%,直到达到所需的负载。一些 SDK 甚至为此提供了支持类,例如 BulkWriter in Node.js。

【讨论】:

这是查询负载而不是写入负载。我确实读过 500/50/5 规则,但这似乎是针对新系列的。我在现有集合上也看到了相同的行为。如果我将线程减少到 300 个并且在进行 API 调用之前在每个线程中包含 1-10 秒的随机睡眠,也会出现相同的行为。 "这是查询负载而不是写入负载" 写入负载无法增加。 500/50/5 规则适用于任何数据的读取负载,而不仅仅是新集合。很遗憾听到应用概述的策略对您不起作用。 ¯_(ツ)_/¯ 好的,感谢您的澄清。那么,一个系列在多长时间内被认为是“新的”?它是基于集合的创建时间还是运行了多少负载?此外,在我们无法控制并发客户端访问新部署数据的生产环境中,作为开发人员,我如何确保 500/50/5 规则。例如,一旦我在生产环境中部署,许多客户端将开始查询以获取数据。 我不确定您所说的“新”是什么意思。增加读取负载的 500/50/5 规则不依赖于集合的年龄。 “您应该逐渐增加“新”集合的流量或按字典顺序关闭文档,以便 Cloud Firestore 有足够的时间准备文档以应对增加的流量。”这来自 Firestore 的“增加流量”文档。那么这里所说的“新”系列是什么?新的定义是什么?

以上是关于500 个并发客户端的 firestore 查询问题的主要内容,如果未能解决你的问题,请参考以下文章

PHP Apache 增加每个客户端的最大并发连接数

性能测试中,并发用户数是指的服务端并发么?客户端并发与服务端并发的区别是啥?

C# 1000个socket客户端并发

Firestore 规则使用 Flutter 客户端验证时间戳

分布式锁不是控制并发幂等的方式

延迟来自客户端的并发请求,直到创建 HttpSession