17

私はデータ グリッドを主要な「データベース」として使用しています。Hazelcast と Ignite のクエリ パフォーマンスに大きな違いがあることに気付きました。適切なカスタム シリアライゼーションとインデックスによってデータ グリッドの使用を最適化しましたが、違いは依然として顕著な IMO です。

ここでは誰も質問していないので、今後のすべての参考のために、私自身の質問に答えます。これは抽象的な (学習) 演習ではなく、実際のベンチマークであり、大規模な SaaS システムでのデータ グリッドの使用をモデル化します。主に、並べ替えおよびフィルター処理されたページ分割されたリストを表示します。私は主に、生のフレームワークなしの Hazelcast と Ignite の使用と比較して、ユニバーサル JDBC 風のデータ グリッド アクセス レイヤーがどのくらいのオーバーヘッドを追加するかを知りたいと思っていました。しかし、私はリンゴとリンゴを比較しているので、ここにベンチマークがあります。

4

2 に答える 2

16

GitHub で提供されているコードを確認しましたが、多くのコメントがあります。

索引付けと結合

  1. おそらく最も重要な点は、Apache Ignite のインデックス作成が Hazelcast よりもはるかに洗練されているということです。Hazelcast とは異なり、Ignite は ANSI 99 SQL をサポートしているため、クエリを自由に記述できます。
  2. 最も重要なことは、Hazelcast とは異なり、Ignite はさまざまなキャッシュまたはデータ型にわたってグループ インデックスと SQL JOIN をサポートすることです。Person テーブルと Organization テーブルがあり、同じ Organization で働くすべての Person を選択する必要があるとします。これは、Hazelcast では 1 ステップで行うのは不可能ですが (間違っていたら訂正してください)、Ignite では単純な SQL JOIN クエリです。

上記を考慮すると、Ignite インデックスの作成には少し時間がかかります。特に、7 つのインデックスがあるテストではそうです。

TestEntity クラスの修正

コードでは、キャッシュに格納するエンティティTestEntityは、getter が呼び出されるたびにidSortcreatedAtSort、およびmodifiedAtSortの値を再計算します。エンティティがインデックス ツリーに格納されている間、Ignite はこれらのゲッターを数回呼び出します。TestEntity クラスを簡単に修正すると、パフォーマンスが 4 倍向上します: https://gist.github.com/dsetrakyan/6bfe089d53f888448503

ヒープの測定が正確ではない

ヒープの測定方法が正しくありません。ヒープ測定を行う前に少なくともSystem.gc()を呼び出す必要がありますが、それでも正確ではありません。たとえば、以下の結果では、メソッドを使用して負のヒープ サイズを取得しています。

準備し始める

すべてのベンチマークにはウォームアップが必要です。たとえば、上記のようにTestEntityの修正を適用し、キャッシュの作成とクエリを 2 回実行すると、より良い結果が得られます。

MySQL の比較

単一ノードの Data Grid テストを MySQL と比較することは、Ignite にとっても Hazelcast にとっても公平ではないと思います。データベースには独自のキャッシングがあり、このような小さなメモリ サイズで作業する場合は、通常、データベースのインメモリ キャッシュとデータ グリッドのインメモリ キャッシュをテストします。

通常、パーティション化されたキャッシュで分散テストを実行すると、パフォーマンスが向上します。このようにして、Data Grid は各クラスター ノードでクエリを並行して実行し、結果がはるかに速く返されます。

結果

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 リポジトリを作成し、目が覚めたときにここに投稿します (コーヒーはもう役に立ちません)。

于 2015-08-11T08:36:45.267 に答える
8

ベンチマークのソース コードは次のとおりです: 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 やその他のものを使用していません。

ベンチマークは、指定された数の appr をトランザクションで挿入します。1K サイズのレコード (そのうち 100000 個 - 増やすことはできますが、メモリに注意してください) を 1000 個のバッチ (トランザクション) で処理します。次に、昇順および降順で並べ替えを行う 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);

以下は、2012 年に 8G のメモリを搭載した 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

発火

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 を消費します。これは、クエリのパフォーマンスの向上を説明できます。インメモリ グリッドを使用することにした場合、メモリについて心配する必要がありますか?

データ グリッドがいつインデックスにヒットし、いつヒットしないか、コンパイルされたクエリ (7 ミリ秒のもの) をキャッシュする方法などを明確に知ることができます。私は推測したくないので、Hazelcast やIgnite 開発者は、いくつかの洞察を提供します。

一般的なパフォーマンスに関しては、MySQL を下回っていない場合でも、同等です。IMO のインメモリ テクノロジの方がうまくいくはずです。両社ともメモを取ってくれると思います。

上記の結果はかなり近いです。ただし、Px100 Data および上位レベルの Px100 (ページ付けのためにインデックス付きの「並べ替えフィールド」に大きく依存している) 内で使用すると、Ignite が先に進み、私のフレームワークにより適しています。私は主にクエリのパフォーマンスに関心があります。

于 2015-08-11T04:08:50.027 に答える