AWS SDK のメンテナーが互換性を壊しました。S3 クローンプロバイダーが追いつき、より良い互換性を実装して、回避策を削除できるようにする必要があります。
念のため確認ですが、これはassetsのJS/map/CSSファイルのみに影響し、アップロードには影響しませんよね?
つまり、孤立したファイルのクリアには影響しますか?
ちなみに、この問題はDiscourseを管理パネルから更新する際にも影響すると思いますか?
実際、管理パネルからのアップデートは私には失敗したので、リビルドを行ったのです。
はい、アセットのみです。
このrakeタスクですか?いいえ。
ただし、AWS SDK全体の変更により、互換性のないクローンを使用しているユーザーにとっては、これも壊れている可能性があります。
私はそれは間違っていると思います。なので、clean up uploadsもオフにする必要がありそうです。それを行うとエラーが発生しますが、ビルドできなくなるわけではありません。
それは可能性が高いです。これは、他のプロバイダーが追いつくまでの間、この問題を解決するために"skip_s3_delete"設定を追加する必要があるかもしれません。そして、おそらく、壊れていることがわかっているプロバイダーには自動的に設定するのが良いでしょう。
そのラクトリックは、期限切れのアセットが削除される唯一の方法ですか?
Discourseのコアサーバーにアセットを保持するオプション(S3に保存しない)を追加してみてはどうでしょうか?
アップロードや孤立したファイルの削除プロセスに影響がない限り、実行可能なソリューションのように思えます。
はい。これは大したことではありません。時々更新される通常のサイトでは、あまり違いは見られないでしょう。
この件を気にする人は、独自のライフサイクルルールを設定できます。
clean up uploads = false を設定することが、すでにそれではありませんか?
笑、いいえ。Discourseは公式にS3をサポートしています。私はアップロード用のS3互換オブジェクトストレージプロバイダーの設定ウィキを開始し、クローン互換性を高めるためのいくつかのトグルを追加するために尽力しましたが、今日、それ以上の時間を投資する計画は全くありません。
コミュニティが互換性を高めるいくつかのPRを送信したい場合、それらはデフォルトでオフになりますが、すぐにすべてのクローンに対する公式サポートがコアで見られることを期待しないでください。
FWIW、Digital Oceanはバックアップの削除や、なくなったアセットの期限切れに問題がないようです。
壊れているプロバイダーの場合、不要なアセットが問題を引き起こすまでにはかなりの時間がかかるでしょう。ストレージにお金を払っている場合、巨大なデータベースやすべてのアップロードを含む、たくさんのバックアップを保持することは、かなりの問題になる可能性があります。
こんにちは。Backblaze の最高技術エバンジェリスト、パット・パターソンです。このスレッドにたどり着いたのは、セルフホスト型の Discourse フォーラムの概念実証を構築しており、Backblaze B2 をバックアップやアップロードに使用するようにフォーラムを設定している際に、まさにこの問題に遭遇したからです。
AWS_REQUEST_CHECKSUM_CALCULATION と AWS_RESPONSE_CHECKSUM_CALCULATION を WHEN_REQUIRED に設定することは、ファイルのアップロードとダウンロードの基本的なケースでは役立つ回避策ですが、これではカバーできないシナリオがいくつかあることを知っておくと役立ちます。それらには以下が含まれます。
- ファイルの削除 - Discourse は、S3 の
DeleteObjects操作を使用して、複数のファイルを 1 回の API 呼び出しで削除しています。これは正しい方法です。 - オブジェクトロックが有効になっているバケットへのファイルのアップロード。
問題は、これらの操作ではチェックサム(Content-MD5 ヘッダーまたは新しいチェックサムヘッダーのいずれか)が(単にサポートされているだけでなく)必須であり、これにより現在の AWS SDK が新しいチェックサムヘッダーを提供するということです。私の知る限り、これをオーバーライドして、SDK が以前のように Content-MD5 を提供させる方法はありません。
エンジニアがこれらの問題を解決するために取り組んでいます。それまでの間、最善の軽減策は、aws-sdk-s3 gem のバージョン 1.177.0 以前を使用することです。
PoC デプロイメントで AWS SDK gem のバージョンをダウングレードしようと、Gemfile を編集して以下のように置き換えました。
gem "aws-sdk-s3", require: false
gem "aws-sdk-sns", require: false
を
gem "aws-sdk-core", "~> 3.215.1", require: false
gem "aws-sdk-kms", "~> 1.96.0", require: false
gem "aws-sdk-s3", "~> 1.177.0", require: false
gem "aws-sdk-sns", "~> 1.92.0", require: false
しかし、私の bundle の腕前はそれほど得意ではなく、以下のエラーでデプロイメントを壊すことしかできませんでした。
/var/www/discourse/config/initializers/100-sidekiq.rb:69:in `<main>': undefined method `logger=' for module Sidekiq (NoMethodError)
Sidekiq.logger = Logger.new(nil)
^^^^^^^^^
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.2.2.1/lib/rails/engine.rb:689:in `load'
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/railties-7.2.2.1/lib/rails/engine.rb:689:in `block in load_config_initializer'
...
何か重要な手順を見落としたようです。
DO の友人を非難するつもりはありませんが、彼らはサービスを更新して、API 呼び出しがサポートされていないチェックサムのために拒否されるのではなく、新しいチェックサムヘッダーを単純に無視することでこれを実行しました。
彼らのインシデントレポート には次のように記載されています。
注意: Spaces は現在、アップロード要求の一部として AWS CLI および AWS SDK によって送信されるデータ整合性チェックサムを検証していません。
私たちは、API クライアントが提供したチェックサムと一致しない可能性のあるデータを単に受け入れて保存することは悪いことだと判断しました。
投稿ありがとうございます!
ええ、そしてAWS SDKのメンテナーは私たちに冷たい態度をとるばかりです
B2チームもこの問題に気づいたようで嬉しいです。
私の応急処置は以下の通りです。
app.ymlのS3関連の設定をすべてコメントアウトし、Discourseの再構築に成功しました。これにより、サイトに以前アップロードされたファイルへのアクセスには影響がなく、この期間中にアップロードされた添付ファイルはローカルに保存され、問題は発生しません。
ところで、アセットをDiscourseコアサーバーに保持するオプション(S3に保存しないという意味です)を追加するのはなぜでしょうか?
???
Discourseは標準でそのように動作します。オブジェクトストレージサービスにアセットを送信するには、明示的にオプトインする必要があります。
つまり、Discourse コアアセット(JS、CSS など)をローカルサーバーに保持するオプションがあると良いかもしれません。同時に、ユーザーがアップロードしたファイルのみが S3 に保存されることになります。
「use_s3」を有効にしないことでそれが可能になりますが、小さいので、そのままプッシュして無駄なスペースを気にする必要はないでしょう。
正しく理解するのを手伝ってもらえますか?
app.yml で DISCOURSE_USE_S3: false を設定するという意味ですか?
Discourseサーバーがアジアにあり、B2には米国にしかサーバーがないため、これを実行したいと思います。
また、今回、AWS SDKの問題はアセット管理に関連していますよね?
もしアセットをローカルサーバーに保存すれば、この問題(状況を正しく理解していれば)を回避できるかもしれません。
問題は、S3 からアセットを削除することに関連しています。未使用のアセットを削除しようとする行を削除するだけで、現在は機能します。そして、すぐに問題は解決されるようです。これが最も簡単な解決策です。お勧めします。それが私の最高の無料の回答です。
ありがとうございます。大変参考になりました!
これは、S3 API の定義で、DeleteObjects 操作 が、例えば PutObject が false に設定している のとは対照的に、httpChecksum.requestChecksumRequired が true に設定されているためです。そのため、SDK はチェックサムが 必要 であるため、WHEN_REQUIRED を尊重しています。
すべての AWS SDK は、最小限の追加コードで API 定義から生成されるようになりました。コードは DeleteObjects がチェックサムを必要とすること、そしてそれを実行する現在の方法は、新しいチェックサムのいずれかを使用することであり、Content-MD5 ではないことを認識します。
残念ながら、AWS は、以前のように ‘Content-MD5 を使用する’ という設定を提供するとは考えていませんでした。彼らは、このような変更を行う際に、サードパーティのオブジェクトストレージエコシステムを考慮しません。なぜなら、彼らは実際には必要としないからです。このような問題が修正されるのは、偶発的に、どこかのコーナーケースで彼ら自身のサービスを台無しにした場合だけです。
B2には米国にのみサーバーがあります
アジアにお住まいの方にはあまり関係ありませんが、記録のために、ヨーロッパ(オランダ、アムステルダム)にもデータセンターがあり、今年初めからはカナダ(トロント)にも設置しました。
約束はできませんが、アジアの拠点も definitely 検討しています。
また、CDNを使用している場合は、オリジンサーバーがどこにあるかはあまり関係ありません。
その通りです!
Backblaze は x-amz-checksum-crc32 をサポートしていません。Discourse の新しい AWS SDK バージョンでは、これがデフォルトで有効になっている可能性があります。
そこで、アプリに入り、
./launcher enter app
現在のバージョンの AWS SDK をアンインストールしました。
gem uninstall aws-sdk-s3 aws-sdk-core aws-sdk-kms
そして、Backblaze の担当者が動作すると言っていたものをインストールしました。
gem install aws-sdk-core -v “~> 3.215.1”
gem install aws-sdk-kms -v “~> 1.96.0”
gem install aws-sdk-s3 -v “~> 1.177.0”
その後、アプリを再構築したところ、動作しました!