mTCPへ

mTCP  マルチコアシステムのユーザーモードネットワークプロトコルスタックです

カーネル状態プロトコルスタックの欠陥

インターネットの発達により、ユーザーのネットワークアプリケーションに対するパフォーマンス要件はますます高くなっています。人々は常にCPU処理能力の向上とコア数の追加に取り組んでいますが、これによりネットワークデバイスのスループットが直線的に増加することはありません。理由の1つは、カーネルプロトコルスタックがネットワークパフォーマンスを制限するボトルネックになっていることです。

相互に排他的なロックのオーバーヘッド

相互に排他的なロックは、マルチコアプラットフォームのパフォーマンスの最大のキラーです。可能な限り高い同時実行性を実現するために、現在のサーバー側アプリケーションは通常、マルチスレッド方式を使用して、クライアントがサービスポートに開始した接続要求を監視します。まず、これにより、複数のスレッド間でacceptキューへの相互排他アクセスが発生します。第2に、スレッド間のファイル記述子スペースへの相互に排他的なアクセスも、パフォーマンスの低下を引き起こす可能性があります。

メッセージによる非効率的な処理

カーネルのプロトコルスタックは、データパケットを1つずつ処理するため、バッチ処理の機能がありません。

頻繁なシステムコールによる負担

頻繁に短い接続を行うと、多数のユーザーモード/カーネルモードの切り替えが発生し、頻繁なコンテキストの切り替えにより、Cache Miss

ユーザーモードプロトコルスタックの導入

ユーザーモードのプロトコルスタック、つまり、カーネルによって最初に完了されたプロトコルスタックの機能は、ユーザーモードの実装に移されます。

ユーザーモードプロトコルスタック

Packet IODPDKたとえば)既存の高性能ライブラリを使用してコアをバイパスすることにより、ユーザーモードプロトコルスタックは、メッセージ処理がないときにユーザーモードとカーネルモードを切り替えることなく、ネットワークメッセージを直接送受信できます。また、ユーザーモードで完全に実装されているため、スケーラビリティや移植性が向上しています。

mTCPの概要

mTCPユーザーモードプロトコルスタックライブラリの実装として、そのアーキテクチャを次の図に示します。

mtcp

mTCP関数ライブラリの形式でアプリケーションプロセスにリンクされ、下部は他のユーザーモードPacket IOライブラリを使用します。

要約するとmTCP、次の特性があります。

  • 優れたマルチコアスケーラビリティ
  • バッチメッセージ処理メカニズム
  • クラスepollイベント駆動型システム
  • BSDスタイルsocket API
  • 複数のユーザーモードPacket IOライブラリをサポート
  • トランスポート層プロトコルのみサポートTCP

マルチコアのスケーラビリティ

共有リソースへのマルチスレッドアクセスによるオーバーヘッドを回避するため。mTCPすべてのリソース(などflow pool socket buffer)はコアに従って割り当てられます。つまり、各コアには独自の共有があります。そして、これらのデータ構造はcache整合しています。

上記のアーキテクチャ図からわかるように、mTCPユーザーアプリケーションスレッド(などごとにThread0追加のスレッド(mTCP thread0を作成する必要がありますこれら二つのスレッドが同じコア(セットにバインドされているCPU使用最大化するために、親和性)CPUのをCache

バッチメッセージ処理メカニズム

スレッドは内部で新しく追加さmTCPれるため、ユーザースレッドにメッセージを送信する場合、スレッド間の通信は不可避であり、スレッド間の通信はシステムコールよりもはるかにコストがかかる可能性があります。したがってmTCP、使用される方法はメッセージのバッチ処理であり、各メッセージの平均処理コストははるかに小さくなります。

クラスepollイベント駆動型システム

使用に慣れてepoll、プログラマーのプログラミングmTCPあまりにも優しい、あなたはそれを行う必要が置いてあるepoll_xxx()mtcp_epoll_xxx()

BSDスタイルのソケットAPI

同様に、ちょうどに必要なアプリケーションBSDのスタイルは、Socket APIが先行するmtcp_ など、十分なmtcp_accept()

複数のユーザーモードのパケットIOライブラリをサポート

ではmTCP、  Packet IOライブラリはとも呼ばれるIO engine現在のバージョン(バージョン2.1)mTCPをサポートDPDK(デフォルト)、 、  、 netmap   4種類onvmpsioIO engine

mTCPの実装の詳細

スレッドモデル

前述のように、mTCPユーザーアプリケーションスレッドごとに個別のスレッドを作成する必要があります。実際には、各ユーザーアプリケーションスレッドが次のインターフェイスを明示的に呼び出して完了する必要があります。

mctx_t mtcp_create_context(int cpu);

この後、各mTCPスレッドは独自のスレッドに入り、Main Loopスレッドの各ペアは、mTCP作成されたバッファーを介してデータプレーンと通信Queueし、一連

スレッドモデル

mTCPスレッドには、リソースの管理を担当する構造struct mtcp_managerあります。スレッドが初期化されると、リソースの作成が完了します。これらのリソースは、このコアのこのスレッドに属し、接続の4倍の情報の保存flow table、ソケットリソースプールを含みますsocket poolソケットの監視listener hashtable、送信方向の制御構造senderなど

ユーザーモードソケット

純粋なユーザーモードプロトコルスタックであるため、すべてのソケット操作はglibcそのセットを使用ていませんソケットmTCPを使用socket_mapすると、カーネルセットよりもはるかにシンプルに見えます。

struct socket_map
{
    int id;
    int socktype;
    uint32_t opts;

    struct sockaddr_in saddr;

    union {
        struct tcp_stream *stream;
        struct tcp_listener *listener; 
        struct mtcp_epoll *ep;
        struct pipe *pp;
    };

    uint32_t epoll;            /* registered events */
    uint32_t events;        /* available events */
    mtcp_epoll_data_t ep_data;

    TAILQ_ENTRY (socket_map) free_smap_link;
};

socketypeこのソケット構造のタイプ表すもので、その値に応じて、後続の共用体のポインターは別の構造として解釈できます。mTCP、通常、ファイル記述子の下部もこのようなsocket_map

enum socket_type
{
    MTCP_SOCK_UNUSED, 
    MTCP_SOCK_STREAM, 
    MTCP_SOCK_PROXY, 
    MTCP_SOCK_LISTENER,   
    MTCP_SOCK_EPOLL, 
    MTCP_SOCK_PIPE, 
};

ユーザーモードEpoll

mTCPepollカーネルのバージョンと比較して、実装も単純化されており、制御構造はstruct mtcp_epoll次のとおりです。

struct mtcp_epoll
{
    struct event_queue *usr_queue;
    struct event_queue *usr_shadow_queue;
    struct event_queue *mtcp_queue;

    uint8_t waiting;
    struct mtcp_epoll_stat stat;
    
    pthread_cond_t epoll_cond;
    pthread_mutex_t epoll_lock;
};

内部に3つのキューを格納し、3種類のイベントが発生するソケットを格納します。

  • MTCP_EVENT_QUEUEイベントは、プロトコルスタックのような、生成されたことを示しているLISTENソケット状態acceptESTABLISHソケットが読み取り可能なデータを有しています。
  • USR_EVENT_QUEUE ユーザーのアプリケーションイベントを表します。現在はのみPIPEです。
  • USR_SHADOW_EVENT_QUEUEユーザーモードがまだ処理ESTABLISHされておらず、最後のソケットデータが読み取られていないなど、生成されたプロトコルスタックイベントをシミュレートする必要があることを示します

TCPストリーム

mTCPUse tcp_streamは、TCPストリームのクワッド情報、TCP接続ステータス、プロトコルパラメータ、およびバッファの場所が格納されるエンドツーエンドのストリーム表します。tcp_stream各スレッドに保存されているflow table

typedef struct tcp_stream
{
    socket_map_t socket;
    
    // code omitted... 
    
    uint32_t saddr;            /* in network order */
    uint32_t daddr;            /* in network order */
    uint16_t sport;            /* in network order */
    uint16_t dport;            /* in network order */
    
    uint8_t state;            /* tcp state */
    
    struct tcp_recv_vars *rcvvar;
    struct tcp_send_vars *sndvar;
    
    // code omitted... 
} tcp_stream;

送信コントローラー

mTCP使用struct mtcp_senderの管理は、方向を送る、この構造が存在する場合、各インタフェースあたりのスレッドで終了2番目のmTCPスレッドは、そこ。3つのネットワークインタフェース、その後の合計がある。6送信コントローラ

struct mtcp_sender
{
    int ifidx;

    /* TCP layer send queues */
    TAILQ_HEAD (control_head, tcp_stream) control_list;
    TAILQ_HEAD (send_head, tcp_stream) send_list;
    TAILQ_HEAD (ack_head, tcp_stream) ack_list;

    int control_list_cnt;
    int send_list_cnt;
    int ack_list_cnt;
};

各コントローラーには3つのキューが含まれ、キュー内の要素は tcp_stream

  • Control キュー:メッセージなど、送信される制御メッセージのバッファリングを担当しSYN-ACKます
  • Send キュー:送信されたデータパケットのバッファリングを担当
  • ACK キュー:純粋なACKメッセージのバッファリングを担当

例:サーバーTCP接続確立プロセス

サーバーアプリケーションがアプリケーションスレッドepollでソケットとリスニングソケットを作成し、このリスニングソケットを追加epollするとします。アプリケーションプロセスはブロックされmtcp_epoll_wait()、mTCPスレッドは独自にmain Loopループします。
画像の説明

  1. マシンはクライアントによって開始された接続を受信し、最初のSYNメッセージを受信します。mTCPスレッドはメッセージmain LoopIO受信するために最下層を読み取ります。このスレッドflow tableで検索を試行した後、クワッドIDのフロー情報がないことが判明したため、新しいクワッドID tcp stream作成されます。
  2. このストリームをControlキューに書き込みます。状態はTCP_ST_SYNRCVD切り替えられTCP、最初のハンドシェイクが受信されたことを示します
  3. mTCPスレッドmain LoopControlキューを読み取り、このストリームだけが存在することを見つけたので、それを取り出し、SYN-ACKメッセージを組み立てて、それを最下層に送信します。IO
  4. mTCPスレッドmain Loopは下部のピアが受信したストリームのACKハンドシェイク情報を読み取り、状態をTCP_ST_ESTABLISHED(TCPスリーウェイハンドシェイク完了)に変更してから、このストリームをリスニングソケットのacceptキューにプラグインします。
  5. リスニングソケットが追加されているのでepoll、そのmTCPスレッドはなりMTCP_EVENT_QUEUEに挿入されたイベントの電子キュー。struct mtcp_epollmtcp_queu
  6. この時点で、ユーザースレッドmtcp_epoll_wait()はイベントmtcp_epoll_accept()Control読み取り、次に呼び出しを行ってキューから接続情報読み取り、接続の確立を完了することができます。

参考文献

mTCP:マルチコアシステム向けの高度にスケーラブルなユーザーレベルのTCPスタック
mTCP Github Repo

拡張データ

カーネルプロトコルスタック最適化スキーム  FastSocket
別のユーザーモードプロトコルスタック  Fスタック

13件の元の記事を公開 Likes6 訪問者10,000以上

おすすめ

転載: blog.csdn.net/majianting/article/details/104155380