クラウドインフラ構築記

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

2017年1月18日
から hiruta
Serverless Meetup Tokyo vol.2に参加しました。 #serverlesstokyo はコメントを受け付けていません。

Serverless Meetup Tokyo vol.2に参加しました。 #serverlesstokyo

昨日Serverless Meetup Tokyo vol.2に参加しました。

Tune up AWS Lambda

Lambdaのパフォーマンスに関する話

知っておくべきこと

  • 同時実行数 ある時点にfunctionsが実行される数
    • ストリーム別
      •  シャードの数を大きくするとスケールしていく
      •  Lambdaの実行数は、シャードの数とイコール

セーフティガードとして、Limit = 100

    • それ以外
      •   一秒あたりのイベント数*実行時間

APIGatewayの時は秒間のリクエスト30s 30rps

同時実行数の制限緩和も可能だけど、実績がない場合は通らない。

実施にThrottleされているか確認

  • ライフサイクルコめコンテナ  Sandbox として動いている。dockerではない
    • 開始 コンテナ作成されて、コンテナ内にロード・展開(コールドスタート)
    • 終了
    • 再利用※時間が経っていない場合は、再利用される
      • 初期化処理は再利用されるのでパフォーマンス的なアドバンテージがある
      • 再利用されるとは保証するわけではない
  • パフォーマンス関連
    • メモリ設定

コンピューティング全体の設定なので、CPU必要な場合はあげるといい

    • バッチサイズ

 一度に取得する最大のレコード数

シャード数増やすことで同時処理数も増えるので、どちらがいいかはワークロード次第

  • Lambda functionを速くする方法
    • 定常的にリクエストする

ファンクションにたいしてPingするなり、ポーリングする処理を実装する

推奨の間隔は五分

    • コンピューティングリソースを増やす
    • 言語を変える

スピンアップの順番は、Java <  C# <  python < node.js

    • VPC使わない

ENIの生成、アタッチ処理は遅い

    • パッケージサイズを小さくする

Javaの場合、ProGuard等難読化ツールでパッケージを小さくできる

Lambdaの場合、使用するモジュールをコードに同封しないといけない。

    • グローバルスコープ
    • 同時実行性

インフラエンジニア”リング”レスアーキテクチャ

AzureFunctions 処理数1,200/ ピーク 3,700/分捌いている。

AzureFunctionsは、bashでコードを書ける。Functions内で、perlも使えてしまう。

Serverless AWS構成でセキュアなSPAを目指す

Cloudfront + Amazon S3に一応Serverless

API Gateway + Lambdaになってしまうので、レイテンシ問題がある

Google Cloud FunctionsとかAzureFunctionsだとHTTP(S) Trigger機能があるので、レイテンシでどの程度違うかは別途検証してもようと。

STSのCredential有効期限(最大1H)とCognito Token(最大24H)なので、気をつける

Json Web Token https://blog.kazu69.net/2016/07/30/authenticate_with_json_web_token/

Data + No-Ops

データ処理、No-Opsでできる

プラットフォーム作らないくてもいい

より良いソフトウェアを作るのに力を費やすのがいい

Googleでは、Billionユーザの大きなデータを日々受け取っている

BigQuery の外にあるデータも分析できる

https://cloud.google.com/bigquery/external-data-sources

Bigqueryでは、構造化したデータしか扱えないので、複雑な処理はGoogle Dataflow

2016年12月29日
から hiruta
Google Cloud FunctionsでLINE Botサーバーを立てる #gcpug #gcpja はコメントを受け付けていません。

Google Cloud FunctionsでLINE Botサーバーを立てる #gcpug #gcpja

Cloud Functions でLINE Botサーバーを立ててみました。

LINE BOTアカウントの作成、LINE@MANAGERの設定は以下を参照

http://qiita.com/saitoryc/items/9f5833495d1e0453e052

AWS Lambdaの場合API Gatewayと併用しないといけないが、Google Cloud FunctionsだとHTTP Triger (HTTPS)でFunctionsを実行できるので、便利です。

LINE BOTサーバーはHTTPS通信できることが必要ですが、Cloud functions HTTP TriggerはHTTPSに対応済みなので、この点問題はありません。

実際のコードですが、Cloud Functions用の引数に変更する点と、HTTP通信でMessageAPIサーバに送信する際、Content-Lengthヘッダーを付与するようにしています。付与しないとMessageAPIサーバーからBad Requestと返ってきます。この点、LINE developersのドキュメントには記載されていません。


var gcloud = require('gcloud')({
projectId: process.env.GCP_PROJECT
});
var https = require('https');
var channel_access_token = '[ACCESS TOKEN]';

exports.linebot = function (req, res) {
var json = req.body;
json.events.forEach ( function(message,index){
events = message;
});
var postData = {
"replyToken" : events.replyToken,
"messages" : [
{
"type" : "text",
"text" : events.message.text
}
]
};
var options = {
hostname: 'api.line.me',
path: '/v2/bot/message/reply',
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "Bearer " +channel_access_token,
"Content-Length": JSON.stringify(postData).length
},
method: 'POST',
};

var req = https.request(options, function(res){
res.on('data', function(chunk){
}).on('error', function(err){
console.log(err);
}).on('end', function(){
console.log('finish sending text message');
});
});
var sendData = JSON.stringify(postData);
req.write(sendData);
req.end();
};

Cloud Vision APIとかGoogleAPIと連携も可能かと思われます。

Content-Lengthで文字数をカウントする際、postData.lengthの代わりにBuffer.byteLength (postData)で文字数をカウントすることで日本語とかも送信が可能になりました。

2016年12月18日
から hiruta
ParquetデータをAmazon Athenaで検証してみました。 #jawsug #gcpug はコメントを受け付けていません。

ParquetデータをAmazon Athenaで検証してみました。 #jawsug #gcpug

BigQueryで公開データとして公開されているNOAA Global Historical Climatology Network の天候データを、エクスポートして、Amazon Athenaで使用してみました。

Column-oriented フォーマットにカテゴリ分けされる Parquetに変換して検証してみました。

ParquentへのConvertはApache Drillを使用

0: jdbc:drill:zk=local> ALTER SESSION SET `store.format` = 'parquet'
. . . . . . . . . . . > ;
+-------+------------------------+
| ok | summary |
+-------+------------------------+
| true | store.format updated. |
+-------+------------------------+
1 row selected (1.655 seconds)

CTASクエリでの変換だと、VARCHARとして扱われてしまうので、カラム毎の型を設定しておく必要があります。それをしないと、Athenaでクエリ実行時、internal errorとなってしまいます。

0: jdbc:drill:zk=local> CREATE TABLE dfs.tmp.`/ghcnd_2016/` AS SELECT
. . . . . . . . . . . > id,
. . . . . . . . . . . > `date`,
. . . . . . . . . . . > `element`,
. . . . . . . . . . . > CAST(`value` AS FLOAT) AS `value`,
. . . . . . . . . . . > mflag,
. . . . . . . . . . . > qflag,
. . . . . . . . . . . > sflag,
. . . . . . . . . . . > `time`
. . . . . . . . . . . > FROM dfs.`/tmp/ghcnd_2016_ja.csvh`;
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
+-----------+----------------------------+
| Fragment | Number of records written |
+-----------+----------------------------+
| 0_0 | 174292 |
+-----------+----------------------------+
1 row selected (3.755 seconds)

気象観測所のデータはCTASクエリによる変換で済ませています。

ParquentのファイルをS3にアップロードし、Athenaのテーブルを作成します。

CREATE EXTERNAL TABLE IF NOT EXISTS athena_test_1.ghcnd_2016 (
id string,
date string,
element string,
value float,
mflag string,
qflag string,
sflag string,
time string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://athena-test-data01/parquent/ghcnd_2016/';
CREATE EXTERNAL TABLE IF NOT EXISTS athena_test_1.ghcnd_stations (
id string,
latitude float,
longitude float,
elevation float,
state string,
name string,
gsn_flag string,
hcn_crn_flag string,
wmoid int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://athena-test-data01/parquent/ghcnd_stations/';

データ数は以下となっています。

ghcnd_2016 174292
ghcnd_stations 100820

Amazon Athenaの実行結果

Row-orientedのCSVファイルの結果。データスキャンサイズが、Column-orientedの場合に比べて、4倍。

BigQueryでの実行結果

BigQueryと比較して、2秒差、スキャンサイズがBigQueryの1/2の結果になりました。

 

2016年12月9日
から hiruta
Google Cloud Functions で環境変数を使うには(Tipsネタも) #gcpug はコメントを受け付けていません。

Google Cloud Functions で環境変数を使うには(Tipsネタも) #gcpug

Google Cloud Platform(1)  Advent Calender 12/10分で書きました。

Runtime Configurationsはまだα版なので、今後仕様が変わる可能性があるかもしれません。

AWS Lambda、Azure Functionsとかでは、環境変数を扱えるので、Google Cloud Functionsでも使いたい願望が。

現状、Google Cloud functionsで環境変数を扱うことはできない。

ただ、Google Cloud FunctionsのEarly Access用Google Groupに環境変数を対応する予定があるか、聞いたところ、現状Runtime Configuration FundamentalsでGoogle Cloud Client libraryでは、対応しておらず、low-level APIのRuntime Configurationで行う必要がる。(Google Cloud Client libraryで対応してほしい。)

Runtime Configurationが対応しているGoogle APIはv1、v2には対応していないので注意。

https://cloud.google.com/deployment-manager/runtime-configurator/

Runtime Configの作成

gcloud alpha deployment-manager runtime-configs create functions-prod
gcloud alpha deployment-manager runtime-configs variables set TEST-KEY abcd1234efgh5678 --config-name functions-prod 

function auth (callback) {
var google = require('googleapis');
google.auth.getApplicationDefault(function (err, authClient) {
if (err) {
callback(err);
return;
}

if (authClient.createScopedRequired && authClient.createScopedRequired()) {
authClient = authClient.createScoped([
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/cloudruntimeconfig'
]);
}
callback(null, authClient);
});
}

function getVariable(configName, variableName, callback) {
var google = require('googleapis');
var config = google.runtimeconfig('v1beta1');

var fullyQualifiedName = 'projects/' + process.env.GCLOUD_PROJECT +
'/configs/' + configName +
'/variables/' + variableName;

auth(function(err, authClient) {
config.projects.configs.variables.get({
auth: authClient,
name: fullyQualifiedName
}, function(err, variable) {
if (err) {
callback(err);
return;
}
// decode the value as values are saved as base64-encoded strings
callback(null, Buffer.from(variable.value, 'base64').toString());
});
});
}

exports.myFunction = function (req, res) {
getVariable('functions-prod', 'TEST-KEY', function(err, stripeKey) {

// do something involving "stripeKey"

res.send('OK');
});
};

GoogleAPIs Node.js clientは8.0.0で確認。

また、Functionsでエラーになった場合、ErrorReportingと連携できるようになっています。

screencapture-console-cloud-google-errors-13056176819937875897-1481114893469

 

functions.env 変数でRuntime Configの環境変数を取れるようになるらしい。

As an FYI for anyone using the Firebase tools for Cloud Functions, the functions.env variable is built using Runtime Config as well.

Tipsネタをいくつか。

GCSトリガーでfunctionsを実行する際、lacks permissionとか発生するケースが。

edit object default permission でcloud functions用Service Account (Service Account名はCloud functionからBigQueryに登録した際にエラーメッセージの中から見つけました)を登録することで解決。以前はこの設定なくてもうまくいっていたんだけど。

error_2

Google Cloud Clinent library for node.jsのバージョンによって、発生しました。発生したバージョンは、0.35.0。Google Cloud Client library は、0.44もでているようだが、使えないバージョンもあるので、注意が要。動作がOKだったバージョンは、0.28.0でした。

error_3

12/9 の0:00ごろ?WEB Consoleでcloud functionsのインライン編集に対応していました。新規でfunctionsを作成すると、現仕様のサンプルコードが自動生成されます。下記はCloud Vision APIでLabel Detectionを使う例になります。package.jsonの編集にも対応していて、便利です。

inlineditor

 

2016年12月5日
から hiruta
Amazon AthenaのPartitioningについて #jawsug #gcpug はコメントを受け付けていません。

Amazon AthenaのPartitioningについて #jawsug #gcpug

https://cloud.google.com/storage/docs/public-datasets/landsat からダウンロードできるデータで、Amazon Athenaをつかって、クエリを実行してみました。

テーブル構成は以下の通りです。

CREATE EXTERNAL TABLE athena_test.landsat_data_csv (
SCENE_ID STRING,
PRODUCT_ID INT,
SPACECRAFT_ID STRING,
SENSOR_ID STRING,
DATE_ACQUIRED DATE,
COLLECTION_NUMBER STRING,
COLLECTION_CATEGORY STRING,
SENSING_TIME timestamp ,
DATA_TYPE STRING,
WRS_PATH INT,
WRS_ROW INT,
CLOUD_COVER decimal ,
NORTH_LAT decimal,
SOUTH_LAT decimal,
WEST_LON decimal,
EAST_LON decimal,
TOTAL_SIZE decimal,
BASE_URL STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
LOCATION 's3://athena-test-data01/csv/';

単一のCSVでは、Partitioningでデータスキャンする容量を減らすことは不可。(Partitioningのために、S3上でフォルダが分かれてファイルが配置されていないといけないため)

Amazon Athenaの課金は、スキャンするサイズによるので、課金にもろ響きます。Athena破産の可能性も。

screencapture-console-aws-amazon-athena-home-1480936289615

データスキャンした容量は、968MB (CSVのファイルサイズと同じなので、全スキャン)が読まれます。

screencapture-bigquery-cloud-google-results-cms-production-1225-bquijob_780f3acf_158cebfd84f-1480937513091

一方、同じクエリでBigQueryで実行させるとほとんどスキャンされないで結果が返る。

BigqueryのようなことがAthenaでできると思ったら、間違いです。

2016年12月4日
から hiruta
GCPUG Shonan vol.9 (re:dash、Data Studio)によるVisualization #gcpug はコメントを受け付けていません。

GCPUG Shonan vol.9 (re:dash、Data Studio)によるVisualization #gcpug

GCPUG Shonan vol.9が本日ありました。お題は、BigQueryのデータのre:dash、DataStudioによるVisualization(可視化)でした。

サンプルデータのBigQueryへのインポート

 bq load --source_format=CSV --field_delimilter=',' --skip_loading_rows=1 --max_bad_records=1000 redash_shonan_handon.taxi gs://bq_shonan_handon/taxi.csv ./schema.json

Cloud Launcherにより、re:dashインスタンスの作成

※re:dash自体は、mac os x上のDocker上にも作ることは可能です。

IAMの設定だけでは、BigQuery Userの権限を与えておいても、re:dashでSELECT SQLすら権限がないよとなっていまいます。

Error running query: { "error": { "errors": [ { "domain": "global", "reason": "accessDenied", "message": "Access Denied: Table XXXXXXXXXXXXXXXXXXX:billing.201612: The user bqclient@XXXXXXXXXXXXXXXXXXX.iam.gserviceaccount.com does not have permission to query table XXXXXXXXXXXXXXXXXXX:billing.201612." } ], "code": 403, "message": "Access Denied: Table XXXXXXXXXXXXXXXXXXX:billing.201612: The user bqclient@XXXXXXXXXXXXXXXXXXX.iam.gserviceaccount.com does not have permission to query table XXXXXXXXXXXXXXXXXXX:billing.201612." } }

BigQueryのdatasetにおいて、Share datasetで最低Service Account名で権限を付与する必要があります。

screencapture-bigquery-cloud-google-queries-cms-production-1225-1480852442942

BigQueryの権限付与もIAMで一括して行ってほしい。

re:dash自体、0.12.0+b2449 (Cloud Launcherのばーじょんは少し古い)となっており、発展途上なところもあり、使い勝手的に?なところもあります。

Google Data Studio ( FREE版はレポートは5つまで)の紹介。re:dashはSQL(legacy SQL/Standard SQL)で組み立てるのが、Data Studioは、クエリの組み立てのカスタマイズは高くない。ただ、緯度経度情報があれば、MAPのコンポーネントがあるので、地図上にBigqueryのデータをplotすることは可能。コンポーネントについては揃っているように見えました。

(おまけ)re:inventで発表されたAmazon Athenaについて

Amazonが、BigQueryを意識して作ったと思いますが、Partitioning しないとCOUNTでもすべてのデータをスキャンしていまうこと。Partitioning Data することで、スキャンする量を制限はできそうですが。

Colossusの仕組みをAthenaで実現するのは不可能ではと思われる。

 

2016年11月13日
から hiruta
GCPUG しょうなん vol.8勉強会に参加しました。 #gcpug はコメントを受け付けていません。

GCPUG しょうなん vol.8勉強会に参加しました。 #gcpug

GCPUG しょうなん 一周年記念パーティとあり、GCP、GAEの2パネルディスカッションで進行しました。

スイートとかN.Gの話とかもありましたので、ここに書けないことも。

  • 東京リージョンの話

asia-east-1だと、時間により速度にむれがあるが、東京リージョンは安定している。

東京リージョンのWindows Serverインスタンスでデータコピーが速い

  • BigQuery

某データウェア製品と比べても、BigQueryはお安くできてしまう。

Bigqueryは、viewとか作成できますが、極力正規化すべき。(来年から価格体系が変わるらしい)

Auditログで、テーブルをフルスキャンする「SELECT *」しているユーザを特定することも。

  • Google Dataflow

GAE → Task Queue →プリエンプティブ インスタンス起動してやっていた処理も、Google Dataflow (Apache Beam)でかなりスマートにできる。 サポート言語は、Java、pythonだけど。

  • GAE

近年のサーバレスアーキテクチャーの流れで、PaaSが再注目。

プロジェクト作成時しかGAEのリージョン指定できないので、海外から東京リージョン(asia-northeast-1)に移行する際、プロジェクト作成から、IAM、Service Accountとかデータストア移行とかが発生する

App Engine Flexible Environment(FE)  1度の処理は保証されるTask Queueが使えるGCE

一周年記念パーティとのこともあり、料理も豪華でした。

15036550_1307693945971247_1726746184250435722_n

15027715_1307693989304576_4623979243900585908_n

15085621_1307705149303460_6262092848792538092_n

 

次回は、12/4予定とのこと。BigQueryとData StudioのVisualizationらしい。

2016年10月2日
から hiruta
CloudSQL Proxyを使用してCloudSQL SEに接続してみた。 #gcpja はコメントを受け付けていません。

CloudSQL Proxyを使用してCloudSQL SEに接続してみた。 #gcpja

CloudSQL インスタンスに接続するのに、通常の3306/tcpを行う方法とは別に、CloudSQL Proxyを使う方法があります。

CloudSQL Proxyを使わない場合、Authorized networksに、GCEインスタンスの外部向けIPアドレス(グローバルIP)を追加する必要があります。追加する必要がないのが、CloudSQL Proxyを使用した接続方法になります。

続きを読む →