モバイル回線で「なぜか遅い」を解決する:DNSキャッシュとECS(EDNS Client Subnet)の深淵
ネットワークエンジニアとして現場を歩いていると、「都心にいるのに、なぜか地方のキャッシュサーバに飛ばされてCDNのレスポンスが悪い」といった、いわゆる“位置情報のミスマッチ”に遭遇することがあります。
特にモバイル回線において、DNSが果たす役割は単なる名前解決に留まりません。今日は、Web APIのパフォーマンスを左右する要、「EDNS Client Subnet (ECS)」の仕組みと、それを踏まえたインフラ運用・アプリ開発の勘所について、泥臭い経験を交えて解説します。
—
1. なぜ「DNSの場所」が重要なのか
現代のWebトラフィックの多くは、AkamaiやCloudflareのようなCDN(Content Delivery Network)を経由しています。CDNはユーザーに最も近い「エッジサーバ」へコンテンツを誘導しますが、その際に参照されるのが「DNSクエリの発信元IPアドレス」です。
しかし、モバイルキャリアのネットワーク環境では、スマホは個別に世界中へDNSクエリを投げるわけではありません。キャリアの巨大な「DNSキャッシュサーバ(フルリゾルバ)」が、数百万人のユーザーを代表してDNS問い合わせを行います。
ここで問題が発生します。CDN側からは、クエリを送ってきた「DNSキャッシュサーバのIP」しか見えません。もし東京のユーザーが大阪のDNSキャッシュを経由して問い合わせると、CDNは「ユーザーは大阪にいる」と誤認し、大阪のエッジサーバを返してしまう。これがレイテンシ悪化の正体です。
2. ECS(EDNS Client Subnet)という魔法
この問題を解決するために標準化されたのが RFC 7871 で定義された ECS です。
ECSは、DNSクエリの拡張仕様(EDNS)を利用し、リゾルバが「最終的なユーザーのIPアドレスのサブネット情報」をDNSクエリに付加して権威DNSサーバに伝える仕組みです。
通信シーケンスのイメージ
1. スマホ → example.com の解決をキャリアのDNSキャッシュへ依頼。
2. DNSキャッシュ → 権威DNSへ問い合わせ。この際、オプションフィールドに「ユーザーのIPサブネット(例: 106.185.xxx.0/24)」を付加(これがECS)。
3. 権威DNS → 受け取ったサブネット情報を元に、そのユーザーに最適なエッジサーバのIPを返却。
4. スマホ → 受け取った最適なエッジサーバへ接続。
3. 実践:ECSを考慮したデバッグと検証
自分の環境やAPIがECSを正しく扱えているか確認するには、dig コマンドで擬似的なECS情報を付加してテストするのが近道です。
# クエリにECS情報(クライアントIPのサブネット)を付加して問い合わせるコマンド
# +subnet=106.185.128.0/24 を指定して権威サーバへ投げる
dig @8.8.8.8 example.com +subnet=106.185.128.0/24 +nocl
PythonでAPIの応答時間を計測するTips
APIのパフォーマンスを測定する際、DNS解決時間を含めると、ECSが効いているかどうかが如実に分かります。requests ライブラリ等で、DNSのキャッシュの影響を排除して計測する際は、以下のように名前解決の時間を計測の対象に含めるのが実務の鉄則です。
import time
import socket
import requests
def measure_request(url):
# DNS解決時間を計測
start_dns = time.time()
ip = socket.gethostbyname(url.split('//')[1].split('/')[0])
end_dns = time.time()
# リクエスト実行
response = requests.get(url)
print(f"DNS解決時間: {end_dns - start_dns:.4f}s")
print(f"ステータスコード: {response.status_code}")
# 実際に運用しているAPIエンドポイントで試す
measure_request("https://api.your-service.com")
4. エンジニアが気をつけるべき実務の注意点
ECSは強力ですが、運用には注意が必要です。
- プライバシーの考慮: ECSはユーザーのIPの一部を権威DNSサーバに送ります。機密性の高いシステムでは、あえてECSを無効化するリゾルバを選択する場合もあります。
- キャッシュ効率の低下: 権威DNS側は、ECSのサブネットごとに異なる回答をキャッシュする必要があるため、キャッシュヒット率が低下します。これは権威DNSの負荷増大に直結します。
- キャリア側の仕様: 一部のモバイルキャリアでは、DNSキャッシュサーバがECSの付加をサポートしていない、あるいはフィルタリングしている場合があります。トラブったときは
digでの確認が第一です。
設定のヒント
もし自前でBINDやUnbound等の権威DNSを運用しているなら、edns-client-subnet の設定値を確認してください。
# BINDの設定例 (named.conf)
# クライアントのサブネット情報を考慮した応答を許可する設定
acl "trusted_networks" {
106.185.0.0/16; # キャリアのIPレンジを指定
};
options {
edns-client-subnet-allow { "trusted_networks"; };
};
まとめ
ECSは、モバイル網という複雑な環境下で、Webのレスポンスを物理的な距離の制約から解き放つ重要な技術です。「なぜか特定のキャリアだけ遅い」という障害に遭遇した際は、まず「DNSリゾルバがECS情報を正しく渡せているか?」を疑ってみてください。
ネットワークは目に見えませんが、パケットは常に正直です。理論を知り、コマンドで事実を確認する。この積み重ねが、シニアエンジニアへの最短ルートですよ。
次は、HTTP/3とQUICがもたらすDNS解決の新たな変化についても深掘りしていきましょうか。現場からは以上です。
コメント