2013年5月26日日曜日

32.Google BigQueryでAnalyticsとAdSenseのデータを分析する(Google I/O 2013)




Ryo Yamasaki(@vierjp)です。

「BigQueryでGoogle AnalyticsとGoogle AdSenseのデータを分析する」というセッションについてのメモです。

I/Oではこの時間帯に別のセッションを聞いていたのでこの件について全く認識しておらず、
Google I/O報告会で初めて知ったので早速動画をチェックしてみました。

Google Analytics and AdSense Data Analysis in BigQuery (セッションページ)
動画


◯ BigQueryでAdsenseのデータを利用する

そのままではデータセット一覧にAdsenseのデータは表示されていませんが、
現時点で既に利用可能になっています。

・使えるテーブル
 DailyReport
 DailyAdUnitReport
 DailyCustomChannelReport
 DailyUrlChannelReport
 DailyDomainReport


・AdsenseのUIと比べて
 ・よりフレキシブルに好きな組み合わせや角度、基準で分析できる
 ・大量データに対して分析できる

・さらに
 ・一日中更新される
 ・Adsenseのデータに対するBigQueryからのQuery実行は無料

* 無料ってのはいいですね!


・クエリの例
 以下は売上の多いカスタムチャネルの一覧とその売上を取得するクエリです。

select custom_channel_id,
custom_channel_name,
sum(earnings) AS earnings
from
[google.com:adsense-reports:Reports.DailyCustomChannelReport]
GROUP BY
 custom_channel_id,
 custom_channel_name
ORDER BY
 earnings DESC
 LIMIT 5
結果がわかりづらかったのでセッション中でのクエリ例に「custom_channel_name」を追加しています。
 Adsenseを利用していてカスタムチャネルを設定しているならこのクエリで自分のAdsenseアカウントの結果を見ることができます。

* カスタムチャネルの命名が変かもしれませんがスルーしてくださいw


・テーブル定義の参照方法

AdSense BigQuery Integration Guide - AdSense — Google Developers」から
各テーブル名のリンクをクリックしてBigQueryのWebインタフェースに遷移するとデータセットにAdsenseのテーブル定義の一覧が追加されます。
(このURLからアクセスした場合のみ表示されるらしく、再度普通に開いても表示されない)

 BigQueryを操作しているのと同じGoogleアカウントに紐付くAdsenseのデータを参照するようです。


◯BigQueryでAnalyticsのデータを利用する


こちらはまだ一般公開されておらず、2013年9月のリリースを目指しているそうです。

・「Google Analytics プレミアム」のユーザーがAnalyticsのデータを「インポート」できるようになる。
 こちらはAnsenseのようにリアルタイムではなくデイリーでデータが更新されるそうです。
  (そもそもAnalytics自体の更新もリアルタイムではありませんが)
  Analyticsのプレミアムアカウントの存在を初めて知ったので調べてみたところ「想定価格 100万円/月」と、
  なかなかお高い。。

・利用できるデータはFirstPartyのデータだけで、AdwordsやGeographyと行ったデータは利用できない。
 (少なくとも2013年9月時点では)

・申請すれば開発者は事前に使えるかもしれないとのことです。
 Google Analytics Premium & BigQuery 申し込みページ


◯セッションで紹介されていたツール Tableau


Tableauというサードパーティ製のWindows用のGUIツールについて紹介していました。
複数のデータを同じ期間(条件)で並べてグラフ化して比較したり関連を見たりするデモでした。


◯まとめ

AdsenseにしてもAnalyticsにしても、
BigQueryを使って解析することで自社で持っている別の情報とJoinして分析できる事が魅力的かと思います。

例えばニュースサイトなら
「その日に公開した記事のカテゴリ」と「Adsenseの売上」「Analyticsのアクセス情報」
を結びつけて分析するような事もできるでしょう。

以前に書いた「23.BigQueryの新機能 (2013/03/15)」のBig JOINもこういった分析を手助けしてくれます。


Adsenseのデータはタダで分析できるのが良いですね。
分析した上での広告の最適化はGoogleにとってもメリットがあるからでしょうか。

Analyticsはお高く感じますが、BigDataの重要性が言われている昨今
AnalyticsのデータをBigQueryで自由に集計できる事には
マーケティング目的の分析において十分に見合う価値があるのかもしれません。


2013年5月24日金曜日

31.Google Cloud Storageに大量データをアップロードする際のテクニック(Google I/O 2013)



Ryo Yamasaki(@vierjp)です。

Google I/Oで聞いた「Importing Large Data Sets into Google Cloud Storage」のセッションについて、
動画を見て復習したのでメモを公開。
(動画も上記URLにあります)


◯Small to medium imports

gsutilを使った小〜中規模のアップロード方法
*「gsutil」はGoogle Cloud Storageを扱うためのCUIのツールです。

・ディレクトリ構造
[Directory]
├data
|├data1.csv
|├data2.csv
|├data3.csv
|└data4.csv
└data.csv

・カレントディレクトリのファイルをUploadする
gsutil cp data* gs://iodemo

・サブディレクトリ内のファイルも再帰的にUploadする
gsutil cp -R data* gs://iodemo

・bucket内のファイルを参照する
gsutil ls gs://iodemo
(Google Cloud Consoleからも同様に確認できます)

・ローカルからCloud StorageにUploadする
gsutil cp *.txt gs://my_bucket

・Cloud StorageからローカルにDownloadする
gsutil cp gs://my_bucket/*.txt .

・S3からローカルにDownloadする
gsutil cp s3://my_bucket/*.txt .

・S3からCloud Storageにコピー
gsutil cp s3://my_bucket/*.txt gs://my_bucket

・Cloud StorageからS3にコピー
gsutil cp gs://my_bucket/*.txt s3://my_bucket

*S3との転送にも対応しているのですね



◯マルチスレッドで高速にUploadする方法

Composite Objects and Parallel Uploads - Google Cloud Storage — Google Developers

通常CPコマンドはファイルを1つずつUploadするのでファイル数が多いと時間がかかります。
そこで「-m」オプションを指定するとマルチスレッドで複数ファイルを並列にUploadできます。
(比較的最近追加された機能なので古いgsutilでは使えません。最新版を使いましょう)

gsutil -m cp 〜〜

複数ファイルを並列に同時アップロードするので帯域とDisk I/Oをフルに使ってアップロードが可能になります。



◯Use object composition to improve throughput
サイズの大きなファイルを高速にUploadする方法

1.ファイル「big-file」を「big-file-part-*」に分割
split -n 10 big-file big-file-part-
2.マルチスレッドでUpload
gsutil -m cp big-file-part-* gs://bucket/dir/
3.ローカルの分割ファイルを削除する
rm big-file-part-*
4.Cloud Storage上で分割ファイルを結合する
gsutil compose gs://bucket/dir/big-file-part-* gs://bucket/dir/big-file
5.Cloud Storage上の分割ファイルを削除する
gsutil -m rm gs://bucket/dir/big-file-part-*

* 操作が増えるのでお金は若干余計にかかるそうです。



◯S3からCloud Storageへ、5ペタByteのデータをコピーした事例


・可能な限り速くコピーする
・Live Migration(ダウンタイム無しに)
という条件。

・AppEngineのDatastoreにオブジェクト(ファイル)のリストを持っているっぽい。
・オブジェクト名の一覧をAppEngine上で取得
・AppEngineからTaskQueueを使ってCompute Engine上に配置した「コピー処理」をキック
・Compute Engineはgsutilを使ってS3からGCSにコピー
 (ピーク時に160のCompute Engineのインスタンスが走っていた)
・顧客のシステムからVerify(hash値が一致する事を確認)
(たぶんこんな感じ?間違ってるかも)

平均で秒間10GB、最大で秒間20GBのコピーを行った。



・Object Change Notification (experimental)

Object Change Notification - Google Cloud Storage — Google Developers
bucketに対する変更の通知をWebアプリで受け取ることができる。



・JSON API  (experimental)

Getting Started - Google Cloud Storage — Google Developers

Cloud Storageに対して操作を行うJSONのAPI
JSON APIを使うと「batch request」をすることができる。
「gsutil -m」のように「呼び出し側からマルチスレッドで並行に複数のリクエストを投げる」のではなく、
「一度のリクエストで複数の命令を投げる」手法。

一気に大量のオブジェクトに対してアクセス権限を設定したり削除したりする場合等に有効。



◯Partition with Prefix

ファイル名の先頭文字列毎にUploadするテクニック。
Prefixを指定してコピーすることで簡単に同時実行する。

例えばファイル名が「0-9」で始まっているなら、以下のようにすることでさらに10分割して並列にUploadできます。

gsutil -m cp 0* gs://my_bucket
gsutil -m cp 1* gs://my_bucket
gsutil -m cp 2* gs://my_bucket
・・・
gsutil -m cp 8* gs://my_bucket
gsutil -m cp 9* gs://my_bucket



◯Copying a specific list of files from a text file or program output

テキストファイルやプログラムの出力結果で指定されたファイルをアップロードするためのテクニック

・files.txt
README.md
notes.txt
images/disk_import.jpg

catした結果をパイプで繋いでgsutilに渡す。
cat files.txt | gsutil -m cp -I gs://my_bucket
→リストに書いてあるファイルが全てコピーされる



◯run gsutil near to your source or target

ネットワーク的に速い環境からコピーするため、
ファイルのコピー元かファイルのコピー先に近いところで実行するべし、というお話。

Cloud StorageにUoloadするならCompute Engineからが速そう。
そして話は次の「Offline Disk Import」に繋がります。



◯Offline Disk Import (Limited Preview)

Offline Disk Import - Google Cloud Storage — Google Developers

Uploadしたいファイルをハードディスクに入れてGoogleに送ると
Google内のネットワークからUploadしてくれる

というまさに究極手段。

Google/IO 初日の5/15にサービス開始。

・手順
1.Offline Disk ImportのInterest Formから申し込み
2.SATAのハードディスクをencfs(暗号化ファイルシステム)でフォーマットする
3.データをハードディスクにコピーする
4.Googleに郵送する
5.Googleが顧客の所有する新しいbucketにimportする(Googleの高速なネットワークを使って)
6.GoogleがHDDを郵送で送り返してくれる

現時点ではアメリカ国内の顧客限定ですが、
間違いなく今後数ヶ月の間に国際的に利用できるように拡大するし、
優先順位が上がるかもしれないので海外の顧客も「Interest Form」から連絡してください、とのこと。

料金は通常のGoogle Cloud Storageの料金「リクエスト回数, 帯域使用料,ストレージ使用料」に加えて
HDD毎に「$80」加算されます。



◯Google Cloud Storageの最近のリリース一覧

Versioning
Durable Reduced Availability storage
30% price drop
Cloud Console
Composite Objects
Notifications
JSON API
Offline disk import



個人的には、あとはリクエスト回数に対する課金額
Amazon S3のリクエスト50%~60%値下げを全リージョンで開始、これまでの半額以下に
に追従してくれれば、と思います。
2013/4/3にAmazonが半額にした結果、
これだけGoogle Cloud StorageがS3の2倍のお値段になっちゃってるんですよね(´・ω・`)
他は概ねS3より若干安い料金体系なのですが。



30.Google App Engine for PHPにおけるポータビリティを考える


Ryo Yamasaki(@vierjp)です。

Google App Engine for PHPでオンプレミス向けのPHP既存アプリはどこまで動くか、
動かす際には何に注意すべきか、「前回行ったWordPressの動作確認」と「公式ドキュメント」を読んだまとめです。


GAE/PHPに関しては
・DatastoreではなくCloudSQLを推していること
・MemcacheのStubの関数の存在
・ドキュメントにWordPressの設置方法について書かれていること
などを見るに、
「既存アプリをそのままAppEngineで動かす」というケースをこれまでよりも強く意識しているように感じました。

これまでAppEngineはこのケースにおいて他のクラウドに遅れを取っていたように思いますが、
(PaaSではWindows Azureが早かった印象)
Cloud SQLやCloud Storage等の関連サービスの充実に伴い現実的になってきたと感じています。

その上でPHPの既存アプリをAppEngineに載せる際に問題になりそうな事を考えながらドキュメントを読んでみました。
と言ってもPHP素人なので考慮しきれていない事は多々あると思いますが。(わかりやすい予防線)



◯File入出力(Google Cloud Storage との連携)


・プログラム内で読み書きしたい場合

AppEngineはその制限上、ローカルのファイルシステムへのアクセスができません。
よって、ファイルの入出力は全てCloud Storageに対して行う必要があります。

・書き込み

$options = [ "gs" => [ "Content-Type" => "text/plain" ]];
$ctx = stream_context_create($options);
file_put_contents("gs://my_bucket/hello.txt", "Hello", 0, $ctx);

・書き込み(Stream)

$fp = fopen("gs://my_bucket/some_file.txt", "w");
fwrite($fp, "Hello");
fclose($fp);

関数的にはPHP標準のものだと思いますが、
Pathの指定方法がGoogle Cloud Storage特有なので
アプリ内でファイルの入出力をしている場合には修正が必要になるでしょう。
(デフォルトのディレクトリとして「gs://[my_bucket]」と指定できたら楽そうですが)


・ブラウザからアップロードしたファイルを保存したい場合

これは前回「29.Google App Engine for PHPでWordPressを動かしてみた」で困った内容です。
※ 2013/6/16追記 WordPressに関してはWordPress用のGoogleの公式プラグインが提供されました。
36.Google App Engine for PHP上でWordPressを運用するためのプラグインが登場


この場合はもう少し大変です。
Direct file uploads to your POST handler, without using the App Engine upload agent, are not supported and will fail.
と書いてある通り、
multipartでアップロードされたファイルの情報を「$_FILES」変数から直接参照することができません。
前回書いたようにダウンロードしてきたWordPressそのままのコードでは画像のUploadができませんでした。

この場合の対応方法は「Uploading Directly to Google Cloud Storage」に書いてあり、
以下のフローにする必要があります。

1.「createUploadUrl」関数でアップロード先のURLを生成してformのactionとして指定する。
2.「createUploadUrlで生成したURL」からPOSTされる「Handler」を作成する。
 「Handler」では一時ファイルの情報を「$_FILES」から取得することができるので、
  ここで「move_uploaded_file」関数を使ってCloud Storageに書き込む。(移動する)

アップロード時の処理のフローは以下のようになります。


元の処理内容によっては簡単に修正できるかもしれません。
CloudStorageTools::createUploadUrl('[元のアップロード先URL]', $options);
formのactionに指定するURLを上記のように生成すれば
「元のアップロード先URL(=Handler)」で一時ファイルの情報を「$_FILES」から取得でき、
その後「move_uploaded_file」で指定するPathをCloud Storageの形式にしてやれば「辻褄が合いそう」な気がします。


ただ、WordPressで修正方針を検討したところでは若干面倒そうでした。
WordPressは「元のアップロード先URL」でCookieから取得したユーザー情報に基づく権限チェック等を行なっています。
しかし、上図③の通り「uploadUrl」から「Handler」には「サーバー間でPOST」しているので、「Handler」ではブラウザが保持するCookieを取得できません。

そうであれば、ユーザー情報に基づく権限チェックは「Handlerがリクエストを受けたタイミング」ではなく
「createUploadUrl」でURLを生成するタイミングで行うことになるでしょうか。
「createUploadUrl」で生成されるURLは推測不可能な文字列を含んでいてかつ有効期間は10分間なので、
ここでチェックしていれば概ね安全そうな気がします。
(さらにHandlerにadmin権限つけて外部からアクセスできないようにできればさらに良い)

ただ、そのためには「元のアップロード先URL」で行なっているチェック処理を
ごっそり「アップロード画面表示時の処理」に移動する必要があります。

Javaの場合でも1分間(AppEngineのリクエストがタイムアウトする時間)でアップロードが終わらないような
サイズの大きいファイルをアップロードする際にはこの「createUploadUrl」を使ったアップロード方法が必要ですが、
この方法しか使えないとなると、既存アプリを修正する場合に元のアプリの作りや処理内容次第では意外と面倒な作業になるかもしれません。

処理フローのレベルで修正が必要になってしまう事を考えると、
ポータビリティの観点では1分制限があってもいいから透過的にやって欲しいなぁというのが正直な想いです。
今のままでは既存アプリのファイルアップロード機能は全て修正が必要になってしまうので。
WordPressを載せてみた感想的には「あとちょっとなのにもったいないなぁ」という気持ちです(´・ω・`)

参考に、上記の挙動を確認した際のログです。

・投稿画面を開いた際のログ(アクセス元IPアドレスが「61.201.***.***」でGET)

・uploadUrlからHandlerにPOSTした際のログ(アクセス元IPアドレスが「0.1.***.***」でPOST)

UserAgentはブラウザから送信された情報を引き継いでいるようなので
Cookieも全部送り直してくれれば辻褄が合いそうですが、それは行儀が悪いからしないのかな(´・ω・`)
それとも何かが間違っていて、もっと簡単な方法で修正できるのかな・・・?

 2013/6/14追記 WordPressに関してはこの問題を解決するプラグインが公開されました。
Blog @vierjp : 36.Google App Engine for PHP上でWordPressを運用するためのプラグインが登場


参考:
ファイル入出力 | PHP Labo
Google Cloud Storage PHP API Overview - Google App Engine — Google Developers



◯MySQLの利用 (Google Cloud SQL との連携)

Using Google Cloud SQL with App Engine PHP SDK - Google App Engine — Google Developers

・PDO
・mysql_connect
・msqli
を使用可能。

WordPressを試してみた限りではDB周りは特に問題無さそうでした。
(どちらかというとCloud SQLについてちゃんと調べた方が良いかも)


◯ログ出力

ググって見たところ、PHP標準のログ出力関数は以下の様なものがあるのでしょうか。
・error_log関数
・syslog関数

ドキュメントに書かれているのは「syslog関数」のみで
「error_log関数」については記載がありませんが、以下の挙動になります。

・log_test.php
<?php
error_log('##### 0 tset Message', 0);
error_log('##### 1 tset Message', 1);
error_log('##### 3 tset Message', 3, '/var/tmp/app.log');
//error_log('##### 3-2 tset Message', 3, 'gs://[bucket名]/app.log'); // エラー
error_log('##### 4 tset Message', 4);
echo "log_test";
?>

・出力されたログ

・ファイル名を指定しているケースはログ出力不可(代わりにWarning)
・Cloud StorageのPathを指定した場合はエラー
・それ以外はsyslogをErrorレベルで出力した場合と同様の結果
となりました。


参考:
unoh.github.com by unoh
Logs PHP API Overview - Google App Engine — Google Developers


◯Session

The PHP Runtime Environment - Google App Engine — Google Developersに書いてあるとおり、

・Sessionに保存

session_start();
$_SESSION['Foo'] = 'Bar';

・Sesionから取得

session_start();
print $_SESSION['Foo'];
という感じに普通に使えます。


しかし一点気になる記述がありました。
By default the App Engine runtime will use memcache to store session information using the MemcacheSessionHandler class.
(中略)
However data in App Engine memcache may be flushed periodically, meaning any session information will be lost.
For longer-lived sessions, it may be preferable to use an alternative storage service such as Cloud SQL.
・デフォルトではSession情報をMemcacheに保存している
・Memcacheのデータはクリアされるかもしれないのでそれによってセッション情報が失われる可能性がある。
・長い期間Sessionを維持したければ、Cloud SQL等にセッション情報を保存した方が良い。

Javaの場合はDatastoreにSessionデータが記録されていますが、
(Memcacheも併用していると聞いた事がある気もするけど、とにかく永続化されている)
PHPの場合はMemcacheにしか保存していないようです。
実際プログラム中でSessionを使ってもJavaと違ってDatastoreにSession情報を保存するためのEntityは生成されません。

大量のクライアントからのアクセスがあった場合にはSession情報が頻繁にMemcacheからクリアされてしまうかもしれません。
それが困る場合はCloud SQLを使った自前のSessionHandlerを作ってそれを使うべし、との事のようです。

ググってみたところではセッションをMYSQLに書き込む方法としては以下のサイトが見つかりました。
PHP/セッション管理 - がしまっくす
( 「MySQLを使ったセッション管理」-「session_mysql.php」の部分)

ただ、近年は自分がJavaでAppEngineのアプリを作成する場合、基本的にセッションを使わずステートレスに作っていたので、
設計次第ではセッションをがっつり使わなくてもそれほど困らないかと思います。
というか、AppEngineに限らず新規に作る場合には可能であればできるだけ使わない方が良いと思っています。

ただし、既存のシステムをAppEngine上に持ってくる場合にはこの点について留意した方が良いでしょう。


◯mbstring

※2013/6/16追記 Google App Engine 1.8.1で mbstringが追加されています。
http://phpinfo.vier-test.appspot.com/

気になるツイートを見かけたので少し試してみました。
phpinfo見たところ mbstring, Zend multibyteが off のようだけど
これらはPHPでマルチバイトを扱う際に必要なのでしょうか。
WordPressを触ったところではマルチバイト関連での問題は起きていませんが、
どういう場合に困るんでしょ。

ググって見よう見まねでphp.iniを書いたところ、
phpinfoで「zend.multibyte ON」にできました。(「Zend Multibyte Support」はdisabledのままですが)
mbstringについては今のところ有効にすることができていません。

・php.ini
;参考
;http://d.hatena.ne.jp/do_aki/20111208/1323315995
;http://wiki.ohgaki.net/index.php?PHP%2Ftips%2F%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%92%B0%E5%A2%83php.ini%E8%A8%AD%E5%AE%9A
;http://www.phpbook.jp/install/phpini/index5.html

google_app_engine.enable_functions = "phpversion, phpinfo"
output_buffering = "On"

default_charset="UTF-8"
magic_quotes_gpc=off

[mbstring]
mbstring.language=Japanese
mbstring.internal_encoding=UTF-8
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.encoding_translation = Off
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
mbstring.substitute_charactor=none
mbstring.strict_detection = Off
mbstring.input_encoding=pass
mbstring.output_encoding=pass

zend.multibyte = On
zend.script_encoding = UTF-8

・mbstring.php
<?php
  if ( extension_loaded('mbstring') ) {
    echo "mbstring is loaded";
  }else{
    echo "mbstring is not loaded"; //←こちらが出力される
  }
?>


他に「この設定を試してみろ」等あれば是非w


◯AppEngine固有サービスの対応状況

ドキュメントに書かれているのは以下の6つです。

Logs
Mail(送信、受信、バウンス)
Memcache
  Javaでは見たことがないstubの関数(呼び出すことはできるが何もしない)がいくつも用意されています
URL Fetch
Users
Task Queues(Pushのみ、Pullは無し)


以下のサービス等はまだ使えないようです。
・Channel API
・Images API
・Prospective Search
・Full Text Search
・Sockets
(他にもPHPにはまだ無いものがあります。正確に知りたい場合はJavaやPythonと比べてみましょう)

Datastore関連の機能もドキュメントにはありません。
(別サービスの「Cloud Datastore」はJSON API経由で使えると思います)


◯まとめ

環境の管理が不要なPaaSのAppEngineはIaaSやオンプレミス環境と比べると比較的制限は多く、
また、PHPはまだLimited Previewです。

と前置きした上で、

オンプレミス環境向けに作られた既存のPHPアプリをAppEngine上で動作させる場合には、
前述のファイルアップロードやSessionのように
「ドキュメントを読んだ上で自分が載せようとしているアプリについてその制限が問題とならないかどうか」
を検証する必要があるでしょう。

ファイル入出力についてはAPI的にはローカルのファイルシステムと同様に行うことができますが、
実際にはネットワークをまたがって別サーバーに対してファイルの読み書きをしているわけですから
Webサーバーのローカルのファイルシステムに対して読み書きする場合と比べて速度は低下するでしょう。
読み書きするファイルの使い道次第ではこれがパフォーマンス的な問題に繋がる事があるかもしれません。

また、プログラムからのファイルの出力先は必ずCloud Storageなので、
「アプリケーションのディレクトリ内に*.phpファイルを生成する仕組み」や、
「*.phpファイルを含むファイルをアップロードするような仕組み」
(WordPressのテーマを管理画面からアップロードする場合なんかはそうなのかな?)
に対応するのは難しいでしょう。


機能的な制限については「The PHP Runtime Environment」から読むのが良いと思います。
その上で各機能毎のページをチェックしてみましょう。
前回のWordPressの例のようにとりあえず載せて動かしてみて、
エラーになったら調べてみるというのも手っ取り早いかもしれません。


Cloud SQLもCloud Storageも無かった頃と比べると、
オンプレミス環境向けに作られた既存アプリを動かすための環境は徐々に整ってきています。
特にPHPはまだLimited Previewなので、今後の発展に期待したいと思います。(`・ω・´)


*ご意見・ご指摘等ありましたらコメントでもGoogle+のメッセージでもメールでも、ご連絡いただけましたら幸いです。


2013年5月22日水曜日

29.Google App Engine for PHPでWordPressを動かしてみた




Ryo Yamasaki(@vierjp)です。

前回「28.Google App Engine for PHP (GAE/PHP) を早速試してみた」というエントリーを書きましたが、
公式ドキュメントに「Running WordPress」という項目があったのでこちらも試してみました。

せっかく日本人が試すのだから、ということでWordpressも日本語版にしてみました。

※後述しますがかなり厳しい問題が一点未解決です
 2013/6/14追記 この問題を解決するWordPress用プラグインが公開されました。
Blog @vierjp : 36.Google App Engine for PHP上でWordPressを運用するためのプラグインが登場



◯構築手順


基本的に公式ドキュメントの通りです。

・WordPress 日本語版をダウンロードする

WordPress › 日本語
今回テストに使用したのは3.5.1です。
日本語版は公式(英語版)とは別に提供されています。
これだけ有名なプロダクトなのに、公式で多言語対応していないのがちょっと驚き。

WordPress › 日本語 « WordPress 日本語版について
(オリジナル英語版と日本語版との違い)


CloudSQLの準備

CloudSQLは一番小さい「D0」のインスタンスを現在無料で使う事ができます。

ただし、Billingは有効にしておく必要があります。
6月までは無料」とのことですが、
無料期間が終わると自動的に有料プランに移行して引き落としが始まる、というよくあるパターンなのでしょう。


* 古いUIから作ってしまいました


DBの初期設定


「Import data」から「gs://appengine-php/setup.sql 」をインポートするか、
「SQL Prompt」から以下を1行ずつ実行します。

CREATE DATABASE IF NOT EXISTS wordpress_db;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'wp_password';
GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wp_user'@'localhost';



アプリの作成

・ディレクトリ構成

アプリケーションのディレクトリとして「wordpress-gae」を作成した上で、
以下の構成にしています。

wordpress-gae
├wordpress ←ダウンロードして展開したWordpressのディレクトリを丸ごと配置
|├wp-admin
|├wp-content
|├wp-includes
|├index.php
|├wp-config.php←以下の手順で修正
|└・・・
├app.yaml ←以下の手順で新規作成
├cron.yaml ←以下の手順で新規作成
└php.ini ←以下の手順で新規作成


・app.yaml
application: YOUR_PROJECT_ID
version: wordpress
runtime: php
api_version: 1
threadsafe: true

handlers:
- url: /(.*\.(htm$|html$|css$|js$))
  static_files: wordpress/\1
  upload: wordpress/(.*\.(htm$|html$|css$|js$))
  application_readable: true

- url: /wp-content/(.*\.(ico$|jpg$|png$|gif$))
  static_files: wordpress/wp-content/\1
  upload: wordpress/wp-content/(.*\.(ico$|jpg$|png$|gif$))
  application_readable: true

- url: /(.*\.(ico$|jpg$|png$|gif$))
  static_files: wordpress/\1
  upload: wordpress/(.*\.(ico$|jpg$|png$|gif$))

- url: /wp-admin/(.+)
  script: wordpress/wp-admin/\1
  secure: always

- url: /wp-admin/
  script: wordpress/wp-admin/index.php
  secure: always

- url: /wp-login.php
  script: wordpress/wp-login.php
  secure: always

- url: /wp-cron.php
  script: wordpress/wp-cron.php
  login: admin

- url: /xmlrpc.php
  script: wordpress/xmlrpc.php

- url: /wp-comments-post.php
  script: wordpress/wp-comments-post.php

- url: /(.+)?/?
  script: wordpress/index.php


上記をコピペして「YOUR_PROJECT_ID」を書き換えればOK。
公式ドキュメントの記述に「wp-comments-post.php」を追記しています。(後述)
https://developers.google.com/appengine/articles/wordpress

・php.ini
google_app_engine.enable_functions = "php_sapi_name, gc_enabled"

・cron.yaml
cron:
- description: wordpress cron tasks
  url: /wp-cron.php
  schedule: every 2 hours

・wp-config.phpの修正
/** WordPress のためのデータベース名(書き換える) */
define('DB_NAME', 'wordpress_db');

/** MySQL データベースのユーザー名(書き換える) */
define('DB_USER', 'wp_user');

/** MySQL データベースのパスワード(書き換える) */
define('DB_PASSWORD', '********');

/** MySQL のホスト名(書き換える) */
//define('DB_HOST', 'localhost');

if(isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'],'Google App Engine') !== false) {
  define('DB_HOST', ':/cloudsql/*****:*****');
}else{
  define('DB_HOST', 'localhost');
}

/** AppEngineのドキュメントに従って以下を追加 */

// Cronを無効化(WordPress自身による処理を無効にしてcron.yamlで直接呼び出すような感じ?)
define ('DISABLE_WP_CRON', 'true');

// プラグインやテーマのアップグレードを無効化
define ('DISALLOW_FILE_MODS', 'true');


DB_HOSTは自動的にローカル環境と本番環境で接続先を切り替えるように分岐しています。

・参考:WordPressのwp-config.phpで出来る事いろいろ - かちびと.net


デプロイ


前回同様アプリケーションのディレクトリ(wordpress-gae)で以下を実行します。

/Users/User/appengine_php_1_8_0/appcfg.py update -R --runtime=php .

デプロイ後に初めてアプリにアクセスすると「初期設定のためのウィザード」が表示されます。
特に問題なく設定は完了し、管理画面にログインできます。



◯正常動作を確認できた事

・初期設定ウィザード
・ブログの参照
・コメントの投稿
・記事の投稿・編集
・カテゴリの追加
・固定ページの追加
・テーマの追加
 追加したテーマは「New World
・テーマの「有効化」
・テーマの「カスタマイズ」
・ウィジェットの変更

 *コメントの投稿をするためにドキュメントからコピペしたapp.yamlに以下の記述を追加する必要がありました
- url: /wp-comments-post.php
  script: wordpress/wp-comments-post.php

◯正常動作を確認できなかった事

・テーマの「ライブプレビュー」
・画像のUpload
 これが大きな課題として残りました。
 AppEngineはローカルのファイルシステムにファイルを書き込みできないし、
 Cloud Storageの設定もしていないのだからまぁ当然かと思っていたら、
 少し根が深そうです。

 内部で「$_FILES」という変数を使っていて、
 本来ファイルをUploadした場合自動でファイルが一時ディレクトリに格納され、
 その後move_uploaded_file関数で任意の場所に移動する、という流れらしいですが、
 AppEngineの制限でローカルディレクトリへのファイルの書き込みを許可していないためか
 「$_FILES」の情報が空になってしまっています。

if ( isset( $_FILES["async-upload"] ) ) {
    syslog(LOG_INFO, "_FILES['async-upload'] is set.");
}else{
    syslog(LOG_INFO, "_FILES['async-upload'] is not set."); // ←こちらに分岐する
}

 画面上のエラーメッセージ
ファイルが空のようです。中身のあるファイルをアップロードしてください。このエラーは php.ini ファイルでアップロードができない設定になっているか、post_max_size が upload_max_filesize よりも小さく設定されているために発生している可能性もあります。

 にしたがって、php.iniで
post_max_size=5M
upload_max_filesize=2M

 と指定してみてもダメ。エラーコードも取得できず。
 何か見落としているのでしょうか・・・?(・ัω・ั)

 「PHP アップロード」でググるとどのページも「$_FILES」の説明をしているあたりおそらく定番だと思うので、
 もし現状サポートしていないなら
 内部的にCloud Storageを使うでもいいから「$_FILES」がそのまま動くようにAppEngine自身がサポートしないと
 既存のアプリを載せた際にファイルアップロード機能が動かないケースが多そうな気がします。

 ・参考:$_FILES - 初心者向けPHPナビ

 2013/6/14追記 この問題を解決するWordPress用プラグインが公開されました。
Blog @vierjp : 36.Google App Engine for PHP上でWordPressを運用するためのプラグインが登場



◯まとめ

日本語の投稿も特に問題なくそこそこ動くのですが、
重要な機能としてはファイル(画像)のUploadができませんでした。
この問題さえなければ実用レベルで使えそうな勢いだっただけに残念(´・ω・`)

PHPはまだLimited Previewなので、今後に期待したいと思います。
・・・私がPHPド素人なのが原因の可能性も十分にありますが(´・ω・`;)
PHPに詳しい方、$_FILESが空になる(PHP的な)原因に心当たりがあれば情報くださいませ。m(´・ω・`)m

* 2013/5/22追記 Google+で +Takashi Matsuo さんから教えていただきました。
https://developers.google.com/appengine/docs/php/googlestorage/overview
createUploadUrl  を使うようにしないとだめでしょうね。上記ドキュメントの最後に普通のファイルアップロードは失敗すると書いてあります。

「About Direct File Uploads」のところに
Direct file uploads to your POST handler, without using the App Engine upload agent, are not supported and will fail.
と書いてありました。
結論、AppEngine的な制限についての私の見落としでした。
Google Cloud Storageにアップロードするようにコードの修正が必要になりそうです。

* 2013/5/23追記 はてブで提案をいただいたので試してみました。

php.iniで
upload_tmp_dir=gs://[bucket名]
としてみましたが、残念ながらダメでした。(´・ω・`)
実際にこれができたらシンプルでいいなぁ。

ブログに晒すと情報もらえていいですね。ありがとうございます。(´▽`)


WordPressは以下に配置してあるので、興味があればアクセスしてみてください。
・WordPress on Google App Engine for PHP by vierjp
管理画面に入るにはIDとPassが必要になってしまいますが、記事の参照とコメントの投稿はできます。
* 6月になってCloud SQLが有料になったら止めるかも。
* 2013/11/10 追記 Cloud SQLの課金が地味に痛いので停止しました。

2013年5月19日日曜日

28.Google App Engine for PHP (GAE/PHP) を早速試してみた




Ryo Yamasaki(@vierjp)です。

Google I/Oでハンズオンに参加したおかげか、
すぐにGoogle App Engine for PHPのLimited Previewを使えるようにしてもらえたので早速試してみました。

◯Google App Engine for PHP Limited Preview申し込み


・Google App Engineのアカウントとアプリの作成


申し込みは自分のGoogleアカウントに紐付いている「AppEngineの"アプリ"」に対して行います。
そのため「AppEngineのアカウントが無い」または「アプリを作成していない」という場合には、
先にアカウントとアプリの作成を行う必要があります。

比較的新しめのところでは以下のサイトが参考になるかもしれません。
egashira.jp : 初めてのGoogle App Engine

アカウントの大量取得を防ぐためか
AppEngineのアカウント登録時には携帯の電話番号やメールアドレスを使った確認があるので、
手元に携帯電話を用意しておいてください。


・Limited Previewの申し込み


Google App Engine for PHP Limited Preview申し込みサイト


中央の緑色のボタン「Register an app for the Limited Preview」を押します。

するとGoogleアカウントの権限の認可を求められるので、許可してください。

・アプリ選択画面


アプリ選択画面に来たら「PHPを使えるようにしたいアプリ」を選択し、
・AppEngine for PHPで何をしたいのか
・MemcacheやURLfetchのようなAppEngineのAPIを使う予定はあるか
・WordpressやphpMyAdminのようなアプリを使う予定はあるか
などを記述します。

最後に「Request PHP for this application」ボタンを押して申し込みは完了です。

申し込み完了直後と、実際に利用できるようになった後にメールが届きます。
また、再度「Register an app for the Limited Preview」を押すと、
現在の状況を参照することができます。

利用できるようになると以下の画面になります。

・申し込み完了画面



◯SDKのダウンロード

Installing the PHP SDK - Google App Engine — Google Developers

手順に従って以下をインストールしてください。
・Python 2.7
・PHP 5.4
・App Engine PHP SDK


◯AppEngine上で「phpinfo()」を表示してみる

適当なディレクトリに以下の内容でファイルを作成します。

・app.yaml

application: vier-test

version: phpinfo

runtime: php

api_version: 1



handlers:

- url: /

  script: index.php



基本的には「runtime: php」の行以外はPython版と同じ書き方のようですね。

・index.php

<?php

  phpinfo();

?>

普通はyamlとphpファイルだけなのですが、
セキュリティ都合か、デフォルトでは「phpinfo()」を実行できないようになっています。
そのため以下の内容で「php.ini」ファイルを作成して同一ディレクトリに配置します。

・php.ini

google_app_engine.enable_functions = "phpversion, phpinfo"

これで一つのディレクトリに
「app.yaml」「index.php」「php.ini」の3つのファイルが存在する状態になります。


◯デプロイする


・デプロイ方法

前項で作成したアプリのディレクトリに移動して以下を実行します。
(「appcfg.py」は展開したSDKのディレクトリにあります)

/Users/User/appengine_php_1_8_0/appcfg.py update -R --runtime=php .

認証中にGoogleアカウントのIDとPassを聞かれます。
二段階認証を設定している場合には
アプリケーション固有のパスワード」を取得するか、
上のコマンドに「--noauth_local_webserver --oauth2」を追加して実行します。


デプロイ後の「Admin ConsoleのVersion画面」です。

言語が「php」になっているのが確認できます。


実際にAppEngine上に配置した状態は、以下のURLで確認できます。
http://phpinfo.vier-test.appspot.com/


「Server API AppEngine PHP Runtime SAPI」となっているのが確認できます。


◯セッションやハンズオンの話

・Datastoreの話

前回「27.Google I/Oで発表されたGoogle Cloud Platformの新機能」にも書いた通り、
現時点でのドキュメントには「Cloud SQLを使う方法」しか書いていませんが
一応セッションではDatastoreにアクセスするコードがありました。
また、新プロダクトの「Cloud Datastore」はJSON APIを使えるので、こちらはPHPからも利用できると思います。


・WordPressは動きそう

セッション内でWordPressの話があったので「Cloud SQL」と組み合わせることで動作するんじゃないでしょうか。

* 2013/05/21追記
コメントでneranさんから教えていただきましたがドキュメントに思いっきり書いてありますね。
Running WordPress - Google App Engine — Google Developers

* 2013/05/22追記
実際に試してみたので詳細については次の記事
29.Google App Engine for PHPでWordPressを動かしてみた」をどうぞ。


・phpMyAdminもAppEngine上で動くかも

ハンズオンでは、CloudSQLを操作するために「AppEngine上に配置したphpMyAdmin」を使用しました。



ハンズオン用に最初から用意されていたので、
完全に素で動くのか、いくらか修正が必要なのかはわかりませんが、
一応AppEngine上で動作させる事はできるようです。


以上、今回もサンフランシスコからでした。(´▽`)


2013年5月17日金曜日

27.Google I/Oで発表されたGoogle Cloud Platformの新機能





こんばんは。Ryo Yamasaki(@vierjp)です。

現在Google I/Oに参加するためサンフランシスコに来ています。
今は2日目の夜ですが、
Google Cloud Platformの変更点についてセッションを聞いて理解した限りで書こうと思います。
まだ検証もドキュメントの確認もちゃんとできていないので間違っている点もあるかもしれませんが予めご了承ください。
3日目のセッションを聞いた後や実際に検証した上で間違いに気がついたら訂正なり追加の記事なり書くと思います。

間違いに気がついた方はツッコミやご指摘いただけたら幸いです。


◯Google App Engine


◯PHP対応


https://developers.google.com/appengine/docs/php/

・概要
AppEngine上で使えるプログラミング言語として、
Python、Java、Goに続く第四の言語としてPHPが追加されました。
言語に関する要望の中では昔からPHPが一番多かったそうで、今回ついに対応となりました。


ドキュメント内ではデータアクセスとして書かれているのが
「Cloud SQL」と「Cloud Storage」のみで「Datastore」についての言及がありませんが、
セッション中のサンプルコードにはDatastoreへのアクセスっぽいコードが存在していました。
* 2013/5/23追記 セッションの動画を見直したら「Cloud Data Store」(後述)と言っていました。



* 2013/5/24追記 早速Limited Previewをもらえたので試してみました。以下の記事も参考にどうぞ。
28.Google App Engine for PHP (GAE/PHP) を早速試してみた
29.Google App Engine for PHPでWordPressを動かしてみた
30.Google App Engine for PHPにおけるポータビリティを考える
36.Google App Engine for PHPでWordPressを運用するためのプラグインが登場
39.Google App Engine for PHPでCakePHPを動かしてみた


◯Modulalized Applications (Servers?)



スライドによって名称が「Modulalized Applications」だったり「Servers」だったりしましたが、同じ物を指していると思います。

おそらくTrusted Tester中に「Servers」と呼ばれていた機能で、
一つの「アプリ」の中に複数の「コンポーネント」を定義できるものではないかと。
これは現在の「アプリケーション」と「バージョン」の概念の間に存在するような仕組み。
たぶんこんな感じ?(想像図です)

概念は既存の「backends」の位置づけに似ていますが、
・スケーリング
・デプロイ
・バージョニング
・パフォーマンス設定
を「コンポーネント」毎にできるようになります。
例えば、
インスタンスクラス(F1等)やインスタンス数等の設定は「コンポーネント」毎に設定できます。
と言っても既存のBackendsでも上記については一応できていたので、
もう少し細かく設定できたり制限がなくなるといった要素もあるのかもしれません。
セッションでは「3つのコンポーネントに分けているアプリ」の例もありましたが、
「Frontendとbackends」という既存の分け方を、より柔軟にするような趣旨かと思います。

これが正式リリースされた際に既存の「Frontend」「Backend」がどうなるかは少し気になります。
(既存のアプリのために何らかの形で残りそうには思いますが)

以下についてはアプリ毎に存在し、各コンポーネントから共有する形になります。
・Datastore
・Memcache
・TaskQueue

この機能について、あるセッションでは「Launched Today」と書いてあったり、
また別のセッションでは「Limited Preview」と書いてあったりで、
リリース時期がいまいち不明です。

ただ、これがリリースされたらさすがに管理画面の構成が変わるはずですが、
現状変わっていないのでおそらくまだ「Limited Preview」なのでしょう。


◯Mobile Backend Starter




「サーバーサイドのコードを一切書かずにサーバーと連携するAndroidアプリを作る」ためのAppEngineアプリ。
「Mobile Backend Starter」は「Platformの拡張」ではなく、「AppEngineのアプリケーション」として提供されます。

以前からこのブログで扱っている「Google Cloud Endpoints」も近い要素がありますが、これは本当にサーバーの知識が不要です。

・サーバー側アプリをデプロイをするための環境を構築する必要が無い
→eclipseをダウンロードして、アプリのソースコードを取得してデプロイする・・・という作業が必要ありません。
Webの画面上から「Mobile Backend Starter」のアプリを直接デプロイすることができます。

・OAuth2の認証をサポート
 (内部的にはCloud Endpointsを使用しています)

・サーバー側のコードを書く必要が無い
→DAOをAPIとして公開するような作りになっていて、クライアント側からクエリの内容を指定してクエリを実行します。
 (詳しく見ていないけどアクセスコントロールの仕組みはちゃんとあるらしい)

・ContinuousQuery
 ・サーバー側でクエリの結果に影響するデータが登録されると自動でクライアント側の画面に反映される
  ・クライアント側からクエリを実行した際にProspective Searchに端末IDとクエリの内容を登録する
  ・データの更新時にProspectiveSearchが呼び出される(登録内容にマッチする更新が行われたか、が確認される)
  ・ProspectiveSearchに登録した条件にマッチした場合、GCMを使ってクライアント側に通知する
  ・クライアント側はGCMのMessageを受け取ると、API経由でクエリを再実行して「最新のクエリ結果」を取得して描画する

・クライアント側を楽に実装するための仕組みも用意されているらしい。

大々的に好評されていませんでしたが実は4/20ぐらいにはリリースされていて、少しソースを読んでいました。
Mobile Solutions - Google Cloud Platform — Cloud Platform」で
「Try it now」ボタンを押して利用を開始する事ができます。

ソースコードも公開されているので、
ProspectiveSearchとGCMの利用方法のサンプルアプリとして見ても面白いと思います。



◯Cloud Datastore


https://developers.google.com/datastore/

Blog @vierjp : 33.Google Cloud Datastoreを試してみた 概要編 (1/3)」に詳細をまとめ直しています。

◯概要
位置づけとしてはAppEngineのDatastoreを単独のサービスとして切り出したもの。
現在「Preview Release」という扱い。
概要レベルでは機能も同じとのこと。
ただしプログラムからの呼び出し方は大きく異なる模様。

これまでDatastoreはAppEngineの各アプリと1:1で完全に紐付いていて、
そのアプリ以外からアクセスすることができなかったが、
Cloud Datastoreとして単独のサービスになった事で、
異なるAppEngineアプリや環境から呼び出すことができるようになった。

複数のAppEngineのアプリから同一のDatastoreにアクセスしたり、
逆に一つのAppEngineのアプリから複数のDatastoreにアクセスしたり、
Compute Engineからアクセスしたりもできる。
さらには別のクラウドやオンプレミスのサーバーからもアクセスできる。


◯Cloud DatastoreのAPI
基本的に既存のDatastoreと機能は同じだそうですが、
ドキュメントを見る限りアクセス方法は異なります。
Protocol Buffer形式でリクエストを投げる「Protocol Buffers API」か、
JSON形式でリクエストを投げる「JSON API」を使用します。
Protocol Buffers APIは現状JavaとPythonから利用できます。
(現時点でGO用・PHP用は用意されていません)

注意が必要なのは既存のDatastoreアクセスに使っている「Low Level API」とは異なるという事。
そのため現在利用している「Low Levle APIベースのフレームワーク」は
「Cloud Datastore」に対してそのままでは使えないのでしょう。
(API Proxyレベルで処理を差し替えて対応できたりしないだろうか)
* 2013/06/11 追記 AppEngine上のアプリからはこれまで通りに使えます。
詳しくは「Blog @vierjp : 33.Google Cloud Datastoreを試してみた 概要編 (1/3)」を参照。

JSON API経由なら言語を問わず利用する事ができるので、
node.jsのサーバーから利用する」ような事もできます。

JSON APIは既にAPIs Explorerに表示されています。
Discovery APIベースなので、多くの言語に対応するClient Libraryが公開されることでしょう。


◯ユースケース
- ケース1 AppEngineアプリのバックエンドとしてCompute Engineを使う場合

AppEngineのアプリが保存する大量データの処理にCompute Engineを使う。
データの保存領域に「Cloud Datastore」を使うことで、
時間のかかる大量データの処理をCompute Engine上のバッチから行う事ができる。
(Cloud DatastoreならAppEngineのアプリとCompute Engineの両方からアクセスできるので)

ComputeEngineを使っていわゆる「夜間バッチ」的な一括処理に使ったり、
DatastoreのデータをBigQueryに転送する前に加工したり、
という用途が思いつきます。

これまではAppEngineアプリの持つ大量データの処理は
「Shutdown対応」をした上でbackendsを使ったり、細かいたくさんのTaskに分散させて処理する等、
実装段階で手間をかけていましたが、それが軽減されるでしょう。


- ケース2 Compute Engine上にWebアプリを配置する場合
AppEngineを使わない場合でも、
例えばCompute Engine上にnode.jsのサーバーを立てて、
そのデータ保存領域としてCloud Datastoreを使うということもできます。

実際にI/O 3日目の「Code Labs」でこの説明が行われるようです。
「Getting Start」では「node.jsからGoogle Cloud Datastoreを使う方法」について書かれています。
Overview - Google Cloud Datastore — Google Developers


- ケース3
 AppEngine・ComputeEngine以外のクラウド環境からデータを操作する
 JSON APIがあるので基本的にどこからでも操作できるはずです。
 自社にあるオンプレミスのサーバーからアクセスすることもできますし、
 アプリのアップグレードに伴うデータの一括更新処理をローカル環境から実行するようなこともできるでしょう。
 (この場合ComputeEngineから動かすのと比べて速度が遅そうですが)


◯Preview期間中の制限
Preview期間中は、課金を有効にしている場合にも、
Read、Write、Small Operationそれぞれに対して
「10 million per day, no more than 500 per second」のlimitが設定されています。
(連絡すれば増やしてもらえるそうです)



◯Google Compute Engine



現地時間で15日についにGoogle Compute Engineが一般公開されたそうです。
以前と比べて変更されたのは以下のとおりです。

- Sub-hour Billing
 課金の時間単位が変わったそうです。
 最低課金額は10分単位だが、その後は一分単位で課金される、とのこと。

- Shared Core Instance
 →f1-micro,g1-smallの追加
  さらに安いインスタンスが追加されました。
  これまでの一番安いインスタンスが「n1-standard-1」の「$0.115/h」ですが、
  「f1-micro」は「$0.019/h」で格段にお安くなっています。
  実際にどのくらいのパフォーマンスがあるのかわかりませんが、
  メモリをそれほど必要としない長時間の処理に良いのでしょう。

- Advanced Routing
3日目のセッションで話されるそうですが未確認です。
* 2013/5/25追記 オンプレミス環境や他のクラウドとセキュアに繋ぐためのVPN的なもの・・・らしいです。

- Persistent Diskのサイズが最大10TBになった。
これまでの最大サイズ「1TB」から10倍の「10TB」になります。

参考:
Google Compute Engine Pricing (料金体系)



◯Google Cloud Storage (2013/5/23追記)

すっかり忘れてましたがセッション動画見直していたら新機能があったので追記。

◯Offline Disk Import (Limited Preview) 
https://developers.google.com/storage/docs/early-access?hl=ja

アップロードしたいファイルをハードディスクに入れてGoogleに送ると、
Google内のネットワークからUploadしてくれる
という究極手段。
(最初ネタかと思ったのは内緒^-^;)

Google/IO 初日の5/15にサービス開始。

・手順
1.Offline Disk ImportのInterest Formから申し込み
2.SATAのハードディスクをencfs(暗号化ファイルシステム)でフォーマットする
3.データをハードディスクにコピーする
4.Googleに郵送する
5.Googleが顧客が所有する新しいbucketにimportする(Googleの高速なネットワークを使って)
6.GoogleがHDDを郵送で返す

* 現時点ではアメリカ国内の顧客限定です
ただし、間違いなく今後数ヶ月の間に国際的に利用できるように拡大するし、
優先順位が上がるかもしれないので海外の顧客も「Interest Form」から連絡してください、とのこと。

料金は通常のGoogle Cloud Storageの料金がリクエスト回数, 帯域使用料,ストレージ使用料」に加えて
HDD一つ毎に「$80」加算されます。

* 2013/5/24追記 Google Cloud Storeのセッションに関して別途詳細記事を書きました。
31.Google Cloud Storageに大量データをアップロードする際のテクニック(Google I/O 2013)



◯Google BigQuery (2013/5/28追記)

IO報告会(#Devfest)で知ったので追記。

◯Google Analytics and AdSense Data Analysis in BigQuery
AdSense BigQuery Integration Guide - AdSense — Google Developers

・BigQueryでGoogle AdSenseのデータを分析可能になりました
・Google Analyticsのデータは2013年9月の公開を目指しているそうです

AdsenseにしてもAnalyticsにしても、
BigQueryを使ってこれらと自社で持っている別の情報とをJoinして分析できる事が魅力です。

Google BigQueryのセッションに関して別途詳細記事を書きました。
32.Google BigQueryでAnalyticsとAdSenseのデータを分析する(Google I/O 2013)


概要レベルですが、今日はここまでとしてまた近日中に続報を書こうと思います。

以上、 San Franciscoからでした!



◯TopGate社 Google I/O フィードバックセミナー (2013/6/11追記)

2013/5/31に行われた「TopGate社 Google I/O フィードバックセミナー」で
私がGoogle Cloud Platform担当として発表したスライドです。
Report of Google I/O 2013 Google Cloud Platform

こちらも併せてどうぞ!


2013年5月9日木曜日

26.Google App Engine 1.8.0リリース




Google App Engine 1.8.0がリリースされたので変更点を確認しました。
また、最後に「おまけ」としてAppEngineのSDK一般について2点書いています。


先日まで1.7.8 Pre-releaseとされていたものが、
正式リリースでは1.8.0というバージョン番号になったようです。
それもあってか本家のMLでも若干の混乱があった模様。


○関連リンク

SdkForJavaReleaseNotes - googleappengine - Google App Engine Java SDK
SDKダウンロードページ


◯1.8.0変更点

- The Mail API now allows attachments with .zip and .gzip extensions as long as
  the archives do not contain entries with blacklisted extensions.
  http://code.google.com/p/googleappengine/issues/detail?id=5933

Mail APIを使ってメールを送信する際にzipとgzipを添付できるようになった。
ただしzipやgzipの中に「禁止されている拡張子のファイル」を含んでいるとダメ。

「禁止されている拡張子」については以下を参照
Mail Java API Overview - Google App Engine — Google Developers
(「As a security measure to protect against viruses〜」以下)


- New Billing Enabled apps will no longer default to an email quota of 20,000 per day.
  Instead, apps will need to file a request through the admin console to get email quotas increased.

課金が有効なアプリケーションのEmailのQuotaがデフォルトで一日当たり20,000になった。
ただし、
Google Checkoutのアカウントで最初の課金が成功するまではQuotaが「100」という点はこれまで同様。
Quotaを増加したい場合はAdmin Consoleの「Quota Details」ページのリンクからリクエストする必要がある。

MailのQuota
Increasing your Daily Mail Quota

「1.8.0以後に課金設定を有効にしたアプリはそれ以前から課金を有効にしているアプリよりもQuotaが下がる」
と書いてあるようですが、
先ほど試しに新しいアプリを作成して課金を有効にしてみたところ、
従来通りのQuota 「1,771,789」のままでした。
んー、条件がよくわかりません。。
まあ少ない場合は最初の課金を待って、20000で足りなければリクエスト送って増やしてもらう、ということで。


- Admin console dashboard charts and reports for all users have been fully
  migrated to the new, more reliable backend announced in 1.7.6.

 管理コンソールのダッシュボードチャートとレポートが
  1.7.6のタイミングでアナウンスされた、新しい、より信頼性の高いバックエンドに完全に移行された。
  (見た目ではわかりませんでした)


- The maximum size of POST requests made through URLfetch has been increased from 5MB to 10MB.

 URLfetchを通じて行うPOSTリクエストの最大サイズが5MBから10MBに増加された。


- Fixed an interaction issue between the Java MapReduce library and the Files API which causes loss of data.
  If you are using the experimental Java MapReduce library,
  we strongly encourage you to update to the latest version of the library in the public svn:
  https://code.google.com/p/appengine-mapreduce/source/checkout

  JavaのMapReduceライブラリとファイルのAPIの相互作用によって
  データの損失を引き起こす問題を修正しました。
  もしexperimentalなJavaのMapReduceのライブラリを使用している場合は、
  public svnにある最新バージョンのライブラリのにアップデートすることを強く勧めます。


- Fixed an issue with the Mail API to prevent sending mail from a Google Apps mail account that has been suspended.
  https://code.google.com/p/googleappengine/issues/detail?id=6181

  「中断されているGoogle Appsのメールアカウントからのメール送信を防いでいた、
  メールAPIの問題を修正しました。」
  と訳してみたけど、Issueを見ると、
  「これまでは中断されているGoogle Appsのメールアカウントから送信した場合に、
   MailAPIの呼び出しはエラーにならないけど実際にはメールが送信されなかった」
  ↓
  「その場合には"unauthorized sender"を返すようにした」
   って書いてあると思う。


- Fixed an issue that caused Full-Text Search to fail in the Java dev_appserver.
   https://code.google.com/p/googleappengine/issues/detail?id=9088
 
  Java dev_serverで全文検索(Full-Text Search)が失敗する問題を修正した。


- Fixed an issue with Java dev_appserver which caused the AdWords API to not work.
  https://code.google.com/p/googleappengine/issues/detail?id=9213

  Java dev_serverでAdwordsのAPIが動作しない問題を修正した。


- Fixed an issue with the Java SDK jar file being too large for Windows 64.

 Java SDKのjarファイルがWindows64環境で大きすぎる問題を修正しました。
 (1.7.7.1で修正された「jarが大きすぎてWindowsでデプロイが失敗していた」と同じ?)


- Fixed a JAXBPermission.setDatatypeConverter permission issue in Java7 runtime.

 Java7で「JAXBPermission.setDatatypeConverter」のパーミッションの問題を修正しました。



◯おまけ1:Production環境のバージョンとSDKのバージョン

AppEngineのProduction環境(クラウド上の実環境)では常に最新のバージョンが動いています。(今なら「1.8.0」)
言い換えれば、他のクラウド(Windows Azureとか)のように
「Production環境でディベロッパーの指定した古いバージョンで動作させる」ということはできません。

ローカルの開発環境(dev server)では古いSDKを指定して動作させることができますが、
この場合、実際に運用する環境と異なるバージョンのSDKを使って開発・テストしていることになるのであまり良い状態ではありません。
自分の過去の経験上ではこれが原因でトラブルになったことはありませんが、
開発環境のSDKのバージョンはできるだけ最新の状態を維持するのが良いでしょう。

と言っても、
今回もそうだったようにProduction環境のリリースの方がSDKのリリースより先に行われるので
その間は開発環境でテストしたバージョンと異なるバージョンで
Production環境のアプリが動作することにはなるわけですが。

現状この期間に関してはどうすることもできないので、
「少なくとも一つ前のバージョンは正しく動くようにテストしているはず」と信じて、
あまり古くならないように維持するのが現実的なところでしょうか。
でも今後一度でもこれに関連してトラブルが起きたら結構なリスクに感じるようになるんだろうな。。



◯おまけ2:SDK1.7.6以降のdev_server(Java)で出力されるStacktrace

リクエストの度にFINEレベル(log4jなんかのtrace相当)で以下のStacktraceが出力されます。

com.google.appengine.tools.development.DevAppServerServersFilter getCurrentServerInstance
詳細レベル(低): Exception getting server instance
com.google.appengine.api.labs.servers.ServersException: No valid instance id for this instance.
at com.google.appengine.api.labs.servers.ServersServiceImpl.getCurrentInstanceId(ServersServiceImpl.java:75)
at com.google.appengine.tools.development.DevAppServerServersFilter.getCurrentServerInstance(DevAppServerServersFilter.java:210)
.....

「1.7.6 の Changelog にある 'multiple logical sub components' 関係のトレース」らしいですが、
これが出力されていても正常に動作はしているようです。(たぶん)

ただ、表示されると邪魔ですし、コンソールにStacktraceが表示されることに慣れてしまうのも良くないので、
logging.propertiesに一行追加して以下のようにしておきましょう。

.level = FINEST
com.google.appengine.tools.development.level = WARNING