データグリッドをプライマリ "データベース"として使用しています。 HazelcastとIgniteのクエリパフォーマンスの劇的な違いに気づきました。適切なカスタムシリアル化とインデックスによってデータグリッドの使用を最適化しましたが、その違いは依然としてIMOで顕著です。
ここでは誰もそれを尋ねなかったので、私は将来のすべての参照のために自分の質問に答えます。これは抽象的な(学習)演習ではなく、実際のベンチマークであり、データグリッドの使用を大規模にモデル化しますSaaSシステム-主にソートおよびフィルター処理されたページ付けされたリストを表示するため。主にフレームワークのない未加工のHazelcastやIgniteの使用量と比較して、JDBC風のユニバーサルデータグリッドアクセスレイヤーがどれだけオーバーヘッドを追加するかを知っています。
私はGitHubで提供されているコードを確認し、多くのコメントがあります。
上記を考慮すると、Igniteインデックスは、特にテストで7つある場合、作成に少し時間がかかります。
コードでは、キャッシュに格納するエンティティTestEntityがidSort、の値を再計算しますcreatedAtSort、およびmodifiedAtSortゲッターが呼び出されるたびに。エンティティがインデックスツリーに格納されている間、Igniteはこれらのゲッターを数回呼び出します。 TestEntityクラスの簡単な修正により、パフォーマンスが4倍向上します。 https://Gist.github.com/dsetrakyan/6bfe089d53f8884485
ヒープの測定方法が正しくありません。ヒープ測定を行う前に、少なくともSystem.gc()を呼び出す必要があります。これでも正確ではありません。たとえば、以下の結果では、あなたのメソッドを使用して負のヒープサイズを取得しています。
すべてのベンチマークにはウォームアップが必要です。たとえば、上記のようにTestEntity修正を適用し、キャッシュの生成とクエリを2回実行すると、より良い結果が得られます。
単一ノードのデータグリッドテストをMySQLと比較することは、IgniteにとってもHazelcastにとっても公平ではないと思います。データベースには独自のキャッシュがあり、このような小さなメモリサイズで作業する場合は常に、データベースのメモリ内キャッシュとデータグリッドのメモリ内キャッシュをテストします。
通常、パフォーマンスの利点は、パーティション化されたキャッシュに対して分散テストを実行するときに必ず得られます。このようにして、データグリッドは各クラスターノードで並列にクエリを実行し、結果がはるかに速く返されます。
Apache Igniteの結果は次のとおりです。私は前述の修正を行った後、彼らはずっとよく見えます。
HotSpot JVMがウォームアップされているため、2回目にキャッシュ作成とキャッシュクエリを実行すると、より良い結果が得られることに注意してください。
Igniteはクエリ結果をキャッシュしないことに注意してください。クエリを実行するたびに、最初から実行します。
[00:45:15] Ignite node started OK (id=0960e091, grid=Benchmark)
[00:45:15] Topology snapshot [ver=1, servers=1, clients=0, CPUs=4, heap=8.0GB]
Starting - used heap: 225847216 bytes
Inserting 100000 records: ....................................................................................................
Inserted all records - used heap: 1001824120 bytes
Cache: 100000 entries, heap size: 775976904 bytes, inserts took 14819 ms
------------------------------------
Starting - used heap: 1139467848 bytes
Inserting 100000 records: ....................................................................................................
Inserted all records - used heap: 978473664 bytes
Cache: 100000 entries, heap size: **-160994184** bytes, inserts took 11082 ms
------------------------------------
Query 1 count: 100, time: 110 ms, heap size: 1037116472 bytes
Query 2 count: 100, time: 285 ms, heap size: 1037116472 bytes
Query 3 count: 100, time: 19 ms, heap size: 1037116472 bytes
Query 4 count: 100, time: 123 ms, heap size: 1037116472 bytes
------------------------------------
Query 1 count: 100, time: 10 ms, heap size: 1037116472 bytes
Query 2 count: 100, time: 116 ms, heap size: 1056692952 bytes
Query 3 count: 100, time: 6 ms, heap size: 1056692952 bytes
Query 4 count: 100, time: 119 ms, heap size: 1056692952 bytes
------------------------------------
[00:45:52] Ignite node stopped OK [uptime=00:00:36:515]
修正したコードで別のGitHubリポジトリを作成し、目が覚めたときにここに投稿します(コーヒーはもう役に立たない)。
ベンチマークソースコードは次のとおりです。 https://github.com/a-rog/px100data/tree/master/examples/HazelcastVsIgnite
これは、前述のJDBC風のNoSQLフレームワークの一部です。 Px100 Data
ビルドして実行する:
cd <project-dir>
mvn clean package
cd target
Java -cp "grid-benchmark.jar:lib/*" -Xms512m -Xmx3000m -Xss4m com.px100systems.platform.benchmark.HazelcastTest 100000
Java -cp "grid-benchmark.jar:lib/*" -Xms512m -Xmx3000m -Xss4m com.px100systems.platform.benchmark.IgniteTest 100000
ご覧のとおり、ガベージコレクションを回避するためにメモリ制限を高く設定しています。また、独自のフレームワークテスト(Px100DataTest.Javaを参照)を実行して上記の2つと比較することもできますが、純粋なパフォーマンスに集中しましょう。どちらのテストも、Hazelcast 3.5.1とIgnite 1.3.3を除いて、Springやその他のものを使用していません。現時点では最新です。
ベンチマークは、指定された数の承認者をトランザクションとして挿入します。 1000のバッチ(トランザクション)で1Kサイズのレコード(そのうちの100000-増やすことができますが、メモリに注意してください)。次に、昇順と降順の2つのクエリを実行します(合計4つ)。すべてのクエリフィールドとORDER BYにインデックスが付けられます。
クラス全体を投稿するつもりはありません(GitHubからダウンロードしてください)。 Hazelcastクエリは次のようになります。
PagingPredicate predicate = new PagingPredicate(
new Predicates.AndPredicate(new Predicates.LikePredicate("textField", "%Jane%"),
new Predicates.GreaterLessPredicate("id", first.getId(), false, false)),
(o1, o2) -> ((TestEntity)o1.getValue()).getId().compareTo(((TestEntity)o2.getValue()).getId()),
100);
一致するIgniteクエリ:
SqlQuery<Object, TestEntity> query = new SqlQuery<>(TestEntity.class,
"FROM TestEntity WHERE textField LIKE '%Jane%' AND id > '" + first.getId() + "' ORDER BY id LIMIT 100");
query.setPageSize(100);
8Gのメモリを搭載した2012 8コアMBPで実行した結果は次のとおりです。
ヘーゼルキャスト
Starting - used heap: 49791048 bytes
Inserting 100000 records: ....................................................................................................
Inserted all records - used heap: 580885264 bytes
Map: 100000 entries, used heap: 531094216 bytes, inserts took 5458 ms
Query 1 count: 100, time: 344 ms, heap size: 298844824 bytes
Query 2 count: 100, time: 115 ms, heap size: 454902648 bytes
Query 3 count: 100, time: 165 ms, heap size: 657153784 bytes
Query 4 count: 100, time: 106 ms, heap size: 811155544 bytes
Ignite
Starting - used heap: 100261632 bytes
Inserting 100000 records: ....................................................................................................
Inserted all records - used heap: 1241999968 bytes
Cache: 100000 entries, heap size: 1141738336 bytes, inserts took 14387 ms
Query 1 count: 100, time: 222 ms, heap size: 917907456 bytes
Query 2 count: 100, time: 128 ms, heap size: 926325264 bytes
Query 3 count: 100, time: 7 ms, heap size: 926325264 bytes
Query 4 count: 100, time: 103 ms, heap size: 934743064 bytes
明らかな違いの1つは、挿入のパフォーマンスです-実生活で顕著です。ただし、ごくまれに1000レコードが挿入されます。通常、これは1つの挿入または更新(入力されたユーザーのデータの保存など)であるため、気になりません。ただし、クエリのパフォーマンスは異なります。ほとんどのデータ中心のビジネスソフトウェアは、読み取りが多いです。
メモリ消費に注意してください。 Igniteは、HazelcastよりもRAMを大量に消費します。これにより、クエリのパフォーマンスが向上します。インメモリグリッドを使用することにした場合、メモリについて心配する必要がありますか?
データグリッドがインデックスにヒットするタイミングとヒットしないタイミング、コンパイルされたクエリ(7msクエリ)をキャッシュする方法などを明確に知ることができます。推測したくないので、Hazelcastや、 Ignite開発者はいくつかの洞察を提供します。
一般的なパフォーマンスとしては、MySQLを下回らなくても同等です。 IMOインメモリテクノロジーの方が優れているはずです。どちらの会社もメモを取ると思います。
上記の結果はかなり近いです。ただし、Px100データおよびより高いレベルのPx100(ページ付けのためにインデックス付きの「ソートフィールド」に大きく依存している)内で使用される場合、Igniteは先行し、私のフレームワークにより適しています。主にクエリのパフォーマンスに関心があります。