问题描述
我的应用程序尚未发布,因此我正在测试Gremlin查询的性能,然后再投入生产。
为了测试,我使用一个查询,该查询将一个顶点的边添加到300个其他顶点。它可以做更多的事情,但这只是简单的描述。我添加了上面提到的300个仅用于测试的工作负载。
如果我一次又一次地运行查询300次,则需要大约3分钟的时间才能完成,并且创建了90.000条边(300 x 300)。
我很担心,因为如果我有60.000个用户同时使用我的应用程序,那么使用此查询他们可能会在2分钟内创建90.000个边,而在我的情况下,同时60.000个用户并不多。 如果我同时拥有100万用户,那么我将需要很多服务器以满负荷运行,这超出了我的预算。
然后我注意到,当我执行测试时,cpu并没有显示太多活动,我不知道为什么,我也不知道DB在内部如何工作。
因此,我认为可能更现实的情况是同时调用所有查询,因为当我尝试测试自己得到ConcurrentModificationException
时,真正的用户就会遇到这种情况。
据我所知,由于同时在2个查询中读取或写入了一条边或顶点,因此发生了该错误,这在我的应用程序中可能会发生很多,因为所有用户顶点都在更改与总是有4个顶点,这种“碰撞”将一直发生。
我正在使用gremlin服务器3.4.8在本地进行测试,并使用套接字与Node.js进行连接。我的计划是在生产时使用AWS Neptune作为数据库。
我该怎么做才能恢复希望?我不知道关于这个主题的非常重要的事情,因为我不知道图形数据库在内部如何工作。
我实现了一种逻辑,该逻辑使用“指数退避”方法在收到错误时重试查询请求。它修复了ConcurrentModificationException 但是在同时发送多个查询时,Gremlin Server中存在很多问题,这表明在Gremlin Server中完全不支持多线程并且不稳定,因此,如响应所示,我们应该在其他与Gremlin兼容的数据库中尝试多线程。我遇到了查询返回的数据中的随机不一致以及诸如NegativeArraySize之类的错误以及来自数据库的其他随机事件,因此请注意这一点,不要浪费时间以为您的代码可能像我遇到的错误一样出错。
解决方法
尽管TinkerPop和Gremlin试图提供与供应商无关的经验,但实际上他们仅在界面级别这样做。因此,虽然您可以在JanusGraph,Neptune,CosmosDB等中运行相同的查询,但是您可能会发现,根据查询的性质以及所涉及图形的优化程度,性能会有所不同。该查询。
对于您的情况,请在本地运行测试时考虑使用TinkerGraph。 TinkerGraph是不具有事务处理功能的内存图,并且未经证明可安全地进行写操作。如果您对它施加了沉重的写入工作量,则可以设想ConcurrentModificationException
易于生成。现在考虑JanusGraph。如果您以此测试了繁重的写工作负载,则可能会发现,如果您的模式需要唯一的属性键,并且不得不修改代码以进行指数重试事务重试,那么您将遇到大量TemporaryLockingException
错误后退。
这里的要点是,如果目标图是Neptune,并且已经遍历了遍历以测试其正确性,并且现在担心性能,那么可能是时候在Neptune上进行测试以查看是否出现任何问题了。
我很担心,因为如果我有60.000个用户同时使用我的应用程序,那么使用此查询他们可能会在2分钟内创建90.000个边,而在我的情况下,同时60.000个用户并不多。如果我同时拥有100万用户,那么我将需要很多服务器以满负荷运行,这超出了我的预算。
您将要制定一个切合实际的测试计划。是否有60,000个用户都在同一时间按下“提交”来触发此查询,真的会发生什么?还是您可能有100,000个用户在进行某些读取操作,也许每三分之二的时间恰好单击了“提交”。
您的图形增长率似乎很高,并且您在此处描述的预期使用将很快将图形置于数十亿条边的类别中(更不用说您可能会写的其他文字了)。您是否在具有数十亿条边的图形上测试了读取的工作负载?您是否在Neptune上进行了明确测试?您是否考虑过如何维护数十亿个边缘图(例如,在需要新功能时更改架构,确保其正确增长等)?
所有这些问题都是修辞性的,旨在让您考虑自己的方向。祝你好运!