知识库

针对高负载的因果集群常见问题解答

跟随者实例滞后以及原因?

跟随者实例滞后的主要原因是高并发和持续的读/写工作负载。这会导致实例不堪重负,从而导致将数据传播到跟随者实例时出现额外延迟(主要是由于缺少可用的线程来执行此操作)。

如何对延迟进行一般性预期?

我们没有数字,也没有工具来了解预期的延迟(时间),因为这取决于许多因素的组合,例如事务大小、并发性、工作负载量、硬件、网络延迟等。几乎不可能将所有这些因素联系起来并得出有关延迟的一般性预期。

我们使用事务 ID 来确定跟随者实例落后于其领导者实例的距离(事务数量)。您可以查看此知识库文章了解如何监控跟随者实例是否与领导者实例同步

因果集群依赖于 Raft 协议来确保在确认事务提交之前数据是安全的和持久的。在实践中,这意味着您集群中的大多数核心服务器已经(接受了)该事务,因此由于 Raft 协议的特性,它在同步方面更接近领导者(您可以查看以下内容:http://thesecretlivesofdata.com/raft/,它以交互方式解释 Raft 协议)。

衡量延迟的一种方法是在重负载下使用两个客户端和书签设置一个简单的测试用例。这个测试用例将让客户端 1 写入数据库并使用书签,记录提交时间;然后让客户端 2 尝试使用相同的书签读取数据并记录数据可用所花费的时间。用不同的工作负载测量这两种时间,将让您了解可以预期的结果以及该值如何随工作负载变化而变化。

您可以在以下链接中阅读有关特定驱动程序因果链接和书签的更多信息JAVA 文档 JavaScript 文档 Go 文档 .NET 文档 Python 文档

我应该考虑对只读事务使用领导者实例吗?

这个问题的出现是因为为了直接路由到领导者实例并更快地获得最新数据,使用了显式写入事务进行读取。

虽然这似乎是解决延迟问题的方法,但我们在这方面的最佳实践非常简单明了:对写入使用写入事务,对读取使用读取事务。对读取使用写入事务意味着领导者实例正在被用来服务大部分(甚至全部!)请求。这会导致领导者实例承受更大的压力,从而增加领导者实例不堪重负的可能性,最终导致跟随者实例出现更大的滞后。

如果您的领导者实例始终处于持续的重负载下,这本身可能会增加延迟。在整个集群中分发负载是推荐的做法。领导者实例的工作量越少,它将数据传播到集群中其他实例的速度就越快。这意味着跟随者实例将更快地获得数据,使对跟随者实例进行读取和仅对领导者实例进行写入成为可能——正如最佳实践中所述。

如何最大限度地减少跟随者实例滞后带来的影响?

为了最大限度地减少滞后,您应该努力做到以下两点:

  • 减少并发事务的数量,因为这实际上是导致跟随者实例落后的原因。

  • 减小事务大小。显然,较大的事务需要更长时间才能提交,不仅在领导者实例上,而且在跟随者实例上也是如此,这也会导致滞后。

我们一直在努力改进 Neo4j 的所有领域,而这也不例外。最近的交付包含了一些功能,可以改善高负载情况下的体验,例如:

  • 缓存预热:使实例能够在启动时进行缓存预热,防止新实例由于没有像领导者实例一样准备好缓存而立即落后于集群(从而增加查询持续时间并增加滞后可能性)。

  • Raft 共识改进:这显着提高了整个集群的写入性能,尤其针对大型事务。现在,我们可以以与小型事务相同的速率处理大型事务。

  • 事务状态占用更少的内存(将事务移出堆,与原生索引协同工作):减少对 JVM 的压力,使整个系统更加稳定,不太容易出现 GC 暂停和滞后。

  • Bolt 线程池:限制和推迟领导者实例上的活动线程数量。这将对这种行为产生更大的影响,因为这是我们现在用来限制领导者实例负载的方法。使用此功能,我们可以调整配置设置,以实现最大可能的吞吐量,而不会让领导者实例处于无法将数据传播到整个集群的情况。您可以阅读有关 Bolt 线程池功能以及如何配置它的更多信息此处

我应该使用因果链接/书签吗?(及其对传播时间的影响)

为了更好地了解此主题,我们建议您首先查看我们的文档,特别是Neo4j 因果集群简介

简单来说,我们可以说——当被调用时——因果一致性确保客户端可以保证至少读取其自己的写入。执行此操作的方式是使用书签,这些书签在执行事务时发挥作用。客户端可以请求一个书签,然后将其作为参数提供给后续事务。使用该书签,集群可以确保只有处理了客户端书签事务的服务器才会运行其下一个事务。

这不会影响数据传播。您的数据将按照 Raft 协议规则以相同的方式传播(参见上面提到的链接)。话虽如此,根据您的用例要求,您可能需要做出设计选择。

  • 如果您绝对需要读取您自己的写入内容,使用书签可以确保这一点。您后续的请求将由拥有与写入时使用的书签相对应数据的实例处理。您将遇到数据访问时间上的损失,因为您需要等待信息可用。这方面的一个例子可以是新闻提要上的评论:您在数据库中写了一条评论,您绝对需要这条信息在评论后立即弹出。

  • 不使用书签意味着后续的读取可能拥有也可能不拥有最新数据。您将更快地访问数据,但由于您没有提供因果链的途径,您读取的数据可能不是最新的,您可能会检索到不想要的结果。这方面的一个例子可能是在线商店的(非实时)推荐系统:您将根据您的过去购买推荐产品,如果您购买了新的东西,您将更新数据库。但是,新添加的信息只会用于推荐未来购买的产品。

您需要决定您的用例是否需要这个因果链来确保真正一致的结果,或者它是否需要最快的數據訪問,即使它可能不是最新的?或者,也许有些客戶需要比其他客戶更强的一致性?如上所述,这是一个设计选择,人们必须选择最适合用例的选择。