ラベル DynamoDB の投稿を表示しています。 すべての投稿を表示
ラベル DynamoDB の投稿を表示しています。 すべての投稿を表示

2022-02-28

No SQL Workbenchを利用する(初期設定とOperation Builderの使い方)

 DynamoDBのデータの中身を確認したり、データモデルを設計するクライアントソフトととして、AWS公式ツールであるNo SQL Workbenchがあります

ダウンロードサイト

下記からダウンロードしてください

初期設定(DynamoDBに接続する)
いろいろメニューがあるのですが、
  • Operation builderを選択
  • Add connection
と進みます。すると、AccessKeyなどを設定するウィンドウが出てきますので、そこに適切な情報を入れてください。

Operation Builderの使い方
Operation Builderをクリックすると、テーブルがリストアップされます。テーブルをダブルクリックすると。その中身を見ることができます。しかし、Operation builderでできることはそれだけではありません。
(1)PartiQL Operations
PratiQL(DynamoDBで使えるSQLライクなクエリー言語)を記述することでその挙動を確認することができます。
(2)Interface based Operations
PratiQLの書き方に不慣れな場合は、こちらがオススメです。GUIメニューに検索条件を追加することで、それに相当する処理を確認できます。

Codeの自動生成もできる
Gererate Codeのボタンを押すことで、Python, JavaScript, JavaでOpearationに相当する記述が自動生成されます。冗長な記述のような気もしますが、参考にはなると思います。

ちょっと大雑把な記事になりましたが、このソフトを利用することでDynamoDBの使い方も理解できるようになるかと思います。





2021-07-10

DynamoDBに正式移行しました

おちラボでは、ようやく、、、、よーやく研究室の公式DBをSimpleDBからDynamoDBに移行しました。

なぜ今まで移行しなかったか?
DynamoDBについては、2012年に

という記事を書いたように、早くから注目していましたが、料金体系に問題があり(後述)、ゼミでの利用に不向きだったこともあり、SimpleDBを利用していました(AWS:SimpleDBをセットアップする)。しかし、SimpleDBはいつ死んでもおかしくないようなサービスなので(全くSDKがバージョンアップしていない)、このまま使う続けるのはまずいよな。。と流石に思い始め、かつ後述するように料金体系がいつの間にか変更されていて、使いやすくなっていたので、今年から切り替えることになりました。

DynamoDBの料金体系を確認する
現在、DynamoDBには2つの料金体系が存在します。
  1. プロビジョニング
  2. オンデマンド
1は昔からあるタイプで、いわゆる事前割当になります。これが問題だったのは、テーブル毎にプロビジョニング設定をしないといけないということ。つまりテーブルを増やせば増やすほど課金されます。これは使わなくてもです。一方、2は最近出てきた料金体系で(2018年に発表されたようです)、使ったぶんだけ、、ということになります。SimpleDBがまさにこの料金体系だったので、おそらくこの料金体系を用意することで、SimpleDBのユーザを移行させようとしているのではないでしょうか(私みたいに)?

実際安くなるのか?
ただし、オンデマンドの場合、青天井に増えていく可能性がありますので注意が必要です。真面目に運用をはじめると、プロビジョニングのほうが割安でしょう。ただ、ゼミでちょっと学生に使わせるとか、テーブルを気軽に増やしておけるというのは大変ありがたく(これが正しいDynamoDBの使い方なのかはおいといて)、現状だとDynamoDBについてコストはほぼ発生していない状況です。

というわけで、今後はDynamoDBについての記事も増えてくると思います。






2015-06-26

DynamoDB: グローバルセカンダリインデックスを使ってみた(DynamoDBMapper利用編)

ネタ的には古いですが、DynamoDBのグローバルセカンダリインデックスを、高レベルAPIであるDynamoDBMapperクラスから利用してみました。Javaでの記述方法について紹介します。

想定環境
この記事では下記のようなテーブルを作成したとして説明します。
  • テーブルの構造は「ハッシュキー:id、レンジキー:a、通常のアトリビュート:v」
  • このテーブルに対して、「ハッシュキー:v、レンジキー:a」というグローバルインデックスを設定(このインデックス名を「v-a-index」とする)
記述例
例を下記に示しますが、悩みどころはアノテーションの書き方でしたね。複数のアノテーションの書き方に悩みました。あとは、通常の検索方法と変わらないと思います。



2014-12-26

DynamoDBにてHash+RangeのQuery設定方法(v2対応)

久しぶりにDynamoDB触ってみたら、Hash+RangeのQuery設定方法がv2で変更になっていて、古いコードがエラーになってしまったので。。。。



2013-06-20

C#:DynamoDBにMapperを利用してデータを保存するサンプル

C#でもDynamoDBを操作することになりそうなのでそのサンプルです。Javaの場合は高レベルAPIであるMapper系のクラスが用意されていましたが、C#でも同様にありました。データクラスにアノテーションを書いて、クライアントクラスで利用するといった感じで、使い方もほぼ同じだと思われます。

本家チュートリアル(Using Amazon DynamoDB Object Persistence Framework - An Introduction)を参考にしました。

2013-04-20

DynamoDB: ローカルセカンダリインデックスを使ってみた(DynamoDBMapper利用編)

早速話題のDynamoDBのローカルセカンダリインデックスを、高レベルAPIであるDynamoDBMapperクラスから利用してみました。以下はJavaDocを見ながら試行錯誤で試してみた速報的なものですので、若干勘違いもあるかもしれません。

なお、ローカルセカンダリインデックスを使うためには、ライブラリのパッケージは
com.amazonaws.services.dynamodbv2.*
以下を使用することになるので注意してください。

ローカルセカンダリインデックスを持つテーブルの作成
テーブル作成時にローカルセカンダリインデックスを定義する必要があります。事後にインデックスを追加することはできないので要注意ですね。


Index Name名というのがよくわからないので、Attributeの名前を同じにしました。

データクラスにアノテーションを記述する
アノテーションの記述方法ですが、ローカルセカンダリインデックスに相当するAttributeについては、
@DynamoDBIndexRangeKey(localSecondaryIndexName ="age")
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
というようにします。

ローカルセカンダリインデックスで検索をかける
従来のRangeKeyに対する検索の方法と同じです。
上記は、年齢(age)をセカンダリインデックスとして20才のデータを探している例です。

ローカルセカンダリインデックスの特徴
個人的にポイントと思っているのは下記の点です。
  • テーブル毎に最大5つのローカルセカンダリインデックスを作成可能
  • あくまでも従来のレンジキーに対する代替 
  • 複数のローカルセカンダリインデックスを組み合わせた検索は不可
  • 従来のレンジキーとの組み合わせも不可
  • 紐付けるAttributeによってコストが増える?
従来よりも便利になることは間違いないですが、どういった検索をするかを考えた上でインデックスを定義しておかないといけないわけで、意外と設計の難易度が高いという印象です。

APIの仕様が若干変化している点に注意
パッケージがcom.amazonaws.services.dynamodbv2に変わるとともに、微妙にAPIの仕様が変わってます。今までのコードが動かなくなる可能性が高いので注意が必要でしょう。現状すでにDynamoDBで運用している場合は、移行の際は注意した方がいいです。

DynamoDBのmapperクラス関係がdeprecatedになっている件

DynamoDBにsecondaryインデックスが定義できるようになったというニュースを聞いて、ではちょっと試してみようかと、久しぶりにDynamoDBのプロジェクトを起動してみると、mapper系のクラスやメソッドがdeprecatedになっている。これは焦るわけですが、とりあえず、
//旧
import com.amazonaws.services.dynamodb.datamodeling.DynamoDBMapper;
//新
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
とすればいいらしいですが、なんだかなぁ。

まだあんまり話題になっていないのが気になるところ。

2013-03-25

DynamoDB:DynamoDBのプロビジョニングされたスループットを探ってみた

おちラボでは、昨年度からDynamoDBをバックエンドとするDBについて密かに?試作しているんですが、実はDynamoDB のキモとなる
プロビジョニングされたスループット
なるものについては、よくわからずに使っていました(つまり、そんなに本格的に使ってないということなんですけどね ^^; )。

で、最近、ネット界隈で、
DynamoDBにおけるスループット超過対策 〜 Fallback-Queueingパターン
なる記事が話題になっているようで、 DynamoDBの正体とその解決策に、なるほどーっと感心していたわけですが、、、

DynamoDBってそんなめんどくさいサービスなのか???
記事を読んでみて素朴な疑問が出てきたわけです。というか、1年間ちょこっと触ってみて個人的に感じたDynamoDBの欠点は、
  • テーブル毎に課金されるということはテーブルいっぱい作れない!!
ってことがまず1点。課金をケチろうと思ったら従来のRDBみたいな考え方ではアカンのですよね。で、今回の話題で発覚したのが、
  • リクエストスループットは、プロビジョニングされた容量を超えるとリクエストが失敗する
というさらなる欠点が、、、失敗したらどーなるの?データは反映されない?そんなのデータベースって使い物にならんだろう。と思うのは僕だけでしょうか?
で、その解決策として、上記のBLOGの解決策は秀作なんですが、これって元々のDynamoDBが奨励している使い方ではないですよね。いわゆる高等テクニックなわけで、ちょこっとプロトタイプ作ってみましたーみたいなレベルの我がラボのようなところではちょっと敷居が高すぎます。

例外処理で条件ワケするってのはどーも気持ち悪い
上記、BLOGを見ると「ProvisionedThroughputExceededException」というのが、プロビジョニングされた容量を超えた場合に発生するということがわかりました。(へぇ!へぇ!へぇ!へぇ!)
しかし、例外処理を条件分岐のように使うってのは、オブジェクト指向的に美しくないって習いませんでしたか?いや私も習ってませんが、どこかの本にそんなこと書いていた気がします。もっと、スマートなやり方ってないのかな?

getUnprocessedItemsメソッドというのがあるらしい!
ちょっといろいろぐぐってみると、getUnprocessedItemsというメソッドがあり、簡単にいうとBatchWriteItemのような処理で書き込みできなかったアイテムのリストを取り出すことができるということ。これを使えば、書き込みの再試行ができるというわけです!サンプルプログラムは下記のようになります。
do {
 batchWriteItemRequest.withRequestItems(requestItems);
 result = client.batchWriteItem(batchWriteItemRequest);
 requestItems = result.getUnprocessedItems();
} while (result.getUnprocessedItems().size() > 0);
ごらんのように、最初にrequestItemsを渡してバッチ実行したあと、getUnprocessedItemsメソッドでrequestItemsで取り残されたアイテムに更新し、もし取り残しがあれば再度バッチ実行するということです。この方法により、ループが回り続ける限り、登録は行われることになります。

ちょっと試してみた
getUnprocessedItemsメソッドで出力されるリストの中身を確認すれば、どんな感じに処理が失敗していくのかがわかります。空であれば、一発でバッチ登録は成功、そうでなければ失敗したということになります。条件として、
  • プロビジョニングスループットを1にしたテーブルを用意
  • batchWriteItemメソッドで、リミットの25件分のitemを一括登録する処理を20回繰り返す
というのを試してみました。挙動は予測するのはちょっと難しくて、最初の試行ではスムーズに登録完了しました。が、一度、中身を全て消して再度試行すると、途中のターンからリストに失敗したitemが残るようになりました。これはどういうことかというと、
  • 実際にリクエストしたスループット(Average Consumed Write Capactiy)の計算方法が単位時間によるもの
ということが想像出来ます、つまり単発的にデータを200件ほど追加するだけだと、プロビジョニングスループットを1にしていても問題なし。しかし、追加や削除などを繰り返すと、スループット平均値が上がってしまい、登録が失敗するということです。

上の図は、今回試した時のスループットのログです。赤線はプロビジョニングスループットの1です。青線の最大値は1.5です。
ちなみに、書き込みが失敗している場合、whileループが継続されてbatchwriteが行われるわけですが、ループを回るたびにitemのリストは1つずつ減って行きました。つまり、1item分しか処理されていないわけで、これってつまり、プロビジョニングスループットが1であるということなんですよね。

低レベルAPIでしかできないようだが、実は、、、、
getUnprocessedItemsメソッドを使えば、ループにより再処理ができ、漏れ無くデータを登録できることがわかりました。ただ、これが使えるのは、DynamoDBのSDKの低レベルAPIだけ。おちラボでは、高レベルAPIのmapperを使ってたんですが、これだとgetUnprocessedItemsメソッドが使えない模様です。もしかして、低レベルAPIで作り直し??
ちょっと気になって、高レベルAPIで同様の一括処理を試してみました。すると、データベースの中身を見てみましたが、時間はかかりますけどちゃんと入っているようです。どうやら高レベルAPIでは内部で同様の処理をしている模様(ソースを覗いたらはっきりするんでしょうけど)。つまり、、、再試行してくれててデータはちゃんとはいってるということ??

うーん、結局、気にしなくてもよかったのかなぁ。。。



2012-06-25

DynamoDB:IAMでのUserPolicyによるアクセス制限 ~その2~

DynamoDBのアクセスをIAMで制御する話の続編です。時々トラブルのでメモ書き程度ですが、、、

下記のようにすれば、
  • ochi_ではじまるテーブルについてのみ操作が可能
となります。ちなみに、操作の記述ですが、Policy Generatorのウィザードを使うと足りないのがあったりします(気のせいだったようです。今見たら全てありました。)Policy Generator使いましょう。


2012-06-05

DynamoDB: DynamoDBMapperでBatch処理をする

DynamoDBでBatch処理ができるようになりました。高レベルAPI、つまりDynamoDBMapperを利用した場合のBatch処理についてメモ書きです。というかこれは非常に簡単で、
  • batchSave ・・・ 保存
  • batchDelete ・・・ 削除
  • batchWrite ・・・ 保存と削除
というメソッドが用意されています。対象とするオブジェクトをリストで渡せばOK。
batchWriteというのがちょっと曲者?というかbatchSaveと何が違うのかというと、batchWriteは引数が2つあり、保存するオブジェクトのリストと削除するオブジェクトのリストを同時に渡せるということのようです。> Batch処理をしたほうが、データベースのパフォーマンスも最大限に挙がりますから、積極的に使いたいですね。



2012-05-18

DynamoDBとは

今年に入って、AmazonがDynamoDBを発表しました。NoSQLでSSD使ってて、スループットを自在に変更できて、、等なにか凄いようなよくわからないようなサービスなわけですが、いろいろ使ってみたりネットを参照してみたりしてようやくその姿が見えてきました。

データの型
扱えるデータの型はString, int, Set(String, int)の4種類です。SetについてはJavaではHashSetしか使えないようです。LinkedHashSetを利用したら、書き込みはできましたが読み込みでエラーが出ました。 何か勘違いしてるかもしれませんが、、、

検索キー
テーブルの検索キーは最大2つ設定できます。具体的には
  • HashKey・・・検索の Hash値として完全一致で特定するKey。
  • RangeKey ・・・ 大小関係や前方一致などで範囲を指定して検索できるKey
の2種類が存在します。そして、その組み合わせは2種類のみです。
【HashKeyのみ】
1つのAttributeをKeyにします。その値は必ず1意にならなければなりません。
【HashKey+RangeKey】
2つのKeyを組み合わせることで一意になるようにキーを設定されます。この方法の場合
HashKey単体では1意にならなくて良いが、2つのKeyの組み合わせは必ず一意にならなければならない。

検索の方法と注意点
次の2種類です。
  • Query ・・・  Keyを対象にした検索
  • Scan ・・・  Key以外に対する検索
 DynamoDBは幾らでもデータを増やすことができ、しかも検索スループットが保証されるという特徴としてあります。しかしこれは、キーを検索キーとした場合です。Scanを利用すると、このメリットは受けられません。Dynamodbの特徴を活かすのであれば、Scanの利用はオススメできないようです。
 なお、一度の検索で最大1MBしか呼び出せないとマニュアルには書いてあります。ということは、1つのアイテムを1KBとした場合、最大でも1000件しか呼べないということになりますよね?じゃあ、1000件を超えることが予想されるデータの場合、どうすればよいのか?それはRangeKeyを利用して範囲検索を繰り返すことができるような設計が必要になるでしょう。

S3との連携は不可欠か?
アイテムの最大サイズは64KBらしく、数値と文字列しか入らないのでこの値が大きいのか小さいのか、、、まあ、画像とかバイナリーデータとか、ファイルなどの管理はここではやらず、S3を使えってことでしょう。これはまあ、SimpleDBのころからそういう流れですからAWSのユーザーであればなんてことはないですね。あと、多くの項目を格納しておきたいのであれば、S3にXMLで保存しておくのもアリだと思いますね。

課金対象と注意事項
課金が実は一番気になるところですが、一言でいうと、
  • 「データベースのサイズ」と「設定した検索のスループット」が課金対象
となります。後者がわかりにくいですが、データベースを使おうが使うまいが、テーブルを作成すると設定したスループットに基づいて時間単位で課金されていきます。そして注意すべき点は、課金対象はテーブル毎に設定されたスループットの総和です。無料枠がReadで10, Writeで5となってますが、テーブルごとではなくその総和に対してです。しかもテーブルに設定するスループットの最低値が5となっているということ。テーブルを増やすほどスループット値は増えていきます。RDBの感覚でホイホイテーブル作ってると即課金対象になります。コストを抑えたいならテーブルをむやみに増やさないデータベース設計がポイントでしょう。ちなみに、read/writeをそれぞれ最低の5にしたテーブルを4~5つほど作っておくと、1ヶ月で10ドル超えます。
また、DynamoDBはスループットを柔軟に上げ下げできるという利点がありますが、ちょっと盲点があります。スループットを高くする場合は短時間で反映されますが、スループットを下げる時は1日ほど時間がかかるということ。つまり、細かく上げ下げしてコストを抑えるという方法が難しいということです。

というわけで、意外ととっつきにくい雰囲気のあるDynamoDBですが、おちラボでは今後、DynamoDBを研究用の基盤DBとして運用することに決めました。RDB的な使い方から脱却すればこんなに魅力のあるDBは他にないなというのが、現在の印象です。今後、DynamoDB周りでプログラミングノウハウが見つかれば、このBLOGでも紹介したいと思います。


2012-02-24

DynamoDB:IAMでのUserPolicyによるアクセス制限

諸事情で、ちょっといまAWSのDynamoDBについて調査中のメモ書き。
DynamoDBをラボで利用しようかと検討しているのだが、問題となるのはゼミ内で共有する時に問題となるのがテーブルへのアクセス制御。EclipseのPluginを使うとテーブルが全て見えてしまうのでこれは正直都合が悪い。そこで、要求仕様として
  • ユーザごとにテーブルへのアクセス制限をする。具体的にはテーブルを見えないようにする。
というのを設定したわけだが、ここでちょっとハマった。。。
DynamoDBではIAMを用いてポリシーを記述することができるらしく、DynamoDBのテーブル参照のActionはおそらく、
  • dynamodb:ListTables
なんだろうと推測。これをユーザとテーブルに対応したARNでDenyさせとけばいいと思ったわけだが、どうやらListTablesのアクションはARNでは制御できないとか。。。。
具体的にいうと
"Resource": "arn:aws:dynamodb:*:xxxxxxxxxxxxx:table/table1"
という記述で、table1に対してDenyするということはできない。ここは、
"Resource": "*" とするしかないわけだ。つまり、
  • テーブルリストは全て見せるか全て見せないかの2択。
  • アイテムの参照のレベルでテーブル毎にアクセス制限をつける
という戦略をとるしかないようだ。具体的には、
  • 全てのリソース(テーブル)に対する"dynamodb:ListTables"をAllowとするステートメントを用意
  • 特定のテーブルに対してアイテムのScanやCRUD操作ができるActionをAllowとするステートメントを用意
とすれば良いようだ。

なお、テーブル毎にステートメントを書いていくのは面倒な気がするがちょっとしたコツがある。AWSのARNの書き方では、*を利用した前方一致の指定ができる。そこで、プロジェクト毎にテーブル名の名前の付け方を決めておけば、*で一発で検索できる。例えばtest用のテーブルにtestという接頭語をつけるようにしておけば、test*の指定でOKとなる。