Redis 互換——クライアントは、そのままつながります。どの操作でも、より高速です。そしてベクトル検索、全文検索、インデックス、ビュー、変更フィードは、周りに並べた 4 つのサービスではなく、エンジンの中にあります。このターミナルは本物です。同じエンジンを WebAssembly にコンパイルしたものが、このタブの中で動いています。
Pick one — each builds its own rows, then asks a question of them.
· 112 of the 191 server verbs — the embedded surface. Arrow keys walk history; a pasted block runs line by line.
以下のコマンドはすべて、このページを出す前に、CI が実際のサーバーに対して実行しています。タブを切り替えてみてください——kevy を使うとは、こういうことです。
# an HNSW index over your keys — declared once,
# kept current by the write path
IDX.CREATE idx:sem ON PREFIX doc: FIELD vec TYPE vector KIND ann DIM 768 DISTANCE cosine M 16 EF 200
HSET doc:4410 title "Ada on pipelining" vec "<768 f32, little-endian>"
# nearest ten. no separate vector database, no sync job.
IDX.QUERY idx:sem KNN "<query vector>" LIMIT 10
-> 1) "doc:4410"
2) "doc:9982"
埋め込みはあなたが持ち込み、kevy がそれを保存し、索引を張り、検索します。エンジンにモデルはありません。それは意図した選択です。
IDX.CREATE idx:ft ON PREFIX doc: FIELD title TYPE str KIND text
IDX.QUERY idx:ft MATCH "pipelining"
-> 1) 1) "doc:1"
2) "0.2877" # BM25 score
# hybrid: fuse the text ranking with the vector ranking
IDX.QUERY HYBRID idx:ft MATCH "pipelining" idx:sem KNN "<vector>" LIMIT 20 RRFK 60CJK のトークン化を備えた BM25。ベクトルが索引している、同じキーの上で。
HSET order:1001 customer 881 status open total 4400
HSET order:1002 customer 881 status paid total 8400
IDX.CREATE idx:cust ON PREFIX order: FIELD customer TYPE i64 KIND range
IDX.CREATE idx:status ON PREFIX order: FIELD status TYPE str KIND range
# the read that would have been a SQL query
IDX.QUERY COMPOSE AND idx:cust EQ 881 idx:status EQ open
-> 1) "0"
2) 1) 1) "order:1001"
絞り込んだ読み取りは、参照のままです。クエリプランナも、スキャンもありません。
# the answer, kept current by the WRITE path
VIEW.CREATE v:open881 QUERY ( AND idx:cust EQ 881 idx:status EQ open ) ORDER BY idx:cust
VIEW.QUERY v:open881
-> 1) "0"
2) 1) "order:1001" 2) "881"
# reads never recompute it; writes keep it freshほとんどのアプリケーションが ORM に本当に求めているもの。
# a table is a declaration — compiled to named indexes, once
TABLE.DECLARE user PREFIX u: PK id COLUMN id str COLUMN name str COLUMN age i64 COLUMN dept str INDEX age range VALUES dept name ORDERPATH by_dept_age ON dept THEN age DESC
HSET u:1 id 1 name ada age 34 dept eng
# the ORDER BY dept, age DESC walk — one composite index, no planner
IDX.QUERY user.by_dept_age WHERE dept EQ eng LIMIT 20 FIELDS name age型付きカラム、セカンダリインデックス、複合 ORDER BY パス——kevy-cli sql compile なら PG/MySQL のスキーマファイルまでコンパイルできます。ランタイム SQL も join もありません。それは Postgres の仕事です。
# kevy.toml — a RAM budget for the whole store
[tiering]
budget = "70%" # or "4gb", or "auto"
# past the budget, the coldest values spill to a disk log
# and page back on access. a cold key is an ordinary key:
GET archive:2019:q3 # pays one disk read, same reply
TTL archive:2019:q3 # metadata answers from RAM
SCAN 0 MATCH archive:* # sees cold keys — one key tableRAM がキー数の上限を、ディスクがデータ量の上限を決めます。AOF の永続化コントラクトは無変更です。v1 で退避するのは文字列とハッシュ——リスト、セット、ストリームはホットのままです。
# tail every write from another process — or an agent.
# [feed] enabled = true in kevy.toml
FEED.SHARDS -> (integer) 16
FEED.TAIL 0 -> 1) (integer) 1 # generation
2) (integer) 1 # offset
FEED.READ 0 1 0 COUNT 2 -> the writes themselves, replayable再開可能なオフセット。ポーリングするものも、取りこぼすものもありません。
# a 16-core server
cargo install kevy && kevy --port 6379
# inside your binary — no socket, no process
let db = Db::open("data/")?;
db.set(b"k", b"v", None)?;
# a browser tab — 481 KB, persists to OPFS
const db = await open({ persist: { name: "app" } });
# a microcontroller — no OS, no allocator
let mut store = Store::new_in(&mut arena);4 つの場所すべてで、同じエンジン、同じコマンドです。
RESP2 と RESP3、206 個のコマンド——redis-cli も、クライアントライブラリも、そのままつながります。1 台のマシン、16 コア、ループバック、5 回実行した中央値です。
kevy 6.3.0 · Redis 8.10.1 — LPUSH と ZADD は、10% と 15% しか上回っていません。リストやソート済みセットがホットパスなら、速さは乗り換える理由になりません。valkey や Dragonfly も含めた、完全な表はこちら。移行はコマンド 3 つ——export、import、digest——で、どちらの向きにも動きます。
バイナリ 1 つです。ランタイムも、解決を待つ依存もありません。
cargo install kevy
kevy --port 6379いま使っているものが、そのまま動きます——kevy製のクライアントを入れる必要はありません。node-redis/ioredis、go-redis、StackExchange.Redis、redis-py、hiredisがそのまま繋がり、kevy独自の動詞は同じクライアントのrawコマンド経路から届きます。この6つは、pushのたびにCIで実サーバーへ同一の梯子を流しています。言語ごとの例(英語)。
redis-cli -p 6379
> SET greeting hello
OK
> TTL greeting
(integer) -1インデックスを宣言すれば、書き込みの側が最新に保ちます。
IDX.CREATE idx:city ON PREFIX user: FIELD city TYPE str KIND range
IDX.QUERY idx:city EQ osakaクラスタではありません。レプリケーションとフェイルオーバーはありますが、マシンをまたぐシャーディングはなく、今後もありません。AUTH も TLS もありません——プライベートなネットワークで動かすか、それらを正しく処理するものの後ろに置いてください。複数キーの書き込みは shard 単位でのみ原子的で、全体では原子的ではありません——shard をまたぐ RENAME や MSET は、1 つの原子的な操作にはなりません。差異はすべて、コマンドごとに文書化してあります。そして、そもそも使うべきでない場合はこちら。