SlideShare a Scribd company logo
第5回 AWS User Group - Sapporo 勉強会




AWS小ネタ集
欧文印刷株式会社 田名辺健人
2012.02.14

        http://www.flickr.com/photos/mendhak/4271441910/
田名辺 健人(たなべたけひと)
              ソフトウェアエンジニア
              欧文印刷株式会社(東京都)
              2011年11月から札幌でテレワーク
@dateofrock


              札幌・東京コアメンバー
              Ustream担当
              好きなサービスはSQS
AWS小ネタ集
AWS小ネタ集
AWS小ネタ集
Happy Valentine




http://www.flickr.com/photos/pinksherbet/1483193019/
LT(Lady's Happy Valentine
          Talk)
してくれた貴女へ…

      http://www.flickr.com/photos/pinksherbet/1483193019/
NUboard
      Happy Valentine
プレゼント♡
       from 欧文印刷



  http://www.flickr.com/photos/pinksherbet/1483193019/
たまには
  技術の話を
しようと思います
    www
• S3 小ネタ
 •   読み書きのスループットを上げる方法
 •   バケット名にピリオドでハマる方法

• S3実践ネタ
 •   設定ファイル置き場
 •   Pre-signed URLの使い道

• Simpleシリーズ2連発
 •   アプリ内エラー通知はSNSが便利
 •   SimpleDB APIがシンプルじゃない件




           http://www.flickr.com/photos/mendhak/4271441910/
ネ
                  タ
                  作
                  り
                  す
                  ぎ
                  た
                  w

http://www.flickr.com/photos/donsolo/2435421847/
• S3 小ネタ
 •   読み書きのスループットを上げる方法
 •   バケット名にピリオドでハマる方法

• S3実践ネタ
 •   設定ファイル置き場
 •   Pre-signed URLの使い道

• Simpleシリーズ2連発
 •   アプリ内エラー通知はSNSが便利
 •   SimpleDB APIがシンプルじゃない件




           http://www.flickr.com/photos/mendhak/4271441910/
半分
• S3 小ネタ
 •   読み書きのスループットを上げる方法
 •   バケット名にピリオドでハマる方法

• S3実践ネタ


           カット
 •   設定ファイル置き場
 •   Pre-signed URLの使い道

• Simpleシリーズ2連発
 •   アプリ内エラー通知はSNSが便利
 •   SimpleDB APIがシンプルじゃない件




            orz
           http://www.flickr.com/photos/mendhak/4271441910/
• S3 小ネタ
 •   読み書きのスループットを上げる方法
 •   バケット名にピリオドでハマる方法

• S3実践ネタ
 •   設定ファイル置き場
 •   Pre-signed URLの使い道

• Simpleシリーズ2連発
 •   アプリ内エラー通知はSNSが便利
 •   SimpleDB APIがシンプルじゃない件




           http://www.flickr.com/photos/mendhak/4271441910/
Pre-signed URLの使い道


• S3オブジェクトに対して有効期限付きの
  パブリックなURLを生成できる

• Query String Request Authentication
  http://docs.amazonwebservices.com/AmazonS3/latest/dev/
  RESTAuthentication.html#RESTAuthenticationQueryStringAuth
Pre-signed URL
  どんなもの?
GET /images/photo.jpg?
AWSAccessKeyId=0PN5J17HBGZHT7JJ3X82
&Expires=1141889120
&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D
Signature =
URL-Encode(
 Base64(
  HMAC-SHA1(
   YourSecretAccessKeyID,
   UTF-8-Encoding-Of(StringToSign))));
StringToSign = HTTP-VERB + "n" +
    Content-MD5 + "n" +
    Content-Type + "n" +
    Expires + "n" +
    CanonicalizedAmzHeaders +
    CanonicalizedResource;
こんなマンドクサイもの
はSDKに頼ろう
Java

Interface AmazonS3
java.net.URL generatePresignedUrl(java.lang.String bucketName,
                                  java.lang.String key,
                                  java.util.Date expiration,
                                  HttpMethod method)
                                  throws AmazonClientException


Date after5Seconds = new Date();
after5Seconds.setTime(System.currentTimeMillis() + 5 * 1000);

AmazonS3 s3 = new AmazonS3Client(cred);
Url url = s3.generatePresignedUrl(“mybucket”, “images/photo.jpg”,
  after5Seconds, HttpMethod.GET);
Ruby
Class: AWS::S3::S3Object
- (URI::HTTP, URI::HTTPS) url_for(method, options = {})




url = s3.buckets['mybucket'].objects['images/photo.jpg'].
      url_for(:read, :expires => 5)
Ruby

      Ruby
Class: AWS::S3::S3Object
- (URI::HTTP, URI::HTTPS) url_for(method, options = {})




     ステキ!
url = s3.buckets['mybucket'].objects['images/photo.jpg'].
      url_for(:read, :expires => 5)
Pre-signed URL
     実 例
AWS小ネタ集
AWS小ネタ集
AWS小ネタ集
AWS小ネタ集
Pre-signed URLの使い道


• Webサーバーの負荷が劇的に減る!
 • アプリはPre-signed URLを生成してS3
  にリダイレクトするだけ

 • 重たいデータ送出はS3にお任せ!
• S3 小ネタ
 •   読み書きのスループットを上げる方法
 •   バケット名にピリオドでハマる方法

• S3実践ネタ
 •   設定ファイル置き場
 •   Pre-signed URLの使い道

• Simpleシリーズ2連発
 •   アプリ内エラー通知はSNSが便利
 •   SimpleDB APIがシンプルじゃない件




           http://www.flickr.com/photos/mendhak/4271441910/
アプリ内の通知は
  SNSが便利

たとえば例外が投げられたら

 メールでお知らせとか
Java
            例えばUncaughtExceptionHandlerを使う

Thread.setDefaultUncaughtExceptionHandler(
  new UncaughtExceptionHandler() {
     public void uncaughtException(Thread t, Throwable e) {
     " AWSCredentials cred = new BasicAWSCredentials(
          "アクセスキー","シークレットキー");
    "    AmazonSNS sns = new AmazonSNSClient(cred);
    "    String stackTrace = getStackTraceString(e);
    "    sns.publish(new PublishRequest(
  " "    " "arn:aws:sns:ap-northeast-1:xxxxx:sns-test",
  " "    " stackTrace, "Java Exception"));
"       }
" }
);
Ruby on Rails
  例えばApplicationController#rescue_fromを使う

require 'rubygems'
require 'aws-sdk'

class ApplicationController < ActionController::Base
  rescue_from StandardError do |exception|
    topic = AWS::SNS::Topic.new(
      'arn:aws:sns:ap-northeast-1:xxxxx:sns-test'
    )

    topic.publish(exception.backtrace.to_s,
      :subject => 'Rails exception');
    raise exception
  end
end
ただし、
  メッセージは
8kB以内に限るorz
SimpleDB APIが
  シンプルじゃない件

• いや、シンプルすぎて冗長なコードに
 なってしまう

• 素のJDBCはチョット…的な。
• データの型は全部文字列だよ!
SimpleDBの
Data Mapperがホスィ
 Hibernate的な
ActiveRecord的な
    WOのEOF的な
Ruby


SDKにSimpleDBの

Data Mapperが!
class Book < AWS::Record::Base
  string_attr :title
end



Book.new(:title => 'スベらないプレゼン').save
Book.where('title like ?', '%プレゼン%').count



$ rails generate scaffold_controller Book title:string



config/routes.rb:
Myapp::Application.routes.draw do
  resources :books
end



           http://aws.amazon.com/articles/8621639827664165 より
class Book < AWS::Record::Base
  string_attr :title
end



Book.new(:title => 'スベらないプレゼン').save


 Railsと違和感なしに
Book.where('title like ?', '%プレゼン%').count




           統合できる!
$ rails generate scaffold_controller Book title:string



config/routes.rb:
Myapp::Application.routes.draw do
  resources :books
end



           http://aws.amazon.com/articles/8621639827664165 より
Java

• AWS SDK for Javaには低レベルAPIしかな
 いのだよ。

• JPA実装とかはあるけど…
 https://github.com/appoxy/simplejpa
でも実はね…
DynamoDBには
DataMapperが
あるのだよ(;́Д`)
@DynamoDBTable(tableName = "BookTable")
public class Book {
    private Long id;
    private String title;

    @DynamoDBHashKey
    public Long getId() {
    " return this.id;
    }

    @DynamoDBAttribute(attributeName = "title")
    public String getTitle() {
    " return this.title;
    }

    // 以下、setter
}
使用例
     (DynamoDBMapper)
AWSCredentials cred = new BasicAWSCredentials(
  "アクセスキ", "シークレットキー");
AmazonDynamoDB db = new AmazonDynamoDBClient(cred);

DynamoDBMapper mapper = new DynamoDBMapper(db);

Long key = 105L;
Book book = mapper.load(Book.class, key);
book.setTitle("スベらないプレゼン");
mapper.save(book);
mapper.delete(book);
なぜSimpleDBに
 は無いのだ!
ついカッとなって
 つくってみたw
AWS小ネタ集
SimpleDBMapper
     (笑)
@SimpleDBDomain(domainName = "BookDomain")
public class Book {

    @SimpleDBItemName
    public Long id;

    @SimpleDBAttribute(attributeName = "title")
    public String title;

}
使用例
       (SimpleDBMapper)
AWSCredentials cred = new BasicAWSCredentials(
  "アクセスキ", "シークレットキー");
AmazonSimpleDB db = new AmazonSimpleDBClient(cred);

SimpleDBMapper mapper = new SimpleDBMapper(db);

Long key = 105L;
Book book = mapper.load(Book.class, key);
book.setTitle("スベらないプレゼン");
mapper.save(book);
mapper.delete(book);
AWS小ネタ集
DynamoをSimple
に変えただけ(笑)
simpledb-mapper(笑)

•   DynamoDBMapperライクなAPI(笑)

•   でもパクっただけじゃない

    •   1024byteを超えるデータ(Blob)はS3に

    •   @SimpleDBVersionでOptimistic
        Lock(Conditional PUT/DELETE)

    •   検索APIにはナウいFluent Interface採用
ナウな感じに書ける

List<Book> books =
  mapper.from(Book.class).
    where("title", Like, "%スベる%").
   and("price", GreaterThan, 1000).
   orderBy("price", DESC).
   limit(10).
   fetch();
ただし
使用上のご注意

• 自分が現状必要としていないものは実装
 していません(笑)

• リレーション機能は持たせないつもりで
 す。(Simpleじゃなくなるので)

• テストは適当です(これはひどい)
というわけで
AWS小ネタ集
dateofrock/
simpledb-mapper
      (笑)
気が向いたら
Forkしてね
残りは後日
ブログに書きますw




   http://www.flickr.com/photos/mendhak/4271441910/
Thank you!


    http://www.flickr.com/photos/mendhak/4271441910/

More Related Content

AWS小ネタ集

  • 1. 第5回 AWS User Group - Sapporo 勉強会 AWS小ネタ集 欧文印刷株式会社 田名辺健人 2012.02.14 http://www.flickr.com/photos/mendhak/4271441910/
  • 2. 田名辺 健人(たなべたけひと) ソフトウェアエンジニア 欧文印刷株式会社(東京都) 2011年11月から札幌でテレワーク @dateofrock 札幌・東京コアメンバー Ustream担当 好きなサービスはSQS
  • 7. LT(Lady's Happy Valentine Talk) してくれた貴女へ… http://www.flickr.com/photos/pinksherbet/1483193019/
  • 8. NUboard Happy Valentine プレゼント♡ from 欧文印刷 http://www.flickr.com/photos/pinksherbet/1483193019/
  • 10. • S3 小ネタ • 読み書きのスループットを上げる方法 • バケット名にピリオドでハマる方法 • S3実践ネタ • 設定ファイル置き場 • Pre-signed URLの使い道 • Simpleシリーズ2連発 • アプリ内エラー通知はSNSが便利 • SimpleDB APIがシンプルじゃない件 http://www.flickr.com/photos/mendhak/4271441910/
  • 11. タ 作 り す ぎ た w http://www.flickr.com/photos/donsolo/2435421847/
  • 12. • S3 小ネタ • 読み書きのスループットを上げる方法 • バケット名にピリオドでハマる方法 • S3実践ネタ • 設定ファイル置き場 • Pre-signed URLの使い道 • Simpleシリーズ2連発 • アプリ内エラー通知はSNSが便利 • SimpleDB APIがシンプルじゃない件 http://www.flickr.com/photos/mendhak/4271441910/
  • 13. 半分 • S3 小ネタ • 読み書きのスループットを上げる方法 • バケット名にピリオドでハマる方法 • S3実践ネタ カット • 設定ファイル置き場 • Pre-signed URLの使い道 • Simpleシリーズ2連発 • アプリ内エラー通知はSNSが便利 • SimpleDB APIがシンプルじゃない件 orz http://www.flickr.com/photos/mendhak/4271441910/
  • 14. • S3 小ネタ • 読み書きのスループットを上げる方法 • バケット名にピリオドでハマる方法 • S3実践ネタ • 設定ファイル置き場 • Pre-signed URLの使い道 • Simpleシリーズ2連発 • アプリ内エラー通知はSNSが便利 • SimpleDB APIがシンプルじゃない件 http://www.flickr.com/photos/mendhak/4271441910/
  • 15. Pre-signed URLの使い道 • S3オブジェクトに対して有効期限付きの パブリックなURLを生成できる • Query String Request Authentication http://docs.amazonwebservices.com/AmazonS3/latest/dev/ RESTAuthentication.html#RESTAuthenticationQueryStringAuth
  • 16. Pre-signed URL どんなもの?
  • 17. GET /images/photo.jpg? AWSAccessKeyId=0PN5J17HBGZHT7JJ3X82 &Expires=1141889120 &Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of(StringToSign)))); StringToSign = HTTP-VERB + "n" + Content-MD5 + "n" + Content-Type + "n" + Expires + "n" + CanonicalizedAmzHeaders + CanonicalizedResource;
  • 19. Java Interface AmazonS3 java.net.URL generatePresignedUrl(java.lang.String bucketName, java.lang.String key, java.util.Date expiration, HttpMethod method) throws AmazonClientException Date after5Seconds = new Date(); after5Seconds.setTime(System.currentTimeMillis() + 5 * 1000); AmazonS3 s3 = new AmazonS3Client(cred); Url url = s3.generatePresignedUrl(“mybucket”, “images/photo.jpg”, after5Seconds, HttpMethod.GET);
  • 20. Ruby Class: AWS::S3::S3Object - (URI::HTTP, URI::HTTPS) url_for(method, options = {}) url = s3.buckets['mybucket'].objects['images/photo.jpg']. url_for(:read, :expires => 5)
  • 21. Ruby Ruby Class: AWS::S3::S3Object - (URI::HTTP, URI::HTTPS) url_for(method, options = {}) ステキ! url = s3.buckets['mybucket'].objects['images/photo.jpg']. url_for(:read, :expires => 5)
  • 22. Pre-signed URL 実 例
  • 27. Pre-signed URLの使い道 • Webサーバーの負荷が劇的に減る! • アプリはPre-signed URLを生成してS3 にリダイレクトするだけ • 重たいデータ送出はS3にお任せ!
  • 28. • S3 小ネタ • 読み書きのスループットを上げる方法 • バケット名にピリオドでハマる方法 • S3実践ネタ • 設定ファイル置き場 • Pre-signed URLの使い道 • Simpleシリーズ2連発 • アプリ内エラー通知はSNSが便利 • SimpleDB APIがシンプルじゃない件 http://www.flickr.com/photos/mendhak/4271441910/
  • 30. Java 例えばUncaughtExceptionHandlerを使う Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { " AWSCredentials cred = new BasicAWSCredentials( "アクセスキー","シークレットキー"); " AmazonSNS sns = new AmazonSNSClient(cred); " String stackTrace = getStackTraceString(e); " sns.publish(new PublishRequest( " " " "arn:aws:sns:ap-northeast-1:xxxxx:sns-test", " " " stackTrace, "Java Exception")); " } " } );
  • 31. Ruby on Rails 例えばApplicationController#rescue_fromを使う require 'rubygems' require 'aws-sdk' class ApplicationController < ActionController::Base rescue_from StandardError do |exception| topic = AWS::SNS::Topic.new( 'arn:aws:sns:ap-northeast-1:xxxxx:sns-test' ) topic.publish(exception.backtrace.to_s, :subject => 'Rails exception'); raise exception end end
  • 33. SimpleDB APIが シンプルじゃない件 • いや、シンプルすぎて冗長なコードに なってしまう • 素のJDBCはチョット…的な。 • データの型は全部文字列だよ!
  • 36. class Book < AWS::Record::Base string_attr :title end Book.new(:title => 'スベらないプレゼン').save Book.where('title like ?', '%プレゼン%').count $ rails generate scaffold_controller Book title:string config/routes.rb: Myapp::Application.routes.draw do resources :books end http://aws.amazon.com/articles/8621639827664165 より
  • 37. class Book < AWS::Record::Base string_attr :title end Book.new(:title => 'スベらないプレゼン').save Railsと違和感なしに Book.where('title like ?', '%プレゼン%').count 統合できる! $ rails generate scaffold_controller Book title:string config/routes.rb: Myapp::Application.routes.draw do resources :books end http://aws.amazon.com/articles/8621639827664165 より
  • 38. Java • AWS SDK for Javaには低レベルAPIしかな いのだよ。 • JPA実装とかはあるけど… https://github.com/appoxy/simplejpa
  • 41. @DynamoDBTable(tableName = "BookTable") public class Book { private Long id; private String title; @DynamoDBHashKey public Long getId() { " return this.id; } @DynamoDBAttribute(attributeName = "title") public String getTitle() { " return this.title; } // 以下、setter }
  • 42. 使用例 (DynamoDBMapper) AWSCredentials cred = new BasicAWSCredentials( "アクセスキ", "シークレットキー"); AmazonDynamoDB db = new AmazonDynamoDBClient(cred); DynamoDBMapper mapper = new DynamoDBMapper(db); Long key = 105L; Book book = mapper.load(Book.class, key); book.setTitle("スベらないプレゼン"); mapper.save(book); mapper.delete(book);
  • 46. SimpleDBMapper (笑)
  • 47. @SimpleDBDomain(domainName = "BookDomain") public class Book { @SimpleDBItemName public Long id; @SimpleDBAttribute(attributeName = "title") public String title; }
  • 48. 使用例 (SimpleDBMapper) AWSCredentials cred = new BasicAWSCredentials( "アクセスキ", "シークレットキー"); AmazonSimpleDB db = new AmazonSimpleDBClient(cred); SimpleDBMapper mapper = new SimpleDBMapper(db); Long key = 105L; Book book = mapper.load(Book.class, key); book.setTitle("スベらないプレゼン"); mapper.save(book); mapper.delete(book);
  • 51. simpledb-mapper(笑) • DynamoDBMapperライクなAPI(笑) • でもパクっただけじゃない • 1024byteを超えるデータ(Blob)はS3に • @SimpleDBVersionでOptimistic Lock(Conditional PUT/DELETE) • 検索APIにはナウいFluent Interface採用
  • 52. ナウな感じに書ける List<Book> books = mapper.from(Book.class). where("title", Like, "%スベる%"). and("price", GreaterThan, 1000). orderBy("price", DESC). limit(10). fetch();
  • 54. 使用上のご注意 • 自分が現状必要としていないものは実装 していません(笑) • リレーション機能は持たせないつもりで す。(Simpleじゃなくなるので) • テストは適当です(これはひどい)
  • 59. 残りは後日 ブログに書きますw http://www.flickr.com/photos/mendhak/4271441910/
  • 60. Thank you! http://www.flickr.com/photos/mendhak/4271441910/