まず第一に、画像 ID を通じてユーザー UID を逆チェックするこのアプリケーションには次の要件があります。
クエリ速度が十分に速い必要があります
すべてのデータはメモリに保存する必要があります。できれば EC2 の高メモリ モデル (17 GB または 34 GB、68 GB は無駄すぎます)
永続化をサポートします。サーバーの再起動後にウォームアップする必要があります
まず第一に、彼らはデータベース ストレージ ソリューションを拒否し、KISS 原則 (Keep It Simple and Stupid) を維持しました。使用しない データベースの更新機能、トランザクション機能、関連クエリなどの優れた機能がないため、これらの使用しない機能のためにデータベースを選択して維持する必要がありません。
そこで彼らは Redis を選択しました。Redis は永続性をサポートするインメモリ データベースです。すべてのデータはメモリに保存され (VM は忘れてください)、最も簡単な実装は Redis の String 構造を使用することです。キーと値店がやります。
SET media:1155315 939 GET media:1155315 > 939
このうち、1155315 がピクチャー ID、939 がユーザー ID なので、それぞれのピクチャー ID をキー、ユーザー uid を値として、キーと値のペアとして保存します。そこで、上記の方法でデータを保存したところ、100万枚のデータで70MB、3億枚の写真で21GBのメモリを使用するテストが行われました。予算の17GBと比べると、やはり使い過ぎです。
(NoSQLFan: 実際、ここに最適化ポイントが見られます。キー値の前にある同じメディアを削除し、数値のみを保存できます。これにより、キーの長さが短縮され、メモリが削減されます。キー値のオーバーヘッド [ 注: Redis のキー値は文字列から数値に変換されないため、ここに保存されるのはメディアの 6 バイトのオーバーヘッドのみです:]。実験後、メモリ使用量は次のように削減されます。 50MB、合計メモリ使用量は 15GB で、ニーズは満たしていますが、その後の Instagram の改善がまだ必要です)
そこで、Instagram の開発者は、Redis の開発者の 1 人である Pieter Noordhuis に最適化計画について尋ねました。 、そして、答えはハッシュ構造を使用するというものでした。具体的な方法としては、データを分割してハッシュ構造を用いて格納する方法ですが、ハッシュ構造は単一のハッシュ要素が一定数以下の場合に圧縮して格納するため、メモリを大幅に節約できます。これは上記の String 構造には存在しません。構成ファイル内の「hash-zipmap-max-entries」パラメータは、特定の数を制御します。開発者による実験の結果、hash-zipmap-max-entries を 1000 に設定するとパフォーマンスが向上しましたが、1000 を超えると、HSET コマンドによる CPU 消費量が非常に大きくなります。
そこで彼らは計画を変更し、次の構造でデータを保存しました。
HSET "mediabucket:1155" "1155315" "939" HGET "mediabucket:1155" "1155315" > "939"
7 桁の画像 ID の最初の 4 桁をハッシュ構造のキー値として取得することで、各ハッシュの内部には 3 桁のキー (1,000) のみが含まれていることを保証します。
別の実験を行った結果、1,000,000 キーごとに消費されるメモリはわずか 16MB であることがわかりました。合計メモリ使用量も 5GB に削減され、アプリケーションの要件を満たします。
(NoSQLFan: 同様に、ここでも最適化できます。1 つ目は、ハッシュ構造のキー値を純粋な数値に変更し、キーの長さが 12 バイト減少することです。2 つ目は、キーの長さを変更することです。ハッシュ構造のキー値。サブキー値は 3 桁になり、以下に示すようにオーバーヘッドが 4 バイト削減されます。実験後、メモリ使用量は 10MB に削減され、合計メモリ使用量は 3GB になります)
リーリー以上がRedis がメモリを節約する仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。