RocketMQはまだDLedgerモードのバージョン4.7.1を使用しているため、4.8.0にアップグレードすることをお勧めします

序文

最新の4.8.0DLedgerモードでは、メッセージを送信するときに、ノードからのackがパイプラインを通過するため、メッセージ送信のスループットが大幅に向上します。
以前のバージョン(4.7.1などのバージョン4.8.0より前)では、DLedgerモードに関して、ソースコードを確認したところ、以下の状況が見つかりました。その一部は4.8.0では最適化されていません。

詳細な説明

マスターとスレーブ間のネットワークは、tpsの送信に影響を与えます

メッセージを送信するときは、スレーブノードのクォーラムが戻るのを待つackを同期的にブロックする必要があるため、メッセージ送信のパフォーマンスに大きな影響を与えます。

    /**
     * Handle the append requests:
     * 1.append the entry to local store
     * 2.submit the future to entry pusher and wait the quorum ack
     * 3.if the pending requests are full, then reject it immediately
     *
     * @param request
     * @return
     * @throws IOException
     */
    @Override
    public CompletableFuture<AppendEntryResponse> handleAppend(AppendEntryRequest request) throws IOException {
        // 前面删除了很多代码
                    DLedgerEntry dLedgerEntry = new DLedgerEntry();
                    dLedgerEntry.setBody(request.getBody());
                    DLedgerEntry resEntry = dLedgerStore.appendAsLeader(dLedgerEntry);
                    return dLedgerEntryPusher.waitAck(resEntry, false);
         //后面删除了一些代码
    }

4.8.0では、ackアクションはパイプラインを介して非同期であり、メッセージを送信しているワーカースレッドをすばやく解放して、後続のメッセージ送信要求を処理できます。
実際、このackアクションの実際のシナリオでは、ネットワークの問題がtps送信のボトルネックになる可能性があります。たとえば、私が使用しているクラウド仮想マシン、rocketmqクラスターが展開されているノードは同じネットワークセグメントになく、実際のホストベースは遠く離れている可能性があります。pingを実行すると、0.3〜0.4ミリ秒の時間が必要であることがわかりました。つまり、1つのリクエストアクションには少なくとも0.3msかかり、0.3msは単なるping時間です。実際には、アクションリクエストrtはもっと長くなる可能性があります。1msで平均3つのtcpリクエストを処理できる場合でも、最大数は1のは3000です。1つのackには少なくとも2つの通信(要求+応答)が必要です。つまり、送信tps、単一ノード送信tpsは3000/2を超えることはできず、tpsは1500のみです。私の環境は圧力テスト済みです。送信tpsは1000未満です。 。
もう一つの問題は、スレーブノードに問題がある場合、それはマスターの送信TPSに大きな影響を与えるということです。私は、スレーブノードのいずれかが押されていたことをシミュレートし、TPSが低かったです。
4.8.0を使用した最適化では、DLedgerの送信tpsは非DLedgerの約半分です。たとえば、通常のモデルは6Wで、DLedgerは3Wに達する可能性があり、これは私の環境にとって恐ろしい改善です。

古いバージョンを解決する方法

4.7.1で、DLedgerの送信tpsが非常に低い場合、解決策は、送信側のスレッド数のデフォルト構成を変更し、スピンロックを再入力ロックに変更して、IOブロッキングによって引き起こされるCPU使用率を解決することです。スレッドを追加することにより、送信者のスレッド数が適切に設定されている限り、tpsの送信はかなりの量になります。これら2つの構成については、前に書かれたこの記事を参照してください。RocketMQブローカーがメッセージコミットを処理するときに、ロックで使用するかどうかスピンロックまたはリエントリーロック4.8.0は、デフォルトの2つの構成を使用できます。基本的に、スレッド数の増加を考慮する必要はありません。
4.8.0より前のバージョンでは、スレッド数を増やすことで送信tpsが低いという問題を解決できますが、ackのために、スレーブノードとのネットワークフラッシュによって、putメッセージがロックを長時間保持する可能性もあります。共通システムがビジー状態で、電流制限をトリガーします。最善の提案は、バージョン4.8.0にアップグレードすることです。

マスターとスレーブの非同期レプリケーションに違いはありません

4.8.0より前のバージョンのDLedgerモデルでは、マスタースレーブ同期二重書き込みと非同期メッセージレプリケーションの間に違いはありません。これらはすべて同期ブロッキングメソッドです。DLedgerCommitLogクラスでは、putMessageメソッドが呼び出され、非同期操作はありません。

    @Override
    public CompletableFuture<PutMessageResult> asyncPutMessage(MessageExtBrokerInner msg) {
        return CompletableFuture.completedFuture(this.putMessage(msg));
    }

    @Override
    public CompletableFuture<PutMessageResult> asyncPutMessages(MessageExtBatch messageExtBatch) {
        return CompletableFuture.completedFuture(putMessages(messageExtBatch));
    }

したがって、バージョン4.8.0にアップグレードすることをお勧めします。

古いバージョンはオフヒープメモリをサポートしていません

DLedgerモデルのもう1つの問題は、メッセージを送信するときにオフヒープメモリの使用をサポートしていないことです。この問題は4.8.0では修正されていません。非DLedgertransientStorePoolEnableは、構成パラメータを使用してオフヒープメモリを有効にすることを選択できますG.メッセージ処理の送信。メッセージを送信するときは、最初にオフヒープメモリに書き込み、ページキャッシュに非同期で書き込み、次にディスクなどをフラッシュすることができます。ページキャッシュから読み取り、読み取りと書き込みの分離を実現します。DLedgerは現在、mmapを介してページキャッシュに直接書き込みます。ソースコードを見てこの問題を見つけたとき、それは非常に奇妙であり、この構成が実際にサポートされていないことを作成者に確認しました。ねえ、私は上司に本番環境でこの構成をオンにして3Gメモリをセットアップするように依頼しました。その結果は無駄でした。
つまり、DLedgerを使用する場合は、4.8.0にアップグレードすることを強くお勧めします。

おすすめ

転載: blog.csdn.net/x763795151/article/details/112853382