課題
- bulk export の再開
- 既にアップロードされたデータを有効活用したいと考えた時に、部分的にアップロードされた圧縮ファイルに次のデータを(現実的な工数で)append 可能な圧縮形式が見当たらない
- bulk export するためのリソース
- リソースが潤沢にあれば、中断されたエクスポート再開ができなくても早い時間でエクスポートが完了するので関係ない
- ユーザが送る複数の bulk export を素早く処理するには別のリソースが用意されていた方が都合が良い
- pdf でのエクスポートを作成する際、サーバ側で pdf を作成するために puppeteer でヘッドレスブラウザを起動する必要があるが、それに使うリソースが無視できなさそう
再開について
tar ball をローカルで作る案
アップロードの再開は難しくて最初からやるにしても、その前段階を途中から再開できないかという案。
-
page documents を読み込む
-
全てのファイルを含んだ tarball を「どこか」に保存
- tarball への追加は途中から行うことができるので、1 を全て読み込む必要はない
-
tarball を「どこか」から読み込み、gz に圧縮
-
アップロード
複数のファイルを一個ずつ圧縮するのではなく、一つのファイルを圧縮するため、圧縮部分が zip よりも早く終わるのではないかという予測。
検証
https://dev.growi.org/66704fdc96a1f7ff8aba51f6
tarball を保存する「どこか」をどこにするか
- tmp dir (local fs)
- コンテナが再起動したときに消えてしまう
- persistent volume
- nfs 的な何か
- S3 / GCS を NFS マウント
- cli ツールとして開発し、更にNFS マウントした環境を用意する案
- こんな感じのものを開発
- OSS 版 GROWI サーバーががんばるシンプル構成
- GROWI サーバーから require('child_process').exec
- GROWI.cloud
- cli を起動して任務完了したら終わるシングルプロセスコンテナのように利用
一旦見送る理由
- 中断された際に、tarball へのファイル追加が再開可能な区切りの良い状態で終わる tar のライブラリがない
- tarball へのファイル追加の再開をサポートしているライブラリがない
ため、再開する際にバイト単位のファイル操作が必要となる。(tar のファイルデータは 512 バイト単位で区切られており、やろうと思えばそれを頼りに途切れたデータを取り除いて再開できなくはないが、勧められているかは怪しい)
tar.gz を分割してアップロードする案
https://dev.growi.org/66791ca13f87616b2825ce78
一旦見送る理由
tar の EOF をいじるイレギュラーな操作が必要 (これが正当化されているソースが見つけられていない) だったり、gcs へのアップロードサイズの制限を突破する方法がなかったりと懸念点が多いため、見送る。
不揮発性 fs にアップロードするファイルを一時的に保持する案 (採用)
mongo から読み取った Page の body を md/pdf で fs に保存 (pdf の場合は変換が必要) し、export が終了したら削除する。
- OSS GROWI: fs の特定の path に読み書きする
- GROWI.cloud: 上記 path に Cloud Storage FUSE external_link をマウント
圧縮部分は再開することができないが、mongo からのファイル読み込み・pdf への変換中に中断された場合はそれを再開することができる。
圧縮部分についての再会可能性が必要になった場合は、また上に記載の別の案を再検討してみる。
リソースについて
GROWI サーバーで処理しない案
- 別コンテナで開発
- GROWI OSS 版では GROWI サーバーから別アプリのコンテナを起動するのは困難
- GROWI.cloud では別アプリコンテナがたくさん起動しているのはリソース面で不利
- AWS Lambda / Cloud Functions 的な serverless
- GROWI.cloud はこちらから処理を設定できるが、OSS 版ではユーザに設定してもらう必要が出てくる