Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MemKV 内存数据库

Feature: memkv

纯内存 KV 数据库,支持与 Redis 兼容的五种数据类型:String / Hash / List / Set / ZSet。线程安全,支持 TTL 过期。暂无持久化(计划通过 ahrifs 实现)。

使用

#![allow(unused)]
fn main() {
use std::time::Duration;
use afaster::memkv::MemKV;

let kv = MemKV::new();

// String
kv.set("name", b"hello".to_vec(), Some(Duration::from_secs(60))).await?;
let v: Option<Vec<u8>> = kv.get("name").await?;
kv.incr("counter", 1).await?;

// Hash
kv.hset("user:1", "name", b"Alice".to_vec()).await?;
let name = kv.hget_str("user:1", "name").await?;

// List
kv.lpush("queue", b"task1".to_vec()).await?;
kv.rpush("queue", b"task2".to_vec()).await?;
let task = kv.lpop("queue").await?;

// Set
kv.sadd("tags", b"rust".to_vec()).await?;
let members = kv.smembers("tags").await?;

// ZSet
kv.zadd("leaderboard", 100.0, "player1").await?;
let top = kv.zrange("leaderboard", 0, -1).await?;
}

API

通用操作

方法参数返回说明
new()MemKV创建实例
del(key)&strResult<bool>删除 key
exists(key)&strResult<bool>key 是否存在
expire(key, ttl)&str, DurationResult<bool>设置过期时间
ttl(key)&strResult<Option<Duration>>获取剩余过期时间
keys(pattern)&strResult<Vec<String>>按模式查找 key(支持 * 通配)
typ(key)&strResult<Option<&str>>获取 key 的类型
dbsize()Result<usize>key 总数
flushdb()Result<()>清空所有数据

String 操作

方法参数返回说明
get(key)&strResult<Option<Vec<u8>>>获取值(bytes)
get_str(key)&strResult<Option<String>>获取值(UTF-8 字符串)
set(key, value, ttl)&str, V, Option<Duration>Result<()>设置值
set_nx(key, value, ttl)&str, V, Option<Duration>Result<bool>仅当 key 不存在时设置
incr(key, delta)&str, i64Result<i64>原子自增

Hash 操作

方法参数返回说明
hget(key, field)&str, &strResult<Option<Vec<u8>>>获取字段值
hget_str(key, field)&str, &strResult<Option<String>>获取字段值(UTF-8)
hset(key, field, value)&str, &str, VResult<bool>设置字段(返回是否新增)
hdel(key, field)&str, &strResult<bool>删除字段
hgetall(key)&strResult<HashMap<String, Vec<u8>>>获取所有字段
hincrby(key, field, delta)&str, &str, i64Result<i64>字段原子自增
hexists(key, field)&str, &strResult<bool>字段是否存在
hkeys(key)&strResult<Vec<String>>获取所有字段名
hvals(key)&strResult<Vec<Vec<u8>>>获取所有字段值
hlen(key)&strResult<usize>字段数量

List 操作

方法参数返回说明
lpush(key, value)&str, VResult<usize>从左侧推入,返回长度
rpush(key, value)&str, VResult<usize>从右侧推入,返回长度
lpop(key)&strResult<Option<Vec<u8>>>从左侧弹出
rpop(key)&strResult<Option<Vec<u8>>>从右侧弹出
lrange(key, start, stop)&str, i64, i64Result<Vec<Vec<u8>>>获取范围(支持负索引)
llen(key)&strResult<usize>列表长度
lindex(key, index)&str, i64Result<Option<Vec<u8>>>按索引获取(支持负索引)

Set 操作

方法参数返回说明
sadd(key, member)&str, VResult<bool>添加成员
srem(key, member)&str, VResult<bool>移除成员
sismember(key, member)&str, VResult<bool>成员是否存在
smembers(key)&strResult<Vec<Vec<u8>>>获取所有成员
scard(key)&strResult<usize>成员数量

ZSet 操作

方法参数返回说明
zadd(key, score, member)&str, f64, &strResult<bool>添加/更新成员
zrem(key, member)&str, &strResult<bool>移除成员
zscore(key, member)&str, &strResult<Option<f64>>获取成员分数
zcard(key)&strResult<usize>成员数量
zrange(key, start, stop)&str, i64, i64Result<Vec<(String, f64)>>按索引范围获取
zrangebyscore(key, min, max)&str, f64, f64Result<Vec<(String, f64)>>按分数范围获取
zincrby(key, delta, member)&str, f64, &strResult<f64>成员分数自增

TTL 过期

所有 set 操作都支持可选的 ttl 参数:

#![allow(unused)]
fn main() {
use std::time::Duration;

// 60 秒后自动过期
kv.set("session", b"abc".to_vec(), Some(Duration::from_secs(60))).await?;

// 永不过期(默认)
kv.set("config", b"{}".to_vec(), None).await?;

// 动态设置过期时间
kv.expire("session", Duration::from_secs(300)).await?;

// 查询剩余时间
if let Some(remaining) = kv.ttl("session").await? {
    println!("剩余 {} 秒", remaining.as_secs());
}
}

过期采用惰性删除策略:访问时检查是否过期,过期则自动清除。

线程安全

MemKV 内部使用 tokio::sync::RwLock 保护数据,可安全地在多个 async task 中共享:

#![allow(unused)]
fn main() {
let kv = MemKV::new();

// Clone 后可在多个 task 中使用
let kv1 = kv.clone();
let kv2 = kv.clone();

tokio::spawn(async move { kv1.set("a", b"1".to_vec(), None).await; });
tokio::spawn(async move { kv2.set("b", b"2".to_vec(), None).await; });
}

错误码

English中文
42901Type mismatch类型不匹配(如对 List key 执行 HGET)
42902Key not foundKey 不存在
42903Index out of range索引越界
42904Value is not a number值不是有效数字(INCR 目标)
52901Command failed操作执行失败

与 Redis 对照

Redis 命令MemKV 方法差异
GETget() / get_str()返回 Vec<u8>String
SETset()TTL 用 Duration 而非秒数
SET NXset_nx()
DELdel()
EXISTSexists()
EXPIREexpire()Duration
TTLttl()返回 Option<Duration>
KEYSkeys()支持 * 前缀/后缀通配
INCRincr()
HGET/HSET/...hget()/hset()/...
LPUSH/RPOP/...lpush()/rpop()/...
SADD/SMEMBERS/...sadd()/smembers()/...
ZADD/ZRANGE/...zadd()/zrange()/...
SCANkeys()简化实现,生产环境慎用
SUBSCRIBE暂不支持
MULTI/EXEC暂不支持