このページは、API サーバーがネットワークリクエストをどのように AkkEngine へ対応付けるかを理解したい場合に読むページです。起動方法とクライアントからの呼び出し例は API サーバーの使い方 に分けています。
実行時の構造
Section titled “実行時の構造”API サーバーのコードは akkara/akkserver/ にあり、AGPLv3 で別ライセンスになっています。サーバー有効ビルドを配布する場合は、この境界を確認してください。
エンジン起動時、AkkEngine::open() は components.apiEnabled を確認します。有効であれば、API サーバーバックエンドを読み込むか既存の生成元を使い、設定された通信方式向けの集約サーバーを作成し、ストレージエンジン構成要素の準備が終わった後に起動します。
サーバーの寿命はエンジンの寿命に従います。AkkEngine::open() の途中で起動し、close() またはエンジン破棄時に停止します。
通信方式バックエンド
Section titled “通信方式バックエンド”| バックエンド | 役割 |
|---|---|
| HTTP | 手元での確認、スクリプト、簡単なサービス境界。 |
| TCP | 高スループットクライアント向けのコンパクトな AK5 バイナリプロトコル。 |
| gRPC | Protobuf/gRPC サポートがある場合の型付き RPC インターフェイス。 |
どの通信方式も、最終的には同じ AkkEngine 操作へ対応付けられます。API サーバーはスキーマ認識を追加しません。キーと値は生のバイト列のままです。
HTTP バイナリレスポンス
Section titled “HTTP バイナリレスポンス”HTTP レスポンスボディは、明示的にテキストを返すエンドポイントを除き、リトルエンディアンのバイナリエンコードです。
| エンドポイント | ボディ |
|---|---|
/v1/exists | [exists:u8]。1 が存在、0 が不存在。 |
/v1/count | [count:u64le]。 |
/v1/scan | [count:u32le][truncated:u8]{row}*。 |
/v1/history | [count:u32le][truncated:u8]{entry}*。 |
/v1/batchGet | [count:u32le]{[status:u8][value_len:u32le][value bytes]}*。 |
/v1/stats | コンパクトなリトルエンディアン形式の EngineStats スナップショット。 |
scan の行は次の形です。
[key_len:u16le][value_len:u32le][key bytes][value bytes]history のエントリは次の形です。
[seq:u64le][source_node_id:u64le][timestamp_ns:u64le][flags:u32le][value_len:u32le][value bytes]truncated が 1 の場合、設定値またはリクエストされた limit に到達して途中で切られています。続きが必要な場合は、limit を増やすか、後続の範囲リクエストを組み立てます。
HTTP ストリーミング
Section titled “HTTP ストリーミング”ストリーミングボディは 5 バイトの前置きから始まります。
| ストリーム | 前置き |
|---|---|
| scan | AKKS\x01 |
| history | AKKH\x01 |
chunk を展開した後のボディは、次のフレーム列です。
[frame_type:u8][payload_len:u32le][payload bytes]フレーム種別 1 は項目です。scan の項目ペイロードは非ストリーミング scan と同じ行形式です。history の項目ペイロードは非ストリーミング history と同じエントリ形式ですが、外側の count と truncated は付きません。
フレーム種別 2 は終端フレームです。
[emitted_count:u32le][truncated:u8]HTTP ストリーミングはサーバーからの返し方を変えるだけです。エンジン側のスナップショット意味論を変えるものではありません。
TCP プロトコル
Section titled “TCP プロトコル”TCP 通信方式は AK5 バイナリフレームを使います。リクエストフレームは 16 バイトのヘッダーから始まります。
char[4] magic = "AK5Q"u8 version = 2u8 opcodeu32 request_idu16 key_lenu32 val_lenレスポンスフレームは 13 バイトのヘッダーから始まります。
char[4] magic = "AK5S"u8 statusu32 request_idu32 val_lenTCP リクエストは次の形です。
[request header][key bytes][value bytes][crc32c:u32le]リクエスト CRC32C は key bytes + value bytes を対象にします。レスポンスは次の形です。
[response header][value bytes][crc32c:u32le]レスポンス CRC32C は value bytes だけを対象にします。
TCP 操作
Section titled “TCP 操作”| Opcode | 操作 |
|---|---|
0x01 | GET |
0x02 | PUT |
0x03 | REMOVE |
0x04 | GET_AT |
0x05 | BATCH_PUT |
0x06 | BATCH_GET |
0x07 | PING |
0x08 | EXISTS |
0x09 | COUNT |
0x0A | SCAN |
0x0B | HISTORY |
0x0C | ROLLBACK_TO |
0x0D | ROLLBACK_KEY |
0x0E | FORCE_SYNC |
0x0F | FORCE_FLUSH |
0x10 | STATS |
0x11 | SCAN_STREAM |
0x12 | HISTORY_STREAM |
status の値は次の通りです。
| Status | 意味 |
|---|---|
0x00 | OK |
0x01 | 見つからない |
0xFF | エラー |
request_id はレスポンスへそのまま返されます。1 つの接続で複数のリクエストをパイプライン処理する場合、レスポンスの対応付けに使います。
TCP ペイロード規約
Section titled “TCP ペイロード規約”| 操作 | リクエストキー | リクエスト値 |
|---|---|---|
GET, PUT, REMOVE, EXISTS, HISTORY | 対象キー | 操作ペイロードまたは空 |
GET_AT, ROLLBACK_KEY | 対象キー | [seq:u64le] |
ROLLBACK_TO | 空 | [seq:u64le] |
COUNT | startKey | endKey |
SCAN | startKey | [limit:u32le][endKey bytes]。limit = 0 は無制限 |
BATCH_PUT, BATCH_GET | 空 | バッチペイロード |
FORCE_SYNC, FORCE_FLUSH, STATS, PING | 空 | 空 |
TCP の scan レスポンスは [count:u32le][truncated:u8]{row}* です。TCP の history レスポンスは [count:u32le]{entry}* です。HTTP history と違い、非ストリーミング TCP history には truncated バイトがありません。
SCAN_STREAM と HISTORY_STREAM は、同じ request_id を持つ複数の AK5S レスポンスを送ります。各レスポンスの値が 1 つのストリームフレームです。
[frame_type:u8][payload_len:u32le][payload bytes]フレーム種別 1 は項目、フレーム種別 2 は終端です。終端ペイロードは [emitted_count:u32le][truncated:u8] です。
gRPC 通信方式
Section titled “gRPC 通信方式”gRPC 通信方式は、同じエンジン操作に対応する単項呼び出しと、scan/history 向けのサーバーストリーミング呼び出しを提供します。サービス名は akkaradb.grpcapi.v1.AkkaraDB です。
単項呼び出しは Ping、Put、Get、Remove、Exists、Count、Scan、GetAt、History、RollbackTo、RollbackKey、BatchPut、BatchGet、ForceSync、ForceFlush、Stats に対応します。ストリーミング呼び出しは ScanStream と HistoryStream です。
gRPC はビルド構成に依存します。Protobuf/gRPC サポートがない場合、gRPC バックエンドは実際のサーバー通信方式として利用できません。gRPC には、api.grpcPort、api.grpcWorkerThreads、api.grpcCompletionQueues、api.grpcMinPollers、api.grpcMaxPollers、api.grpcMaxConcurrentStreams、api.grpcResourceQuotaBytes、api.grpcMaxBatchItems、api.grpcMaxScanItems、api.grpcMaxHistoryEntries が反映されます。
api.transportMode == TLS の場合、gRPC は api.tls.certPath、api.tls.keyPath、api.tls.caPath を使います。api.tls.verifyPeer が true で CA パスが設定されている場合、クライアント証明書が要求されます。
制限値とチューニング
Section titled “制限値とチューニング”| オプション | 対象 | メモ |
|---|---|---|
api.httpMaxBatchItems | HTTP バッチエンドポイント | 大きすぎるバッチボディを拒否します。 |
api.httpMaxScanItems | HTTP scan | 1 リクエストで返す、またはストリーミングする行数を制限します。 |
api.httpMaxHistoryEntries | HTTP history | 1 リクエストで返す、またはストリーミングする履歴エントリ数を制限します。 |
api.httpMaxContentLength | HTTP リクエストボディ | POST ボディによるメモリ使用量を制限します。 |
api.tcpWorkerThreads | TCP | 0 は自動動作です。 |
api.tcpAcceptQueueLimit | TCP | ワーカー待ちの受け入れ済みソケット数を制限します。 |
api.tcpAcceptQueueTimeoutMs | TCP | 待ちすぎたキュー内ソケットを落とします。0 でタイムアウトを無効化します。 |
api.tcpPipelineBatchLimit | TCP | パイプライン化されたリクエストをまとめて処理する上限です。 |
api.tcpMaxBatchItems | TCP バッチエンドポイント | 大きすぎるバッチペイロードを拒否します。 |
api.tcpMaxPendingResponseBytes | TCP/gRPC | バックプレッシャー制限です。gRPC の送受信メッセージサイズにも使われます。 |
api.tcpReadTimeoutMs | TCP | アイドル状態または部分フレーム読み取りのタイムアウトです。0 で無効化します。 |
api.tcpWriteTimeoutMs | TCP | レスポンス書き込みのタイムアウトです。0 で無効化します。 |
ローカル開発では既定値から始めるのが自然です。制限値は、リクエストサイズ、同時接続数、レスポンスのバックプレッシャーを測ってから調整してください。