Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A key like_a_folder_is_returned_from_s3

79 views

Published on

2020/08/26
AWS LT会@オンライン 資料
同内容のqiita : https://qiita.com/Takayuki_Nakano/items/716362baf8ffe31d632f

Published in: Software
  • Be the first to comment

  • Be the first to like this

A key like_a_folder_is_returned_from_s3

  1. 1. S3からフォルダのようなkeyが返 ってくる ユニークビジョン株式会社 中野 隆行
  2. 2. 発端 以前担当していた、とある受託システムでのこと。 このシステムはユーザーが画像をアップロードする機能があった。 アップロードされた画像はとあるバケットに user_images/{user_id}/{image_id} という key で保存される。 ちなみに開発言語は ruby
  3. 3. ある時、保存されているユーザー画像の key の一覧が欲しくなりました。 require 'aws-sdk' client = Aws::Credentials.new( region: 'REGION', access_key_id: 'YOUR_ACCESS_KEY', secret_access_key: 'YOUR_SECRET_KEY' ) client.list_objects(:bucket => 'some-bucket', :prefix => 'user_images/').contents.each do |object| p object.key end
  4. 4. 得られた結果はこんな感じ user_images/ user_images/1/1 user_images/1/2 user_images/2/3 当時の私の考え 「ユーザー 1 が 画像 1, 2 を持っていて、」 「ユーザー 2 が 画像 3 を持っている。」 「へー、フォルダのパスも key として取得してくるんだー。」 「・・・。」 「邪魔だし削除して使わなきゃ」
  5. 5. フォルダのkeyが取れるなら user_images/ user_images/1/ user_images/1/1 user_images/1/2 user_images/2/ user_images/2/3 どうしてこうならないのだろう? もしかして単純にフォルダの key が取得できているわけではないのか? というわけで「S3 フォルダ」で検索!
  6. 6. 出てくる記事はこれ Amazon S3における「フォルダ」という幻想をぶち壊し、その実体を明らかにす る 記事によると > Amazon S3には実はフォルダという概念は無い > Amazon S3の基礎技術は、単純なKVS(Key-Value型データストア)でしかあ りません。
  7. 7. つまり、「hoge」 とだけ書いたテキストファイルをとあるバケットに foo/bar.txt という key でアップロードした場合、その実態は。 バケット └ foo └ bar.txt <- "hoge" こんなファイル構造ではなく。 key value foo/bar.txt hoge ただ単純にこのような key value で保存されているだけなのだという。 なので、bar.txt を削除した場合 S3 的には foo/bar.txt を削除したことになるので foo というファイルもコンソールから消える。
  8. 8. そして、フォルダの様に見えるものは key の / を判断して 階層構造のように見せてくれているだけ。
  9. 9. なるほどなー。フォルダなんてものは S3 に無いんだ。 ん?じゃあ何だこのボタン。
  10. 10. やっと本題 先程の「S3 にフォルダは無い」という話に真っ向から立ち向かう コンソールに居座るこの これこそが当初の目的である なんか返ってきたフォルダっぽい key の原因なのです。
  11. 11. フォルダ(のようなもの)の正体 この を押して実行すると、 指定したフォルダ名を key にした size 0 のファイルが作成されるようです。 これが list_objects に引っかかる。
  12. 12. つまり、この場合 user_images/ はコンソールから で作成されたファイルということ。 うーん、たしかにそんなことをしたかと聞かれると否定できないぞ!? user_images/ user_images/1/1 user_images/1/2 user_images/2/3
  13. 13. そして、実際には回収されなかった赤字のファイル(っぽいもの)の key これは user_images/1/1 や user_images/2/3 はシステムからアップロードされたため 表示されないのである。 user_images/ user_images/1/ user_images/1/1 user_images/1/2 user_images/2/ user_images/2/3
  14. 14. 結論 コンソールから作成したフォルダ(っぽいもの) が list_objects で回収される コンソールから作成したフォルダ(っぽいもの)と ファイルのアップロードででき た見せかけのフォルダ(っぽいもの) が混在すると list_objects が非常に使いづら くなる。 少なくとも、同じ階層のフォルダ(っぽいもの)の作成方法は統一しよう。
  15. 15. 追記 どうもフォルダっぽく見えるファイルは key が / で終わるので、 これでフィルタリングできるかもしれない。 そもそも、これだってファイルなのだから delete_object とかなんとか言って 削除すれば解決なのかも。
  16. 16. おまけ せっかくなので で出来たファイルを取得。 key が取れてるのだから取れるだろう。 obj = client.get_object(:bucket => 'some-backet', :key => 'baz/') p obj.content_length # => 0 p obj.body # => #<StringIO:0x00007fbeddc347d8> p obj.body.read # =>
  17. 17. おまけ2 じゃあ空ファイルアップしたらどうなるのか? client.put_object( :bucket => 'some-backet', :key => 'hoge/', :body => "" ) 適当に空文字でも送りつけてみるか。
  18. 18. 出来た。 開くと「このパスにオブジェクトはありません。」の表示。 使いみちは謎。
  19. 19. では 一緒に働く仲間を 募集しています! <募集職種> 【エンジニア】 ⮚ 凄腕の技術者集団!Belugaシリーズの開発 ⮚ レベルアップしたいエンジニア募集!! 【ディレクター】 ⮚ ソーシャルメディア統合管理ツール 「Beluga」の企画、マネジメント ⮚ SE・プログラマーなどシステム開発、 ディレクション経験者歓迎!!
  20. 20. エントリーお待ちしております! 募集媒体・・・・ ⮚ Green、paiza、Wantedly 採用情報はTwitter (@uv_recruit)を ご確認ください! UVリクルートページは こちら🐬

×