クラウドインフラ構築記

現在AWSの構築支援に携わっております。今注視しているのは、GKE、BigQuery、Google Dataflowなどサービスを展開しているGoolge Cloud Platformです。

2016年3月27日
から hiruta
Google Cloud FounctionsからBigQueryへのアクセス #gcpja #gcpug はコメントを受け付けていません

Google Cloud FounctionsからBigQueryへのアクセス #gcpja #gcpug

Google Cloud Founctionsからgcloudのnode.js moduleでbigqueryにアクセスをしてみました。

が、デプロイ失敗。

$ gcloud alpha functions deploy bigquerytest --bucket XXXXX-deploy --trigger-http
Copying file:///tmp/tmp6OEBwr/fun.zip [Content-Type=application/zip]...
Uploading ...deploy/us-central1-bigquerytest-zyupwaipvuxb.zip: 16 MiB/16 MiB
Waiting for operation to finish...failed.
ERROR: (gcloud.alpha.functions.deploy) OperationError: code=13, message=Error during function code deployment: User function failed to load: Code in file index.js can't be parsed. Please check whether syntax is correct.
Detailed stack trace: Error: Module version mismatch. Expected 14, got 46.
at Error (native)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/user_code/node_modules/gcloud/node_modules/grpc/src/node/src/grpc_extension.js:38:15)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)

モジュールバージョンが合っていないエラーのようだ。

Alphaテスター用google group(cloud-functions-trusted-testers)だと、同じ症状が起きている方の回答を見ると、0.12.7で動くとのこと。

I’ve changed the version of node.js gcloud dependency to 0.28.0 and it has fixed the problem.
What version of node.js are you using ? The function runs under node.js in version 0.12.7.

Ubuntu 14.10には下記node.jsのバージョンがインストールされている。新しめのが入っていた。

hiruta@ubuntu:~$ node -v
v4.4.0
hiruta@ubuntu:~$ npm -v
2.14.20

該当するnode.jsをダウンロードして試してみました。

$ wget https://nodejs.org/download/release/v0.12.7/node-v0.12.7-linux-x64.tar.gz 

パッケージjsonも作成。

$ cat package.json
{
"name": "bigquerytest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"gcloud": "^0.28.0"
},
"devDependencies": {},
"scripts": {
"test": "npm test"
}
}
 npm install gcloud --save 

vi index.js
var gcloud = require('gcloud')({
projectId: '<PROJECT ID>'
});

exports.bigquerytest = function (context, data){
var bigquery = gcloud.bigquery();

var query = 'SELECT url FROM [bigquery-public-data:samples.github_nested] LIMIT 20';
bigquery.query(query, function(err, rows, nextQuery) {
if (err) {
console.log('err::', err);
}
console.log(rows);
if (nextQuery) {
bigquery.query(nextQuery, function(err, rows, nextQuery) {});
}
console.log(rows);
});
context.success();
};

credentialsは別段指定する必要がない。Backendのインスタンス(alpha版の場合、GKE)でCloud APIへのアクセスが許可されているため。
ただし、projectIdの記載は必要です。

$  gcloud alpha functions deploy  bigquerytest  --bucket XXXXX-deploy --trigger-http

デプロイが成功したら、Functions用のHTTP(S) Endpointsにアクセスしてみます。

$ curl -X POST <Functions用のEndPoinit>

ログに、BigQueryから情報が取得できています。

$ gcloud alpha functions get-logs

また、GCSにnginx等のアクセスログを退避して、Cloud FounctionsでBigQueryにinsertするユースケースにも使えると思われます。

2016年3月12日
から hiruta
Google Cloud Functions 試用レポート #gcpja #gcpug はコメントを受け付けていません

Google Cloud Functions 試用レポート #gcpja #gcpug

gcf_email_img

AWS LambdaライクなEvent Driven なサービスがGoogle Cloud Platformにも、以前書きましたが、
Google Cloud Functionsが使えるようになりましたので、レポートします。

まずは、プログラムコードをアップロードするGCSバケットを作成しておきます。

$ gsutil mb gs://BUCKET/
 $ mkdir helloworld; cd helloworld 

まずは、お約束なhelloworldから

$ vi index.js
exports.helloworld = function (context, data) {
context.success('Hello World!');
};

次に、コードのデプロイ。実行トリガーとして、HTTPトリガーを指定しています。HTTPトリガーはAWS API Gatewayに近い。
ただし、HTTP POSTのみ対応しており、GETは現状未対応になります。
トリガーとして、GCS、Google Pub/Subがそのほかに対応しています。

Cron トリガーについては、テスター用のGoogle Groupで今後対応しそうなdiscussionがありました。

Cron triggering for Cloud Functions is on our radar.

$ gcloud alpha functions deploy helloworld --bucket BUCKET --trigger-http
Copying file:///tmp/tmpjPc7fq/fun.zip [Content-Type=application/zip]...
Uploading ...g-deploy/us-centra
l1-helloworld-mtlxhowupkjw.zip: 193 B/193 B
Waiting for operation to finish...done.
entryPoint: helloworld
gcsUrl: gs://BUCKET/us-central1-helloworld-mtlxhowupkjw.zip
latestOperation: operation-adc6aebf-e0d9-471e-92fb-8cdf865fc206
name: projects/PROJECT_ID/regions/us-central1/functions/helloworld
status: READY
triggers:
- webTrigger:
url: https://us-central1.PROJECTID.cloudfunctions.net/helloworld

初回のデプロイは、GKE Clusterを作成する(クラスタ数2)ので、多少時間がかかります。

$ curl -X POST https://us-central1.PROJECTID.cloudfunctions.net/helloworld
Hello World!

Cloud Function用のSSL証明書として、Let’s Encrypt Authority X1が使われていることを確認。

画像4

実行ログを確認すると、functionsコールは1 ms。

$ gcloud alpha functions get-logs helloworld
LEVEL NAME EXECUTION_ID TIME_UTC LOG
D helloworld - 2016-03-12 00:36:54.512 User function helloworld loaded
D helloworld OLsMt0WnTFFG-0 2016-03-12 00:38:20.796 User function triggered, starting execution
D helloworld OLsMt0WnTFFG-0 2016-03-12 00:38:20.797 Execution took 1 ms, user function completed successfully

最後に、Cloud Founctionsの削除。


$ gcloud alpha functions delete helloworld
Resource [projects/PROJECTID/regions/us-central1/functions/h
elloworld] will be deleted.

Do you want to continue (Y/n)? y

Waiting for operation to finish...done.
Deleted [projects/PROJECTID/regions/us-central1/functions/helloworld].

Google Cloud Functions削除してもGKE cluterが削除されません。GKEクラスタはn1-standard-1(クラスタのタイプは変えられない?)。

GKE Clusterを頻度に削除すると、週5の証明書の制限に抵触して接続が行えなくなることがあります。

I inspected your logs – we are not really supporting a model in which you would remove clusters that often
(after every deployment).
That is why you got issues with HTTPS (hitting limit on number certificates,
currently 5 per week for whole project). HTTP (without S) endpoint should be fine.

The workaround would be not to remove clusters after each “test” – instead let them run –
you should get a coupon from us to finance it for a while.

 

実行環境のDebianの実行コマンドをnode.jsから実行させることもむろん可能です。


$ vi index.js
var exec = require('child_process').exec;

exports.sampletest = function ( context,data) {
child = exec(data.cmd, function (error) {
context.done(error, 'Process complete!');
});

child.stdout.on('data', console.log);
child.stdout.on('data', console.error);
};
$ gcloud alpha functions deploy sampletest --bucket cms-stg-deploy  --trigger-http
$ curl -X POST https://us-central1.PROJECTID.cloudfunctions.net/sampletest --data '{"cmd":"cat  /etc/debian_version"}'
$ gcloud alpha functions get-logs
sampletest nRrOVegpcqrn-0 2016-03-12 01:11:34.008 7.9

Cloud Functionsの実行環境としてはDebian 7.9が使われていますことがわかります。BigQuery、DataStoreとの連携も可能かと。BackendでVMインスタンスが利用されていますが、インスタンスの管理が低減できる。

現在以下Execution Failureがあるようです。

  • リトライの保証はないが、60秒間隔で2回行われること
  • 最大実行時間60秒(デフォルトでデプロイ時に変更可能)
  • Functionsが無限ループを起こす場合、ブロックされる。

2016年2月25日
から hiruta
無料SSL証明書Let’s Encrypt 導入してみました。 はコメントを受け付けていません

無料SSL証明書Let’s Encrypt 導入してみました。

https://letsencrypt.org/ 無料SSL証明書を導入してみました。

letsencrypt-autoを実行すると、必須パッケージをもろもろダウンロード、インストールを自動で行ってくれます。

./letsencrypt-auto certonly --webroot --webroot-path /www -d <domain> -d www.<domain>

GCP HTTP Load balancerで使うためには、global forwarding ruleを追加します。

screencapture-console-cloud-google-com-networking-loadbalancing-http-details-web-map-globalForwardingRules-add-1456408980943

上記Certificateから、SSL証明書、秘密鍵、中間証明書を登録します。

GCP HTTP Load balancerにも発行した証明書を登録できました。ただ、中間証明書は、letsencrpt-autoコマンドで作成されたものではなく、下記から取得しました。中間証明書は、Let’s Encrypt Authority X2でなく、Let’s Encrypt Authority X1を使います。

https://letsencrypt.org/certificates/

Redirect Loopを防ぐのに、nginxの設定を一部変更しています。

location / {
root /www;
index index.php index.html index.htm;
if ($http_x_forwarded_proto = "http") {
rewrite ^/(.*)$ https://www.domain/$1 permanent;
}

また、ブログとしてWordpressを利用している場合、wp-config.phpも変更します。

define('FORCE_SSL_ADMIN', true);
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
$_SERVER['HTTPS']='on';
}

ただ、Let’s EncryptのSSL証明書は三ヶ月と短いので、更新の自動化は必要かと。

SSL証明書の更新自動化は下記を使えばできそうか。

gcloud compute ssl-certificates create NAME --certificate LOCAL_FILE_PATH --private-key LOCAL_FILE_PATH [--description DESCRIPTION] [GLOBAL-FLAG …]
gcloud compute target-https-proxies update NAME [--ssl-certificate SSL_CERTIFICATE | --url-map URL_MAP] [GLOBAL-FLAG …]

2016年2月14日
から hiruta
Google Cloud Functionsアルファー版公開 #gcpja はコメントを受け付けていません

Google Cloud Functionsアルファー版公開 #gcpja

Google Cloud Functionsがアルファー版公開。

ついに、GCPでもサーバーレスアーキテクチャー

現時点で公式に公開されている情報をまとめてみました。

https://cloud.google.com/functions/docs

マネージドサーバー、実行環境なしで特定機能を利用できるイベントベース非同期のコンピュートソリューション

AWS LambdaのGCS版てところ。

  • マネジードのNode.js実行環境上で実行することができる。
  • イベントトリガーは、Google Cloud Storage、Cloud Pub/Subからのイベントをトリガに実行できる
    ※スケジュール機能はdocsから見る限り現時点ではなさそうな印象

GCS(Google Cloud Storage)をトリガーとして対応しているので、GCSに蓄積されるbilling ログをBigQueryに入れる実装が可能になると思われます。

ログはCloud Loggingに出力されます。
data パラメータにCloud Pub/Subあるいは、Google Cloud Storageバケットから送られたメッセージが含まれているようです。BigQuery Client libraries なども使えるのではと思われます。

module.exports = {
helloworld: function (context, data) {
if (data.message !== undefined) {
// Everything is ok
console.log(data.message);
context.success();
} else {
// This is an error case
context.failure('No message defined!');
}
}
};

gcloud コマンドでデプロイ、ログ確認、テスト実行等が行えるようですが、Web UIから行えるかは不明。

Cloud Functionsの実行時間等Limitの情報はdocsから確認することができない。制限があるかも不明。

2016年2月14日
から hiruta
Googe Cloud Vision GCSに対応 #gcpja はコメントを受け付けていません

Googe Cloud Vision GCSに対応 #gcpja

Cloud Vision Early Access ProgramのGoogleグループに流れていたことですが、Cloud Visionは、Google Cloud Storageの画像を読み込むことが可能になっています。

ようやく動作できるように(解析結果がレスポンスデータとして戻ってくるように)なりましたので、サンプルコードを掲載します。

下記ソースのbatch_requestのところがポイント。


from PIL import Image
from PIL import ImageDraw
from pprint import pprint
# The url template to retrieve the discovery document for trusted testers.
DISCOVERY_URL='https://{api}.googleapis.com/$discovery/rest?version={apiVersion}'

def get_vision_service():
credentials = GoogleCredentials.get_application_default()
return discovery.build('vision', 'v1', credentials=credentials,discoveryServiceUrl=DISCOVERY_URL)

def main():

batch_request = [{
'image': {
'source': {
'gcs_image_uri': "gs://XXXXXXXXX/top-bnr-70.png"
}
},
'features': [{
'type': 'FACE_DETECTION',
'maxResults': 30,
}]
}]

service = get_vision_service()
request = service.images().annotate(body={
'requests': batch_request,
})
response = request.execute()
pprint(response['responses'][0])

faces = response['responses'][0]['faceAnnotations']

Googleでは、Google Cloud Visionだけでなく、音声認識、Google Photo等Deep Learningをすでに運用されているので、Google Cloud Visionも解析にDeep Learning技術を使用しています。

Deep LearningのFrameworkとして切り出して公開されているのが、TensorFlowになります。(分散環境に対応したTensorFlowも公開されるとのこと)

TensorFlowは複数台の分散環境(40G portsのスペックを有しているJupiter network)で初めて性能を発揮します。スタンドアロンでは性能を発揮できません。つまり、TensorFlowをAWSのGPインスタンスで動かしても期待して性能がでません。

なお、Google Cloud Vision は、数週間後パブリックβでだれでも使用できるようになるようです。

2016年2月11日
から hiruta
Hadoop Spark Conference 2016参加レポート #hcj2016 はコメントを受け付けていません

Hadoop Spark Conference 2016参加レポート #hcj2016

2/8 のHadoop Spark Conference 2016 参加サポートです。今回はSpark Conference 併催になります。1,300名を超える申込者と人気で、各セッション立ち見も出るほど1日中熱気に満たしていました。

キーノート

Hadoopはひとつものではなくなった。

従来は、HDFS+MapReduceが中核でしたが、組み合わせで使っていく方向に。

パッケージの多様化。

並列分散エンジン(Apache Tez)も登場し、現在変化も激しいので、現在の状況を見ておくことが重要

hadoop上で多様なエコシステムが動作している。

バッチ処理をストリーミング処理を透過的に行えるものも。Google Dataflow (Apache Beam)

https://cloud.google.com/dataflow/blog/dataflow-beam-and-spark-comparison

ResourceManagerであるYARNもCPUだけでなく、GPCPUなどにも焦点を置く方向に。

HDFSについても、SSD、メモリの活用で中間データのR/Wの高速化

無停止でローリングアップデート

メンテナンスリリース(2.6、2.7)の継続、Java8対応

Spark 2.0

ユースケースてには、BIが一番。Dataware、レコメンドエンジン、ログ、不正検出等にも

サブクエリー、ビューもDataFrames APIで

Tungsten backendでStreamingの課題を解決

Next-gen Streaming with Dataframesは数週間後発表があるので

Spark 2.0では、125 million rows/secのベンチ結果も。(1.6では13.95 milliion rows/sec)

今年4月~5月にリリース予定。

JVMチューニング

heap memoryのサイズを変更するだけでパフォーマンスが変わる

Spark 1.6ではGCのオーバーヘッドが減っている

ストリーミングアーキテクチャー StateからFlowへ

3-Tierとマイクロサービスの違い

従来のバッチの有限の入出力に対し、ストリーミングは、無限の入出力、サービス間遅延にも考慮が要

非同期なサービス間疎結合の設計が必要

これに対応できるのが、Kafka、MapR Stream

ビックデータ可視化の性能を検証

DWHに比べて、デフォルト設定のHiveは遅い

Spark SQLは、ヒット件数が多だと、1/2

チューニングポイント

エグゼキュータ、パーティション数

データフォーマット

Hive

分散処理エンジンにMR使用している場合は、Apache Tezへの切替を

 

MLLib Now and Beyond

[slideshare id=58034098&doc=2016-02-06spark-conference-japan-160209041021]

手軽に機械学習を扱うことができる

DataSetとDataFrameは今後統合予定

MLLib Pipeline API

Modelを、S3他クラウドストレージに保存することもできるが、永続化に対応していないアルゴリズムもあるので注意が必要

MLLib 2.0 Roadmap

時系列データのSparkでの処理

時系列データをSparkで扱うと不便になるのでは?

が、結論時系列データも問題なく扱える。

Hive on Spark

Hiveは遅い。Hiveクエリによっては、数時間、1日かかるケースも

Hive on Sparkは、HiveQ互換なので、Hive資産の再利用も可能、バッチ処理が1/3になる。

また、Spark on elasticSearch -hadoop データの可視化ツールとして導入コストも低くそうな印象でした。standaloneのSpark 1.6の環境で試してみよう。

2016年2月7日
から hiruta
Instance GroupでAutoHealingに対応 #gcpja はコメントを受け付けていません

Instance GroupでAutoHealingに対応 #gcpja

Instance Templates、Instance Group(AWSだとAutoScaling)を使う場合、以前はheath checkに失敗していも、インスタンスのre-createが行えなかったが、(いつからはわかりませんが)heath checkがNGの場合、インスタンスを作り直してくれるAutoHealingに対応しています。GCE(Google Compute Engine)の場合、0.5sでパケロスなしで別の仮想サーバーにマイグレーションと組み合わせることで可用性を高めることも可能。

screencapture-console-cloud-google-com-compute-instanceGroups-details-asia-east1-a-instance-group-1-1454847528634

揮発性ディスクであるLocalSSDをインスタンスに対して8diskまで付けることも可能。LocalSSDは、ディスク容量375GBかつ高いディスクIOを特徴をもっている。f2-microでもLocalSSDは使用可能。

screencapture-console-cloud-google-com-compute-instancesAdd-1454847393294

2016年1月31日
から hiruta
Google Cloud Visionでランドマーク認識 #gcpja はコメントを受け付けていません

Google Cloud Visionでランドマーク認識 #gcpja

Google の画像認識APIであるGoogle Cloud Visionが使えるようになりましたので、少しいじってみました。

Google Cloud Visonは、物体検知、有害コンテンツ検知、ランドマーク検知、OCR、顔検知など画像の情報を抜き出すことが可能です。REST APIでGoogleサイドと通信していると想定される。

Vision用のService Accountを作成し、credentialsの設定をするしておく必要があります。

export GOOGLE_APPLICATION_CREDENTIALS=deeplearning-environment-78bacd3d4b5b.json

Google APIにアクセスするのに、API discovery documentをベースとしたservice objectを作成する。GAリリースしたものは自動でfetchされるのだが、Vision APIは、alphaリリースなので、下記よりダウンロードする必要があります。

https://cloud.google.com/vision/docs/vision_discovery_v1alpha1.json

def get_vision_service():
 credentials = GoogleCredentials.get_application_default()
 with open(API_DISCOVERY_FILE, 'r') as f:
 doc = f.read()

 return discovery.build_from_document(
 doc, credentials=credentials, http=httplib2.Http())
LABEL_DETECTION  ラベル
FACE_DETECTION 顔認識
LANDMARK_DETECTION ランドマーク認識
TEXT_DETECTION OCR
LOGO__DETECTION ロゴ
SAFE_SEARCH__DETECTION  有害情報検知
SUGGESTION_DETECTION

以下ランドマーク認識の例です。以下で画像データをbase64にエンコードし、Vison APIに渡しています。

 with open(photo_file, 'rb') as image:
 image_content = image.read()
 batch_request = [{
 'image': {
 'content': base64.b64encode(image_content)
 },
 'features': [{
 'type': 'LANDMARK_DETECTION',
 'maxResults': 4,
 }]
 }]
 service = get_vision_service()
 request = service.images().annotate(body={
 'requests': batch_request,
 })
 response = request.execute()

IMAG0142

過去デジカメで撮影した写真を解析すると大阪城(Osaka Castle)として認識されています。位置情報もばっしり。

 {u'responses': [{u'landmarkAnnotations': [{u'locations': [{u'latLng': {u'latitude': 34.686777, u'longitude': 135.525799}}], u'score': 0.613115, u'mid': u'/m/024b_g', u'boundingPoly': {u'vertices': [{u'y': 955, u'x': 1545}, {u'y': 955, u'x': 2411}, {u'y': 1346, u'x': 2411}, {u'y': 1346, u'x': 1545}]}, u'description': u'Osaka Castle'}]}]}

TEXT_DETECTIONを使うと、ちらし画像から文字情報を取り出す(OCR)することもできます。

顔認識は、認識したポリゴン点の座標(fdBoundingPoly)を返してくれます。ただ、画像の中のすべての顔を認識してくれない、顔認識に失敗するケースがあるようです。

2016年1月26日
から hiruta
Autorecoveryの致命的な仕様 はコメントを受け付けていません

Autorecoveryの致命的な仕様

インスタンスの自動復旧機能として、Auto recoveryが用意されています。一時的な障害、インスタンスストアがアタッチしている、1日3度のリカバリのリトライに失敗する際、Auto recoveryを諦めるという運用上致命的な仕様があります。諦めたインスタンスの復旧は手動でstop/startを行えること。Autorecoveryを復旧手段に頼るのはやめるのがいいかもしれません。

screencapture-docs-aws-amazon-com-AWSEC2-latest-UserGuide-TroubleshootingInstanceRecovery-html-1453810845891

上記仕様については、トラブルシューティングで記載されております。(トラブルシューティングは英語版ドキュメントのみです。)

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstanceRecovery.html

この一方、GCEは稼働中のVMを0.5sでパケロスなしで別の仮想サーバーに移動してくれる。(http://qiita.com/kazunori279/items/41520689337a644a87b4 にGoogleの中の人が詳しく書いています。)

本ブログ稼働中のGCEインスタンスは100day連続稼働中です。instance template差し替え後止まっていないじゃないかと。

2016年1月24日
から hiruta
GCE間ネットワークのスループット #gcpja はコメントを受け付けていません

GCE間ネットワークのスループット #gcpja

ツイートに以下がありましたので、

iperf3で実際GCE間スループットを計測してみました。Preemptible VMでも制限されることなく、2Gbit/secでます。

同じリージョン間

0.00-10.00  sec  2.33 GBytes  2.00 Gbits/sec  491             sender

異なるリージョン間

.00-10.00  sec   131 MBytes   110 Mbits/sec   59             sender

2Gbits/secのスループットが出るのは、同一リージョンのGCE間になります。
異なるリージョンのGCEでも同じNetworkに属しているなら、Private IPで通信が可能。GCPの場合、リージョンを意識しないシステム構成も可能です。