を持っている私は、.NETのための公式のNeo4jドライバを使用してプロジェクトのためのNeo4jを使用していますここで見つける:のNeo4jは非常に高遅延
https://www.nuget.org/packages/Neo4j.Driver
をこのドライバは、私の仮定がされ、ボルトプロトコル上で動作します特殊なバイナリプロトコルがHTTP APIより効率的であることを示しています。しかし、プロジェクトの開始以来、私は非常に簡単な操作でさえ、Neo4jからのレイテンシが比較的高いことに気付きました。 UserID
は、インデックスフィールドがあり、データベースがそうでなければ完全に空にするときは、次の撮影のような試合は30-60msのような:
match(n:User { UserID: 1 }) return n.UserID
この現象は、両方の私のローカルマシン上で、当社の生産環境(ゼロネットワークオーバーヘッド近く) 。私は今日これを調査し始めて、クエリがすぐに返されることを発見しましたが、実際に結果をストリームするには時間がかかります。たとえば、ローカルホストで呼び出しが返される前に0.2msを受け取るが、ToArray()
をresult
(この場合は単一の整数フィールドであるレコードをバッファリングする)を呼び出すと、60msに時間が長くなります。
using (var driver = GraphDatabase.Driver($"bolt://localhost:7687", AuthTokens.Basic("neo4j", "1")))
{
using (var session = driver.Session())
{
// 0.2ms to return from this call
var result = session.Run("match(n:User { ID: 1}) return n.ID");
// Uncommenting this makes the whole thing take 60ms
// result.ToArray();
}
}
私は、コミュニティはHTTP上で動作Neo4jClientパッケージ、後援試してみました:同じクエリで
https://github.com/Readify/Neo4jClient
を、合計時間はちょうど0.5msのに縮小されています
var client = new GraphClient(new Uri("http://localhost:7474/db/data"), "neo4j", "1");
client.Connect();
client.Cypher.Match("(n:User { ID: 1})").Return<int>("n.ID").Results.ToArray();
より公式なベンチマークを実行すると、ボルト駆動の公式ドライバとHTTPベースのNeo4jClientとの大きな違い、次の結果が得られます。
Host Process Environment Information:
BenchmarkDotNet.Core=v0.9.9.0
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-4770 CPU 3.40GHz, ProcessorCount=8
Frequency=3312642 ticks, Resolution=301.8739 ns, Timer=TSC
CLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
GC=Concurrent Workstation
JitModules=clrjit-v4.6.1586.0
Type=Neo4jBenchmarks Mode=Throughput Platform=X64
Jit=RyuJit
Method | Median | StdDev | Scaled | Scaled-SD |
------------- |--------------- |------------ |------- |---------- |
Neo4jClient | 382.5675 us | 3.3771 us | 1.00 | 0.00 |
Neo4jSession | 61,299.9382 us | 690.1626 us | 160.02 | 2.24 |
だから、HTTPクライアントは、ネットワークのオーバーヘッドが無視できるとき160X高速です。
私たちの実稼働環境でもベンチマークを実行しましたが、その差はそれほど大きくはありませんでしたが、HTTPメソッドはまだ6倍高速でした(ネットワーク接続がかなり遅い)。
フルベンチマークコード:
public class Neo4jBenchmarks
{
private readonly IDriver _driver;
private readonly GraphClient _client;
public Neo4jBenchmarks()
{
_driver = GraphDatabase.Driver("bolt://localhost:7687", AuthTokens.Basic("neo4j", "1"));
_client = new GraphClient(new Uri("http://localhost:7474/db/data"), "neo4j", "1");
_client.Connect();
}
[Benchmark(Baseline = true)]
public void Neo4jClient()
{
_client.Cypher.Match("(n:User { ID: 1})").Return<int>("n.ID").Results.ToArray();
}
[Benchmark]
public void Neo4jSession()
{
using (var session = _driver.Session())
{
session.Run("match(n:User { ID: 1}) return n.ID").ToArray();
}
}
}
私は、Windows 10および生産上でそれを実行しているのに、私のマシンと生産の両方が、のNeo4j CE 3.0.4(現在はコミュニティ版)を実行しているがLinuxマシンであります。私は自分の知る限り設定を微調整していませんが、パフォーマンス上の違いが160倍になるとは思えません。
セッションを作成するにはトランザクションを作成する必要があるため、セッションオブジェクトを再利用しようとしました(これはスレッドセーフではないので非常に悪い考えです)目立つ。
私はNeo4jClientを使うことができますが、実際には任意の文字列クエリを実行する必要があります。Neo4jClientは流暢なAPIに大いに依存していますが、低レベルの文字列モードを提供します。
私は、文字列をクエリに使用できるようにするために全面的にオープンしています。必要な構文を使用してバグを立てたり、理想的にバグを修正することができます。 –
@ChrisSkardon - これは素晴らしいことだ!私が何かをハックすることができるかどうか見てみましょう。私が基本的に探しているのは、Neo4jのDapperです:低レベル、入力は文字列とパラメータで、結果をオブジェクトにマッピングするだけです。 – JulianR