Apache Pinotとは?超低遅延OLAPの仕組み・star-tree索引とupsert設計から採用判断まで解説
Apache Pinotは、取り込んだ直後のデータに対して、多数の同時クエリを秒以下で返すことを狙って作られた分散OLAPデータベースです。LinkedInで利用者向けの分析画面を支えるために生まれ、列指向の格納に複数の索引を重ねる構造を取ります。この記事では、4種類のノード構成、star-tree索引の事前集計、REALTIMEテーブルのupsert要件、Apache DruidやClickHouseとの違い、採用しない方がよい条件までを実装者の目線で整理しました。
まとめ|Apache Pinot採用の判断軸と向く用途
Pinotが効くのは、確定済みのイベントを追記し続けながら、多数の利用者が同時に叩く画面へ、絞り込みと集計の結果を秒以下で返したい場面に絞られます。ECサイトの購買実績ダッシュボード、広告主向けの配信レポート、SaaSの利用状況画面がその典型例。社内の少人数がアドホックに探索する分析や、大きなテーブル同士の結合を前提にした集計には向きません。
規模の線引きもはっきりしています。1日あたり数百万行を超える追記があり、同時に走るクエリが二桁後半から三桁に届き、応答時間の要求が1秒未満。この3つが揃ったときに固定費が見合い始めます。逆に、社内の数人がBIから叩くだけならPostgreSQLかDWHで足ります。
設計で最初に固めるのは、主キーとストリームの分割、star-tree索引の対象、保持期間の3点になります。特にupsertを使う構成では、パーティション数を後から変えられない制約が効いてくるため、取り込みを始める前に確定させておく必要があるでしょう。
Apache Pinotの定義とユーザー向け分析基盤としての立ち位置
Pinotを一言でいえば「エンドユーザーに見せる画面の裏側へ置くOLAPデータベース」です。
LinkedIn発のPinotが狙う高同時実行と秒以下の応答特性
Pinotが他のOLAP基盤と分かれるのは、想定する利用者の位置づけにあります。社内アナリストが少数で叩く分析基盤ではなく、サービスの利用者本人へ数値を見せる画面を支える前提で設計されました。LinkedInの「プロフィール閲覧者」や企業向けの分析画面がその出発点です。
この前提は要求仕様へ直結します。画面を開いた人数分だけクエリが飛ぶため、同時実行数は数千に達し、1件あたりの応答は数十ミリ秒から数百ミリ秒に収める必要が出てくるためです。多次元集計そのものの考え方はOLAP分析の定義と多次元集計の基本を先に押さえると、索引設計の意図が読み取りやすくなります。
Pinot 1.5系(2026年8月時点)の到達点と直近の変更点
公式のダウンロードページが安定版として掲示しているのは1.5系で、直近の1.5.1は2026年6月5日のリリースです(2026年8月時点)。1.5.1はCVE対応のための依存更新だけを含む修正版で、機能・API・設定・通信形式の変更は入っていません。
機能面の変更は1.5.0にまとまっています。OFFLINEテーブルへのupsert拡張、複数クラスタへクエリを振り分けるフェデレーション、Kafka 4系クライアント対応、時系列クエリエンジンの正式版化などが並びました。
Controller・Broker・Server・Minionの4役割と依存構成
Pinotは単一プロセスではなく、役割の違う4種類のノードで動きます。
Controller・Broker・Server・Minionの担当範囲
公式ドキュメントが挙げるノード種別は次の4つです。
- Controller:メタデータ変更やノード障害の際にリソースを再配置する
- Broker:クエリを該当サーバへ振り分け、部分結果を統合して返す
- Server:セグメントをローカルストレージへ保持し、クエリを処理する
- Minion:バッチ変換やデータ削除など、クエリ以外の背景処理を担う
Serverは慣例として「リアルタイム」と「オフライン」に分けて運用します。取り込み中のデータを抱えるノードと、確定済みセグメントを配るノードを分ければ、取り込みの負荷がクエリ応答へ波及しにくくなるためです。
Apache HelixとZooKeeperが担うクラスタ状態の管理
クラスタ管理はPinot自前ではなく、Apache Helixへ委ねられています。Helixは分散クラスタの状態管理を担う仕組みで、コントローラ上のプロセスと、Broker・Server上の組み込みエージェントで構成される作りです。
状態の保管先はZooKeeperになります。クラスタ構成、テーブルのメタデータ、セグメントの配置情報がここへ集まるため、ZooKeeperを失うとクラスタは自分の持ち物を判断できません。バックアップと冗長化の優先度は、Serverよりも先に置いてください。
セグメントとdeep storeが決める耐障害性と復旧手順の前提
データの実体はセグメントという単位で置かれます。REALTIMEテーブルでは、ストリームから読んだ行がメモリ上のconsuming segmentへ積まれ、行数かサイズの閾値に達した時点でcompleted segmentとして確定する流れです。
確定したセグメントはdeep storeへ書き出されます。deep storeはクラウドストレージやHDFSのような共有ストレージで、ここに正本が残るため、Serverが全滅してもセグメントを再配布して復旧できる設計です。裏返せば、検証用にローカルディスクをdeep storeへ充てた構成は、本番へそのまま持ち込めません。
star-tree索引と12種の索引種別が決める応答速度の設計余地
Pinotの応答速度は索引の設計余地から来ています。列ごとに何を付けるかで、同じクエリの処理量が桁で変わるためです。
star-tree索引の事前集計とmaxLeafRecordsの決め方
Pinot固有の仕組みがstar-tree索引です。事前集計はクエリ遅延の上限を固定できる反面、次元の組み合わせが増えると保管量が指数関数的に膨らみます。star-treeはその中間を取り、木構造の各ノードを指定した次元で分割しながら、分割に使った次元を落とした事前集計レコードをスターノードとして持ちます。
設定は3つの項目で決まります。dimensionsSplitOrder には分割する次元を順序付きで並べ、絞り込みと集計に使う列を含めます。時刻列は末尾へ置くのが通例。functionColumnPairs には集計関数と列の組をアンダースコア2つでつないだ形(たとえば SUM__Impressions や COUNT__*)で指定します。
残る maxLeafRecords はリーフノードが含む最大レコード数の閾値で、既定値は10,000です。値を小さくすると事前集計が深くまで作られて応答は速くなり、そのぶんセグメントの容量が増えます。画面から飛ぶクエリの形が固まっているなら小さめ、まだ揺れているなら既定値から始めて実測で詰めてください。
転置索引・範囲索引・JSON索引・テキスト索引の使い分けと付与の判断
star-tree以外にも索引は揃っています。公式ドキュメントが列挙する種別は次のとおりです。
| 索引種別 | 効く場面 |
|---|---|
| Forward index | 既定の行から値への参照経路 |
| Inverted index | 等値やINの絞り込み |
| Range index | 数値や時刻の範囲条件 |
| Star-tree index | 繰り返す集計とグループ化 |
| JSON index | 入れ子JSONの条件指定 |
| Timestamp index | 時間粒度の集計と丸め |
| Bloom filter | 選択性の高い検索の枝刈り |
| Vector index | 埋め込みの類似検索 |
このほかFSTによる前方一致、トークン化したテキスト述語、地理空間の距離条件、半構造化オブジェクト向けの列単位索引もあります。全部を付ける設計は取りません。索引はセグメント容量と取り込み時のCPUを消費するため、実際に飛ぶクエリの述語だけへ絞って付与するのが基本になります。
scatter-gatherの分散実行とマルチステージエンジンの適用
クエリの実行経路は2系統あります。単段のエンジンはBrokerがクエリをServerへ配り部分結果を集める流れで、単純な絞り込み集計へのオーバーヘッドが小さい作りです。
結合やウィンドウ関数を使うならマルチステージエンジンを選びます。こちらはクエリを木構造の複数ステージへ分解し、葉がテーブルを読み、中間が結合やサブクエリを処理し、根が結果を返す構成です。1.0.0で実運用可能な位置づけとされており、実験的な機能ではありません。
有効化はクエリ単位で行えます。SQLなら SET useMultistageEngine=true を先頭へ置き、REST経由なら queryOptions に同じ指定を渡す形。ただし大文字小文字の扱いや型の一致、関数の戻り値型の判定は単段エンジンより厳しくなるため、既存クエリをそのまま切り替えると通らない場合があります。
REALTIMEテーブルの取り込み設計とupsertの前提条件
PinotのテーブルはOFFLINE・REALTIME・HYBRIDの3種類です。ストリーム取り込みを使うなら、設計の分岐はほぼupsertを使うかどうかで決まります。
consuming segmentからcompleted segmentへの遷移
REALTIMEテーブルは、KafkaやKinesis、Pulsarといったストリームから直接読み込みます。読んだ行はまずconsuming segmentとしてメモリ上へ置かれ、この状態でもクエリの対象です。
閾値に達したconsuming segmentは確定処理へ入り、completed segmentとしてdeep storeへ書き出されたうえでServerへ配られます。ここで生まれるセグメントが小さすぎると、クエリのたびに走査対象の数が増えて応答が鈍ります。
primaryKeyColumns指定とKafkaのパーティション要件
upsertを使う場合、まずスキーマ側で主キーを宣言します。primaryKeyColumns に列名を並べる形で、複合キーも指定できる仕様です。
設計上の要は、ストリーム側の分割条件になります。公式ドキュメントは、主キーでストリームをパーティション化することを必須の要件として挙げています。同じ主キーのメッセージが常に同じパーティションへ入らないと、更新の適用先が分散して整合が崩れるためです。送信側でキーを設定するのが前提で、それができない場合はFlinkなどで前段に再パーティションの処理を挟みます。
パーティション数は作成後に変更できません。ここは後戻りの費用が最も高い箇所で、将来の書き込み量を見込んだ数を最初に決めておく必要があります。ストリーム側の分割設計とメッセージ保持の考え方はApache Kafkaが選ばれる理由と特徴を押さえておくと判断しやすいでしょう。
FULLとPARTIALの違いとupsert利用時に外れる機能
upsertのモードは2つに分かれます。FULLは同じ主キーの新しいレコードが古いレコードを丸ごと置き換える動きで、PARTIALは指定した列だけを更新し、残りは元の値を保持する動きです。
対応範囲には差があります。FULLはREALTIME・OFFLINE・HYBRIDで使え、PARTIALはREALTIMEテーブルに限られる仕様です。PARTIALを使う際はnullの扱いを有効にしたうえで、列ごとの更新方針を指定します。
見落としやすいのは、upsertと引き換えに外れる機能があることです。star-tree索引はupsertを有効にしたテーブルでは使えません。事前集計と行の置き換えが噛み合わないためで、集計の速さを索引で稼ぐ設計とは併用できない前提になります。削除もソフト削除に限られ、順序が逆転したイベント(比較列の値が現在値より小さいもの)はスキップされます。
Apache Druid・ClickHouseとの違いと選定で効く判断基準
Pinotの検討は必ず類似製品との比較になります。軸を先に固定してから当てはめます。
Apache Druidとの違いが出る同時実行数と索引の作り方
Apache Druidは最も近い位置にある製品です。どちらも列指向でストリーム取り込みを持ち、時刻を軸にした集計を秒以下で返す点は共通します。分かれるのは同時実行数の想定と、集計を先に作る方法になります。
| 比較軸 | Apache Pinot | Apache Druid |
|---|---|---|
| 想定利用者 | サービス利用者向けの画面 | 社内の分析と監視 |
| 同時実行 | 数千クエリ規模を想定 | 数十から数百が中心 |
| 事前集計 | star-tree索引で部分的に | 取り込み時のロールアップ |
| 更新 | 主キーupsertに対応 | 区間の入れ替えで対応 |
| 外部依存 | ZooKeeperとdeep store | ZK・メタデータDB・保管 |
実務での分かれ目は、更新をどう扱うかにも出ます。主キー単位で最新値へ寄せる要件があるならPinotのupsertが素直で、Druidでは区間ごとの入れ替えになるためです。逆に、取り込み時のロールアップで保管量を大きく落としたい要件ならDruidが噛み合います。設計判断の並びはApache Druidのセグメント構造と取り込み設計と読み比べると差分が掴めるでしょう。
ClickHouse・StarRocksとの役割分担と併存構成の組み方
ClickHouseは構成要素の少なさが持ち味です。単一サーバから始められ、索引は設計者が明示的に管理します。少人数が重いクエリを流す用途では、構築も運用もこちらのほうが釣り合うはずです。詳しくはClickHouseの列指向構造とMergeTreeの実装で整理しています。
StarRocksはMPP構成で結合の性能を前面へ出した製品で、Pinotより広い分析クエリを1つの基盤で受けたい場合の候補になります。比較の観点はStarRocksのMPP構成とテーブル設計にまとめました。
3者を併存させる構成も現実的です。確定済みイベントの即時集計をPinot、社内向けの重い探索をClickHouseかStarRocks、履歴の正本をDWHへ置く分担にすれば、それぞれの苦手な領域を押しつけずに済みます。
Apache Pinotを採用しない方がよい条件と失敗しやすい設計パターン
Pinotの検討で費用対効果が高いのは、見送る判断を早く下すことです。
クエリ同時実行数が二桁に届かない規模でPinotが過剰になる分岐点
同時実行数が二桁に届かない用途では、Pinotを採用しません。最小構成でもController・Broker・Server・Minionの4役割にZooKeeperとdeep storeが加わり、運用対象が一気に増えるためです。
検討に載せる下限も示します。画面を見る利用者が数百人以上いて、その画面が開かれるたびにクエリが飛び、応答が1秒を超えると使いものにならない。この条件が仕様書に書かれているときが、Pinotを候補へ入れる場面です。日次数十万行の追記でも、同時実行の要求が高ければ選ぶ理由が立ちます。
アドホックな探索分析が主用途のときにPinotを避けるべき理由と代替
用途がアドホックな探索分析なら、Pinotは主役に据えません。Pinotの速さは、事前に分かっている述語へ索引を張り、star-treeで集計を先に作っておくことで成り立つためです。どんな軸で切るか事前に読めない分析では、索引が効かず持ち味が出ません。
この場合の代替は明確です。列指向のDWHかレイクハウスを主役にして、探索はそちらで回します。そのうえで、画面へ出す確定指標だけをPinotへ非正規化して流す構成なら両立できるでしょう。
高カーディナリティな主キーのupsertでメモリが破綻する兆候
upsertを使う構成では、主キーの選び方が破綻の起点になります。Pinotは主キーからレコード位置への対応表をメモリへ保持し、その量はおおよそ「主キーの件数×(キーのサイズ+24バイト)」で見積もる形だからです。件数が億の単位になれば、Serverのヒープが先に尽きます。
公式ドキュメントも単純なキー型を推奨し、複合キーは避けるよう促しています。リクエストIDのような一意に近い値を主キーにする設計は取りません。兆候はServerのヒープ使用率とGCの頻度に出るため、取り込み検証の段階で主キー件数を実測し、想定の伸びに対して余裕があるか確かめておきましょう。
本番投入前に決める設計項目と、運用コスト・監視体制のチェック観点
Pinotは後戻りの費用が高い基盤です。取り込みを始める前に決めておく項目を挙げます。
REALTIMEテーブル設定で先に固めるセグメント閾値と保持方針
REALTIMEテーブルで先に固めるのは、consuming segmentを確定させる閾値になります。行数かサイズで指定し、確定後のセグメントが小さくなりすぎない値へ寄せます。目安は取り込み量から逆算して、1セグメントが数百MB前後へ収まる範囲。小さいセグメントが大量に生まれた場合は、Minionのタスクで後から結合する運用へ切り替えます。
保持方針はテーブル設定のリテンションで表現します。REALTIMEとOFFLINEを併用する構成では、両者が同じ時間範囲を持たないよう境界を決めておく必要があるでしょう。重なりが残ると、同じ行が二重に数えられます。
Pinotクラスタのテナント分離とサーバ台数・メモリ量の見積り方
Pinotはテナントという単位でBrokerとServerを論理的に分けられます。取り込みが重いテーブルと、応答時間の要求が厳しいテーブルを別テナントへ寄せれば、片方の負荷がもう片方の応答へ波及しにくくなる仕組みです。
台数の見積りは、索引を含めたセグメント容量とメモリ量の2本立てで積みます。容量は検証環境で実データを1週間分入れ、索引付与の前後で圧縮後サイズを実測してください。机上の圧縮率で決めると、稼働後にディスクが先に尽きます。
小規模検証から本番へ広げる手順と、外部委託する場合の分担の決め方
検証から本番までは、次の順序が事故を減らします。
- 単一ノード構成で1週間分の実データを取り込み、セグメント容量を実測する
- 画面から飛ぶクエリを10本ほど書き、同時実行を上げたときの劣化を測る
- 実測値からstar-tree索引の対象と
maxLeafRecordsを確定する - upsertを使う場合は主キーとストリームのパーティション数を決め切る
- 4役割を分離した構成へ移し、deep storeを本番相当のストレージへ差し替える
- 取り込み遅延・クエリの応答分布・ヒープ使用率を監視項目に設定する
このうち2と3は、Pinot固有の知見がないと判断を誤りやすい部分になります。社内に運用経験がない場合、設計と初期構築を外部へ任せ、定常運用を内製へ引き取る分担が現実的です。一創では取り込み設計から監視設計までを含むデータ分析基盤構築・MLOps構築支援を提供しており、既存のDWHとの役割分担を含めて検討できます。
よくある質問
Apache Pinotの検討時に実務で挙がる質問をまとめます。
Apache Pinotは無料で使えますか?
Apache PinotはApache License 2.0のオープンソースソフトウェアで、ソフトウェア自体の費用は発生しません。ただし実費はかかります。Controller・Broker・Server・Minionを分離した構成のサーバ費用に加え、ZooKeeperとdeep store用のオブジェクトストレージが必要になるためです。
Apache PinotとApache Druidはどちらを選ぶべきですか?
同時実行数と更新要件で分けます。サービス利用者向けの画面から数千規模のクエリが飛び、主キー単位の更新が要るならPinot。社内の監視や分析が中心で、取り込み時のロールアップで保管量を落としたいならDruidが噛み合います。両者とも運用対象が多いので、どちらか一方へ絞る前提で検討してください。
Pinotでテーブルの結合はできますか?
マルチステージエンジンを有効にすれば、結合やウィンドウ関数を使えます。ただし結合を多用する設計はPinotの持ち味と噛み合いません。必要な属性を取り込み前段で1つのテーブルへ寄せ、クエリ時は絞り込みと集計だけで答えが出る形に寄せるのが基本です。
Pinotの学習コストはどのくらいですか?
SQLで問い合わせる部分だけなら、DWHの経験があるエンジニアは数日で書けるようになります。負担が大きいのは設定と運用の側です。テーブル設定とスキーマの分離、索引の指定方法、セグメントの状態遷移までを掴むには、数週間から数か月を見込むのが妥当でしょう。
既存のBIツールからPinotへ接続できますか?
接続できます。PinotはSQLインターフェースとJDBCドライバを備えており、SQLで問い合わせるBIツールから参照できる作りです。相性がよいのは、述語が固定されたダッシュボード用途。BIが自動生成する結合の多いクエリをそのまま投げると、索引が効かず遅くなります。参照先は非正規化した幅広テーブルとして設計します。
関連記事
- Apache Druidとは?リアルタイムOLAPの仕組みと取り込み設計:最も近い位置にある製品の設計判断を並べて比較できます
- データ分析基盤の構築とは?5層アーキテクチャと実装手順:Pinotを置く前段の層構成を決める下地になります
- OLTPとは|OLAP・DWHとの違いとデータベース選定の比較:処理特性からデータベースの役割分担を確認できます