aptpod Tech Blog

株式会社アプトポッドのテクノロジーブログです

Multipath TCPで通信性能を向上してみる

aptpod Hardwareグループ所属、組込みソフトウェアエンジニアの矢部です。

aptpodで取り扱っているサービスでは、通信機能は重要な要素の一つです。LTE通信網を利用して計測を行うことが多いですが、時間帯や地域によって通信性能が低下することがあります。皆さんも普段スマホを利用していて、昼時は遅い、山間部だと繋がりにくい、などと感じることがあるかもしれません。

今回は通信性能を向上させるための一つの案として、Multipath TCPというものを紹介します。なお、現時点(2023年)ではaptpod内でソリューションとして確立できていないので、あくまで実験的な要素となります。

Multipath TCP (MPTCP) て何?

MPTCP概要

Multipath TCPは、TCP接続が同時に複数のパスを利用できるようにすることで、通信のスループットを最大化し、冗長性を高めることを目的としたものです。

公式サイトはこちらにありますが、最新のカーネルで採用されているMPTCP v1についてはGithub上で公開されている情報のほうが詳しいです。

github.com

もっと詳細を知りたい方は、各バージョンごとのRFCはご覧ください。

まず、これらから抜粋したMPTCPの仕組みを簡単に説明します。

MPTCPの接続方法

MPTCPでは、ピア間の接続パスを一つではなく、複数パス(サブフロー)を同時に利用できるようにするためのTCP拡張を定義しています。

MPTCP利用シナリオの例

MPTCPの接続は、通常のTCP接続と同じ形で開始されます。

  1. まず最初にMPTCPの接続はホストAのアドレスA1と、ホストBのアドレスB1との間で確立する
  2. 追加パス(上の例だと A2 と B1 間)が利用可能な場合、MPCTPサブフローと呼ばれる追加のTCPセッションが作成される
  3. サブフローは既存のセッションと結合され、ホストAとB上のアプリケーション間の単一の接続として見えるようになる

追加サブフローの検出方法はパス管理の設定方法に依存しますが、上の例でいえば、A2 ↔︎ B2と A1 ↔︎ B1も追加可能なパスになります。

ネットワークスタックについて

MPTCPはトランスポート層で動作するため、既存のアプリケーションでも変更なしで利用可能となっています。実際利用してみると、これがかなりの強みであることがわかります。

データシーケンス信号(DSS)オプション

これを利用することで、あるサブフローでのデータ送信で障害が発生した場合に、同じDSNのデータを異なるサブフローで再送信が可能となっています。

v0 と v1 の互換性

RFC上では、v1の仕様はv0とは下位互換性がないと記述されています。そのため、v1のみに対応しているカーネルでは、v0での通信を行うことができませんし、逆もまた然りです。

ただ、仕様上はMP_CAPABLEオプションという、パケット内でバージョンを判別する方法は存在しています。ですので、ホストが複数のMPTCPバージョンをサポートすることでどちらでも動作できるようにすることは可能かとは思いますが、今回検証した限りLinuxカーネルはそのような実装になっていないようでした。

MP_CAPABLE オプション

各パケットには、マルチパス対応(MP_CAPABLE)オプションが含まれています。

MP_CAPABLE(v1)

この部分の仕様が、v0とv1では異なっています。

MP_CAPABLE(v0)

ホスト側が複数のバージョンをサポートする場合、オプションを送信する側がサポート可能な最大のバージョンを送り、受信側がそれを見て利用したいバージョンを通知する形となります。

Linux カーネルの対応状況

MPTCP v1 が公式にLinuxカーネルに採用されたのは、v5.6からです。現行の最新ディストリビューションであれば、ほぼ対応していると言って問題ないかと思います。対応状況については、公式のChangelogに記載があります。

この後に記載している今回の検証では、カーネルバージョンをv5.15.32利用しています。なお、aptpodが現在販売しているEDGEPLANT T1はカーネルバージョンがv4.9となっているため、残念ながらMPTCP v1を利用することができません。

MPTCP 検証結果

Raspberry Pi によるMPTCP v1検証

現在のメインストリームはv1なので、こちらを使います。以前テックブログでも紹介しましたRaspberry Piベースの小型コンピュータを使って検証してみました。

tech.aptpod.co.jp

なお、T1でもMPTCP v0であれば利用可能であることは検証していますが、性能的な差はないので記載は割愛しています。

MPTCPの有効化

RaspberryPi OSの場合、カーネルコンフィグで設定を有効にすればMPTCP v1が利用できるようになります。

コンフィグ設定したもので確認すると、MPTCP設定が有効になっていることがわかります。

apt@raspberrypi:~ $ sysctl net.mptcp.enabled 
net.mptcp.enabled = 1

mptcpdの利用

MPTCP v1を利用する場合、mptcpdという非常に便利なツールがあります。

github.com

これを利用することで、アプリケーションに何ら手を加えることなく、MPTCPに対応した通信ができるようになります。例えば iperf3 をMPTCPに対応した形で通信させる場合、以下のコマンドを実行するだけです。

$ mptcpize run iperf3 -s

有線LANと無線LANの同時利用の場合

まずは室内でLANを2系統(eth0,wlan0)使うケースで試験してみます。速度の検証には iperf3 を用いました。

MPTCPの設定を行った状態でiperf3で通信している状況をtcpdumpしてみると、それぞれのNICからMPTCPのオプションが付いたパケットが送信されていることがわかります。

apt@raspberrypi:~ $ sudo tcpdump -i wlan0 dst port 5201 -n -nn
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:11:22.004375 IP 192.168.11.22.38851 > 192.168.11.19.5201: Flags [S], seq 399502012, win 64240, options [mss 1460,sackOK,TS val 1740192247 ecr 0,nop,wscale 7,mptcp join id 7 token 0xa808d87f nonce 0x251cca21], length 0
17:11:22.008050 IP 192.168.11.22.38851 > 192.168.11.19.5201: Flags [.], ack 2143962676, win 502, options [nop,nop,TS val 1740192251 ecr 667182969,mptcp join hmac 0xf686d1acd242cf317cf5c1f9c3b61230a75cf74e], length 0
17:11:22.047919 IP 192.168.11.22.60827 > 192.168.11.19.5201: Flags [S], seq 2712815829, win 64240, options [mss 1460,sackOK,TS val 1740192291 ecr 0,nop,wscale 7,mptcp join id 7 token 0xd7358f3e nonce 0xfd3c2dbd], length 0
17:11:22.049973 IP 192.168.11.22.60827 > 192.168.11.19.5201: Flags [.], ack 1616183346, win 502, options [nop,nop,TS val 1740192293 ecr 667183011,mptcp join hmac 0xd54c9ad8aa6276037996de49cf98d78062709e4a], length 0
apt@raspberrypi:~ $ sudo tcpdump -i eth1 dst port 5201 -n -nn
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:11:20.350554 IP 192.168.11.24.56846 > 192.168.11.19.5201: Flags [.], seq 3439394281:3439395705, ack 307584348, win 502, options [nop,nop,TS val 3397519411 ecr 3244345261,mptcp dss ack 1465887935 seq 2403971799896915964 subseq 19174102 len 9936,nop,nop], length 1424
17:11:20.350579 IP 192.168.11.24.56846 > 192.168.11.19.5201: Flags [.], seq 1424:2848, ack 1, win 502, options [nop,nop,TS val 3397519411 ecr 3244345261,mptcp dss ack 1465887935 seq 2403971799896915964 subseq 19174102 len 9936,nop,nop], length 1424
17:11:20.350592 IP 192.168.11.24.56846 > 192.168.11.19.5201: Flags [.], seq 2848:4272, ack 1, win 502, options [nop,nop,TS val 3397519411 ecr 3244345261,mptcp dss ack 1465887935 seq 2403971799896915964 subseq 19174102 len 9936,nop,nop], length 1424
17:11:20.350604 IP 192.168.11.24.56846 > 192.168.11.19.5201: Flags [.], seq 4272:5696, ack 1, win 502, options [nop,nop,TS val 3397519411 ecr 3244345261,mptcp dss ack 1465887935 seq 2403971799896915964 subseq 19174102 len 9936,nop,nop], length 1424
17:11:20.350628 IP 192.168.11.24.56846 > 192.168.11.19.5201: Flags [.], seq 5696:7120, ack 1, win 502, options [nop,nop,TS val 3397519411 ecr 3244345261,mptcp dss ack 1465887935 seq 2403971799896915964 subseq 19174102 len 9936,nop,nop], length 1424

速度については、以下の結果となりました。

構成 速度(avg)
eth + wlan 53.3 Mbits/s
eth only 82.6 Mbits/s
wlan only 6.46 Mbits/s

実験した場所(私の自室)が電波の入りが悪かったのかWLAN単体での通信がかなり遅かったため、同時に利用した際に有線単体と比べると通信が遅くなってしまったようです。

LTE2回線利用の場合

内蔵しているLTEモジュール EM7431と、LTEドングル GH-UDG-MLCTE を利用した、LTE2回線利用による通信性能の測定を行います。同一キャリアを利用すると通信帯域が重なる恐れがあるため、キャリアは分けました。

実際に通信速度を測ってみた結果は、以下の通りです。

通信速度計測結果

構成 速度(avg)
内蔵LTEモジュール + LTE ドングル 9.39 Mbits/s
内蔵LTEモジュール のみ 5.98 Mbits/s
LTEドングルのみ 6.93 Mbits/s

同じタイミングで何度か通信速度を測ってみましたが、おおむね同じような値となっています。

複数回の通信性能計測結果

こちらの結果からは、LTE通信で単一の通信経路だと5~6 Mbpsくらいしか出せないところでも、Mulitpath TCPを使えば 9~10 Mbps程度の速度を安定して出せることがわかりました。

MPTCPを利用したintdash通信

通信性能向上に関する調査

実際にMPTCPをaptpodの製品であるintdashに適用した場合にどの程度通信性能が向上するかを見てみます。分かりやすく比較できるよう、16Mbpsという高いビットレートでカメラ映像を利用する設定にしてみました。

まずは、内蔵LTEモジュールのみの1回線利用での測定結果から。

内蔵LTEモジュールのみでの計測

こちらのグラフは、青が送信データ量、赤が送信できずに内部に溜まったデータ量を示しています。一定量のデータは送れてはいるものの、間に合わずにデータが溜まっているのがわかります。

続いて、内蔵LTEモジュールとLTEドングルの2回線利用での結果がこちら。

2回線利用した場合の計測

先ほどと比べて送信データ量が大きく改善しており、データもほとんど溜まっていません。

この結果から、MPTCPを利用することで、1回線では難しいデータ量の計測が実現できそうだ、ということがわかりました。ただ、実際に運用に乗せるためには、時間や場所などを変えてもっと試行回数を増やす必要はありそうです。

耐障害性に関する調査

MPTCPのメリットとして冗長性を高めるというものあるので、こちらの検証も行いました。

有線LANとLTE通信の2回線を利用した状態で、途中で有線LANを抜いた際の挙動がこちらになります。

途中で1回線を途絶させるデモ

有線LANを抜いた瞬間に1秒程度動画が止まるものの、すぐに復帰しているのがわかります。MPTCP使っていない状態で同じことを実施すると、復帰までにかなり時間がかかるため、冗長性という点でかなりの改善が見られます。

発生した問題と対処法について

LTE通信で検証を行っていた際、うまくMPTCPとして動作しないという問題が発生しました。調査を行った結果、送っているパケットにはmptcp capableオプションが付いているが、サーバー側に到達したパケットには同オプションが付いていないことがわかりました。

今まで未検証だった技術ということもあり、まずはMPTCP周りから洗っていたのですが、結果としてはSIMに固定グローバルIPを割り当てることで解決することができました。あまり使う機会はないかもしれませんが、各キャリアで有料の固定グローバルIPオプションというものが用意されており、弊社ではお客様からの要望で利用することがあります。

この現象について、今回の検証でサーバー側を担当してくれたSREエンジニアに相談したところ、キャリアグレードNATが原因かも、という見解でした。

ja.wikipedia.org

名前は伏せますが通信キャリア2社を利用し、両方とも同様の現象が発生しています。自宅のネットワーク環境から利用した場合は問題なかったため、LTE通信網のどこかに原因があるのかもしれません。

さいごに

上手な使い方があるのかもしれませんが、MPTCP自体はNICの状況に応じた通信速度の細かい調整などはやってくれないため、今回の検証例でもあったように速度の速いNICの足を引っ張るような結果が起こり得ます。このあたりはPeplink社のSpeedFusionといったサービスはうまくできそうです。国内だとCASO社がサービス提供をしており、aptpodでも連携した実績があります。

www.caso.co.jp

youtu.be

また、TIER Ⅳ社も多回線通信について高度な技術を開発されているようで、参考になります。

medium.com

ただ、当然ながら商用サービスを利用する場合はそれなりにいいお値段するため、Linuxの機能を用いて実行できるのは大きなアドバンテージであると感じています。このあたりは実運用での要求に応じて、何を選択すべきかを考えるところかと思います。

aptpodでは多種多様な通信環境で安定的な計測ソリューションを提供できるよう、日々研究開発を行っていますので、ご興味ある方、困りごとがある方など気軽にご相談ください!

www.aptpod.co.jp