06-gpu-scheduling.md 3.3 KB

GPU 异构资源调度方案

问题背景

当前 GPU 分配:

  • 图片/扫描 PDF → GPU 0,1
  • 音频 → GPU 7
  • 视频 → GPU 5,6

问题

  • 图片任务把 Flink 占满了
  • 音频/视频任务排队
  • 但音频/视频的 GPU 是空闲的!

解决方案:按类型分 Topic + 独立 Flink Job

架构

图片/扫描 PDF → Topic: parse-image → Flink Job A → parse-service (GPU 0,1)
音频 → Topic: parse-audio → Flink Job B → parse-service (GPU 7)
视频 → Topic: parse-video → Flink Job C → parse-service (GPU 5,6)
原生 PDF/Office → Topic: parse-document → Flink Job D → parse-service (CPU)

优点

  • ✅ 不同类型任务完全隔离,互不影响
  • ✅ 可以独立调优每个 Flink Job 的并行度
  • ✅ GPU 资源利用率最大化
  • ✅ 简单,改造成本小

文件分类逻辑

分类规则

扩展名 类型 Topic GPU
.jpg, .jpeg, .png, .tiff, .bmp, .gif, .webp 图片 parse-image 0,1
.mp3, .wav, .flac, .aac, .m4a, .ogg 音频 parse-audio 7
.mp4, .avi, .mov, .mkv, .flv, .wmv 视频 parse-video 5,6
.pdf (扫描件) 扫描 PDF parse-image 0,1
.pdf (原生) 原生 PDF parse-document CPU
.doc, .docx, .ppt, .pptx, .xls, .xlsx, .txt Office parse-document CPU

PDF 扫描检测

关键逻辑:只看前 3 页,统计有效字符数

def is_scanned_pdf(file_path):
    import fitz  # PyMuPDF
    doc = fitz.open(file_path)
    total_chars = 0
    for page_num in range(min(3, len(doc))):
        page = doc[page_num]
        text = page.get_text()
        total_chars += len([c for c in text if c.isalnum()])
    doc.close()
    return total_chars < 50  # 少于 50 个字符认为是扫描件

已创建的文件

文件 说明
send_task_to_kafka_by_type.py 按类型分发任务到不同 Topic

下一步

1. 创建 Kafka Topic

# 创建 4 个 Topic
kafka-topics.sh --create --topic parse-image --bootstrap-server 10.192.72.13:9092 --partitions 3 --replication-factor 1
kafka-topics.sh --create --topic parse-audio --bootstrap-server 10.192.72.13:9092 --partitions 3 --replication-factor 1
kafka-topics.sh --create --topic parse-video --bootstrap-server 10.192.72.13:9092 --partitions 3 --replication-factor 1
kafka-topics.sh --create --topic parse-document --bootstrap-server 10.192.72.13:9092 --partitions 3 --replication-factor 1

2. 创建 4 个 Flink Job

每个 Job 消费一个 Topic:

  • ImageParseFlinkJob - 消费 parse-image
  • AudioParseFlinkJob - 消费 parse-audio
  • VideoParseFlinkJob - 消费 parse-video
  • DocumentParseFlinkJob - 消费 parse-document

3. 配置 parse-service 实例池

每个类型的任务绑定对应的 GPU 实例:

  • parse-service 实例 1,2 → 绑定 GPU 0,1 → 处理 parse-image
  • parse-service 实例 3 → 绑定 GPU 7 → 处理 parse-audio
  • parse-service 实例 4,5 → 绑定 GPU 5,6 → 处理 parse-video
  • parse-service 实例 6,7 → CPU → 处理 parse-document

相关文件

  • send_task_to_kafka_by_type.py(新创建)
  • send_task_to_kafka.py(旧版本,单 Topic)
  • schedule-flink/src/main/java/com/yusys/flink/RealFlinkJob.java(需要扩展为多 Job)