Kafka 文件消费处理 + 文本切割 + 向量化处理

Kafka 业务逻辑

  • 通过@KafkaListener 注解监听 Kafka 主题,检测到该主题有要处理的任务,会自动调用 processTask 该方法并且传入要处理的类 task,对文件开始处理
  • 在 MinIO 中进行文件合并之后会产生预签名URL, 在 Kafka 中通过这个 URL 下载文件并且转换成可缓存流,对该文件进行解析
  • 在数据库保存了文件的分块信息之后,通过 file_md5 或者这些分块进行向量化处理
    • 通过 Embedding 处理 chunk 形成List<float[]> 向量

文本切割业务逻辑

  • 先进行JVM虚拟机的内存检查
  • 创建 BufferedInputStream 对象用来缓冲数据
  • 创建流程内部处理器,处理父块的切分和子块的分片存储
  • Apache Tika解析文件: 1.Metadata 对象,用于存储文件的元数据,2.创建一个 ParseContext 对象,用于传递解析上下文信息 3.创建一个 AutoDetectParser 实例,这是 Tika 的核心解析器。
  • 在解析文件的时候就把分片信息存入到数据库中了

流式处理器StreamingContentHandler

  • 继承了 BodyContentHandler ,内部有一个 StringBuffer ,通过 characters 方法不断向 buffer 中积累文本,当长度达到 1MB 字节长度,进行子块处理。当文档最后剩余的不足 1MB 的时候,在 endDocument方法中处理,也直接进入子块处理
  • 子块处理,先是按照段落通过换行符分割获得字符串数组,然后循环遍历。有一个 currentChunk 用来不断追加累计文本,子块规定大小 chunkSize 是 512 字节。遍历时如果遍历的这个段落本身就已经大于 chunkSize, 那么对段落进行句子分割;如果遍历的这个段落+currentChunk大于 chunkSize,就先把这个buffer保存到 List chunks,再把这个段落 new 一个新的 buffer 对象;如果不大于 chunkSize 就直接添加
  • 对段落按照句子进行分割,首先按照标点符号用正则表达式分开,如果某个句子特别长超过 chunkSize,按照词进行分割,使用HanLP智能分割超长句子,中文按语义切割,最后兜底方案如果分词失败了按照字符进行分割
  • 最后把所有分割好的子块合集写入到数据库中,这里会维护一个变量 savedChunkCount 每一个分片都有一个自己的唯一标识,不依赖于数据库的自增 id

BufferedInputStream 缓冲区

  • 减少底层 I/O 次数,缓冲区就像是一个水杯去水龙头(磁盘/网络资源)接了一杯,不用一滴一滴的去水龙头接,减少频繁交换
  • 调用 read() 方法会检查缓存区是否有数据,如果没有就从底层交互,默认 8192字节也就是 8KB 字节大小
  • 防止OOM,设置缓存区能避免一次把所有数据全部读入到内存,超出 JVM 内存限制,要分块读入

JVM 内存检测

  • Runtime 类能获得 JVM信息,maxMemory()是JVM 最大内存,可通过 -Xmx 设置, totalMemory()是JVM 根据需求想操作系统申请到的内存资源,freeMemory()还未使用的空间
  • 计算内存的使用率,如果超过 80% 手动进行一次 GC,再次计算内存使用情况,如果再次超过,抛出异常内存不足
posted @ 2026-02-11 16:15  Huangyien  阅读(23)  评论(0)    收藏  举报