Pub / Subメッセージを圧縮する方法とさらに、大量のお金を節約する

2020年12月29日)

圧縮は、大量の問題を解決するために使用できるトリックです。多くの場合、ツールはコンテンツを透過的に圧縮します。最近のほとんどのブラウザはgzip圧縮されたHTTPペイロードを要求し、一部のファイルシステムは、ユーザーが要求することなくブロックを圧縮するように構成できます。

よく知られたユースケース以外にも、圧縮を活用することにより、効率を改善したり、コストを節約したりするためのさまざまな機会。一般的なユースケースを知っておくと便利です。そうすれば、これらの機会が発生したときに利用できます。

ログの移行

最近の例として、私のチームは1つのElasticsearchクラスターからログを移行していました。別のものに。 BigData™ではありませんが、このクラスターには100億のログエントリまたは約60TBの生のJSONがありました。

このような長期にわたる大規模な移行に取り組んだ経験がある場合は、次のようなプロセスを構築する必要があります。できるだけ頻繁に「ゲームを保存」することができます。つまり、エクスポートプロセスを構築して実行し、発生する問題をすべて処理してから(約束します!)、インポートプロセスに問題なく進むことができます。エクスポートと同様に、インポートプロセスも失敗します。したがって、インポートプロセスも簡単に再実行できるはずです。

GoCardlessシステムの負荷全体で使用されるため、 Google Pub / Sub は、この問題に自然に適合します。 Googleのマーケティングキャッチフレーズは、理想的な分離プロセスを説明するために作成されたように聞こえます。

Pub / Subは、イベントを生成するサービスを、イベントを処理するサービスから分離する非同期メッセージングサービスです。

Pub / Subでは、トピックにメッセージを公開します。各トピックには多くのサブスクリプションを含めることができ、コンシューマーはそこからメッセージをプルできます。最も簡単に言えば、移行は次のようになります。

  1. 元のクラスターから(インデックスごとの)Pub / Subトピックにログをエクスポートする
  2. Pub / Subサブスクリプションを構成するイベントを保持するには(retain\_acked\_messagesを設定、メッセージの再生とパージを参照)、イベントを再生できるようにします。インポートがうまくいかない
  3. トピックサブスクリプションからメッセージをプルしてログをインポートする

では、これは圧縮と何の関係があるのでしょうか。ほとんどのクラウドサービスと同様に、Pub / Subは使用量に応じて課金されます。つまり、サービスを通じてプッシュするデータに比例した料金が発生します。

これらの料金は次のとおりです。

  • 配信されたTiBあたり40ドル、パブリッシュおよびサブスクライブに適用
  • Google Compute Engineネットワークレート(複雑になるため、これらは無視します)
  • シーク関連のメッセージストレージメッセージをGiB月あたり0.27ドルで保持します

最初の試行で正常にインポート/エクスポートする最良の場合(これは発生せず、発生しませんでした)、 2 x $ 40 x 60TB =メッセージ配信の$ 4,800 は、パブリッシュとサブスクライブの両方に適用されるため、課金されます。移行の進行中にメッセージを2週間保持すると、メッセージの保存に 0.5 x $ 0.27 x 60,000GB = $ 8,100が請求されます

これにより、移行を実行するための下限$ 12,900が残ります

現在、GoCardlessは貧弱ではありません。また、原則として、通常はインフラストラクチャのコストよりもエンジニアリング時間を最適化する必要があります。

ただし、最小限の労力でコストを削減できる場合は、そうする必要があります。

公開圧縮されたメッセージ

この目的のために、Pub / Subに公開したメッセージの圧縮をサポートするために、移行ツール(elastic-toolbox)に小さな変更を加えました。

エラー処理が削除された、これは公開メソッドであり、シリアル化後に圧縮を適用します。

条件付きでメッセージペイロードに圧縮を適用します

圧縮自体は非常に単純で、ほぼ完全に可観測性コードです:

可観測性を備えたgzip圧縮の実装

節約量は圧縮率(圧縮/元のバイト)に比例するため、どのように私たちのデータは圧縮可能です。

JSONログは、次のように非常に圧縮可能である可能性があります。

  • ログは、重複排除できるJSONキーの多くを共有します(kubernetes.pod\_name
  • 一般的なログフィールドの値は非常に頻繁に発生する可能性があります(kubernetes.labels.namespace

変更されたelastic-toolbox 3つの異なるインデックスの同時エクスポートを実行するには、elastic\_toolbox\_export\_pubsub\_write\_compression\_ratioプロメテウスメトリックを使用できます(compress上記の方法)圧縮率のヒートマップを作成するには:

Compressedバイト/元のバイト、常に0%

このヒートマップは、すべてのメッセージが元のサイズの最大30%。ログのコーパス全体で測定すると、平均で 〜12%の圧縮率になります。つまり、1GiBのログはわずか120MiBになります。

元の12,900ドルの請求額は、12%x 12,900ドル= 1,548ドルになりました。

これは、約11,500ドル節約できたことを意味します。

この Raintankスナップショット:elastic-toolboxcompression でデータを自分で調べてください。

次のステップ?フルタイムで適用します。

最も明白な次のステップは、これをログパイプラインに常に適用することでした。コンテナログをPub / Subに直接送信し、サブスクリプションからElasticsearchにプルすると、同じ圧縮戦略を適用する fluentd フィルターを簡単に作成できます。

同僚のBenは、節約した金額を追跡するためのすばらしいダッシュボードを作成しました。これは、月に数千:

ログがログパイプラインに入るときにログを圧縮することによる節約

圧縮は他にどこで役立ちますか?

クラウド環境で作業している場合、次のような機会がたくさんあります。データを圧縮してコストを節約します。

ログ以外に、GoCardlessのもう1つの例は、 draupnir というツールです。このサービスは、負荷テストとフォレンジック分析(クエリプラン予測など)のために、本番データベースのコピーをホストします。 Google SSDストレージの費用はTiB /月あたり187ドルです。つまり、 5TBPostgresのすべてのコピーの費用は月額1,000ドルです。

Draupnirは、ユースケースに応じて、一度に複数のコピーをホストする場合があります。 btrfs圧縮を有効にしてファイルシステムブロックを透過的に圧縮し、を使用できるようにすることで、コストを節約できます。 SSDの容量が他の方法よりも最大70%少ない

圧縮がコスト削減に限定されていると思ったら、間違いです。人々が大規模なバックフィルを実行したり、新しいデータベースインデックスを構築したりすると、ときどきマイクロ停止が発生するため、Postgres WAL圧縮を有効にすることで問題を解決しました( Postgresの十分に活用されていない機能:WAL圧縮、または Postgresの先行書き込みログドキュメント)。

データベース操作が原因で、大量のWALチャーンが発生しました。 WALをディスクに書き込む間、レプリカはストールします。 WALストリームを圧縮することで、 IOスパイクを大幅に削減し、レプリカが問題なくストリームを処理できるようにしました

他にも例はありますが、これは良い絵になると思います。

これはどのように役立ちますか?

圧縮はトレードオフであり、私たちが下す決定です。 CPUを、より高価または利用可能性が低い可能性のある別のリソースと交換します。 CPU、メモリ、またはネットワーク帯域幅に割り当てられる値は絶えず変化するため、ケースバイケースでこの計算を行う必要があります。

この投稿は、コンピューティングリソースとビルドまでの時間の両方で、圧縮はそれがもたらす節約によって大幅に上回りました。すべての状況で同じ経済性が得られるわけではありませんが、どちらの方法を決定するのにも数分のナプキン計算が必要です。

このケーススタディが、標準的で退屈なユースケース以外の圧縮の検討を促し、役立つことを願っています。自分のシステムに適用できる機会を見つけるために。

この投稿について Hackernews

最初は https:// blogで公開されました.lawrencejones.dev 2020年12月29日。