大きいファイルは HTTP リクエストを分けてアップロードできるようにする
Summary
Cloudflare の 100 MB 制限などが実質的なファイルサイズ制限になっているため
use case: #5364 のテストのためにisoを添付しようとしたらCfに怒られた
use case: 動画をアップロードしようとしたら怒られた
https://community.cloudflare.com/t/max-upload-size/630925/3 Enterpriseにあげても気休めにしかならないことが判明
オブジェクトストレージのマルチパートアップロード機能を前提に実装する必要がありそうな感じがします……?
分割したものをつなぎ合わせるシステムが意外に面倒 (RFCもなさそう)
- s3のマルチパートアップロードの利用を考えてAPIを設計する?
- Misskeyサーバーからクライアントへ一時idを発行する時は、完成後のURLを推測されないようにする必要がある
どのサーバーもs3を使っているというわけではないだろうからオブジェクトストレージ中立な設計にしたい
PUTに対する課金ってマルチパートアップロードの場合どうなるんだろう
s3の場合: UploadPartの呼び出し回数に比例?
リクエストを開始するときにはアップロードしようとしているファイルサイズを含めたい。 そうすることでドライブの容量が足りないときに無駄なアップロードを発生させず、即エラーにできる
S3マルチパートアップロードを使わない場合
- クライアントから別のクラスタにパートが送られる可能性もあるので、Misskeyバックエンドがアップロード前につなぎ合わせる処理をする方式は取れない
- ので、ひとまずパートごとにダイレクトにオブジェクトストレージもしくはローカルファイルに保存しておいて、クライアントがファイルを要求するときは、Misskeyバックエンドに
/files/で繋ぎ合わせながらダウンロードできる機能をつけるみたいなのが考えられる- ただしこれはバックエンドにストリーミングの負荷がかかる
- もしくはクライアントが要求する?
- クライアントはメモリが無理そう
- 動画はHLSにしちゃうとか?
- mp4を全部読んで解釈しなきゃいけないので無理そう?
- S3のPUTコストは膨れるけどアップロード終了後に後処理で動画専用処理をやってやる(サーバー管理者がオプションでこれをやるか選べるようにする)というのもありっちゃあり
PUTコストはかかるがファイルアップロード終了時に整理して後々のMisskeyバックエンドの負荷を減らす(動画はhls化/それ以外は単一ファイルとして再アップロード) vs PUTコストをかけず/files/で繋ぎ合わせたものをダウンロードさせる (Misskeyバックエンドの負荷は増える)
みたいなのを選べるようにすればいいか
大規模なサーバーだったら結合されてた方が嬉しそうではある
リクエストを開始するときにはアップロードしようとしているファイルサイズを含めたい。 そうすることでドライブの容量が足りないときに無駄なアップロードを発生させず、即エラーにできる
どの方法をとるにしてもこれは必ずやるとして…(先出しでやっておいても良いレベル)
上記に加え、サーバ側で1ファイルあたりのサイズ上限を決められたらいいようにも思えます(既にある?) 大容量ファイルのアップロード方式以前に、大容量ファイルのアップロードそのものを歓迎しないところもあるでしょうから
上記に加え、サーバ側で1ファイルあたりのサイズ上限を決められたらいいようにも思えます(既にある?)
ないかも?現状はドライブの合計容量だけ存在する認識
https://github.com/misskey-dev/misskey/issues/11801#issuecomment-2209842457
- PUTコストはかかるがファイルアップロード終了時に整理して後々のMisskeyバックエンドの負荷を減らす
- PUTコストをかけず/files/で繋ぎ合わせたものをダウンロードさせる
に加え、マルチパートアップロード対応(かつS3互換のAPIで動かせる)なオブジェクトストレージを使ってる場合は、それを使用できる選択肢があってもいいかも…? いずれもバックエンドに負担がかかるので損な選択肢ではないと考えています
サーバー単位でのファイルサイズ制限はこれかも? https://github.com/misskey-dev/misskey/blob/6dd2e9fc0b1eeea6b5f04ccac93ccfab658f976d/.config/example.yml#L296
ありがとうございます。そんなところに…
ロール単位でのサイズ制限が欲しくて独自フォークで実装したけど、Cherrypickベースのフォークだから別に実装した方が楽かもしれない
もし単体での上限を実装するときは
ロール単位でのサイズ制限が欲しくて
のほうが融通を利かせやすいかもですね。ちょっと実装量増えるけど…
逆に、先にロール単位でのサイズ制限を実装してしまう?
私の独自フォークからプルリクエスト作れるかも
メモ: Resumable Uploads for HTTP (draft) https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/
ほむん https://github.com/tus/tus-node-server
bump
これか
Misskeyの場合水平スケーリングを考慮する必要があるため面倒
アップロード途中のファイルをPostgres, Redis, ObjectStorageのいずれかに保持しておく必要がある
アップロードも大変ならダウンロードも大変なので、いっそのことファイルのダウンロードもクライアントで繋ぎ合わせさせればいいのでは(
濫用を避けるためにチャンクの最低サイズを設定できると良さそう(16MBとか?)
Misskeyの場合水平スケーリングを考慮する必要があるため面倒
ロードバランサでSticky sessionsを設定すればあまり問題がないのでは…?
クライアントはメモリが無理そう
https://github.com/misskey-dev/misskey/issues/11801#issuecomment-2209840688
大きいファイルを処理するときは一般的に(分割してあるかどうかに関わらず)メモリが厳しくなるのでは…?