我们正尝试在分布式模式下扩展OrientDB,但面临性能瓶颈。
我们的用例
数据模型和处理方法:
我们有一些子图消息,我们正在从kafka中读取这些消息,并将其持久化/追加到数据库中的图上。子图消息可以包含要在图中保存/更新的多个顶点/边。这些顶点/边可能与数据库不存在,因此我们必须先查询数据库是否存在。如果它们存在,我们必须检查是否更改了任何属性,并必须执行相应的更新操作。 Vertices
属于two types
,上面有10 to 15 properties
,而edges
属于two types
,上面只有3 properties
。服务并行使用来自16 kafka threads
的子图消息,并执行读取/更新/创建操作concurrently
。
我们正在使用Graph API
(定向图的蓝图实现)。当前,要处理一个子图,我们利用池中的一个图transactional graph
实例。 pool
周围有250 instances
,可以远程连接数据库。处理完所有必要的更新/创建transaction is committed only once
操作之后。
性能瓶颈
目前,15K
和16 threads
在分布式模式下运行,每分钟只能处理大约OrientDB v2.2.35
个子图消息。
由于并发而导致的性能下降: 在单线程上处理子图消息时,它大约需要10毫秒(大约35次读取,15次更新和20个创建操作),但同时执行到20-45毫秒则呈指数增长。
水平扩展东方数据库:
答:由于以下错误,无法在分布式模式下运行OrientDB v3.0.3:https://github.com/orientechnologies/orientdb/issues/8427
B.用OrientDB 2.2.35
试过了。但是,使用standalone
OrientDB和并发调用,大约需要20-45ms
来处理子图。而在distributed mode
中,平均有2个服务器节点都作为主节点运行,大约需要100-110 ms
。尽管将writeQurom
设置为majority
会花费更多的时间,但是可以做些什么来减少它。
慢边创建: 我们注意到,使用Graph API进行边创建是繁重的操作,因为它需要引用两个顶点,因此也需要读取这些顶点以在活动事务中获取引用。
到目前为止我们尝试过的事情:
调整图API
indexes
上查找顶点和边massive insertion intent
在写上有所改进,但由于禁用了本地缓存,因此对读取的性能造成了影响。 schema
。 off data validation
:没有明显的改进client level cache
虽然可以减少JVM的使用,但是对性能很重要transactional logs
:没有明显的改进。调整分布式数据库集群:
Master-Replica
模型没有明显的改进。Load balancing
:将对数据库的并发调用和负载均衡策略设置为ROUND_ROBIN
,这会导致大量并发修改异常,从而导致重试次数增加。 sharding
中进行了探索,但是由于其无法维护唯一索引的限制,在我们的用例中无法使用它。向上创建边缘