GCSからS3へのデータ転送 ~GCPに慣れていない人向け~
とある事情でGCSからS3へ巨大なデータを転送する必要があり、かつ、それをGCPに慣れていない人向けにご連絡する必要がありまして、記録です。2019年9月版です。
前段:GCS→S3はレア?
Amazon Web Service (AWS) の S3 と、Google Cloud Platform (GCP) の Google Cloud Storage (GCS) は両方ともクラウドストレージです。それぞれ一長一短ありつつも、便利でとっつきやすいサービスとしてかなり利用されていて、データ分析界隈でも巨大なデータはだいたいどちらかに置いてあります。
さて、このどちらを使っているかは、もともとどちらのプラットホームを使っているかにだいたい依存していると思うのですが、両者の間でデータを相互に行き来させることはしばしば発生するようで、「GCS S3 転送」などで検索すると沢山記事が出てきます。が、よくみてみるとそのほとんどが S3 から GCS への転送。確かに、かなり先発していたAWSに比べて、GCSはここ5年くらいで急速に伸びてきたサービスですから、現状はS3に置いてあって、それをGCSに持ってこようというニーズの方が大きいのかな、などと思っていますが、それにしても少ない。
さらに、S3 → GCS では、GCSのメニューに「転送」というそのまんまのメニューがあって、ボタンをぽちぽち押していくと強烈なスピードでS3のデータをGCSに転送してくれるサービスがあったりします。しかし、逆はどれだけ探しても見つかりません。なんでかな?と思うに、GCPユーザーとAWSユーザーではITリテラシ、クラウドリテラシのレベルが違うんじゃないかな、と。元々のAWSユーザーはリテラシが高く、ファイル転送など誰に聞かなくてもすぐできちゃうからなんじゃないか。AWSのサービスは非常に柔軟で、何でもかんでもカスタマイズできて、痒いところを掻く手が沢山ありますが、その代わりにちゃんと設定ができないと穴だらけになってしまいそう。他方、GCPは結構アバウトで、痒いところにはジャストで手が届かないけれど、普通にやるでしょってことはだいたいやってくれている。既製品をうまく使う様なイメージがあります。AWSがパーツ屋さんでマザーボードからファンから筐体から買ってきて組み立てるモンスターマシンとすれば、GCPは出来合のノートブックという感じ。
でも、最近はITエンジニア以外の人がどんどんクラウドを使うようになってきて、特にデータサイエンティストなど、ITエンジニアほどは知らないけれど、とにかく使い倒したいという人がどんどん流入してきている気がします。そんなとき、なんでもできるけど、知らないと使えない AWS よりかは、制約はいろいろあるけれど、なんとなくでも使える GCP の方が相性がいいな、という印象があります。S3→GCSの転送ツールなんかも、ITエンジニアならそんなものがなくてもコマンドラインでパパッと転送できるんですが、データサイエンティストなどは専用ツールがあると嬉しいですよね。
前提
ということで、この文書の前提は、
・AWSはそこそこ使えるけれど、GCPは全然不慣れ
・GCPにおいてある巨大なデータをS3に転送したい
という前提で書きます。
s3での準備
まず、AWS s3 の側でバケットを用意、また、それへアクセスするためのIAMのユーザーとクレデンシャルを用意します。ここは「前提:そこそこAWSは使える」ということで、お任せ。ちゃんとセキュアにバケットにアクセスするためのIAMを作って下さい。
そのユーザーのクレデンシャルをダウンロードして、Access key ID と Secret access key を入手します。後で使います。
GCPでの作業
次に、データの置いてあるGCSと同じプロジェクトにて、GCEインスタンスを一つ立ち上げます。このインスタンスが、GCS から S3 へのデータ転送を仲介します。
GCPのメニューから、[Compute Engine] → [VMインスタンス] を選択すると、次の画面になるので、[作成]します。
ここで作るインスタンスはデフォルトのままの設定でも構いません。お好みで、イメージやCPU数を変えてもOK。私はDebian系よりCentOSが好きなので、CentOS7を選びましたが、Debianでも全く同じだと思います。また、CPU数は多くすると気持ち転送が速くなります。
インスタンスが立ち上がると、インスタンス一覧の接続のところに[SSH]のボタンが出てくるので、これを押すとコンソールが立ち上がります。
立ち上がったら、AWSのクレデンシャルを、設定ファイル「.boto」に記入します。何にも無いサーバーでは vi が便利ですね。
[user@instance-1 ~]$ vi .boto
.boto ファイルにクレデンシャルを書き込みます。
[Credentials]
aws_access_key_id = MYACCESSKEY
aws_secret_access_key = MYSECRETKEY
MYACCESSKEY と MYSECRETKEY の部分は AWS の IAM で作成したものを入力して下さい。
そして、転送のコマンドを入れます。
[user@instance-1 ~]$ gsutil -m cp gs://MYGCSBUCKET/HEADER_* s3://MYS3BUCKET/
MYGCSBUCKET はGCSの転送元バケット、MYS3BUCKETは転送先、HEADER_* は転送するファイル名です。アスタリスクで複数選択できます。gsutil cp は -m オプションで並列コピーできるので、上のインスタンス作成でCPU数が多めのインスタンスにしておくと沢山を並行して作業するのですが、通信の制約でしょうか、そんなには速くなりません。
転送には非常に時間がかかるので、画面を立ち上げっぱなしにできない環境でしたら、screenを使ったり、nohup で実行したりするとよいと思います。
EC2でもできるのでは?
今回は GCP でインスタンスを立てて実行しましたが、EC2 に慣れている方でしたら、同じことを EC2 でもできると思います。EC2 でインスタンスを立てて、GCP の認証を通してあげれば、EC2 から GCS を見ることができるので、それをS3に落としてあげればOKだと思います。GCPでインスタンスを立ち上げると、デフォルトでCGSへのアクセス権が設定されていたり、gsutil がインストール済みだったりするのが便利だと思うのですが、EC2 でもおそらく同じなのでは?(s3cmdなどを使えばいいのでしょうか?)
まとめ
・S3→GCSはGCPに専用の転送ツールがあって、これを使うと便利で速い。
・GCS→S3はサーバーを立てて転送する。
・GCPでインスタンスを立ち上げれば、デフォルトで gsutil がインストールされており、認証も通っているので、s3のクレデンシャルだけ教えてあげればすぐに転送できる。