Jodis 是一个用 Java 实现的内存键值数据库,兼容 Redis RESP2 协议。项目初衷是学习数据库的设计与实现,同时也提供了一个轻量级的缓存方案。
项目简介
Jodis (Java Object Dictionary Server) 是一个高性能的基于内存的键值数据库,核心特点:
- 纯 Java 实现:JDK 21+,代码简洁易读
- 兼容 Redis 协议:支持 RESP2 协议,可用 redis-cli 直接连接
- 丰富的数据结构:String、List、Hash、Set、Sorted Set 五大类型
- 双模式部署:支持独立服务器和嵌入式两种使用方式
- 持久化支持:WAL 预写日志 + JDB 快照双重保障
支持的数据结构
| 数据类型 | 典型应用场景 | 示例命令 |
|---|---|---|
| String | 缓存、计数器、分布式锁 | SET, GET, INCR |
| List | 消息队列、最新列表 | LPUSH, RPOP, LRANGE |
| Hash | 对象存储、购物车 | HSET, HGET, HGETALL |
| Set | 标签系统、社交关系 | SADD, SMEMBERS, SINTER |
| Sorted Set | 排行榜、优先队列 | ZADD, ZRANGE, ZSCORE |
快速上手
1. 编译项目
git clone https://github.com/abel-huang/Jodis.git
cd Jodis
mvn clean package -DskipTests
2. 启动服务器
java -cp target/classes:target/test-classes:$(cat .classpath.deps) \
cn.abelib.jodis.Jodis conf/jodis.properties
服务器默认监听 6059 端口。
3. 使用 Redis CLI 连接
是的,你可以直接用 redis-cli 连接 Jodis:
redis-cli -h localhost -p 6059
试试这些命令:
127.0.0.1:6059> PING
PONG
127.0.0.1:6059> SET greeting "Hello, Jodis!"
OK
127.0.0.1:6059> GET greeting
"Hello, Jodis!"
127.0.0.1:6059> LPUSH mylist item1 item2 item3
(integer) 3
127.0.0.1:6059> LRANGE mylist 0 -1
1) "item3"
2) "item2"
3) "item1"
127.0.0.1:6059> HSET user:1 name "Alice" age 25
(integer) 2
127.0.0.1:6059> HGETALL user:1
1) "name"
2) "Alice"
3) "age"
4) "25"
Java 客户端使用
Jodis 提供了原生的 Java 客户端,API 设计简洁直观:
import cn.abelib.jodis.client.JodisClient;
public class MyApp {
public static void main(String[] args) throws Exception {
try (JodisClient client = new JodisClient("localhost", 6059)) {
client.connect();
// String 操作
client.set("app:name", "My Application");
String name = client.get("app:name");
// 计数器
client.set("counter", "0");
client.incr("counter"); // 1
client.incrBy("counter", 10); // 11
// Hash 操作 - 存储用户信息
client.hset("user:1001", "name", "张三");
client.hset("user:1001", "email", "zhangsan@example.com");
Map<String, String> user = client.hgetAll("user:1001");
// List 操作 - 消息队列
client.lpush("queue:emails", "email1@test.com");
client.lpush("queue:emails", "email2@test.com");
String email = client.rpop("queue:emails"); // FIFO
// Sorted Set - 排行榜
client.zadd("leaderboard", 100, "player1");
client.zadd("leaderboard", 200, "player2");
List<String> topPlayers = client.zrange("leaderboard", 0, 9);
}
}
}
嵌入式模式
如果你不想单独部署服务器,Jodis 支持嵌入式运行,直接集成到你的应用中:
import cn.abelib.jodis.EmbeddedJodis;
import cn.abelib.jodis.protocol.Request;
// 启动嵌入式实例
EmbeddedJodis jodis = EmbeddedJodis.start("conf/jodis.properties");
// 直接执行命令
Response response = jodis.execute(new Request("GET", "mykey"));
// 关闭
jodis.close();
这种模式特别适合:
- 单元测试环境
- 小型应用内嵌缓存
- 学习和教学用途
配置说明
Jodis 的配置文件简单明了:
# 服务器配置
jodis.port=6059
server.type=netty
server.max.request=1024
server.max.concurrency=64
# 持久化配置
log.dir=log/
log.jdb=default.jdb
log.wal=default.wal
log.reload.mode=2 # 0=WAL, 1=JDB, 2=混合加载
# 自动保存
store.auto.save.enabled=1
store.auto.save.interval=60 # 每 60 秒自动保存
持久化机制
Jodis 提供两层持久化保障:
WAL (Write-Ahead Log)
- 所有写操作先记录日志,再更新内存
- 故障恢复时回放日志,数据不丢失
- 支持自动重写,避免日志无限增长
JDB (Jodis DataBase Dump)
- 定期生成数据快照
- 二进制格式,加载速度快
- 适合作为冷备份
适用场景
Jodis 适合以下使用场景:
推荐使用:
- 应用内嵌缓存
- 开发测试环境
- 学习 Redis 原理
- 原型验证
- 小规模数据存储
不推荐使用:
- 大规模生产环境(建议使用 Redis)
- 高并发写入场景
- 需要集群支持的场景
技术栈
- 语言: Java 21
- 网络框架: Netty 4.x (NIO Reactor)
- 协议: Redis RESP2
- 构建工具: Maven
- 测试框架: JUnit
总结
无论你是想学习数据库原理,还是需要一个轻量级的 Java 缓存方案,Jodis 都值得一试。
项目地址: github.com/abel-huang/…
许可证: MIT License