AWSの話題を中心に、日々の業務やプログラミングの徒然を綴るエンジニアブログです。

HANDS LAB

HANDS LAB ENGINEERS BLOG

ハンズラボエンジニアブログ

One Day Outing

Pocket

つい最近、ハンズラボでは、月に1日だけ社外勤務ができるという制度ができました。

ネットの繋がるところならどこでもOK(たぶん)。
たまにはいつもと環境を変えて仕事することで、いろいろこびりつかないようにしようという取り組みです。

そこで本日、まさに今、この制度を活用しています。
訪れた場所は・・・ 続きを読む One Day Outing

Pocket

DynamoDB PHP SDKのMarshalerクラスを使った時にはでかい数値に気をつける

Pocket

下記のblogで紹介されているように、AWS PHP SDKの 2.7.7 から PHPの型とjsonとDynamoDBの型の相互変換を行うクラス、Marshaler が追加されています。

DynamoDB JSON and Array Marshaling for PHP

この Marshaler クラスを使うと、型変換が行われるため、数値型に大きな値を入れている場合に注意が必要です。

以下に例を示します。

id = 1 のレコードに number = 9223372036854775808 という値が入っているレコードを取り出してみます。

結果

9223372036854775808 という値が取り出せました。

これを Marshaler でPHPの型に戻してみます。
使用するメソッドは、unmarshalItem です。

結果

9.2233720368548E+18 になってしまいました。/(^o^)\ ナンテコッタイ

原因

PHPでの整数の最大値はPHP_INT_MAXで定められており、9223372036854775807 になっています。(64bitの場合)
それを超えた数字を整数に変換しようとすると、指数表記になってしまいます。

参考:PHP>マニュアル>言語リファレンス>型>整数

一方、DynamoDBの方は、下記ドキュメントにて、最大 38 桁の精度とあるように、 99999999999999999999999999999999999999 まで投入できます。

参考:DynamoDB データモデル

この辺りの相互変換は、言語側の精度に依存する形になると思うので、使っている言語側の仕様を確認しておいた方がよさそうです。
たしか、rubyの場合には BigDecimal に変換されたと思います。

参考

Pocket

既存のDynamoDBテーブルからテーブル定義を作成する

Pocket

開発環境で作ったDynamoDBのテーブルと全く同じテーブルを本番環境で作ったり、
既存のテーブルのインデックス定義をちょっと変えて作り直したい、そんなケースがあると思います。

マネージメントコンソールで作ってもよいのですが、インデックス名を間違ったり、インデックスが不足したりすると思わぬトラブルになります。(実際ありました)

きちんと、テーブル定義をjsonファイルで管理しておけばよいのですが、そうでない場合は、既存のテーブルからテーブル定義となるjsonを吐き出して、それを読みこませて作成したいと考えると思います。

ただ、aws dynamodb describe-table で吐き出すjsonには、create-table に不要な項目が多数含まれていて、そのままでは実行できません。

「ああjson手で直すのめんどくさいなー」 と弊社今井の周りでつぶやいていたところ、

つ 「出来た」

と下記のようなスクリプトが送られてきました。仕事早っ。

jq でjsonの要素簡単に消せるんですね。
これで出力された json を使って、下記のように作成すればまったく同じ定義のテーブルが作れました。

まとめるとこんな感じです。

既存のテーブルと同じ定義のテーブルを作成する

最初からテーブル定義をjsonで管理する

上記のような事態にならないように、最初からjsonで管理しておけばよかったな、と思ってます。
具体的には、下記のような手順でしょうか。

1)テーブル定義のスケルトンを作成

2)スケルトンをベースに編集する

不要な定義消したり、インデックス名をきめたりとか。

3)テーブル作る

describe-table とかできちんと出来ているか確認する。

4)git に登録

問題なければ、git などに入れておく。

 おわりに

もっとこうしたほうがいいよとか、CloudFormation使うとこんな感じでできるとか、追加情報ありましたら教えていただけると嬉しいです。

あと、プロビジョニングツールとかないのでしょうか。(後から追加できるのがGSIくらいだから需要ない?)

Pocket

ハンズラボが採用しているユニケージという謎テクノロジーについて 第2回

Pocket

謎テクノロジー第2回目です。
諸事情によりだいぶ時間が空いてしまいました。色々と厳しい。

今回は簡単なサンプルコードを用いて、もう少し突っ込んでユニケージの処理例について解説します。
繰り返しになりますが、この連載での記述は全て筆者の見解であります。と、念押し。
# しかしまた長くなってしまった……
# 削ったり分割したかったけど、いい加減アウトプットしたかったのでひとまずこれで。

目次

  • コード例
    • フィールド選択での例
    • ごく簡単な集計での例
    • ログ集計
    • まとめ
  • 第1回に対するネット上の声Q&A的なもの
  • 次回以降の内容

コード例

フィールド選択での例

前述の様に、ユニケージ開発手法では、原則半角スペースをセパレータとするフラットファイルをデータストアとして用います。
セパレータが半角スペースであることについては賛否両論有りますが、

  • シェルスクリプトが半角スペースを引数の区切りとして使っている
  • ユニケージコマンドの補助として多用するawkのデフォルトセパレータも半角スペース

であるので、それなりに合理的ではあると考えます。

簡単な具体例として、あるファイルの特定の列のみ選択する操作について説明します。
以下のファイルをサンプルとします。

このファイルから商品コードと販売価格のみを出力する場合は、
self コマンドを用いて以下のように行います。

上記と同じファイルをスクリプト内で読み込み、等価な標準出力を行うPHPのコードを以下に記します。

もうちょっといい感じにできるとは思うのですが、
単にフラットファイル丸ごと開いて数列を選択して出力するだけでも冗長な感じです。
# 強引だ……

ユニケージコマンドセットには、概ねこの程度の粒度のコマンドがたくさんあるのですが、
実務的には概ね数十程度(筆者の感覚では50以下)のコマンドの組み合わせにて、アプリケーションを記述しています。

また、前述の様に、ユニケージコマンドだけでは行いにくい処理を行う場合は、だいたいawkを使う事になります。
前述の self コマンドの例と等価なawkを使用したワンライナーは、書くまでもないかも知れませんが、

となります。
フラットファイルの行の集合に対して、各々フィルタ処理を行って目的の出力を得る、という処理が中心のユニケージに対して、
awkは枯れている上に、短いフィルタ処理を書く為には簡潔に書けるので、ユニケージ開発には重宝します。
# ただし、awkはなるべく使うな、というふわっとした規約もあったりします……
# 商用版ユニケージコマンドはほぼ全てpure Cで書かれているので、awkでコマンドの組み合わせに相当する処理を記述すると比較して十分に遅くなってしまうので……

ごく簡単な集計での例

前述の商品マスタを用いて、さらに販売実績に関する簡単な集計の例を示します。
以下の様な販売実績のファイルがあるとします。

上記の販売実績から、店舗と販売日問わず商品毎の販売合計金額を算出する場合は、以下の様にします。

join1コマンドは、指定したキーにて、2つのファイルまたはファイルと標準入力に対して、内部結合を行うものです。
ユニケージコマンドでのキー指定は、極一部の例外を除き、事前にそのキーにてソートされている必要があります。
lcalcコマンドは、基本的な算術演算をawkのようなシンタックスの式で、
36桁の10進数で加減乗除と四捨五入・丸め操作を行うものです。
sm2コマンドは、第1,2引数で集計範囲キーを指定し、第3,4引数の範囲の値の総和を個別に取るものです。

また、店毎のある日の総販売実績は以下の様にして求められます。

集計したいキーと集計したい値だけに着目し、コマンドを作用させれば求める値が得られる、というのは、単純な算術演算だけ行うようなロジックにおいては、他にケアするべきことが少なくなるのでよいです。

ログ集計

簡易なWebサーバのステータス集計など、ログ集計も可能です。
例えば、以下の様なフォーマットのログのみが /var/log/httpd/access_log に出力されている場合、

1時間毎のステータスコードを以下の様に集計出来ます。

yarrコマンドは、指定列数になるようにファイルの行を横に展開するものです。
countコマンドは、指定キーにマッチする行の数をカウントするものです。
ログ集計がシェルスクリプトで、下手すればワンライナーで完結するので、あまりアプリケーションコードを書かない方のインフラエンジニアの方やデータ分析官の方にも重宝するのではないでしょうか。
yarr,count共にOpen版に含まれているので、こういった作業をすることがあるならば導入しておくと便利です。

まとめ

普通のプログラミング言語よりも、手続き的な処理が少なく、データに対する操作が主になっている様子を掴んでもらえたと思います。
例示したように、1つのプログラムで、前述の例の様なパイプライン処理で作成した複数のデータを、一時ファイルに置きつつさらに操作して、最終的に求める出力を得ます。
求める出力は、DBのビューに相当するデータであったり、HTMLテンプレートにはめ込むデータであったり、バッチ処理により更新されたテーブルであったりしますが、基本的な手法はほぼ変わりません。
アプリケーションコードが殆どデータに対する宣言的操作だけでできている、と言えます。
基本的には無名のフィールドに対して操作を連続して行い、操作中にフィールド構成がよく変化するので、変化ある毎にフィールド内容を正しくコメントすることは必須です。
これを正しく行っていないと、人間非可読なコードがあっという間に出来上がります。
しかしながら当然あり得るツッコミとしては、コメントが多すぎて可読性がひどいのでは、というのがあります。
これに関しては、また次回以降……

第1回に対するネット上の声Q&A的なもの

エゴサ力を駆使したところ、第1回公開後のネット上の声が思ったよりあったので、勝手に回答します。
ソースは必要があれば正しくURLを引用しますが、晒す感じになってしまいそうなので、 意図を歪めない範囲で省略した文に対してインライン回答する形式にします。

プログラマ視点で引き続き解説を

そのようにしていきます。
ビジネス中心の話はビジネスおじさんに任せればよいのです。
小耳に挟んだところによると、色々な所から人を集めて推進するようなプロジェクトでもユニケージ案件は一定数存在するようなので、そこに突っ込まれた普通のエンジニアにとっても有益なものになるようにしたいです。
また、公にされている情報がビジネス的な話ばかり目立って存在して、技術寄りの話が少ないテクノロジーというのは、はっきり言ってエンジニア視点からは胡散臭さマシマシとなり、それ自身にとって不幸だと思うので、引き続きこのくらいのスタンスでやっていきます。

考え方が関数型言語っぽい

せやな。
……などというとマサカリが四方八方から飛んできそうです。
その上で言うと、

  • データ構造が2次元配列だけの、シンプルなデータ構造で
  • しかもデータソースでもアプリケーション中でも出力でも構造が殆ど変わらない
    • 所詮はフィールド数が多いだけの、テーブルに出力する一覧画面や帳票リプレースものなアプリケーションが多い。
    • 更新系も、所詮表形式データの編集に過ぎないものが多い。

最も抽象度の低い宣言型プログラミング、とも言えるかも知れません。
そろそろ強いマサカリが怖いのでこの辺で……。

これについては、より知見の深い、シェルスクリプト高速開発手法入門で皆様ご存じの上田先生にもご意見を賜りたく。
シェル芸とHaskellの対応を考える | 上田ブログ

エンドユーザーコンピューティングとしてはmuch better Excel。ファイルシステムというドキュメント型KVSの上に実現するための知見の集合?

確かにExcel/Accessによるエンドユーザたこつぼシステムの代替である側面はあります。

ユニケージコマンドがフラットファイル処理に特化しているので、ファイルシステム上のフラットファイルに、という感じではありますが、
ユニケージにはデータの階層構造の概念があり、それが実現できればファイルシステム上のフラットファイルでなくとも、ユニケージ的なものは出来そうです。
例えば、AWSやAzure,GCPなどのクラウドのマネージドサービスにて、各々のデータ階層のデータストアとしての役割や、データ操作の役割を割り当てる、など考えられます。
単純にファイル置き場をS3にして実現したシステムの事例については、
既に当社の田部井による事例紹介が公開されています。
フラットファイルを用いないユニケージ的な考え方については、
ユニケージのデータの階層構造を説明する時に、考えながらあわせて触れたいと思います。

また、等価なコードはだいたいの言語で書けるはずなので、言語もシェルスクリプトである必要はないと思います。

# 個人的にはシェルスクリプトはあまり好きではないし、追加・削除したコード量的にも、一生のうちに書いてよいシェルスクリプトの閾値を超えた気持ちになっているので、おなかいっぱいです。
# あとシェルスクリプトは他の言語に比べて簡単かというと、そうでもない。
# ユニケージコマンドやそれに類するコマンド群がなければ、アプリケーション記述用言語としては初心者に全くおすすめできません。

RDBMSを使用しない理由が不明確

これは確かにそうです。
私はユニケージガチ勢ではないので、普通の言語や普通のRDBMSや普通の分散環境がはまるケースなら普通にそれでやればいいと思います。
適材適所、ユースケースにはまれば採用すればよい。

その上で、エンドユーザーコンピューティング的な視点だけで言うと、
諸々の実行環境やミドルウェアの設定・依存関係に悩まされず、ユーザが脱Excel|Accessして、
自社のデータを自分の手で素データからガンガン取り回すという経験を最速でやれるのは、ユーザ企業にとって、自社を動かすシステムのブラックボックス度を軽減させるという点で、重要な事と考えています。
システムを作ることから離れすぎた・放棄したユーザ企業が、SIerに上手に仕事を投げられなくなり、
ダメなSIの発生率が上がっていそう(ダメSIの定義が出来ていないので妄想みたいなものですが)という気がしますので。
もっと言えば、SIに限らずWeb制作などの、一定以上の専門性を要するものの外注などにも、発注側の過度の “わかってなさ” が良くない事態を招くこともあると思います。
# 自分が何をわかってないかをわかってない人と仕事をするのはつらいです。

システムの物理的実体がRDBMSを使っているかどうかなどの適材適所とは、また別の軸の話となってしまいました。
とりあえず、バージョンや設定に依存するミドルウェアやコンパイラ・インタプリタが事実上ほぼ無いと言える(一応Apache httpd とbash、ユニケージコマンドに依存するが)というのは、
ユーザ企業出身エンジニアにとっては、余計なことを考えず自社のデータのことだけを考えればよい、という点が良いのではないか、と考えています。
筆者はハンズのプロパーではないので、他のプロパーの人たちを見て、という意味です。
エンジニアとしての練度が上がり、業務だけでなく技術に対する理解力もついてくれば、
なんでもユニケージでなく、ケースによって最適なアーキテクチャをエンジニアが選定して推進していけばよいのではないでしょうか。

あんまビジネスの話したくないけどそれっぽい話をしてしまった。あかん。

シェルスクリプトでJSON操作できるコマンドが必要では

ユニケージコマンドには存在しないのですが、一定の範囲では間に合ってますw
例えば、

みたいな入力を食わせると、

みたいなJSONを吐くコマンドは2年以上前から社内に存在してます。
上記のような、
キー名 値
が連続したファイルを読みこんでjson_encodeするPHPのスクリプトを外部コマンドとして作成し、使用していました。
# しかしシェルスクリプトでJSONパーサ書くとかぞっとする……。
また、AWSのCLIを使用する際などは、jqコマンドを使用してレスポンスをパースしています。

シェルスクリプトでJSONを操るのは、少なくとも弊チーム(EC・アプリ系)は色々あって卒業しました。
色々、については、書く機会があればそのうち書きます。

次回以降の内容

次回は、ユニケージのデータ階層構造の概念について、を予定しています。
可能であれば、クラウドマネージドサービスとの対応を考えてみるところまでやってみたいと思います。
pros/cons については、次々回以降に、ここまでの記述で書いたこと、察せそうなことをまとめる形でやっていく予定です。

第3回はこちら

Pocket

S3をDB利用したポイントシステムについて話しました

Pocket

田部井です。
時間が立ってしまったのですが、2月7日に新大阪で開催されたカンファレンス『JAWS-UG KANSAI 特別編』のハンズラボ枠の中で20分ほど講演してきました。
カンファレンスのテーマが「AWSを使い倒せ。AWSのフルマネージドサービス活用によるネイティブクラウドシステムへの誘い」ということなので、S3を活用して構築したシステムの事例をご紹介しました。
その際の私のパートの資料をUPしました。

S3をDBとして使っていること、ほぼ素のAWSとLinuxの機能だけでイミュータブルインフラストラクチャーに近づけたことが、このシステムのポイントになっています。

S3をDBとするにあたり、これまで東急ハンズのシステム内製構築で培ってきたユニケージ開発手法のノウハウを使っています。
クラウドとは親和性が低いと思っていた『テキストファイルデータ管理』が、新しいCDPに繋がったと自画自賛しています!

ユニケージ開発手法に関しては、こちら
謎テクノロジーの一端を見ることができます

今回私の初めての講演だったので、色々いい勉強になりました。
来る3月22日のJAWS DAYSでも話すかもしれないので、ぜひご来場ください!

Pocket