Webサービスとアプリケーションをサポートするために私が何度も見た実証済みのアーキテクチャがあります。
- データストレージ用のPostgreSQL
- バックグラウンドジョブキュー(および一部の限定されたアトミック操作)を調整するためのRedis
Redisは素晴らしいですが、このスタックの最も一般的なユースケースは実際にはPostgreSQLのみを使用して実現できると言ったらどうでしょうか。
シナリオ1:ジョブキュー
おそらく、私が見たRedisの最も一般的な使用法は、Webサービスからバックグラウンドワーカープールへのジョブの送信を調整することです。アイデアは、ある種のバックグラウンドジョブを実行したいという願望を記録し(おそらく何らかの入力を使用して)、多くのバックグラウンドワーカーのうちの1人だけがそれを実行するようにすることです。Redisは、データ構造に豊富なアトミック操作のセットを提供するため、これを支援します。
ただし、バージョン9.5のリリース以降、PostgreSQLには
SELECT…FOR…ステートメント用のSKIP LOCKED関数 があります( ドキュメントはこちら)。このオプションを指定すると、PostgreSQLはロック解除待機を必要とする行を単に無視します。
バックグラウンドワーカーの観点からこの例を見てみましょう。
BEGIN;
WITH job AS (
SELECT
id
FROM
jobs
WHERE
status = 'pending'
LIMIT 1
FOR UPDATE SKIP LOCKED
)
UPDATE
jobs
SET
status = 'running'
WHERE
jobs.id = job.id
RETURNING
jobs.*;
COMMIT;
FOR UPDATE SKIP LOCKEDが指定されている場合、行レベルのロックはSELECTから返されたすべての行に暗黙的に設定されます。また、SKIP LOCKEDを指定したため、このステートメントは別のトランザクションでブロックされません。処理する準備ができている別のジョブがある場合、それは返されます。このコマンドを実行する複数のワーカープロセスが、行レベルのブロックのために同じ行を受け取る心配はありません。
この方法の最大の注意点は、このキューを実行しようとしているワーカーが多数あり、多数のジョブがそれらを提供している場合、ジョブ間をジャンプしてロックを取得しようとするために時間がかかる可能性があることです。実際には、私が取り組んだほとんどのアプリケーションには12人未満のバックグラウンドワーカーがいて、コストが大きくなる可能性はほとんどありません。
シナリオ2:アプリケーションブロック
サードパーティのサービスとの同期ルーチンがあり、そのインスタンスが1つだけ必要で、すべてのサーバープロセスの特定のユーザーに対して機能するとします。私が見たもう1つの一般的なRedisアプリケーションは、分散ロックです。
PostgreSQLは、推奨ロック(推奨ロック)を使用してこれを実現することもでき ます。アドバイザリロックを使用すると、PostgreSQLが内部で使用するのと同じロックメカニズムを、独自のアプリケーション定義の目的で使用できます。
シナリオ3:Pub / Sub
最後に最もクールな例を残しました。アクティブなクライアントにイベントを送信することです。たとえば、新しいメッセージを読むことができることをユーザーに通知する必要があるとします。または、データが利用可能になったときにクライアントにデータを転送したい場合もあります。通常、WebSocketはこれらのイベントのトランスポート層であり、RedisはPub / Subエンジンとして機能します。
ただし、バージョン9以降、PostgreSQLはこの機能をLISTENおよび NOTIFY演算子で提供します。 ..。すべてのPostgreSQLクライアントは、任意の文字列である特定のメッセージチャネルにサブスクライブ(LISTEN)できます。他のクライアントがこのチャネルを介してNOTIFYメッセージを送信すると、他のすべてのサブスクライブされたクライアントに通知されます。オプションで、小さなメッセージを添付できます。
RailsとActionCableを使用している場合は、PostgreSQLの使用もすぐにサポートされます。
PostgreSQLを最大限に活用する
Redisは基本的にPostgreSQLとは異なるニッチを占めており、PostgreSQLが目指していないことに優れています。例としては、TTLを使用したデータのキャッシュ、一時的なデータの保存と処理などがあります。
ただし、PostgreSQLは、別のSQLデータベースまたはORMの背後にある不思議なエンティティの観点からアプローチした場合に予想されるよりもはるかに強力です。
Redisを使用しているものがPostgreSQLにとっても良いものになる可能性は十分にあります。複数のデータサービスに依存することで、Redisを廃止し、運用コストと開発の複雑さを節約する価値があるかもしれません。