ファイルシステムに画像を保存する方法
-
08-07-2019 - |
質問
現在、InnoDBテーブルにBLOBとして保存されている画像(最大6MB)があります。 データのサイズが大きくなるにつれて、夜間のバックアップはますます遅くなり、通常のパフォーマンスを妨げています。
したがって、バイナリデータはファイルシステムに移動する必要があります。 (ファイルへのポインターはDBに保持されます。)
データには関係のようなツリーがあります:
- main site
- user_0
- album_0
- album_1
- album_n
- user_1
- user_n
etc...
ここで、ディレクトリ構造全体にデータを均等に分散させます。どうすればこれを達成できますか?
MD5( 'userId、albumId、imageId');
を試して、結果の文字列をスライスしてディレクトリパスを取得できると思います:
/var/imageStorage/f/347e/013b/c042/51cf/985f7ad0daa987d.jpeg
これにより、最初の文字をサーバーにマップし、ディレクトリ構造を複数のサーバーに均等に分散できます。
ただし、これはユーザーごとに画像を整理しません 、1つのアルバムの画像を複数のサーバーに分散する可能性があります。
私の質問:
ユーザー/アルバムのデータをまとめながら、バランスのとれた方法でファイルシステムに画像データを保存する最良の方法は何ですか?
私は正しい方向に考えていますか?または、これはすべて物事を行う間違った方法ですか?
更新:
最高レベルで分割するための md5(user_id)
文字列スライスに行きます。
そして、すべてのユーザーデータを同じバケットに入れます。これにより、ユーザーデータを近くに保存したまま、データを均等に分散できます。
/var - imageStorage - f/347e/013b - f347e013bc04251cf985f7ad0daa987d - 0 - album1_10 - picture_1.jpeg - 1 - album1_1 - picture_2.jpeg - picture_3.jpeg - album1_11 - picture_n.jpeg - n - album1_n
ディレクトリごとのアルバム数を少なくするために、後ろから分割されたalbumIdを使用すると思います(ほとんどのユーザーには必要ありませんが)。
ありがとう!
解決
ユーザーIDを背後から分割するだけです。例:
UserID = 6435624
Path = /images/24/56/6435624
バックアップについては、MySQL Replicationを使用してスレーブをバックアップできます バックアップ中の問題(ロックなど)を避けるためのデータベース。
他のヒント
ファイル名を異なるディレクトリに配布することに関する1つのこと、md5ファイル名を異なるサブディレクトリに分割することを検討する場合(一般的には良い考えです)、完全なハッシュをファイル名として保持し、最初の数文字をディレクトリ名として複製することをお勧めします。これにより、ファイルの識別が簡単になります。ディレクトリを移動する必要がある場合。
e.g。
abcdefgh.jpg-> a / ab / abc / abcdefgh.jpg
ファイル名が均等に分配されていない場合(ハッシュではない)、均等に分配される分割方法を選択してみてください。最後の文字(ユーザーIDが増加する場合)
一意の画像IDを指定してこの戦略を使用しています
- 文字列を逆にします
- 桁数が奇数の場合、先頭にゼロをゼロで埋めます
- 文字列を2桁の部分文字列に分割します
-
以下のようにパスを作成します
17 >> 71 >> /71.jpg 163 >> 0361 >> /03/61.jpg 6978 >> 8796 >> /87/96.jpg 1687941 >> 01497861 >> /01/49/78/61.jpg
この方法では、各フォルダーに最大100個の画像と100個のサブフォルダーが含まれ、左端のフォルダー間で負荷が均等に分散されます。
さらに、ファイルに到達するには画像のIDが必要であり、他のメタデータを含む画像テーブルを読み取る必要はありません。 ユーザーデータは実際には近くに保存されておらず、IDとパスの関係は予測可能であり、ニーズによって異なります。