Slide 1

Slide 1 text

Surge - Amazon DynamoDB for Elixir hirocaster @ ElixirConf Japan 2017 - 2017/04/01

Slide 2

Slide 2 text

hirocaster Mixi たんぽぽ Blog: http://hiroki.jp Twitter: hirocaster / GitHub: hirocaster Book: GitHub実践入門

Slide 3

Slide 3 text

Developed Elixir modules Surge - DynamoDB for Elixir alphanumeric - 62進数 <=> 10進数 変換 KMS in ExAWS - AWS Key Management Service

Slide 4

Slide 4 text

Surge - Amazon DynamoDB for Elixir

Slide 5

Slide 5 text

Surgeの現状 Surge - github.com/hirocaster/surge 動く、使える状態(基本的にgithub master branchを利用し てくださ) 内部のコアなコードは仕様変更の予定はない NameSpaceは一部適切に修正するかもしれない エラー処理はもっと丁寧に実装したい ドキュメントが無い 参考になるのはTestコード ドキュメントや説明は徐々に追加していきたい 雑なTestコードを整理 DSLやコアな仕様を変更する可能性があったので雑 圧倒的OSS貢献のチャンス!!! 5

Slide 6

Slide 6 text

What's DynamoDB ? AWS提供のフルマネージドサービス NoSQL Database データ容量は無制限で自動的に拡張 自動的にテーブルのデータとトラフィックが多数のサーバー に分散 保存されたデータは自動的に異なる3か所以上の物理拠点に冗 長的にレプリケーション 6

Slide 7

Slide 7 text

How to use DynamoDB by Elixir ? 基本的にはAWS SDKを経由してAPIと通信(JSON/HTTPS) Elixirには公式のAWS SDKは存在しない CargoSense/ex_aws 7

Slide 8

Slide 8 text

ExAws - CargoSense/ex_aws A flexible easy to use set of AWS APIs. Dynamo / DynamoStreams EC2 / ElasticTranscoder Firehose / Kinesis KMS Lambda RDS Route53 S3 SES / SNS / SQS /STS 8

Slide 9

Slide 9 text

ExAws Dynamo - sample code PutItem u s e r = % T e s t . U s e r { e m a i l : " f o o @ b a r . c o m " , n a m e : % { f i r s t : " b o b " , l a s t : " b u b b a " } , a g e : 2 3 , a d m i n : f a l s e } # = > { : o k , _ } D y n a m o . p u t _ i t e m ( " U s e r s " , u s e r ) | > E x A w s . r e q u e s t GetItem u s e r = T e s t . U s e r | > D y n a m o . g e t _ i t e m ( % { e m a i l : u s e r . e m a i l } ) | > E x A w s . r e q u e s t ! | > D y n a m o . d e c o d e _ i t e m ( a s : T e s t . U s e r ) 9

Slide 10

Slide 10 text

ExAws Dynamo それぞれの処理が分離されているのが特徴 リクエストパラメータの生成 リクエスト処理 Encode/Decode DynamoDBのリクエストを愚直に作るようなコードになる D y n a m o . q u e r y ( " U s e r s " , # t a b l e n a m e e x p r e s s i o n _ a t t r i b u t e _ n a m e s : [ a g e : " # a g e " ] e x p r e s s i o n _ a t t r i b u t e _ v a l u e s : [ a g e : 2 3 ] , c o n d i t i o n _ e x p r e s s i o n : " A g e = # a g e " ) | > E x A w s . r e q u e s t | > E n u m . m a p ( f n ( i t e m ) - > d e c o d e ( i t e m , m o d e l ) e n d ) DynamoDBのリクエスト生成に精通してないと使いにくい 精通してる人はDynamoDBの機能をフルに使いこなせる 10

Slide 11

Slide 11 text

Motivation RDBを利用してた人が使うとリクエストを作るだけでハマる GetItem/PutItem/Query/Scan expression_attribute_names/expression_attribute_v alues key_condition_expression/condition_expression/Filt erExpression ModuleレベルでのI/Oをシンプルに安全に記述したい id:23の U s e r とか A c t i v e R e c o r d や e c t o のレベルでデータを操作したい 11

Slide 12

Slide 12 text

Surge - hirocaster/surge モジュール(1レコード)単位でシンプルにDynamoDBを扱う シンプルな記述でExAWSの処理を生成する ExAWSのリクエストと結果を扱いやすいように整形 12

Slide 13

Slide 13 text

Create table ExAWS D y n a m o . c r e a t e _ t a b l e ( " U s e r s " , [ e m a i l : : h a s h , a g e : : r a n g e ] , [ e m a i l : : s t r i n g , a g e : : n u m b e r ] , 1 , 1 ) Surge d e f m o d u l e U s e r d o u s e S u r g e . M o d e l h a s h e m a i l : { : s t r i n g , n i l } r a n g e a g e : { : n u m b e r , n i l } a t t r i b u t e s n a m e : { : s t r i n g , n i l } t h r o u g h p u t r e a d : 1 , w r i t e : 1 e n d S u r g e . D D L . c r e a t e _ t a b l e ( U s e r ) 13

Slide 14

Slide 14 text

PutItem 1レコード保存する場合 ExAWS D y n a m o . p u t _ i t e m ( " U s e r s " , u s e r ) | > E x A w s . r e q u e s t Surge S u r g e . D M L . p u t _ i t e m ( u s e r , i n t o : T e s t . U s e r ) 14

Slide 15

Slide 15 text

GetItem 1レコード取得する場合 ExAWS u s e r = T e s t . U s e r | > D y n a m o . g e t _ i t e m ( % { e m a i l : u s e r . e m a i l } ) | > E x A w s . r e q u e s t ! | > D y n a m o . d e c o d e _ i t e m ( a s : T e s t . U s e r ) Surge S u r g e . D M L . g e t _ i t e m ( e m a i l : u s e r . e m a i l , f r o m : T e s t . U s e r ) 15

Slide 16

Slide 16 text

Query 複数レコード取得する場合 ExAWS D y n a m o . q u e r y ( " U s e r s " , # t a b l e n a m e e x p r e s s i o n _ a t t r i b u t e _ n a m e s : [ a g e : " # a g e " ] e x p r e s s i o n _ a t t r i b u t e _ v a l u e s : [ a g e : 2 3 ] , c o n d i t i o n _ e x p r e s s i o n : " A g e = # a g e " ) | > E x A w s . r e q u e s t | > E n u m . m a p ( f n ( i t e m ) - > d e c o d e ( i t e m , m o d e l ) e n d ) Surge S u r g e . Q u e r y . q u e r y ( w h e r e : [ " # a g e = ? " , 2 3 ] , f o r : T e s t . U s e r ) 16

Slide 17

Slide 17 text

Query and Filter 複数レコード取得し、さらに条件でフィルターする場合 ExAWS D y n a m o . q u e r y ( " U s e r s " , # t a b l e n a m e e x p r e s s i o n _ a t t r i b u t e _ n a m e s : [ a g e : " # a g e " , a d m i n : " # a d m i n " ] , e x p r e s s i o n _ a t t r i b u t e _ v a l u e s : [ a g e : 2 3 , a d m i n : t r u e ] , c o n d i t i o n _ e x p r e s s i o n : " A g e = # a g e " , F i l t e r E x p r e s s i o n : " A d m i n = # a d m i n " ) | > E x A w s . r e q u e s t | > E n u m . m a p ( f n ( i t e m ) - > d e c o d e ( i t e m , m o d e l ) e n d ) Surge S u r g e . Q u e r y . q u e r y ( w h e r e : [ " # a g e = ? " , 2 3 ] , f o r : T e s t . U s e r 、 f i l t e r : [ " # a d m i n = ? " , t r u e ] ) 17