Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OOM of thumbnail generation #7120

Closed
wants to merge 12 commits into from
Closed

Conversation

Muione
Copy link
Contributor

@Muione Muione commented Sep 1, 2024

对一些内存较少的服务器,本机存储 开启略缩图后,如果目录图像文件过多,访问时程序会启用大量线程生成略缩图,通常会使得 alist 占用大量内存,有可能导致服务器卡死。
解决思路是使用任务队列对前端发起请求进行串行处理,以限制单次并发数量从而限制内存占用,512MB 的服务器上进行下列测试:

  • 使用 100 张 1MB 图片,设置生成略缩图线程的并发数量为 1 时,alist 占用最大内存为 72MB,平均值 72MB;
  • 使用 100 张 8MB 图片,设置生成略缩图线程的并发数量为 1 时,alist 占用最大内存为 200MB,平均值 130MB;
  • 使用 100 张 28MB 图片,设置生成略缩图线程的并发数量为 1 时,alist 占用最大内存为 260MB,平均值 190MB;

应该可以解决爆内存的问题。

设置选项:
在 LocalDriver 里添加了 Thumb concurrency 参数可以控制生成略缩图的并发数量(对前端不熟悉,希望有大佬能汉化一下提示:

ThumbConcurrency string `json:"thumb_concurrency" default:"16" required:"true" help:"Number of concurrent thumbnail generation goroutines. This controls how many thumbnails can be generated in parallel."`

image

1G 以上内存的服务器可以设置 Thumb concurrency >= 8 以加快略缩图生成,具体自行测试。

close #7082

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

如果能在前端增加懒加载的话,效果会更好一些。目前增加 concurrent 可能会引起队列堵塞,比如单页过多 thumbnails 生成任务,切换页面后前面的生成任务能否取消,切换页面后是否会因为队列堵塞无法及时生成当前页面缩略图

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

如果能在前端增加懒加载的话,效果会更好一些。目前增加 concurrent 可能会引起队列堵塞,比如单页过多 thumbnails 生成任务,切换页面后前面的生成任务能否取消,切换页面后是否会因为队列堵塞无法及时生成当前页面缩略图

目前前端请求略缩图应该是应用了懒加载的;
增加并发限制的目的也是为了应对一些配置较低的服务器无法支持过大的并发数量,比如前端应用了懒加载,但是一次发送的请求依然超过服务器能承载的数量(在512MB 服务器上,可能最大的并发数量只能小于2,否则会超过内存限制,导致服务器卡住);
不过当切换页面后取消任务这个想法我觉得可行,但也需要折衷考虑,我可以尝试在其中加入context进行控制。

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

此 PR 貌似会引起 goroutine 泄漏。当 local driver config 被修改时,旧的携程不会退出。

能不能让我改改,thumbnails 生成应该放在 request handler goroutine 以避免 ffmpeg 操作引起 fatal panic。此外我还想使用令牌桶控制 concurrent,并加入 context 以允许控制超时或取消

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

如果能在前端增加懒加载的话,效果会更好一些。目前增加 concurrent 可能会引起队列堵塞,比如单页过多 thumbnails 生成任务,切换页面后前面的生成任务能否取消,切换页面后是否会因为队列堵塞无法及时生成当前页面缩略图

目前前端请求略缩图应该是应用了懒加载的; 增加并发限制的目的也是为了应对一些配置较低的服务器无法支持过大的并发数量,比如前端应用了懒加载,但是一次发送的请求依然超过服务器能承载的数量(在512MB 服务器上,可能最大的并发数量只能小于2,否则会超过内存限制,导致服务器卡住); 不过当切换页面后取消任务这个想法我觉得可行,但也需要折衷考虑,我可以尝试在其中加入context进行控制。

加入 context 支持只是支持取消的后端部分,取消操作主要还是需要修改前端。除此之外还需要考虑前端等待过久请求超时如何处理的问题

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

此 PR 貌似会引起 goroutine 泄漏。当 local driver config 被修改时,旧的携程不会退出。

这个问题我没注意,之后可以改进一下逻辑。

能不能让我改改,thumbnails 生成应该放在 request handler goroutine 以避免 ffmpeg 操作引起 fatal panic。此外我还想使用令牌桶控制 concurrent,并加入 context 以允许控制超时或取消

如果大佬想要修改的话也可以,你是想获得仓库的访问权限还是fork到你的仓库修改?我不是很清楚怎样给你权限

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

我 fork 然后 PR 到你的仓库吧

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

我 fork 然后 PR 到你的仓库吧

好的好的

@pull-request-size pull-request-size bot added size/L and removed size/M labels Sep 2, 2024
@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

@Muione 在合并 Muione#1 前你需要撤销 7ff81ba 的变更

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

Muione#1 变更:

  • 使用基于 Channel 的静态令牌桶,解决携程泄漏问题
  • 支持使用 context
  • 支持设置 ThumbConcurrent 为 0 解除并发限制
  • 全程不创建新的 goroutine,getThumb 调用移动到原携程,避免未捕获的 fatal error
  • 当 local config 变更时,会创建新的桶,短时间峰值并发为 SUM(old concurrent, new concurrent)

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

测试镜像为:mmx233/alist:v3.36.0-delta1 mmx233/alist:v3.36.0-delta1-ffmpeg, @Muione 请你也测试一遍

CAUTION:此镜像同时包含 #7123 的变更,可以更准确地统计内存占用

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

测试镜像为:mmx233/alist:v3.36.0-delta1 mmx233/alist:v3.36.0-delta1-ffmpeg, @Muione 请你也测试一遍

CAUTION:此镜像同时包含 #7123 的变更,可以更准确地统计内存占用

我正在测试你推送的代码,请稍等

This reverts commit 997dde5, reversing
changes made to e31d3d6.
@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

ac48a0a revert 了错误的提交,需要 revert 的是 7ff81ba 不是 997dde5

…nail generation concurrency"

This reverts commit 7ff81ba.
refactor: new TokenBucket alg, fixed goroutine leak, support context controlling
@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

ac48a0a revert 了错误的提交,需要 revert 的是 7ff81ba 不是 997dde5

好的好的,已经改回来了,感谢大佬。
我测试了下你这个方法确实更好,赞

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

ccfe904 此 commit 引入了 unclean 的变更到 pikpak driver,请移除这些变更 @Muione

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

或者我直接从我的分支提新的 PR 也行,你之前的 commit 会被保留

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

ccfe904 此 commit 引入了 unclean 的变更到 pikpak driver,请移除这些变更 @Muione

我检查一下,我好像没有修改别的文件

@Mmx233
Copy link
Contributor

Mmx233 commented Sep 2, 2024

我已发起新的 PR,此 PR 可以直接关闭

@Muione
Copy link
Contributor Author

Muione commented Sep 2, 2024

我已发起新的 PR,此 PR 可以直接关闭

好的

@Muione Muione closed this Sep 2, 2024
@Muione Muione deleted the fix-thumbnail-oom branch September 3, 2024 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

生成缩略图疑似内存爆炸
3 participants