kevy4.0

エラーリプライ・カタログ

kevyが送出するすべてのワイヤレベルのエラーリプライについて、何が引き金になり、クライアントは次に何をすべきかを引ける一覧表です。

この表の読み方

kevyのエラーはRESPのsimple-error文字列——-<PREFIX> <message>\r\n——として流れます。空白区切りの最初のトークンがプレフィックスERRWRONGTYPEMOVEDCROSSSLOTなど)です。クライアントライブラリは通常これを、.kind.code/クラス名がプレフィックスに一致するエラーバリアントや例外として表面化します。行の残りは人間向けのメッセージです。

このカタログはプレフィックスでグループ化しています。エラーを構造的に処理するなら(推奨)、プレフィックスでマッチしてください。後続のメッセージはログとオペレーター向けであって、パースするためのものではありません。

エラーはkevyのユーザー向け契約の一部です。プレフィックスの追加・改名・転用は、パターンマッチするクライアントにとって破壊的変更になります。

コアリファレンス

プレフィックス引き金回復/次の一手
-ERR unknown command '<cmd>'コマンド名が未実装、または認識されない。READMEのコマンドカバレッジを確認し、綴りを検証する。
-ERR wrong number of arguments for '<cmd>' commandargcがそのコマンドの受け付ける形と一致しない。文書化された引数の数で再発行する。
-ERR value is not an integer or out of rangeパース可能なi64でない値へのINCR/DECR系コマンド、または数値引数が範囲外。SETでパース可能な整数に上書きするか、入力をクランプする。
-ERR no such keyRENAME / RENAMENX / COPY / GETEX の対象キーが存在しない。キーを不在として扱う(必要ならEXISTSで事前確認)。
-ERR kevy only supports DB 0SELECT NがN ≠ 0で発行された。kevyにマルチDBはない。別インスタンスか名前空間付きキーを使う。
-ERR MULTI calls can not be nestedMULTIブロックの中でさらにMULTIが送られた。次のトランザクションを開く前にEXECDISCARDを待つ。
-ERR EXEC without MULTI開いたトランザクションがないのにEXECが送られた。MULTIと対にするか、コマンドを落とす。
-ERR DISCARD without MULTI開いたトランザクションがないのにDISCARDが送られた。MULTIと対にするか、コマンドを落とす。
-ERR WATCH inside MULTI is not allowedMULTIブロックの中でWATCHが送られた。WATCHMULTIの前に発行する。
-ERR <cmd> not allowed inside MULTIキュー不能なコマンド(pub/sub、WATCHHELLORENAME)がMULTI内でキューされた。これらはトランザクションの外で発行する。
-ERR Protocol error受信バイト列が正しいRESPでない。再接続してリトライ。続くならクライアントのシリアライザを監査する。
-ERR CONFIG SET failed for '<key>': <reason>未知のCONFIGフィールド、または値が範囲外。CONFIG GET *でサポートされるフィールドと現在値を見る。
-ERR CONFIG REWRITE could not write <path>: <io-error>設定TOMLのパスが存在しないか書き込めない。--configのパスとファイルシステム権限を確認する。
-WRONGTYPE Operation against a key holding the wrong kind of value既存の別Redis型のキーに対してコマンドを実行した。WRONGTYPEの規則参照。
-EXECABORT Transaction discarded because of previous errors.MULTI中にキューしたコマンドが未知の動詞、または引数が少なすぎた。EXECはバッチを拒否し、何も実行しない。問題のコマンドを直してから、再度MULTI/キュー/EXEC
-MOVED <slot> <host:port>キーのハッシュスロットをこのノードが所有していない。クラスタルーティング系リプライ参照。
-CROSSSLOT Keys in request don't hash to the same slot複数キーコマンドが複数のハッシュスロットにまたがった。クラスタルーティング系リプライ参照。
-MISDIRECTED writer is <host:port>書き込みが、このキーのスコープを所有しないノードに着地した。またはREPL.WAITがこのレプリカでread-your-writesを提供できなかった(タイムアウトか世代不一致)。クラスタルーティング系リプライ参照。REPL.WAITの場合は<host:port>のプライマリを読む。
-QUIESCED migrating to <host:port>スロットまたはスコープが移行中でこのノード上で凍結されている。またはノードが<host:port>へのFAILOVER引き継ぎの最中。クラスタルーティング系リプライ参照。
-OOM command not allowed when used memory > 'maxmemory'ポリシーnoevictionで上限超過後に書き込み系コマンドが来た。maxmemoryを上げる、退去ポリシーを設定する(例:allkeys-lru)、またはDELで空きを作る。既存データは無傷。
-READONLY You can't write against a read only replica.レプリカノードへ書き込みコマンドが送られた。プライマリへ送るか、ルーティングクライアントを使う。
-NOREPLICAS Not enough good replicas to write.min_replicas_to_write = Nのプライマリから見える健全なレプリカがN未満。バックオフしてリトライ。レプリカを復旧する(docs/availability.md参照)。
-NOREPLICAS primary lost quorum; writes fencedelectクォーラムのプライマリがピアの厳密過半数へ到達できない(パーティションの少数派側)。書き込みはリース期間だけ自己フェンスする。バックオフしてリトライ——パーティションが治ればフェンスは解け、あるいは多数派が新プライマリを選出してルーティングクライアントが見つける。
-STALE replica is stale; read the primary or raise replica_max_staleness_ms最後のプライマリハートビートがreplica_max_staleness_msの上限より古いレプリカへ読み取りが送られた。レプリカが追いつくまでプライマリを読むか、上限を上げる/無効化する。
-READONLY can't write against a read-only scriptEVAL_ROEVALSHA_ROで評価されたスクリプトが書き込みを試みた。書き込み可能なEVALEVALSHA側を使う。
-NOSCRIPT No matching script. Please use EVAL.EVALSHA <sha>がキャッシュにないスクリプトを要求した。直接EVALを呼ぶ(kevyは自動キャッシュ)か、先にSCRIPT LOADする。
-LOADING kevy is loading the dataset in memoryプライマリからフル再同期スナップショットを受信中のレプリカへ読み取りが送られた。待ってリトライ(ウィンドウはスナップショット転送で有界)。ローディング中もPINGINFOHELLOは応答されるので、ヘルスチェックと監視は動き続ける。
-ERR No such client address in the listレガシー形のCLIENT KILL <addr:port>がどのコネクションにも一致しなかった。CLIENT LISTで稼働中コネクションを列挙し、実在のaddrで再発行する。フィルタ形(`CLIENT KILL ID\ADDR\LADDR …`)はエラーではなくカウント0を返す。

kevyが決して送出しないプレフィックス

設計上、kevyはプロトコル層での認証・認可を行いません。次のRedis互換プレフィックスは意図的に不在です。

クライアントがこれらの発生を想定しているなら、kevy上では到達不能として扱ってください。アクセス制御はデプロイの境界に委譲されています(kevyはデフォルトで127.0.0.1にbindします)。

WRONGTYPEの規則

WRONGTYPEリプライは、そのキーがコマンドの期待と異なるRedisデータ型ですでに存在することを意味します。規則は次の通りです。

回復は常にどちらかです。別のキーを選ぶか、既存キーをDELして意図した型で作り直すかです。

クラスタルーティング系リプライ

これらのプレフィックスは、kevyがルーティングされたモード(クラスタまたはスコープ)で動いているときにだけ現れます。非クラスタのクライアントは一度も見ないかもしれません。

ルーティングモデルの全体はdocs/のプロトコルノートを参照してください。

FAQ

クライアントが-MOVEDを致命的エラーとして扱うのですが——どう直せば? そのクライアントはクラスタ対応ではありません。クラスタ対応クライアント(redis-cli -cCluster付きioredisRedisCluster付きredis-py、kevyのルーティングクライアント)へ乗り換えるか、ドライバをラップしてMOVEDを捕まえ、メッセージ内のホストへ再接続して再発行してください。

単一キーのコマンドに-CROSSSLOTが返ってきました——バグですか? いいえ。CROSSSLOTは複数キーコマンドでしか発火しません。単一キーに見える呼び出しで出たなら、そのコマンドは実際には複数キーです(2つのKEYSを持つEVAL、ソース+宛先のSUNIONSTOREなど)。{tag}記法でスロットの同居を強制するか、呼び出しを分割してください。

-OOMが出ました——データは壊れていますか? いいえ。-OOMはコマンド受理の時点で拒否されており、その書き込みは一切着地していません。キー空間はコマンドの前と正確に同じ状態です。空きを作って(DEL/退去ポリシー設定/maxmemory引き上げ)リトライしてください。

-LOADINGが繰り返し返ってきます——どれくらい待つべき? フル再同期のスナップショット転送にかかる時間だけです(データセットのサイズとリンク速度に比例)。ローディング中もPINGINFOHELLOは応答され(INFO replicationloading:1を報告します)、ヘルスチェックは動き続けます。レプリカがこの状態に入るのは、プライマリのバックログから遠く離れて再接続したときだけです。-LOADINGが恒常的に再発するなら、[replication] replication_buffer_sizeを上げるか、リンクを調査してください。

キューしたMULTIコマンドが-EXECABORTを返しました——どれかの書き込みは適用された? いいえ。EXECABORTはトランザクションがバッチとして拒否されたことを意味し、キューされた列の何も実行されていません。問題のコマンドを直してMULTIを開き直してください。

拡張面(IDX. / VIEW. / FEED.)

拡張verbも同じプレフィックス契約に従います。すべてのエラーは自己説明的です。verbと対象オブジェクトを名指しし、発見面を指し示します(これに当たったエージェントはインバンドで回復できます)。

プレフィックス送出タイミング回復
ERR <VERB> '<name>': bad arguments — run COMMAND DOCS <VERB> for the syntaxIDX./VIEW. verbの引数パースが失敗したCOMMAND DOCS <verb>が完全な構文文字列を返す
ERR no such index '<name>' (IDX.LIST enumerates them)クエリが存在しないインデックスを名指ししたIDX.LISTVIEW.LISTがカタログを列挙する
INDEXBUILDING index '<name>' is still building (poll IDX.LIST until state=ready)クエリが作成後バックフィルとレースしたIDX.LISTstateをポーリング。docs/migration.md参照
INDEXOVERBUDGET index '<name>' build exceeded MAXMEM (raise maxmemory or DROP the index)構築がメモリ予算に当たったmaxmemoryを上げるかIDX.DROP
FEEDRESYNC <gen> <tail>FEEDカーソルがもうサービスできない(世代の増加か、バックログ超過)新しいスナップショット+返されたカーソルから消費を再開。docs/cdc.md参照

このカタログの更新手順

-<PREFIX> ...リプライを送出するコードパスを追加・変更したら:

  1. コアリファレンスの行を更新します(または新しい行を追加)。
  2. 新しいプレフィックスを導入したなら、ワイヤレベルのカオステストcrates/kevy/tests/wire_torture_chaos.rsを拡張します。
  3. それを出荷するリリースのCHANGELOG.mdに変更を記載します。

エラーはクライアント契約の一部です。メッセージの黙った変更は、それをパターンマッチするエコシステムのライブラリを壊し得ます。