一. 概述
该告警表示播放器的预取(read-ahead)队列被消费得过快而补不满,导致消息发送延迟。通常由磁盘读速、CPU解压/编解码开销、话题数量/频率过高、QoS阻塞或SQLite读取缓存过小引起。
首选:增大预取队列
直接按提示增大:
ros2 bag play <bag_path> --read-ahead-queue-size 10000
如果发行版支持"按时间"预取:
ros2 bag play <bag_path> --read-ahead-queue-duration 10s
观察是否仍出现 starved 警告;根据频率逐步加大(如 20000、50000)。
降低播放压力
降速回放:
ros2 bag play <bag_path> --rate 0.5
只播放关键话题:
ros2 bag play <bag_path> --topics /camera/image /lidar/points
或用正则过滤:
ros2 bag play <bag_path> --regex ".(image|imu)."
提升磁盘与CPU可用性
将包拷到本地SSD再播,避免网络盘/机械盘瓶颈。
关闭其他高IO/高CPU进程;确认没有同时进行重度录制等任务。
如包使用压缩(zstd/lz4),可先解压减少播放时CPU开销:
ros2 bag info <bag_path>
ros2 bag decompress <bag_path>
得到解压后的新包目录后再播放
ros2 bag play <decompressed_bag_path>
增大SQLite读取缓存(storage config)
创建 storage_config.yaml:
sqlite3:
pragmas: "cache_size=-200000;page_size=4096"
说明:cache_size 负值为 KB(此处约200MB缓存);可按内存情况上调。
播放时指定:
ros2 bag play <bag_path> --storage-config-file storage_config.yaml
避免QoS阻塞(将播放端QoS改成非阻塞)
若订阅端使用可靠(reliable)且处理慢,播放器可能被背压。
创建 qos_override.yaml(示例将所有话题改为更"宽松"的Best Effort):
qos_overrides:
/: # 匹配所有话题
reliability: best_effort
durability: volatile
history: keep_last
depth: 20
播放指定:
ros2 bag play <bag_path> --qos-profile-overrides-path qos_override.yaml
修复索引与检查包体
若包损坏或索引异常,可能导致读取抖动:
ros2 bag reindex <bag_path>
使用 ros2 bag info 查看话题频率与压缩配置,结合实际调参。
其它实用建议
优先传入包目录(包含 metadata.yaml 的目录),而非直接 .db3 文件路径。
逐步调参法:先加大 --read-ahead-queue-size;若仍告警,再降速/限话题;仍不行,再用 storage_config 与解压组合。
监控系统资源:top/htop、iostat、iotop、nvidia-smi(如含GPU解码),定位瓶颈。
常见组合命令示例
读取SSD、放大预取、降速、只播关键话题:
ros2 bag play <bag_dir>
--read-ahead-queue-size 20000
--rate 0.7
--topics /camera/image_raw /imu/data
配合SQLite大缓存与QoS放宽:
ros2 bag play <bag_dir>
--read-ahead-queue-size 50000
--storage-config-file storage_config.yaml
--qos-profile-overrides-path qos_override.yaml
如果包是压缩的,先解压再播:
ros2 bag decompress <bag_dir>
ros2 bag play <decompressed_bag_dir> --read-ahead-queue-size 20000