ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RAG 知识库

RAG 知识库 知识库搭建增加kafkaminiomysql异步解析上传文件到chroma一. 注意的坑1. 大文件 OOMPDFBox 千万别 loadPDF(file.getBytes())要流式读取MinIO 下载也别整读内存。2. 幂等Kafka at-least-once 会重复投递消费者用 fileId 做去重Redis SETNX 或查状态否则同一文件入库两次。3. Chroma 幂等vectorStore.add() 最好能按 fileId 标识切片metadata 或 Document id重复消费时覆盖而非重复插入——具体 API 需要在 Spring AI 2.0 里确认。4. 消息堆积大文件解析慢消费者加并发、必要时拆 topic别让大文件拖垮队列。5. 失败可观测死信 topic 状态 FAILED 错误信息否则文件静默丢失很难排查。二. 落地顺序建议1. 先起 MinIO Kafka 环境引入依赖跑通「存 MinIO → 发 Kafka → 消费打印日志」。2. 把解析/切片/入库逻辑从 Controller 迁到 Consumer。3. 加状态追踪 轮询接口前端改异步。4. 最后补幂等、重试、死信、大文件分片等加固项。(1. 起 MinIO Kafka MySQL引入依赖MinioService 流式上传/下载跑通。2. 建 ingest_task 表 JPA 实体/仓库/Service。3. 改造 UploadController存 MinIO → 插表 → 发 KafkaPdfService 改流式。4. 写 DocumentConsumer 消费编排手动 ack 幂等 重试 死信。5. 加状态查询接口前端 index.html 改为「上传 → 拿 fileId → 轮询状态」。6. 最后补大文件压测、死信监控、失败重投工具。)三. 落地建议1. PdfService 要加 InputStream 重载现在它是 readPdf(MultipartFile)内部 Loader.loadPDF(file.getBytes()) 整读内存大文件会 OOM。改成readPdf(InputStream) 流式解析MultipartFile.getInputStream() 和 minioService.download() 都能复用。2. application.yml 的上传大小限制要调大现在是 max-file-size: 20MB既然要大文件按实际需求调比如 500MB。3. 先中转后演进的预留MinioService 里先把 presignedUrl() 方法留好UploadController 的存储调用抽象在 MinioService 内部——以后切预签名直传时Controller只多一个 POST /presign 接口消费链路完全不动。4. 幂等要双重保证DB 层用 uk_file_id 唯一键 消费前 isSuccess 判断Chroma 侧给切片打 fileId metadata若底层 API 支持按 id 覆盖则更好Spring AI 2.0 的VectorStore.add 具体幂等能力需验证。5. 环境依赖MinIO、Kafka、MySQL 三个中间件要先起起来Ollama Chroma 沿用现状。四. 防止Claude Code卡住对应的prompt优化不要继续大范围分析项目也不要重新设计架构。连接信息已经确认MinIOhttp://8.x.237.x:9000Kafkalocalhost:9092MySQLlocalhost:3306usernamerootpasswordroot现在直接开始第 1 步开发1. 检查 pom.xml 和 application.yml2. 配置 MinIO、Kafka、MySQL3. 检查并实现 MinioService4. 不要安装或下载 MinIO5. 不要修改 Docker 中已经运行的 MinIO6. 不要重新设计现有 RAG 架构请边检查边修改代码。每完成一个小步骤就运行编译/测试验证不要花几分钟继续思考整个项目。如果发现配置有问题直接修复并继续。现在开始实际编码。五. MinIodocker inspect minio | grep -E MINIO_ROOT_USER|MINIO_ROOT_PASSWORDMINIO_ROOT_USERadmin,MINIO_ROOT_PASSWORDadmin123456,MINIO_ROOT_USER_FILEaccess_key,MINIO_ROOT_PASSWORD_FILEsecret_key,服务器│┌───────────┴───────────┐│ │9000 9001│ │↓ ↓MinIO API MinIO Console│Docker│minio六. Kafka总结1. 为啥Producer和Consumer的key和value都需要序列化?由于kafka的broker端存的是byte[]而不是java对象。生产者:ProducerJava对象↓Serializer↓byte[]↓Kafka消费者:Kafka↓byte[]↓Deserializer↓Java对象2. auto-offset-reset: earliest含义?这个配置和消费者第一次读取 Kafka 消息时从哪里开始读有关。如果这个消费者组没有找到已经提交的 offset那么从最早的消息开始消费。消息:Kafka0 PDF-A1 PDF-B2 PDF-C3 PDF-D4 PDF-E七. Chroma / Milvus / PGVector 这三种向量库的区别和联系1. 三种向量库对比ChromaMilvuspgvector本质AI/RAG 向量数据库专业、高性能向量数据库PostgreSQL 扩展上手难度⭐⭐⭐⭐⭐⭐⭐小型 RAG非常适合可以适合大规模向量一般/可扩展非常强中大型可用分布式支持云/服务化部署强项PostgreSQL 集群能力为主业务数据 JOIN一般不是强项非常强SQL不以 SQL 为核心自己的查询 API标准 SQL事务/ACID不以此为核心不以此为核心PostgreSQL 原生能力Java 后端可以很好很好RAG 学习非常推荐推荐推荐企业业务系统看场景大规模 AI 场景业务数据向量一体化2. 各自特点与适用场景Chroma- 一个命令装好就能跑,API 极简,内置持久化(默认 SQLite)。- 适合:原型验证、demo、个人项目、小团队 MVP,数据量不大但想快速上线。- 缺点:不是为高并发/海量数据设计的,规模上去了通常要换。PGVector- 最大优势是**向量 关系数据一体化**:你不需要再维护一个独立的向量库,业务数据和向量数据在同一张表、同一个事务里。例如 SELECT * FROM docs ORDER BYembedding :q LIMIT 5。- 适合:已经用 PostgreSQL 的团队、需要强一致性和复杂过滤(向量 结构化条件混合查询)的场景。- 缺点:性能天花板受单机 PG 限制,海量向量规模(亿级)不如专用分布式库。Milvus- 功能最全、性能最强:多索引类型、分区、数据分片、流式/批式写入、GPU 加速等。- 适合:数据量亿级、高并发 QPS、需要水平扩展的生产级系统(如大型知识库、电商以图搜图、推荐系统)。3. 选型建议- 快速起步 / 原型 → Chroma- 已经有 PostgreSQL / 想少维护一套系统 → PGVector- 海量数据 高并发 生产级 → Milvus一个常见的演进路径是:先用 Chroma 或 PGVector 跑通 → 数据量和 QPS 上来了 → 迁移到 Milvus。第一种 ChromaChroma↓专门帮你保存vectortextmetadataJava开发规范.pdf切成chunk1chunk2chunk3...chunk100Embeddingchunk1 → [0.12, 0.38, ...]chunk2 → [0.25, 0.11, ...]Kafka消费者如何提交offset转成向量query → [0.13, 0.39, ...]Chroma 找最相似的chunk17chunk31chunk72然后交给 LLM。Chroma 官方目前也支持 metadata filtering、dense/sparse/hybrid search 等能力。第二种Milvus专业的向量数据库官方文档现在把 Milvus 的部署从本地原型一直覆盖到 Kubernetes 大规模分布式系统并支持 HNSW、IVF、DiskANN 等多种索引和大规模扩展。比如100万向量↓1000万向量↓1亿向量↓10亿向量这种情况下Milvus 的优势越来越明显。架构可能变成它本身就是围绕向量检索设计的。第三种: pgvectorpgvector 和前两个最大的区别是它不是一个独立的向量数据库产品而是 PostgreSQL 的一个扩展。例如CREATE EXTENSION vector;然后CREATE TABLE document_chunk (id BIGSERIAL PRIMARY KEY,content TEXT,embedding VECTOR(1536));于是 PostgreSQL 就可以直接存普通数据向量pgvector 支持精确搜索和近似最近邻搜索并支持 HNSW、IVFFlat 等索引同时你还能继续使用 PostgreSQL 的 JOIN、事务、备份等能力。pgvector 最大的优势:业务数据和向量可以放一起比如document----------------idnamecategorytenant_idcreated_at然后document_chunk----------------iddocument_idcontentembedding那么你可以直接SELECT *FROM document_chunkWHERE tenant_id 100ORDER BY embedding [...]LIMIT 10;甚至文档↓JOIN↓用户权限↓分类↓向量相似度这对企业知识库特别有意义。pgvector 官方也明确支持和 PostgreSQL 全文搜索一起实现 hybrid search。
返回列表