# eBPFマップ
## 定義
eBPFマップは、[[eBPF]]プログラムにデータ保存とユーザ空間との通信の能力を提供するカーネル内データ構造である。array・hash・per-cpu array・per-cpu hash・ring buffer・perf buffer・queue・stackなど複数の型が存在し、eBPFプログラム間、あるいはeBPFプログラムとユーザ空間プログラムの間でデータを受け渡す主要な手段として機能する。eBPFプログラムの機能性がこれまでの研究・実務の焦点だったのに対し、その性能特性は長らく体系的に調べられてこなかった。(Source: [[@2024__eBPF'24__Understanding Performance of eBPF Maps]])
## 横断的知見
- 本conceptは長らく単一ソース([[@2024__eBPF'24__Understanding Performance of eBPF Maps]])のみに基づいていたが、[[@2025__PhD__Scaling Telemetry Workloads in Cloud Applications - Chapter 3 Efficient TCP-UDP Socket-based Instrumentation in Kernel for Continuous Construction of Network Call Graphs]](博士論文 Ch.3, §3.3.2)により初めて実運用実装の裏付けを得た。同ソースが示す「メモリフットプリントとキャッシュホット性がeBPFマップのオーバーヘッドの主要因である」という知見は、[[eBPF]]概念ページが蓄積してきた「情報を最上流(カーネル)で絞る」という設計指針(LogReducer・go-conntracer-bpf・cache_ext等)と接続しうる——マップアクセス自体のオーバーヘッドが値サイズとキャッシュ状態に強く依存するという事実は、カーネル内で扱うデータ量を絞る設計判断(小さな値サイズを保つ、事前確保済みhashマップを使う等)が実装レベルでも性能上正当化されることを示唆する。
- **per-CPU ハッシュマップの選択は「ゼロ初期化コストの増幅」という既知の欠点を承知の上での実装判断である**: [[@2024__eBPF'24__Understanding Performance of eBPF Maps]] は per-cpu hash マップが新規キー挿入時に全 CPU 分の値領域をゼロ初期化するためオーバーヘッドが増幅されると指摘するが、go-conntracer-bpf(博士論文 Ch.3, §3.3.2)はマルチコア環境での競合緩和のため意図的に `BPF_MAP_TYPE_PERCPU_HASH` を採用している。これは「ゼロ初期化コストの増幅」と「マルチコア書き込み競合の回避」という 2 つの性能特性がトレードオフの関係にあり、go-conntracer-bpf は後者を優先する実装判断を下したことを示す一次実装事例である。ただし go-conntracer-bpf 自身はこのトレードオフを定量評価しておらず(§3.4 の CPU オーバーヘッド評価は per-cpu マップ有無の比較実験ではない)、eBPF'24 ベンチマークが示す「新規キー挿入頻度が高いワークロードほど per-cpu 化のコストが顕在化する」という一般則が、go-conntracer-bpf の「同一宛先への複数フローを 1 エントリへ束ねる(=新規キー挿入頻度が抑制される)」設計とどう相互作用するかは、両ソースを突き合わせても定量的には未検証のまま残る。(Source: [[@2024__eBPF'24__Understanding Performance of eBPF Maps]], [[@2025__PhD__Scaling Telemetry Workloads in Cloud Applications - Chapter 3 Efficient TCP-UDP Socket-based Instrumentation in Kernel for Continuous Construction of Network Call Graphs]])
- **固定長のper-CPU配列は、キーの種類が事前に決まるPod単位集計に適した選択である**: [[@2024__Preferred Networks__eBPFを用いてPod ごとのインターネットトラフィック量を計測するツールの開発]]は、Pod・Service・Otherという3キーだけを持つIngress/Egress Mapに`BPF_MAP_TYPE_PERCPU_ARRAY`を使う。多数の可変キーを扱うper-CPU hashとは異なり、キー挿入と寿命管理を避けながらCPU間の更新競合をなくせるため、集計対象をあらかじめ粗く定義できるメトリクス用途で有利になる。一方、Podごとに2つのMapを作るため、全体コストはMap数とCPU数にも依存する。(Source: [[@2024__Preferred Networks__eBPFを用いてPod ごとのインターネットトラフィック量を計測するツールの開発]], [[@2024__eBPF'24__Understanding Performance of eBPF Maps]])
## 未解決の問い
- PodごとにIngress/Egressのper-CPU配列を2つずつ作る方式で、Pod数とCPU数が増えた場合のカーネルメモリ使用量・Map読み出し時間はどの程度になるか。固定長配列の利点がMap数の増加で失われる境界を測定する必要がある。([[@2024__Preferred Networks__eBPFを用いてPod ごとのインターネットトラフィック量を計測するツールの開発]])
- [[Linuxカーネルインタフェース]]が提起した「eBPFマップやBPF_PROG_QUERYはNetlinkの4性質フレームワーク(可搬性・イベント通知・拡張容易性・大規模転送)のどこに位置づけられるか」という問いに対し、本ソースのring buffer/perf bufferの性能比較(reserve+submit方式によるメモリコピー削減)は「大規模データ転送」軸の実証的な性能データを提供しうる。両ページを突き合わせて具体的な位置づけを行う余地がある。
- per-cpu hashマップの「新規キー挿入時に全CPU分の値領域をゼロ初期化する」という設計は、[[eBPF]]の他の性能重視の設計判断(sched_ext・cache_extの「情報を最上流で絞る」パターン)と対照的に、CPU数のスケールとともにオーバーヘッドが増大する可能性がある。マルチソケット・多コア環境(数十〜百コア級)でこの初期化コストがどう振る舞うかは本ソース(2ソケット×10コア)の範囲を超えており未検証。
- 本ソースの測定はLinux 6.0.1・x86-64・JIT有効という単一環境に限定されている。他のカーネルバージョン、ARM等の他アーキテクチャ、SmartNICオフロード環境でeBPFマップの性能特性がどう変化するかは未調査。
- eBPFマップの並行アクセス時のオーバーヘッド(本ソースはベンチマークシステム自体は対応するが、紙幅の都合で結果を割愛)、およびユーザ空間からのeBPFマップアクセスのオーバーヘッドは、本ソースでは実測されておらず、著者ら自身がfuture workとして残している。
## 関連
- ソース: [[@2024__eBPF'24__Understanding Performance of eBPF Maps]] / [[@2025__PhD__Scaling Telemetry Workloads in Cloud Applications - Chapter 3 Efficient TCP-UDP Socket-based Instrumentation in Kernel for Continuous Construction of Network Call Graphs]]
- 概念: [[eBPF]] / [[BPF]] / [[Linuxカーネルインタフェース]] / [[カーネル内VM]]
## 出典
- [[@2024__eBPF'24__Understanding Performance of eBPF Maps]](array・hash・per-cpu変種・ring/perf buffer・queue/stackの網羅的性能ベンチマーク。メモリフットプリントとキャッシュホット性が主要因。「volume discount」特性)
- [[@2025__PhD__Scaling Telemetry Workloads in Cloud Applications - Chapter 3 Efficient TCP-UDP Socket-based Instrumentation in Kernel for Continuous Construction of Network Call Graphs]](§3.3.2 `BPF_MAP_TYPE_HASH`によるフロー束ね格納・`BPF_MAP_TYPE_PERCPU_HASH`によるマルチコア競合緩和の実装判断)
- [[@2024__Preferred Networks__eBPFを用いてPod ごとのインターネットトラフィック量を計測するツールの開発]](PodごとのIngress/Egress Map、`BPF_MAP_TYPE_PERCPU_ARRAY`、Pinning、DaemonSetからの周期読み出し)