diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 521de864..84ea8b8e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -42,7 +42,7 @@ the routing api on `Engine` has five methods: | `send_to_shard(idx, req)` | direct shard access by index (SCAN) | | `dispatch_to_shard(idx, req)` | non-blocking dispatch returning a oneshot receiver | -all five data types and all 135+ commands are supported. +all five data types and all 150+ commands are supported. --- @@ -412,4 +412,4 @@ feature propagation: `ember-server` features flow down to `emberkv-core`, which --- -*updated to reflect the state of the codebase as of the clustering milestone.* +*updated to reflect the current state of the codebase.* diff --git a/CHANGELOG.md b/CHANGELOG.md index eeaea1f4..9c2af687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,7 +94,7 @@ this is the "make it real" milestone. ember went from a single-node cache to a c - bincode for raft rpcs — smaller wire format than json - o(log n) sorted set rank via vec-based structure - incremental memory tracking — `grow_by` / `shrink_by` instead of full recompute -- concurrent pipeline dispatch for multi-core throughput +- parallel pipeline dispatch for multi-core throughput - `now_ms()` caching to avoid repeated syscalls in expiry checks ### fixes @@ -139,7 +139,6 @@ with the foundation solid, this milestone filled in everything that makes ember - `--shards` flag to tune the number of keyspace partitions - jemalloc as the global allocator - pipeline dispatch optimization — batched command processing -- concurrent keyspace mode with dashmap for read-heavy workloads - memory overhead reduction — keyspace entry footprint profiled and trimmed - memtier benchmark integration - bench-all.sh for running all benchmark suites in one pass diff --git a/bench/README.md b/bench/README.md index e658a320..38f26f11 100644 --- a/bench/README.md +++ b/bench/README.md @@ -50,7 +50,7 @@ tested on GCP c2-standard-8 (8 vCPU Intel Xeon @ 3.10GHz), Ubuntu 22.04. dragonfly in particular offers features ember simply doesn't have: -- full Redis API compatibility (200+ commands vs ember's ~135) +- full Redis API compatibility (200+ commands vs ember's ~150) - sophisticated memory management (dashtable for ~25% of Redis memory usage) - Lua scripting - fork-free snapshotting diff --git a/docs/compatibility.md b/docs/compatibility.md index 93018de0..6c785f47 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -30,7 +30,9 @@ Ember also exposes port `6379` by default, the same as Redis, so most default co | GETSET | ✓ | atomic get-and-set; deprecated in Redis 6.2 but supported | | GETDEL | ✓ | | | GETEX | ✓ | | -| SETNX | ✗ | use `SET key value NX` instead | +| SETNX | ✓ | legacy alias; prefer `SET key value NX` | +| SETEX | ✓ | legacy alias; prefer `SET key value EX seconds` | +| PSETEX | ✓ | legacy alias; prefer `SET key value PX millis` | | MSETNX | ✓ | | | SUBSTR | ✗ | deprecated; use GETRANGE instead | diff --git a/docs/migration-from-redis.md b/docs/migration-from-redis.md index b4a776fa..fdea0f67 100644 --- a/docs/migration-from-redis.md +++ b/docs/migration-from-redis.md @@ -15,7 +15,7 @@ Ember speaks RESP3, so the first thing to know is that your existing Redis clien ## command compatibility -Ember implements over 135 Redis commands. The tables below show what's supported, what's missing, and any behavioral differences worth knowing about. +Ember implements over 150 Redis commands. The tables below show what's supported, what's missing, and any behavioral differences worth knowing about. Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. @@ -40,10 +40,10 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | SETEX | ✓ | legacy alias; prefer `SET key value EX seconds` | | PSETEX | ✓ | legacy alias; prefer `SET key value PX millis` | | SUBSTR | ✓ | alias for GETRANGE | -| GETSET | ✗ | use `SET key value GET` instead | -| GETDEL | ✗ | not implemented | -| GETEX | ✗ | not implemented | -| MSETNX | ✗ | not implemented | +| GETSET | ✓ | atomic get-and-set; deprecated in Redis 6.2 | +| GETDEL | ✓ | | +| GETEX | ✓ | | +| MSETNX | ✓ | | ### lists @@ -65,8 +65,8 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | BRPOP | ✓ | multi-key with timeout | | LPUSHX | ✗ | not implemented | | RPUSHX | ✗ | not implemented | -| LMOVE | ✗ | not implemented | -| LMPOP | ✗ | not implemented | +| LMOVE | ✓ | | +| LMPOP | ✓ | | | BLMOVE | ✗ | not implemented | ### sets @@ -88,8 +88,8 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | SRANDMEMBER | ✓ | optional count | | SPOP | ✓ | optional count | | SSCAN | ✓ | | -| SMOVE | ✗ | not implemented | -| SINTERCARD | ✗ | not implemented | +| SMOVE | ✓ | cross-shard moves are sequential (not atomic) | +| SINTERCARD | ✓ | optional LIMIT cap | ### sorted sets @@ -115,14 +115,14 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | ZLEXCOUNT | ✗ | not implemented | | BZPOPMIN | ✗ | not implemented | | BZPOPMAX | ✗ | not implemented | -| ZRANDMEMBER | ✗ | not implemented | +| ZRANDMEMBER | ✓ | optional count with WITHSCORES | | ZUNIONSTORE | ✗ | not implemented | | ZINTERSTORE | ✗ | not implemented | | ZDIFFSTORE | ✗ | not implemented | -| ZUNION | ✗ | not implemented | -| ZINTER | ✗ | not implemented | -| ZDIFF | ✗ | not implemented | -| ZMPOP | ✗ | not implemented | +| ZUNION | ✓ | | +| ZINTER | ✓ | | +| ZDIFF | ✓ | | +| ZMPOP | ✓ | | | ZMSCORE | ✗ | not implemented | ### hashes @@ -142,7 +142,7 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | HSCAN | ✓ | | | HMSET | ✗ | use HSET with multiple fields instead | | HINCRBYFLOAT | ✗ | not implemented | -| HRANDFIELD | ✗ | not implemented | +| HRANDFIELD | ✓ | optional count with WITHVALUES | ### keys @@ -171,11 +171,11 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | SWAPDB | ✗ | single database only | | DUMP | ✗ | not implemented | | RESTORE | ~ | supported for cluster MIGRATE only | -| WAIT | ✗ | not implemented | -| EXPIREAT | ✗ | not implemented | -| PEXPIREAT | ✗ | not implemented | -| EXPIRETIME | ✗ | not implemented | -| PEXPIRETIME | ✗ | not implemented | +| WAIT | ✓ | waits for replica acknowledgements | +| EXPIREAT | ✓ | | +| PEXPIREAT | ✓ | | +| EXPIRETIME | ✓ | | +| PEXPIRETIME | ✓ | | ### server @@ -191,7 +191,7 @@ Legend: `✓` supported, `~` partial or with caveats, `✗` not supported. | FLUSHDB | ✓ | ASYNC mode supported | | CONFIG GET | ✓ | glob pattern matching | | CONFIG SET | ✓ | mutable: slowlog-log-slower-than, slowlog-max-len | -| CONFIG REWRITE | ✗ | not implemented | +| CONFIG REWRITE | ✓ | flushes runtime config back to file | | CONFIG RESETSTAT | ✗ | not implemented | | SLOWLOG GET | ✓ | optional count argument | | SLOWLOG LEN | ✓ | | @@ -307,7 +307,7 @@ A few Redis command families are explicitly out of scope: - **lua scripting** — EVAL, EVALSHA, EVALRO, SCRIPT LOAD/EXISTS/FLUSH, FCALL, and the FUNCTION family. Lua scripting is an anti-goal. WASM-based extensions may come in a future release. - **streams** — XADD, XREAD, XRANGE, and the full Streams family. Ember focuses on caching workloads; use a dedicated stream store for this. -- **bit operations** — BITCOUNT, SETBIT, GETBIT, BITOP, BITPOS, BITFIELD. Not implemented yet, may be added later. +- **BITFIELD / BITFIELD_RO** — not planned; use application-level serialization if needed. - **geo** — GEOADD, GEOPOS, GEODIST, GEORADIUS, GEOSEARCH, GEOHASH, and variants. Not implemented. - **hyperloglog** — PFADD, PFCOUNT, PFMERGE. Not implemented. @@ -463,7 +463,6 @@ before anything else, check which commands your application uses. the compatibil common substitutions: -- `GETSET key value` → `SET key value GET` - `SETNX key value` → `SET key value NX` - `SETEX key seconds value` → `SET key value EX seconds` - `HMSET key field value ...` → `HSET key field value ...`