简体中文 | English
RogueMap 是一个高性能的嵌入式存储引擎库,突破 JVM 内存墙。基于内存映射文件,提供四种堆外数据结构,同时配备支持向量 + 关键词混合检索的 AI 记忆层。
| 特性 | 传统集合 | RogueMap |
|---|---|---|
| 数据容量 | 受限于堆大小 | 无限制,可达 TB 级 |
| 堆内存占用 | 100% | 仅 15.3% |
| GC 影响 | 严重(Full GC 停顿) | 几乎无影响 |
| 持久化 | 不支持 | 支持 |
| 事务 | 不支持 | 原子多键操作 |
| AI 记忆 | 不支持 | RogueMemory — 向量 + 关键词混合检索 |
传统 Java 集合和嵌入式数据库只关注键值或关系型存储。RogueMap 在此基础上更进一步,内置 RogueMemory —— 提供 HNSW 向量近似搜索(ANN)与 BM25 关键词检索的混合记忆层,通过 Reciprocal Rank Fusion 融合排序,所有数据基于 mmap 持久化,无需额外引入向量数据库或搜索引擎。
RogueMemory 适用于以下场景:
- AI Agent 长期记忆 —— 跨会话持久化对话上下文与用户偏好,让 Agent 具备真正的记忆能力
- RAG(检索增强生成) —— 基于 Embedding 的文档/知识库检索,为 LLM 应用提供精准上下文
- 语义搜索 —— 对文本、代码等任意可嵌入内容进行"找相似"查询
- 混合检索 —— 语义理解 + 精确关键词匹配双通道召回,提升召回准确率
| 模块 | Java 版本 | 说明 |
|---|---|---|
roguemap-core |
8+ | 核心堆外存储 — RogueMap、RogueList、RogueSet、RogueQueue |
roguemap-embedding |
8+ | UniversalEmbeddingProvider — 零依赖 OpenAI 兼容 Embedding 客户端 |
roguemap-memory |
8+ | AI 记忆层,向量 + BM25 混合检索,基于 mmap 持久化 |
- 四种数据结构 — RogueMap、RogueList、RogueSet、RogueQueue
- 持久化支持 — 进程重启后数据自动恢复,支持崩溃恢复(CRC32 校验 + 写入代数 + 脏标志)
- 自动扩容 — 通过
autoExpand(true)可选开启文件自动增长 - 事务支持 — RogueMap 默认分段索引支持原子多键操作,Read Committed 隔离级别
- TTL 过期 — RogueMap 支持默认 TTL 与单条 TTL
- 碎片整理 — Copy-on-Compact 方式回收碎片空间
- 检查点 — 手动及自动(时间间隔或操作次数)触发检查点
- 零拷贝序列化 — 原始类型直接内存布局
- 高并发支持 — 64 段分段锁,StampedLock 乐观读
- 零依赖 — 核心库无第三方依赖
- AI 记忆层 — 向量 + BM25 混合检索,基于 mmap 持久化存储
<!-- 核心堆外数据结构 -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>roguemap-core</artifactId>
<version>1.1.5</version>
</dependency>
<!-- 通用 Embedding 客户端(零额外依赖) -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>roguemap-embedding</artifactId>
<version>1.1.5</version>
</dependency>
<!-- AI 记忆层 -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>roguemap-memory</artifactId>
<version>1.1.5</version>
</dependency>// 临时文件模式(JVM 关闭后自动删除)
RogueMap<String, Long> map = RogueMap.<String, Long>mmap()
.temporary()
.allocateSize(64 * 1024 * 1024L)
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.build();
map.put("alice", 100L);
map.get("alice"); // 100L
// 持久化模式 + 自动扩容
RogueMap<String, Long> persistentMap = RogueMap.<String, Long>mmap()
.persistent("data/mydata.db")
.autoExpand(true)
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.build();
// 超低堆 String Key 模式(索引与 key 字节放在 mmap)
RogueMap<String, Long> lowHeapMap = RogueMap.<String, Long>mmap()
.persistent("data/lowheap.db")
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.lowHeapIndex()
.build();
// 事务 — 原子多键操作
try (RogueMapTransaction<String, Long> txn = map.beginTransaction()) {
txn.put("key1", 1L);
txn.put("key2", 2L);
txn.commit(); // 原子提交;close() 未 commit 自动回滚
}
// TTL — 30 秒后过期
map.put("session", 42L, 30, TimeUnit.SECONDS);
// 遍历所有键值对
map.forEach((key, value) -> System.out.println(key + " = " + value));事务仅支持默认的
segmentedIndex(...)实现。basicIndex()、primitiveIndex()和lowHeapIndex()均不支持beginTransaction()。
RogueList<String> list = RogueList.<String>mmap()
.temporary()
.elementCodec(StringCodec.INSTANCE)
.build();
list.addLast("hello"); // O(1) — 推荐
list.addLast("world");
list.get(0); // "hello" — O(1) 随机访问(位置索引)
addFirst()/removeFirst()因位置索引移位为 O(n),大列表请优先使用addLast()/removeLast()。
RogueSet<String> set = RogueSet.<String>mmap()
.temporary()
.elementCodec(StringCodec.INSTANCE)
.build();
set.add("apple"); // true
set.contains("apple"); // true
set.remove("apple"); // true// 链表模式(无界)
RogueQueue<String> queue = RogueQueue.<String>mmap()
.temporary()
.linked()
.elementCodec(StringCodec.INSTANCE)
.build();
queue.offer("task1");
queue.poll(); // "task1"
// 环形缓冲区模式(有界)
RogueQueue<Long> circular = RogueQueue.<Long>mmap()
.persistent("data/queue.db")
.circular(1024, 64) // 容量=1024,最大元素=64字节
.elementCodec(PrimitiveCodecs.LONG)
.build();RogueMap 同时支持构建器级默认 TTL 与单条 TTL。
// Map 全局默认 TTL
RogueMap<String, String> map = RogueMap.<String, String>mmap()
.temporary()
.defaultTTL(60, TimeUnit.SECONDS)
.keyCodec(StringCodec.INSTANCE)
.valueCodec(StringCodec.INSTANCE)
.build();
// 单条 TTL(仅 RogueMap 支持)
map.put("token", "abc123", 30, TimeUnit.SECONDS);追加写入会在更新/删除后积累死字节。使用 StorageMetrics 监控碎片率,使用 compact() 回收空间。
StorageMetrics metrics = map.getMetrics();
System.out.println("碎片率: " + metrics.getFragmentationRatio());
if (metrics.shouldCompact(0.5)) {
map = map.compact(64 * 1024 * 1024L); // 返回新实例,旧实例自动关闭
}
compact()不支持临时模式和环形队列(CircularQueue)。
// 手动检查点 — 将索引/元数据强制刷盘
map.checkpoint();
// 自动检查点 — 每 60 秒触发一次
RogueMap<String, Long> map = RogueMap.<String, Long>mmap()
.persistent("data/mydata.db")
.autoCheckpoint(60, TimeUnit.SECONDS)
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.build();
// 自动检查点 — 每 1000 次操作触发一次
RogueMap<String, Long> map2 = RogueMap.<String, Long>mmap()
.persistent("data/mydata.db")
.autoCheckpoint(1000)
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.build();roguemap-memory 提供持久化 AI 记忆存储,支持向量 + BM25 混合检索,底层基于 mmap 存储。专为 AI Agent 和 LLM 应用的长期记忆场景设计。
UniversalEmbeddingProvider(来自 roguemap-embedding)兼容所有实现了 OpenAI /v1/embeddings 协议的服务,仅使用 HttpURLConnection,零额外依赖。
| 服务商 | Base URL | 常用模型 |
|---|---|---|
| OpenAI | https://api.openai.com/v1 |
text-embedding-3-small(1536维)、text-embedding-3-large(3072维)、text-embedding-ada-002(1536维) |
| Mistral | https://api.mistral.ai/v1 |
mistral-embed(1024维) |
| Jina AI | https://api.jina.ai/v1 |
jina-embeddings-v3(1024维)、jina-embeddings-v2-base-en(768维) |
| Voyage AI | https://api.voyageai.com/v1 |
voyage-3(1024维)、voyage-3-lite(512维) |
| 阿里云百炼(DashScope) | https://dashscope.aliyuncs.com/compatible-mode/v1 |
text-embedding-v3(1024维)、text-embedding-v2(1536维) |
| 智谱 GLM | https://open.bigmodel.cn/api/paas/v4 |
embedding-3(2048维)、embedding-2(1024维) |
| Ollama(OpenAI 兼容模式) | http://localhost:11434/v1 |
nomic-embed-text(768维)及任意本地模型 |
| vLLM / LocalAI / Together / Fireworks | 自定义 | 任意兼容模型 |
你不需要自己查阅或硬编码任何维度数值。UniversalEmbeddingProvider 会通过以下两个阶段自动解决:
- 内置表 — 对上表中列出的已知模型,维度在构造时直接从内置表读取,无需任何网络请求。
- 自动探测 — 对不在内置表中的模型,首次
embed()调用时通过读取返回向量的长度自动确定维度,并缓存供后续使用。
// OpenAI(默认:text-embedding-3-small,维度从内置表读取)
EmbeddingProvider provider = new UniversalEmbeddingProvider(apiKey);
// OpenAI 指定模型
EmbeddingProvider provider = new UniversalEmbeddingProvider(apiKey, "text-embedding-3-large");
// 任意兼容服务 — 只需传 baseUrl + apiKey + model,维度自动处理
EmbeddingProvider provider = new UniversalEmbeddingProvider(
"https://api.mistral.ai/v1", apiKey, "mistral-embed");
// 本地 Ollama 自定义模型(不在内置表中)— 首次调用时自动探测
EmbeddingProvider provider = new UniversalEmbeddingProvider(
"http://localhost:11434/v1", "", "my-custom-model");
// 强制指定维度(例如服务支持截断时)
EmbeddingProvider provider = new UniversalEmbeddingProvider(
"https://api.openai.com/v1", apiKey, "text-embedding-3-small", 512);
// 随时查看已解析的维度
System.out.println(provider.getDimension());RogueMemory mem = RogueMemory.mmap()
.persistent("data/mem")
.searchMode(SearchMode.HYBRID) // HYBRID | VECTOR_ONLY | KEYWORD_ONLY
.embeddingProvider(new UniversalEmbeddingProvider(apiKey))
.build();
// 存入记忆(支持元数据与命名空间)
Map<String, String> metadata = new HashMap<>();
metadata.put("source", "settings");
String id = mem.add("用户偏好深色模式", metadata, "user-123");
// 检索
List<MemoryResult> results = mem.search(
"用户界面偏好",
5,
SearchOptions.builder().namespace("user-123").build());
for (MemoryResult r : results) {
System.out.println(r.getContent() + " (score=" + r.getScore() + ")");
}
// 删除
mem.delete(id);
mem.close();检索模式:
HYBRID(默认)— 向量 ANN + BM25,通过 RRF 合并结果;提供EmbeddingProvider后启用向量检索VECTOR_ONLY— 纯 ANN 检索;需要EmbeddingProvider才会返回结果KEYWORD_ONLY— 纯 BM25 检索;无需EmbeddingProvider
原始类型(零拷贝):Long、Integer、Double、Float、Short、Byte、Boolean
字符串:StringCodec.INSTANCE
对象:KryoObjectCodec.create(YourClass.class)(可选 Kryo 依赖)
复杂泛型:KryoObjectCodec.create(new TypeReference<List<User>>() {})(可选 Kryo 依赖)
- Java 8+
- Maven 3.6+