Apache Ignite-グリッドコンピューティング

グリッド計算または「美しい」ハッシュのマイニングを行ったため、Apache Igniteグリッドでこのようなタスクをチェックすることにしました。 以前、 IgniteをSqlデータベースとして試して作成しましたが、自分にとっては、これがこのコンピューティングシステムでまだ便利なオプションであることに気付きました(IgniteでSQLに戻ります)。 。 ここで、計算を迅速かつ安価に増やすことができるかどうかを確認します。たとえば、1台の強力なコンピューターにいくつかの弱いコンピューターを追加して計算を増やすことはできません。



タスクは、データトランザクションブロックのハッシュを計算することですが、単純ではありませんが、たとえば、7つの「A」文字が連続して含まれるなど、多少複雑です。 これを可能にするために、特定の複雑さのハッシュが取得されるまで、サイクルで絶えず増加する数値をデータブロックに固定します。 はい、マイナーは暗号通貨をマイニングしているようです。 複数のトランザクションがあるので、それらを計算グリッドに送信します。 計算グリッドはIgniteノードであり、異なるコンピューターでインスタンスを実行し、自身を検出してグリッドを形成します。 これらの計算は、ノード間で均等かつ自動的に分散されます。



したがって、自宅での私の計算能力は次のとおりです。



Intel Core I5-7400 3.5 GHz 8 GB。 RAM

Intel Core I3-6100 3.7 GHz 8 GB。 RAM

Intel Core 2Duo E6550 2.3 GHz 8 GB RAM

Igniteはそれぞれで起動されます。



以下は、グリッドでのコンピューティング用にIgniteが提供するテンプレートの1つです。
//  Ignition.setClientMode(true); try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { //  ,   //        ,    for (final T item: list) { calls.add(new IgniteCallable<String>() { @Override public String call() throws Exception { //      ,      return result; } }); } //       Collection<String> res = ignite.compute().call(calls); //      for (String hash : res) { System.out.println(">>> Check all nodes for output : " + result); } }
      
      







グリッドのノードで計算されるコードは次のとおりです(public String call())
  calls.add(new IgniteCallable<String>() { @Override public String call() throws Exception { System.out.println(); System.out.println(">>> Id transaction=#" + transaction.getId() + " on this node from ignite job."); MessageDigest md = MessageDigest.getInstance("MD5"); String transactHash; //    do { md.update(transaction.getDifficultyContent().getBytes()); byte[] digest = md.digest(); transactHash = DatatypeConverter.printHexBinary(digest).toUpperCase(); //   transaction.setDifficulty(transaction.getDifficulty() + 1); } while (!transactHash.contains("AAAAAAA")); return transactHash; } });
      
      







完全なコード
 public class MyComputeCallable { //    public static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr,# " + "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.#" + "At vero eos et accusam et justo duo dolores et ea rebum.#" + "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."; /** * Executes example. * * @param args Command line arguments, none required. * @throws IgniteException If example execution failed. */ public static void main(String[] args) throws IgniteException { String[] loremIpsum = LOREM_IPSUM.split("#"); List<Transaction> transactionList = new ArrayList<>(); for (int i= 0; i <= 10; i++) { transactionList.add(i, new Transaction(i, loremIpsum[i % 4])); } Ignition.setClientMode(true); try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { System.out.println(); System.out.println(">>> Compute callable example started."); Collection<IgniteCallable<String>> calls = new ArrayList<>(); // Iterate through all words in the sentence and create callable jobs. for (final Transaction transaction : transactionList) { calls.add(new IgniteCallable<String>() { @Override public String call() throws Exception { System.out.println(); System.out.println(">>> Id transaction=#" + transaction.getId() + " on this node from ignite job."); MessageDigest md = MessageDigest.getInstance("MD5"); String transactHash; do { md.update(transaction.getDifficultyContent().getBytes()); byte[] digest = md.digest(); transactHash = DatatypeConverter.printHexBinary(digest).toUpperCase(); //   transaction.setDifficulty(transaction.getDifficulty() + 1); } while (!transactHash.contains("AAAAAAA")); return transactHash; } }); } // Execute collection of callables on the ignite. long millis = System.currentTimeMillis(); Collection<String> res = ignite.compute().call(calls); System.out.println(); // individual received from remote nodes. for (String hash : res) { System.out.println(">>> Check all nodes for output hash: " + hash); } System.out.println(">>> Total msec: " + (System.currentTimeMillis() - millis)); } } } //----------------------- Transaction --------------------------------- public class Transaction { private int difficulty; private int id; private String content; public Transaction(int id, String content) { this.id = id; this.content = content; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getDifficulty() { return difficulty; } public void setDifficulty(int difficulty) { this.difficulty = difficulty; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getDifficultyContent() { return "" + difficulty + content; } }
      
      







1つのノード(1台のコンピューター)での11トランザクションの計算結果、上記のコード

パソコン

ミリ秒の結果。

I5

40 909

I3

57 162

2デュオ

140 673



2Duoの時代からパワーが成長したことは素晴らしいことです。 そして、これはI5の写真でどのように見えたかです



Igniteコンソール
画像

クライアントがサーバーに接続されていることがわかります(サーバー= 1、クライアント= 1)、計算のトランザクションがノードに到着しました(合計11)>>> Id transaction ...

最後に、クライアントは切断されました(srevers = 1、clients = 0)



プログラム出力(美しいハッシュ)
画像

しかし、計算された「美しい」ハッシュ



そして今、私たちは計算能力を高め始めます。 複数のコンピューターでIgniteサーバーを実行します。 この例は、すべてのタスクが完了することを期待するように実装されているため、最後は最後のノードで計算され、弱いコンピューターを強いコンピューターに接続すると、結果は(少なくとも最初は)低下します。



複数のノードでの計算の結果。

ノード

ミリ秒の結果。

I5 + I3

44,389

I5 + I3 + 2Duo

68 892



たとえば、I5、I3に追加すると、結果は1つのI5の場合よりも低くなりますが、1つのI3の場合よりも優れていることがわかります。 したがって、この実装の計算時間は弱いノードによって測定され、ノードがタスクの一部を処理する時間に等しくなります 。 I5、I3の組み合わせで計算時間を取得するには、I5が1つのI5よりも良くなったため、I3がどれだけ多くのトランザクションをI5よりもよく表示するかを理解する必要があります。 彼はすぐに、I3が4-5トランザクションの一部を処理し、I5すべての11トランザクションと同等またはそれ以上を処理することをすぐに確立しました。 30秒(1つのI5では40秒)、このようなスケーラビリティ。



もちろん、グリッド内の弱いコンピューターに強力なコンピューターを追加すると、すぐに増加します。 1つの2Duoは140秒をカウントし、68秒で他のグリッドとグリッドになりました。



これは、グリッド内の3つのノード用のIgniteコンソールの1つです。



画像



3台のサーバー、1台のクライアントがタスクを送信するクライアント、CPUは3台のコンピューターからの合計、メモリー、合計として表示されます。 ノードが11(トランザクション)のうち4つの再タスクを受信し、最後に3つのサーバーがあったことがわかります。



一般に、分散タスクは適切に解決され、さまざまな機能を備えたさまざまなテンプレートが提供されます。 次に、IgniteでSQLに戻り、キャッシュを操作したいと思います。



トポロジー
画像

画像



材料:



着火する



All Articles