私たちの目標は当初から一貫しています。私たちは、すべての企業のために最もオープンなクラウドを構築し、素晴らしいソフトウェアを簡単に開発、運用できるようにしたいと考えています。

私たちはこのたび、お客様に大きな価値を提供する新しいプロダクトやサービスを発表しました。また、インフラストラクチャのアップデートも公表しています。私たちはこのアップデートにより、10 億人のユーザーを抱える Gmail や Android といった Google プロダクトだけでなく、世界中の企業をより強力にサポートできるようになります。

リージョンの増設が加速

Google Cloud Platform のお客様のサービスを利用するエンドユーザーが先ごろ 10 億人を超え、GCP は 10 億ユーザーを抱える Google プロダクトの仲間入りを果たしました。

こうした需要の拡大に対応するため、私たちは地理的な拡張の取り組みを大きく加速させており、このほど Google Cloud Platform のリージョンを 8 つ新設することを発表しました。

これらのリージョンのデータセンターは、インドのムンバイ、シンガポール、オーストラリアのシドニー、米国北バージニア、ブラジルのサンパウロ、英国のロンドン、フィンランド、ドイツのフランクフルトに設置されます。また、2017 年にもリージョンの追加が発表されることになっています。

リージョンの増設により、私たちはより高いパフォーマンスをお客様に提供できます。実際、北米西海岸の Oregon Cloud Region を最近新設したことで、お客様のレイテンシが最大 80 % 改善されました。私たちは 2017 年に新しいリージョンの運用を順次開始し、お客様を迎えることを楽しみにしています。



マルチクラウドの活用をサポート

Google Cloud Platform で実行されるアプリケーションは、最新のインフラストラクチャの恩恵を受けるだけでなく、最新の優れたコンピュート プラットフォームで実行されることの恩恵も受けます。

Google が開発し、オープンソース化したコンテナ管理システムである Kubernetes が、このほどバージョン 1.4 になりました。私たちは、Google Container Engine(GKE)をこの新バージョンに対応させるアップデートを精力的に進めています。

GKE のお客様は、Kubernetes の最新機能の恩恵を最も早く受けることができます。Kubernetes の最新機能には、クラスタ アドオンのモニタリング、ワンクリックでのクラスタのスピンアップ、強化されたセキュリティ、Kubernetes Federation との統合、新しい Google Container-VM イメージ(GCI)のサポートなどがあります。

Kubernetes 1.4 では Kubernetes Federation が強化され、複数のクラスタや複数のクラウドにわたるデプロイが容易になりました。GKE はこの機能をサポートしていますので、お客様は複数のクラウドに容易に展開可能なアプリケーションを構築できます。これらのクラウドは、オンプレミスのプライベート クラウドでも、異なるクラウド ベンダーのパブリック クラウドでも、両者のハイブリッド クラウドでも構いません。

私たちは Google Cloud Platform をお客さまのワークロードの実行に最適な環境にしたいと考えており、Kubernetes はお客様の Google Cloud Platform への移行に役立っています。たとえば、Philips Lighting のようなお客様は、最もクリティカルなワークロードの実行環境を GKE に移行しています。

クラウド データ ウェアハウジングや機械学習への移行を後押し

クラウド インフラストラクチャは、アプリケーションとデータのサービスの質を左右します。データ分析はすべての企業にとって極めて重要であり、増加するデータ ソースから得られるデータの保存および分析ニーズは急増しています。またデータ分析は、ビジネス インテリジェンスの次の波となる機械学習の基盤を提供します。

大企業に当てはまる、データ分析と機械学習の共通原理をご存じでしょうか。それは、「データからビジネス インテリジェンスを得るには、多くのデータ ソースにアクセスし、それらのデータをシームレスに処理できる必要がある」というものです。多くの企業にとって、クラウド コンピューティングが自然で適切な選択肢となるのはそのためです。

私たちは今回、データ分析サービスと機械学習サービスについて、このニーズに対応したアップデートを行いました。

  • Google BigQuery : このフルマネージド データ ウェアハウスは大幅にアップグレードされ、クラウド データ分析の広範な導入が可能になりました。Standard SQL のサポートが GA となり、これまで以上に多くのデータ ツールとの互換性が向上し、クエリの共有の簡易化によって、より深い社内コラボレーションを促進します。また、セキュリティ ポリシーを細かく設定できる Identity and Access Management(IAM)が BigQuery に統合されました。さらに、企業が BigQuery を利用しやすいように、クエリの制限をなくし、データ ストレージ コストを予測可能にした固定料金プランも導入されました。

  • Cloud Machine Learning : すべての企業が利用できるようになりました。BigQueryCloud DataflowCloud Storage といったクラウド データ分析およびストレージ サービスと統合されており、ユーザー企業は自社のデータで高速かつ簡単に機械学習モデルを訓練できます。機械学習においても「百聞は一見にしかず」ですので、私たちは機械学習に特化した教育プログラムや認定プログラムを実施しています。これらは、多くのお客様が自社にとっての機械学習のメリットを理解できるように支援し、機械学習を利用するためのツールも提供します。

Google Cloud Platform 全体でのデータ管理方法の詳細については、私たちの新しいドキュメント Data Lifecycle on GCP をご覧ください。

顧客サポートのために新しいエンゲージメント モデルを導入

私たち Google は、お客様のアプリケーションの全体的な信頼性と健全な運用状態に関する責任は共有されるべきものだと理解しています。そうした考えのもと、私たちはこのたび、Google Cloud チームの新たな役割として Customer Reliability Engineering(CRE : 顧客信頼性エンジニアリング)を発表しました。

CRE は、私たちとお客様のパートナーシップを深めることを目的としており、Google のエンジニアが担当します。担当エンジニアはお客様の運用チームと連携し、基幹クラウド アプリケーションの信頼性に関する責任を共有します。

この連携を通じて、私たちが 20 年近くにわたって培ってきたクラウド コンピューティングの経験とノウハウを共有、適用する新しいモデルが、お客様の組織の一部として組み込まれます。これについては、近いうちに詳しい発表を行います。

CRE モデルを初めて導入した事例の 1 つが、Pokémon GO をリリースした Niantic への協力でした。この事例では、世界中の数百万人のユーザーに対応するためのスケーリングが数日間で実現されました。
Niantic などのお客様をサポートする、Google Cloud GKE/Kubernetes チーム


パブリック クラウドはお客様の信頼の上に成り立っています。お客様にとって物理インフラストラクチャをパブリック クラウド ベンダーに任せることは大きなコミットメントであることを、私たちは理解しています。

お客様のニーズに応える新機能を提供し、機械学習のようなツールによってお客様が未来を切り開くお手伝いをすることで、私たちはパブリック クラウドのユーザビリティ向上を継続し、Google Cloud Platform にますます多くの企業をお迎えしていきます。今後のさらなる展開にご期待ください。

* この投稿は米国時間 9 月 29 日、Google Cloud の Vice President である Brian Stevens によって投稿されたもの(投稿はこちら)の抄訳です。


- Posted by Brian Stevens, Vice President, Google Cloud



新しい Firebase プラットフォームに備わるクラウド統合機能のうち、私が特に気に入っているのは、カスタム分析のために Firebase Analytics から Google BigQuery に生データを送れる機能です。このカスタム分析は、Firebase Analytics イベントに渡されたカスタム パラメータにもアクセスでき、iOS および Android の両バージョンのデータ集計で特に役に立ちます。


以下では、この強力な組み合わせによって何ができるのかを紹介します。


BigQuery へのエクスポートの仕組み

Firebase プロジェクトを BigQuery にリンクすると、Firebase は新しいテーブルを自動的に毎日、対応する BigQuery データセットにエクスポートするようになります。対象のアプリに iOS 版と Android 版の両方がある場合は、Firebase は各プラットフォームのデータを別々のデータセットにエクスポートします。


エクスポートされた各テーブルには、Firebase Analytics が自動的にキャプチャしたユーザーのアクティビティおよびデモグラフィック データと、アプリの中でキャプチャされたカスタム イベントが含まれています。そのため、クロスプラットフォーム アプリの 1 週間分のデータをエクスポートした場合、BigQuery プロジェクトはそれぞれ 7 個のテーブルを持つ 2 つのデータセットを持つことになります。

データの概要

Firebase Analytics がエクスポートするテーブルのスキーマはどれも同じです。私たちは以下のサンプル クエリを実行するため、サンプル ユーザー データで 2 つのデータセット(iOS 用Android 用)を作りました。このデータセットは、iOS と Android の両プラットフォームに対応したサンプル ゲーム アプリのためのものです。それぞれのデータセットには 7 個のテーブル、つまり 1 週間分のアナリティクス データが含まれています。


次のクエリは、ある 1 日を対象に、iOS 版アプリの利用状況に関する基本的なデモグラフィックとデバイス データを返します。

SELECT
  user_dim.app_info.app_instance_id,
  user_dim.device_info.device_category,
  user_dim.device_info.user_default_language,
  user_dim.device_info.platform_version,
  user_dim.device_info.device_model,
  user_dim.geo_info.country,
  user_dim.geo_info.city,
  user_dim.app_info.app_version, 
  user_dim.app_info.app_store,
  user_dim.app_info.app_platform
FROM
  [firebase-analytics-sample-data:ios_dataset.app_events_20160601]

Firebase Analytics からエクスポートされる BigQuery テーブルのスキーマはすべて同じなので、ここで挙げたクエリのデータセットやテーブル名を皆さんのプロジェクトのものに置き換えれば、皆さんの Firebase Analytics データに対して実行できます。


このスキーマにはユーザー データとイベント データが含まれています。ユーザー データはすべて Firebase Analytics が自動的にキャプチャするのに対し、イベント データはアプリに追加されたカスタム イベントによって作られます。


ユーザー データ

ユーザー レコードには、ユーザーごとに一意なアプリ インスタンス ID(このスキーマの user_dim.app_info.app_instance_id )とともに、位置、デバイス、アプリのバージョンのデータが含まれています。


Firebase コンソールには、アプリの iOS 版と Android 版のアナリティクス向けに用意された別々のダッシュボードがあります。BigQuery では、両プラットフォームのユーザーが世界中のどこからアプリにアクセスしているかを調べるためのクエリを実行できます。


次のクエリは、UNION ALL 演算子としてカンマが使える BigQuery の union 機能を使用しています。私たちのサンプル テーブルにおける行はユーザーが発生させたイベントごとに作られるため、各ユーザーがちょうど 1 回ずつ数えられるようにするために EXACT_COUNT_DISTINCT 関数を使っています。

SELECT
  user_dim.geo_info.country as country,
  EXACT_COUNT_DISTINCT( user_dim.app_info.app_instance_id ) as users
FROM
  [firebase-analytics-sample-data:android_dataset.app_events_20160601],
  [firebase-analytics-sample-data:ios_dataset.app_events_20160601]
GROUP BY
  country
ORDER BY
  users DESC

また、使用言語や地理的な位置といった、ユーザー ベースのさまざまなセグメントを表現するために定義した属性を格納する user_properties レコードも、ユーザー データに含まれています。なお、Firebase Analytics はデフォルトで数種類のユーザー プロパティをキャプチャするため、独自に定義できるプロパティは 25 個までです。


ユーザーの使用言語はデフォルト ユーザー プロパティの 1 つです。次のクエリを実行すれば、両プラットフォームを通じてユーザーがどの言語を使っているかがわかります。

SELECT
  user_dim.user_properties.value.value.string_value as language_code, 
  EXACT_COUNT_DISTINCT(user_dim.app_info.app_instance_id) as users,
FROM
  [firebase-analytics-sample-data:android_dataset.app_events_20160601],
  [firebase-analytics-sample-data:ios_dataset.app_events_20160601]
WHERE
  user_dim.user_properties.key = "language"
GROUP BY
  language_code
ORDER BY 
  users DESC

イベント データ

Firebase Analytics では、アプリ内でのアイテム購入やボタン クリックといったカスタム イベントのログを簡単に取得できます。イベントのログを出力するときは、Firebase Analytics にイベント名と 25 個までのパラメータを渡すと、Firebase Analytics が自動的にイベント発生回数をカウントします。


次のクエリは、特定の 1 日間に Android 版アプリで発生した各イベントの回数を明らかにします。

SELECT 
  event_dim.name,
  COUNT(event_dim.name) as event_count 
FROM
  [firebase-analytics-sample-data:android_dataset.app_events_20160601]
GROUP BY 
  event_dim.name
ORDER BY 
  event_count DESC


他のタイプの値(たとえばアイテムの料金)がイベントと関連づけられている場合は、それをオプションの value パラメータとして渡すと、BigQuery でその値によるフィルタリングが可能です。


私たちのサンプル テーブルには spend_virtual_currency イベントがあります。そこで、次のクエリを実行すれば、ゲームのプレーヤーが一度にどれくらいの仮想通貨を消費するのかがわかります。

SELECT 
  event_dim.params.value.int_value as virtual_currency_amt,
  COUNT(*) as num_times_spent
FROM
  [firebase-analytics-sample-data:android_dataset.app_events_20160601]
WHERE
  event_dim.name = "spend_virtual_currency"
AND
  event_dim.params.key = "value"
GROUP BY
  1
ORDER BY 
  num_times_spent DESC


複雑なクエリ

両プラットフォームのアプリを使用して、特定の期間を対象とするクエリを実行したいときはどうすればよいでしょうか。Firebase Analytics データは日ごとにテーブルに分割されるので、BigQuery の TABLE_DATE_RANGE 関数を使えばこれを実現できます。


次のクエリは、1 週間の間にいくつの都市のユーザーがアクセスしているかを返します。
SELECT
  user_dim.geo_info.city,
  COUNT(user_dim.geo_info.city) as city_count 
FROM
TABLE_DATE_RANGE([firebase-analytics-sample-data:android_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP()),
TABLE_DATE_RANGE([firebase-analytics-sample-data:ios_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP())
GROUP BY
  user_dim.geo_info.city
ORDER BY
  city_count DESC

同様に、両プラットフォームにおけるスマートフォンとタブレットからのアクセス回数が、1 週間でどれだけなのかを比較するクエリも書くことができます。

SELECT
  user_dim.app_info.app_platform as appPlatform,
  user_dim.device_info.device_category as deviceType,
  COUNT(user_dim.device_info.device_category) AS device_type_count FROM
TABLE_DATE_RANGE([firebase-analytics-sample-data:android_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP()),
TABLE_DATE_RANGE([firebase-analytics-sample-data:ios_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP())
GROUP BY
  1,2
ORDER BY
  device_type_count DESC

少し複雑になりますが、次のクエリは、2 週間の間に発生した両プラットフォームのユニーク ユーザー イベントのレポートを生成するものです。ここでは、PARTITION BYEXACT_COUNT_DISTINCT でユーザー プロパティと user_dim.user_id フィールドを使用し、イベント レポートからユーザーの重複を取り除いています。


SELECT 
  STRFTIME_UTC_USEC(eventTime,"%Y%m%d") as date,
  appPlatform,
  eventName,
  COUNT(*) totalEvents,
  EXACT_COUNT_DISTINCT(IF(userId IS NOT NULL, userId, fullVisitorid)) as users
FROM (
  SELECT
    fullVisitorid,
    openTimestamp,
    FORMAT_UTC_USEC(openTimestamp) firstOpenedTime,
    userIdSet,
    MAX(userIdSet) OVER(PARTITION BY fullVisitorid) userId,
    appPlatform,
    eventTimestamp,
    FORMAT_UTC_USEC(eventTimestamp) as eventTime,
    eventName
    FROM FLATTEN(
      (
        SELECT 
          user_dim.app_info.app_instance_id as fullVisitorid,
          user_dim.first_open_timestamp_micros as openTimestamp,
          user_dim.user_properties.value.value.string_value,
          IF(user_dim.user_properties.key = 'user_id',user_dim.user_properties.value.value.string_value, null) as userIdSet,
          user_dim.app_info.app_platform as appPlatform,
          event_dim.timestamp_micros as eventTimestamp,
          event_dim.name AS eventName,
          event_dim.params.key,
          event_dim.params.value.string_value
        FROM
         TABLE_DATE_RANGE([firebase-analytics-sample-data:android_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP()),
TABLE_DATE_RANGE([firebase-analytics-sample-data:ios_dataset.app_events_], DATE_ADD('2016-06-07', -7, 'DAY'), CURRENT_TIMESTAMP())
), user_dim.user_properties)
)
GROUP BY
  date, appPlatform, eventName
同じアプリのデータが Google Analytics にある場合は、Google Analytics データを BigQuery にエクスポートし、Firebase Analytics からエクスポートされた BigQuery テーブルと JOIN することも可能です。


アナリティクス データのビジュアライズ

データの BigQuery へのエクスポートによって、モバイル アプリ データから新しいインサイトを収集したら、Google Data Studio を使用してそれをイメージとして視覚化してみましょう。


Data Studio は、BigQuery テーブルを直接読み出せるだけでなく、上述したようなカスタム クエリにも対応します。Data Studio を使用すれば、データの構造に応じた形で、時系列図、棒グラフ、円グラフ、ジオマップなど、さまざまなタイプのグラフやチャートを生成できます。


最初に、ユーザーがアプリにアクセスするために使っているデバイス タイプ(スマートフォンかタブレット)をプラットフォームごとに比較する棒グラフを描いてみましょう。先ほどのスマートフォン対タブレットのクエリを直接 Data Studio にペーストすると、次のグラフが得られます。



このグラフを見ると、iOS ユーザーの場合は、スマートフォンよりもタブレットを使ってゲームをしている傾向が強いことが簡単にわかります。


もう少し複雑にして、前述したプラットフォームごとのイベント数を比較するクエリから、比較のための棒グラフを作ることもできます。

BigQuery プロジェクトと Data Studio の詳細な接続手順については、こちらの投稿を参照してください。


使ってみよう

Firebase を初めて使う方は、ここから始めてください。すでに Firebase でモバイル アプリを構築している方は、Firebase プロジェクトと BigQuery のリンクに関する詳細なガイドを参照してください。


疑問点については、BigQuery のクエリ リファレンスと Stack Overflow の firebase-analyticsgoogle-bigquery タグをご覧ください。そして、このブログで取り上げてほしいテーマがありましたら、ぜひこちらまでお寄せください。


* この投稿は米国時間 9 月 22 日、Developer Advocate である Sara Robinson によって投稿されたもの(投稿はこちら)の抄訳です。

- Posted by Sara Robinson, Developer Advocate



この設定を有効にすると、利用できるデータベース ストレージが 30 秒ごとにチェックされ、必要に応じてデータベースのサイズが 5 GB ~ 25 GB の範囲で拡張されます。つまり、将来のデータベースの拡張に備えてストレージをプロビジョニングする必要はなく、データベースの成長に歩調を合わせた形でストレージ容量を追加できます。


Cloud SQL のストレージ自動拡張機能には 2 つの大きなメリットがあります。


  1. データベースが必要に応じて拡張されれば、データベースの容量を使い尽くすリスクが低減され、そのぶんアプリケーションのダウンタイムも短くなります。容量決定の際に当て推量が不要になり、しかもダウンタイムが発生したりデータベースのメンテナンスが必要になったりすることはありません。
  2. 徐々にサイズが大きくなるデータベースを管理している場合、この機能によって使用料をかなり節約できます。あらかじめ大量のスペースをプロビジョニングするのではなく、必要に応じてストレージを拡張できるからです。つまり、実際に使用しているぶんに若干のマージンを上乗せした額を支払えば済みます。



ドキュメントによると、Cloud SQL は次の方法で追加容量を決定します。


しきい値のサイズとインスタンスに追加されるストレージの容量は、現在のインスタンスにプロビジョニングされているストレージの容量によって決まり、最大で 25 GB になります。そこで、現在のストレージ容量を 25 で割り、その結果の端数を切り捨てて整数にします。そして、その値に 5 GB を加えます。すると、それがしきい値のサイズになり、利用可能ストレージがしきい値よりも小さくなったときに追加されるストレージ容量になります。


これを JavaScript の数式で表現すると、次のようになります(単位 : GB)。


Math.min((Math.floor(currentCapacity/25) + 5),25)


以下は、現在の容量に対するしきい値、および自動的に追加される容量がどれくらいなのかをまとめた表です。

現在の容量
しきい値
自動的に追加される容量
50GB
7GB
7GB
100GB
9GB
9GB
250GB
15GB
15GB
500GB
25GB
25GB
1000GB
25GB
25GB
5000GB
25GB
25GB



Cloud SQL Second Generation で実行中のデータベース インスタンスがすでに存在すれば、この機能をすぐに有効にすることができます。


* この投稿は米国時間 9 月 21 日、Head of Developer Advocacy である Greg Wilson によって投稿されたもの(投稿はこちら)の抄訳です。


- Posted by Greg Wilson, Head of Developer Advocacy


■ 写真左から
株式会社True Data
  • 企画本部 アナリティクス・ソリューション部課長 烏谷正彦さん
  • 顧問 田中覚さん

■ 利用中の Google  Cloud Platform サービス
Google BigQuery など




True Data の業務は、クライアントとなる小売業者(スーパー、ドラッグストア、コンビニエンスストアなど)から預かったポイントカードを保有する消費者の購入情報(ID-POSデータ)を分析し、それに基づいたコンサルティングや、簡単にデータ活用ができるようにするための分析基盤を提供するというもの。2000 年の創業以来、オンプレミスの社内システムでこれを行ってきましたが、年々、膨大になっていくデータの前に、いよいよそれが限界に。これを受け同社顧問・田中覚さんはクラウドを利用したシステムへの移行を検討し始めました。

「True Data が保有する約 5000 万人の、20~30 億件にも及ぶ購買データをより効率的に分析できるようにすること、それが当時の私のミッションでした。その際、最も重視したのがスピードです。これまでのシステムも悪いものではなかったのですが、あまりに扱うデータが大きくなりすぎたため、何をするにも時間がかかってしまっていました。“分析”とは“仮説”と“検証”の繰り返し。ああでもない、こうでもないとトライ&エラーを繰り返していくことでデータを読み解いていきます。この際、システムの応答が遅いというのは大きな足かせになってしまいます。システムを利用する業務メンバーの思考を止めない処理速度を実現する必要がありました」


そこで選ばれたのが、処理速度に定評のあった Google BigQuery。システム開発を担当した株式会社グルーヴノーツからの推薦もあり、多くの選択肢との比較の末、今春から BigQuery を利用した新システムの運用がスタートしました。

「グルーヴノーツさんが言うような速度が出るのか、当初はやや懐疑的でした」と当時をふり返るのは、システムを現場で利用する分析チームのリーダーである烏谷さん。社内の技術者も、分析チームの他のメンバーも、これまでの苦労を知っているだけに、それが一気に解決するとはとても思えなかったそうです。「これまで何時間もかかっていた処理が、5 分で終わりますなんて言われてもそう簡単には信じられませんよね(笑)」(烏谷さん)

「ところが、実際にデータを回してみると、これが想像以上に速い。圧倒的でしたね。軽く 10 倍以上は出ていると思いました。確かにこれなら、思考を止めることなく作業ができます。また、いままでのシステムでは速度の問題もあって、対象とするデータをある程度まで絞り込むようにしていました。しかし、BigQuery 導入後は全てのデータを 1 つの箱に放り込んでおけるようになるなど、使い勝手も劇的に改善。これまでの 10 倍以上の効率で作業を進められるようになりました」(烏谷さん)


「ちなみに、この使い勝手の向上には、グルーヴノーツさんの誇る「BLOCKS」というソリューションが大いに貢献してくれました。BigQuery はアナリストならともかく、業務メンバーにはそこそこ敷居が高かったのですが、BLOCKS を使えば、技術的知識がそこまでないメンバーでも、一度レクチャーするだけで複雑な分析を気軽に行えるようになるんです。最終的には営業チームも含めた、全てのスタッフがBigQuery を使えるようになることが目標。これが実現すれば、顧客先で気になる数字をサッと取り出すなんてこともできるようになりますよね。本格導入してまだ数ヶ月といったところですが、すでにこのシステムに懐疑的なスタッフは 1 人もいません」(田中さん)

ただし、BigQueryの導入はいまだ道半ば。まだ社内でアナリストがコンサルティング業務に利用するデータ分析基盤の構築が完了したところで、今後はクライアントである小売店やメーカーに提供している分析基盤にも適用範囲を拡大していきたいそうです。

「顧客向けデータ分析基盤についても、データマートを作るところまでBigQueryの導入が進みました。これによって、データマートの最適化が進み、パフォーマンスの向上や扱うデータの鮮度が高くなるという恩恵が得られています。ただ、この作業はここからが大変。なまじ、一部分が上手くいっているため、大きなプレッシャーを感じますね(笑)」(田中さん)


また、コスト面での最適化も課題の 1 つ。現時点でも既に従来システムと比べて 7割のコストダウンに成功しているものの、いろいろなことを試しながら進めていることもあって、目標としている数値には至っていません。「BigQuery のクセをつかめるようになれば、そう遠くない未来には当初の 10 分の 1 程度にまでコストダウンできるはず。そうすれば、速度×効率×コストパフォーマンスでそれぞれ 10 倍の改善が図れたことになりますから、トータルで 1000 倍の効率化ということになりますね(笑)」(田中さん)


「現在は、まずBigQuery の利用を始めたという状況ですが、Google Cloud Platform の先進的な機能にはとても興味を持っています。例えば機械学習などを駆使して、より有用なデータモデリングや処理の自動化などができるようになると面白そうですよね。将来的にはそういったシステムの開発も検討していきたいと考えています」(烏谷さん)



優れた技術のおかげで、世界が盛り上がる瞬間にこれまでにない多様なコミュニケーションが行われるようになりました。たとえばハッシュタグは、特定のアスリートや瞬間、あるいは大会全体などについて人々が考えたことや感じたことを素早くまとめ、一覧するのに役立ちます。


ですが、視聴者やファンがリオ オリンピックについてどう感じていたかを定量的に理解できれば、クールではないでしょうか。何百万件ものツイートを読まなくても、私たち Google の機械学習 API を使えば、それが可能です。この投稿では、そうした定量的な理解に向けて、私たちがどのような分析を行ったかをかいつまんで紹介します。


私たちはまず、Twitter Streaming API を使って、#olympics、#Rio2016、#RioOlympics2016 というハッシュタグを使っているツイート(ラベル付けされたリツイートを除く)を集めました。


次に、Cloud Natural Language API をそれらに適用しました。この API はテキストの構造と意味を理解し、ツイートを分析しました。




そのデータが集まったら、私たちはそれらに対して分析サービスの BigQuery を実行し、Natural Language API が特定したすべての形容詞(感情を知るための大きな手がかりです)を抽出して、それらが使われた回数をカウントしました。さらに、データを細分化し、特定のアスリートに対する形容詞を抽出して、それらのアスリートへの直接的な感情を探りました。


Usain Bolt(ウサイン・ボルト)

Simone Biles(シモーネ・バイルズ)

もちろん、絵文字(emoji)入りのツイートもたくさんありました。私たちは、どの絵文字が一番使われているかがわかれば面白いと考えました。Natural Language API は絵文字に対応していますので、私たちがやるべきことは絵文字の画像と Unicode 値を対応づけて、各絵文字が使われた回数をカウントすることだけでした。


私たちの機械学習 API を組み合わせて興味深いインサイトを得る方法には、無限の可能性があります。私たちは自身の実験を通じて、そして世界中の開発者および企業の素晴らしいプロジェクトから学ぶことにより、新しいユースケースを日々楽しく発見しています。


* この投稿は米国時間 9 月 8 日、Google Cloud Platform の Developer Advocate である Sara Robinson によって投稿されたもの(投稿はこちら)を要約し、抄訳したものです。


- Posted by Sara Robinson, Developer Advocate, Google Cloud Platform

ドキュメントはこちら
リリースに関するブログ記事はこちら




Cloud Shell

Google Cloud Shell は GCP ユーザーのための無料の VM です。この VM はウェブ コンソールに組み込まれており、このコンソールを利用して、GCP リソースの管理、テストやビルドなどを行うことができます。

Cloud Shell には、Google Cloud SDK、Git、Mercurial、Docker、Gradle、Make、Maven、npm、nvm、pip、iPython、MySQL クライアント、gRPC コンパイラ、Emacs、Vim、Nano など、一般的なツールが多数プリインストールされています。

Cloud Shell は、Java や Go、Python、Node.js、PHP、Ruby といった言語もサポートしています。また、GCP Console のプロジェクトやリソースにアクセスするための認証機能も組み込まれています。
ドキュメントはこちら

概要はこちら

クイックスタートはこちら

使い方の YouTube 動画はこちら

リリースに関するブログ記事はこちら





カスタム マシン タイプ

Compute Engine ではさまざまなサイズの VM を提供していますが、ぴったり合うサイズがない場合は、ちょうど必要な数のコアとメモリを持つカスタム マシン タイプを作成できます。これにより、標準サイズのインスタンスと比べてコストを 50 % 削減したユーザーもいます。
概要はこちら

ドキュメントはこちら

カスタム インスタンス作成の YouTube 動画はこちら

リリースに関するブログ記事はこちら




プリエンプティブル VM


プリエンプティブル VM を使用すれば、バッチ ジョブやフォールト トレラントなワークロードの処理コストを通常の VM に比べて最大 70 % 削減できます。

プリエンプティブル VM のリソースは Google データセンターの空き容量を割り当てたものですが、この容量は必要に応じて再利用できるので、データセンターの利用効率を最適化するのに役立ちます。これにより、利用しやすい価格設定が可能になりました。

概要はこちら

ドキュメントはこちら

リリースに関するブログ記事はこちら

料金値下げに関するブログ記事はこちら




Cloud SQL のストレージ自動拡張

Cloud SQL のストレージ自動拡張機能を有効にすると、利用できるデータベース ストレージが 30 秒ごとにチェックされ、必要に応じてストレージが 5 GB ~ 25 GB ずつ追加されます(追加量はデータベースのサイズによって異なります)。

将来の拡張を見越してストレージをあらかじめ用意するのではなく、データベースの拡大に合わせてストレージを追加していくわけです。これにより、データベースのメンテナンスに必要な時間を減らし、ストレージのコストを節約できます。
ドキュメントはこちら





ダウンタイムなしでの永続ディスクのオンライン リサイジング

Google Compute Engine の永続ディスクの容量が一杯になった場合でも、ダウンタイムを発生させることなく、稼働したまま永続ディスクのサイズを変更できます。

リリースに関するブログ記事はこちら

ドキュメントはこちら

永続ディスク追加の YouTube 動画はこちら

以上のように、GCP の機能を使ってコスト削減やパフォーマンス改善を図る方法はたくさんあります。他の方法をご存じでしたら、ぜひコメントでお知らせください。



* この投稿は米国時間 9 月 15 日、Google Cloud Platform の Head of Developer Advocacy である Greg Wilson によって投稿されたもの(投稿はこちら)の抄訳です。
- Posted by Greg Wilson, Head of Developer Advocacy, Google Cloud Platform

Share on Twitter Share on Facebook

アナログ情報をデジタル データに変換できるセンサーやアクチュエータは日夜増え続けていますが、データセンターを越えた先にあるそのような機器に IT インフラを接続する機会を提供するのが、IoT(Internet of Things : モノのインターネット)です。そして、そうした価値ある情報のあるべき場所は Google Cloud Platform(GCP)であると、私たち Google は信じています。

Google Cloud Pub/Sub で受け取ったイベントを処理するにせよ、Google Cloud Dataflow で複数デバイスのデータ ストリームを処理するにせよ、Google Cloud Bigtable に時系列データを保存するにせよ、Google BigQuery で IoT や IoT 以外のデータに問い合わせを行うにせよ、GCP のデータおよび分析製品は、IoT データを管理して意味あるものに変えるために役立ちます。

ソフトウェアの場合と同様に、IoT プロジェクトを素早くプロトタイピングして検証することは有益です。とはいえ、あらゆる会社が電気技術者や組み込みソフトウェア開発者のチームを有しているわけではありません。だからこそ、私たちは Seeed Studio および Beagleboard.org と協力して、GCP 向けの BeagleBone Green Wireless IoT Developer プロトタイピング キットをお届けできるようにしたのです。

BeagleBone IoT プロトタイピング キットには以下のような機能があります。

BeagleBone Green Wireless IoT Developer プロトタイピング キットがあれば、身の回りの世界のデータを瞬時に GCP に直接取り込めます。そこからは、お馴染みの Debian Linux OS 上で、お好きなクライアント ライブラリを利用できます。

このキットやデモについてより深く知りたい方は、こちらをクリックしてください。まだキットをお持ちでない方は、こちらでお求めになるか、もしくは電話を使ったシミュレーションをお試しください。そして、その結果をぜひ私たちに教えてください。

* この投稿は米国時間 9 月 13 日、Head of IoT Solutions である Preston Holmes によって投稿されたもの(投稿はこちら)の抄訳です。

- Posted by Preston Holmes, Head of IoT Solutions
Share on Twitter Share on Facebook



This blog post includes forward-looking statements within the meaning of Section 27A of the Securities Act of 1933 and Section 21E of the Securities Exchange Act of 1934. These forward-looking statements generally can be identified by phrases such as Google or management “believes,” “expects,” “anticipates,” “foresees,” “forecasts,” “estimates” or other words or phrases of similar import. Similarly, statements herein that describe the proposed transaction, including its financial impact, and other statements of management’s beliefs, intentions or goals also are forward-looking statements. It is uncertain whether any of the events anticipated by the forward-looking statements will transpire or occur, or if any of them do, what impact they will have on the results of operations and financial condition of the combined companies or the price of Alphabet or Apigee stock. These forward-looking statements involve certain risks and uncertainties that could cause actual results to differ materially from those indicated in such forward-looking statements, including but not limited to the ability of the parties to consummate the proposed transaction and the satisfaction of the conditions precedent to consummation of the proposed transaction, including the ability to secure regulatory approvals at all or in a timely manner; the ability of Google to successfully integrate Apigee’s operations, product lines and technology; the ability of Google to implement its plans, forecasts and other expectations with respect to Apigee’s business after the completion of the transaction and realize additional opportunities for growth and innovation; and the other risks and important factors contained and identified in Alphabet’s filings with the Securities and Exchange Commission (the "SEC"), any of which could cause actual results to differ materially from the forward-looking statements. The forward-looking statements included in this blog post are made only as of the date hereof. Google and Alphabet undertake no obligation to update the forward-looking statements to reflect subsequent events or circumstances.


Share on Twitter Share on Facebook

Share on Twitter Share on Facebook



■ 写真左から
株式会社プレイド

■ 利用中の Google Cloud Platformサービス
Google BigQueryGoogle Bigtable など






『Web 上では店頭のようにお客様の動向を確認した上でのリアルタイムな接客は不可能』。それは改めて確認するまでもない“常識”でした。その常識を覆すサービスとして、今、EC サイト運営者などを中心に話題となっているのが、株式会社プレイド独自のウェブ接客プラットフォーム「KARTE」です。このサービスはサイト来訪者の行動データを解析・蓄積し、それをリアルタイムにサイト運営者に届けることで、ウェブ サイト越しの接客を可能にするというもの。EC サイトでのリピート促進から、旅行サイトでの予約率アップ、不動産サイトでの問い合わせ件数アップなど、既に多くのウェブ サイトの背後で、KARTE が稼働しています。


img_user_01.png
(KARTE のインターフェイス)


「昨年 3 月のリリース以降、EC サイトを中心に、人材派遣、不動産、金融、メディアなど、幅広い業種で採用が進んでいます。サービス開始から一周年、今年 2 月末の時点で 845 社に導入していただき、その後も順調に導入社数は増えています。解析したユニークユーザー数は 4 億にも達しました」と胸を張るのは、株式会社プレイドの Chief Engineer、後藤圭史さん。その開発は 2013 年夏頃からスタートし、その当時は Google Cloud Platform がまだ国内で大きなプレゼンスを持っていなかったことから、他のクラウドプラットフォーム上で構築することを選択されたということです。


ところがサービスが拡大していくにつれ、その維持コストが馬鹿にならない金額へと膨れあがっていきます。特にデータベース システムの利用料金が想定を越えて膨らみ始めたのです。

「何より困ったのが、コストの問題以上に、思ったようなパフォーマンスが出ないということ。設定値の半分もでないことはざらで、シーンによっては 100 分の 1 にも及ばないということすらありました。リアルタイムを売りにした解析サービスを提供しているのに、これでは話になりません。早急に対策を考える必要がありました」(株式会社プレイド Technology Officer 牧野祐己さん)


そんな中、いくつかの選択肢の中で、想定を越える結果を得られたのが Google BigQuery だったそうです。

「BigQuery が良さそうだと言うことが分かり、まず手始めに、契約企業様に毎月末に提出する毎月の利用状況(金額)集計に使ってみました。そしてこれが大成功。想像以上のパフォーマンスがでて、これだ! と思いましたね。現在ではこれをお客様の側で利用する管理画面にも適用。お客様がリアルタイムに配信状況を確認できるようになりました。ほか、多くの処理を BigQuery に置き換え始めています」(株式会社プレイド Co-Founder and CTO 柴山直樹さん)

それまではサービスのレスポンス速度を優先するため、集計のリアルタイム性を妥協していた面もあったそうですが、BigQuery を使うようになってからはそのどちらも両立できるように。また、もちろん費用についても劇的に改善したそうです。

「とは言え、効率的に回していくための工夫は必要。使わないデータは入れない、カラムをしっかり切る、アプリケーション側で使うスキーマを自動的に書き込むモジュールを作るなど、必要な時期の、必要なデータだけを参照できるようにしています」(牧野さん)

また、BigQuery に加え、Google Bigtable も、KARTE のサービス品質向上に貢献。KARTE では、サイトを訪れているユーザーの行動データ(来訪回数や購入金額など)を個別に集計・リアルタイムに表示する機能があるのですが、そこではBigtable が使われています。


「新しくイベントが発生した際、データベースをコンマ数秒で書き換える必要があるのですが、こうしたそれなりに大きな統計情報を高速に出し入れできるのがBigtable のいいところ。BigQuery でも同じような事ができるのですが、ここはレイテンシの少ない Bigtable を利用しています」(牧野さん)

なお、気になる移行の手間についても、大きなトラブルはほとんどなかったそうです。

「この手の移行作業では、やってみたら思ったようにパフォーマンスがでなくて、トライ&エラーを繰り返して正解を見つけていくというのが普通なのですが、Google Cloud Platform への移行に関しては、やってみたら思った以上にパフォーマンスが出て驚くということの繰り返し(笑)。最初の置き換え作業は 1 週間程度で無事完了しています」(柴山さん)


「開発者としてうれしかったのがドキュメントが完璧だったこと。実際にどのような仕組みで動いているのかや、パフォーマンスを上げるためのアドバイスまで記載されていて、非常に助かりました。それまで使っていたクラウド プラットフォームはブラックボックス感がとても強かったのですが、Google Cloud Platform はとてもオープン。信頼できると思いました」(牧野さん)

「とは言えまだ、移行の第一ステップが終わったばかり。本格的な移行はこれからです。現在はもともと使っていたクラウド プラットフォームと Google Cloud Platform の間の通信コストが馬鹿にならない金額になってしまっているので、早急にこれらを Google に移行していく予定です。移行が完了した部分でパフォーマンス、コスト面が大幅改善することが分かっているので、他のところでもそれが起きることを期待しています」(後藤さん)

Share on Twitter Share on Facebook



注 : 今回の執筆者は Streak.com の共同創業者 Aleem Mawani 氏です。Streak.com は Google Cloud Platform のお客様で、Google Apps に対応した Streak の CRM ソリューションは全面的に Google プロダクト(Gmail、Google App Engine、Google Cloud Datastore)上に構築されています。この記事では、Cloud Datastore のオブジェクト ストレージ システムに Streak がどのように高度な機能を追加したかを知ることができます。
Streak は、Gmail に直接組み込まれるフル機能の CRM ソリューションです。Google Cloud Platform 上に(Google App Engine を最も活用して)構築されており、Google Cloud Datastore にテラバイト(TB)規模のユーザー データを保存しています。

Cloud Datastore は私たちのプライマリ データベースです。そのスケーラビリティや一貫したパフォーマンス、フルマネージド管理にとても満足しています。

しかし、私たちはいくつかの分野で機能が物足りなくなりました。ユーザーがデータを更新するたびに、データベース エンティティを新しいコンテンツで上書きするのではなく、これらのバージョンをすべて保存し、それらに簡単にアクセスできるようにしたかったのです。つまり、すべてのデータをイミュータブル(不変)にする方法が欲しいと考えたわけです。

この投稿では、どのような場合にイミュータブル エンティティを使いたくなるのか、私たちがどのようなアプローチでそれらを Cloud Datastore 上に実装したのかを説明します。
私たちがイミュータブル エンティティを重要と考えた理由は次のとおりです。

  1. 私たちはニュースフィード スタイルの UI を簡単に実装できる方法を求めていました。一般的なニュースフィードは、エンティティが時間の経過とともにどのように変化したかを、グラフィカルなフォーマットでユーザーに表示します。従来、私たちは 1 つのエンティティの異なるバージョン間の差分を記録するために、独立したサイド エンティティを保存していました。こうしたサイド エンティティをクエリして、ニュースフィードをレンダリングしていたのです。しかし、このようなサイド エンティティは設計上、エラーが起こりやすく、メンテナンスが面倒でした。たとえば、エンティティに新しいプロパティを追加したときは、サイド エンティティにも忘れずに追加する必要がありました。特定のデータをサイド エンティティに追加し忘れると、後で必要になったときにそのデータを再構築する方法はなく、そのデータは永久に失われました。

    エンティティ “Contact” は、ユーザーの連絡先に関するデータを保存します。イミュータブル エンティティとして実装されているので、連絡先が時間とともにどのように変わってきたかを示す履歴を簡単に生成できます。

  2. イミュータブル エンティティを持つことで、ユーザー エラーからのリカバリが非常に簡単になります。ユーザーはデータを前のバージョンにロールバックでき、うっかり削除してしまったようなデータをリカバリすることもできます(私たちが削除操作をどのように実装したかについては後述します)1
  3. デバッグが容易になる可能性が高まります。エンティティが時間とともにどのように変化し、現在の状態になったのかがわかると、便利な場合がよくあります。エンティティに対する多数の変更の履歴に対してクエリを実行することもでき、これはユーザー行動分析やパフォーマンス最適化に役立ちます。



コンテキスト


Cloud Datastore でのイミュータブル エンティティの実装について見る前に、このデータストアの動作の基本的な仕組みをある程度理解しておく必要があります。なお、Cloud Datastore に精通している方は、このセクションを飛ばしていただいてかまいません。

Cloud Datastore はキー バリュー ストアと考えることができます。バリュー(データストア内のエンティティ)はキーで特定され、エンティティ自体は 1 つまたは複数のプロパティを持ちます。テーブル内のすべてのエンティティにスキーマが強制されることはありません。このため、2 つのエンティティのプロパティが同じである必要はありません。

このデータベースは 1 つのテーブルに対する基本的なクエリもサポートします。ジョインやアグリゲーションは行われず、単純なテーブル スキャンだけが行われ、そのためのインデックスが作成できます。これは制限のように思われるかもしれませんが、この特徴のおかげで、高速で一貫したクエリ パフォーマンスが得られます。通常、データの非正規化が行われるからです。

今回のイミュータブル エンティティの実装では、Cloud Datastore の最も重要な特徴は “エンティティ グループ” にあります。エンティティ グループはエンティティのグループであり、このグループでは以下の 2 つのことが保証されます。

  1. 1 つのエンティティ グループのみに対するクエリからは整合性のある結果が得られます。これは、書き込みの直後にクエリを行った場合、その結果は、その書き込みによる変更を反映することが保証されているということです。逆に、クエリの対象が 1 つのエンティティ グループに限定されていなければ、整合性のある結果は得られないかもしれません(データの陳腐化のため)。
  2. マルチエンティティ トランザクションは、1 つのエンティティ グループ内にのみ適用できます(この機能は最近、改良されました。Cloud Datastore は現在、エンティティ グループ間のトランザクションをサポートしています。ただし、トランザクションに含まれるエンティティ グループの数は 25 までに制限されています)。


この 2 つのことは、いずれも私たちの実装にとって重要です。Cloud Datastore 自体の詳細についてはドキュメントをご覧ください。


どのようにイミュータブル エンティティを実装したか


私たちは、1 つのエンティティに対して行った変更をすべて保存するとともに、エンティティの一般的な操作(取得、削除、更新、作成、クエリ)をサポートする方法を必要としていました。私たちが選択した全体的な戦略は、2 つのレベルの抽象化により、“データストア エンティティ” と “論理エンティティ” を使用することでした。個々の “データストア エンティティ” で “論理エンティティ” の個々のバージョンを表すようにしたのです。

私たちの API のユーザーは論理エンティティだけを操作し、それぞれの論理エンティティはデータストア エンティティを特定するキーを持ち、一般的な取得、作成、更新、削除、クエリの各操作をサポートします。これらの論理エンティティは、その論理エンティティのさまざまなバージョンを構成する実際のデータストア エンティティにバッキングされるわけです。最新の、あるいは最も Tip(先頭)のバージョンのデータストア エンティティが、論理エンティティの現在の値を表します。

まず、データ モデルがどのようなものかを見てみましょう。私たちは以下のようにエンティティを設計しました。

ユーザーがエンティティに変更を加えようとするたびに、必ず新しいデータストア エンティティが保存される仕組みになっています。最新のデータストア エンティティは isTip の値が true に設定され、他のデータストア エンティティは false に設定されます。

後でこのフィールドを使ってクエリを実行し、最新のデータストア エンティティを特定することで、特定の論理エンティティを取得します。このクエリはデータストアで高速に実行されます。すべてのクエリがインデックスを持つ必要があるからです。また私たちは、各データストア エンティティが作成された日時のタイムスタンプも保存します。

versionId フィールドは、各データストア エンティティのグローバル一意識別子(GUID)です。この ID は、エンティティを保存するときに Cloud Datastore によって自動的に割り当てられます。


consistentId は論理エンティティを特定します。これは、私たちがこの API のユーザーに提供できる ID です。1 つの論理エンティティ内のデータストア エンティティは、すべて同じコンシステント ID を持ちます。

私たちは、論理エンティティのコンシステント ID を、チェーンの最初のデータストア エンティティの ID と同じにしました。コンシステント ID はある程度任意に決めることができ、どのような一意識別子を選んでもかまいません。しかし、低レベルの Cloud Datastore API がどのデータストア エンティティにもユニークな ID を割り当てるので、私たちはコンシステント ID として、最初のデータストア エンティティの ID を使うことにしたのです。

このデータモデルには、興味深い点がもう 1 つあります。それは firstEntityInChain フィールドです。

上の図には示されていませんが、すべてのデータストア エンティティは親を持ちます(親を基準にエンティティ グループが決まります)。チェーン内の最初のデータストア エンティティが親として設定されます。

重要なのは、チェーン内のすべてのデータストア エンティティ(最初のものを含む)が同じ親を持ち、それゆえ同じエンティティ グループに属することです。そのおかげで、これらに対して整合性を持つクエリを実行できます。以上のものが必要な理由については後述します。

コードで定義された同じイミュータブル エンティティを以下に示します。私たちは素晴らしい Objectify ライブラリと Cloud Datastore を使っており、以下ではこれらを活用したコード例を随時紹介します。


public class ImmutableDatastoreEntity {
@Id
Long versionId;
@Parent
Key<T> firstEntityInChain;
protected Long consistentId;
protected boolean isTip;
Key<User> savedByUser;
}

それでは、論理エンティティに対する一般的な操作をどのように行うのかを見ていきましょう。論理エンティティがデータストア エンティティでバッキングされることを念頭に置いてください。

作成を実行

論理エンティティを作成するときは、1 つの新しいデータストア エンティティを作成し、Cloud Datastore の ID 割り当てを利用して versionId フィールドを設定し、consistentId フィールドに同じ値を設定するだけです。

また、親キー(firstEntityInChain)として自身を指定します。後でこのエンティティをクエリできるように、isTip を true に設定する必要もあります。さらに、タイムスタンプとデータストア エンティティの作成者を設定し、このエンティティを Cloud Datastore に永続的に保存します。

ImmutableDatastoreEntity entity = new ImmutableDatastoreEntity();
entity.setVersionId(DAO.allocateId(this.getClass()));
entity.setConsistentId(entity.getVersionId());
entity.setFirstEntityInChain((Key<T>) Key.create(entity.getClass(), entity.versionId));
entity.setTip(true);

更新を実行

論理エンティティを新しいデータで更新するには、まずチェーン内の最新のデータストア エンティティをフェッチする必要があります(手順については、下の “取得” のセクションで説明します)。

次に、新しいデータストア エンティティを作成し、consistentId と firstEntityInChain を、フェッチしたデータストア エンティティのものに設定します。新しいデータストア エンティティの isTip を true に設定し、フェッチしたデータストア エンティティのこのフィールドを false に設定します(既存エンティティの中で、このインスタンスだけを変更することに注意してください。つまり、100 % イミュータブルなわけではないということです)。
最後に、タイムスタンプとユーザー キーのフィールドを埋めます。これで、新しいデータストア エンティティを保存する準備が整いました。

ここで重要なポイントが 2 つあります。1 つは、新しいデータストア エンティティについては、保存時に Cloud Datastore が ID を自動的に割り当てるようにすればよいということです(ID を他の用途で使う必要はないからです)。

そしてもう 1 つのポイントは極めて重要です。それは、既存データストア エンティティのフェッチと、新旧のデータストア エンティティの保存は、同一のトランザクションで実行するということです。そうしないと、データの内部整合性がなくなるおそれがあります。

// start transaction
ImmutableDatastoreEntity oldVersion = getImmutableEntity(immutableId)
oldVersion.setTip(false);
ImmutableDatastoreEntity newVersion = oldVersion.clone();
// make the user edits needed
newVersion.setVersionId(null);
newVersion.setConsistentId(this.getConsistentId());
newVersion.setFirstEntityInChain(oldVersion.getFirstEntityInChain());
// .clone also performs the last two lines but just to be explicit this, just fyi
newVersion.setTip(true);
ofy().save(oldVersion, newVersion).now();
// end transaction

取得を実行

取得を実行するには、Cloud Datastore に対してクエリ操作を行わなければなりません。特定の consistentId  を持ち、かつ isTip が true に設定されているデータストア エンティティを検索する必要があるからです。

このエンティティが論理エンティティを表します。クエリを整合性のあるものにしたいので、“祖先クエリ” を実行する必要があります(つまり、特定のエンティティ グループに対してのみクエリを実行するように Cloud Datastore に指示する必要があります)。このクエリが動作するのは、特定の論理エンティティのすべてのデータストア エンティティが、同じエンティティ グループに属するようにした場合に限られます。

このクエリが返す結果は 1 つだけ、つまり論理エンティティを表すデータストア エンティティだけでなければなりません。

Key ancestorKey = KeyFactory.createKey(ImmutableDatastoreEntity.class, consistentId);
ImmutableDatastoreEntity e = ofy().load()
.kind(ImmutableDatastoreEntity.class)
.filter("consistentId", consistentId)
.filter("isTip", true)
.ancestor(ancestorKey) // this limits our query to just the 1 entity group
.list()
.first();

削除を実行

論理エンティティを削除するには、最新のデータストア エンティティの isTip を false に設定するだけです。こうすることで、上に述べた “取得” の操作を行っても、結果が返されなくなります。その一方で、以下に述べるようなクエリは引き続き動作します。

// wrap block in transaction
ImmutableDatastoreEntity oldVersion = getImmutableEntity(immutableId);
oldVersion.setTip(false);
ofy().save(oldVersion, newVersion).now();

クエリを実行

すべての論理エンティティに対してクエリを実行できる必要があります。ただし、どのデータストア エンティティをクエリするときも、各論理エンティティの最新のデータストア エンティティだけをクエリの対象とするように、クエリを設定する必要があります(データの古いバージョンを明示的に検索したいのでなければ)。そのためには、クエリの対象を最新のエンティティに限定する特別なフィルタをクエリに追加することが必要です。

ここで重要な注意点があります。この場合、整合性を持つクエリを実行することはできないということです。すべてのクエリ結果が同じエンティティ グループに属することを保証できないからです(実は、結果が複数の場合は、それらが同じエンティティ グループに属さないことは自明です)。


List<ImmutableDatastoreEntity> results = ofy().load()
.kind(ImmutableDatastoreEntity.class)
.filter("isTip", true)
.filter(/** apply other filters here */)
.list();


ニュースフィード クエリを実行


私たちの目標の 1 つは、論理エンティティが時間とともにどのように変わってきたかを示すことでした。そのためには、チェーン内のすべてのデータストア エンティティをクエリできなければなりません。

これはかなりシンプルなクエリです。consistentId でクエリし、結果をタイムスタンプで並べるだけです。そうすれば、論理エンティティのすべてのバージョンが得られます。各データストア エンティティについて、前のデータストア エンティティとの差分を取れば、ニュースフィードに必要なデータを生成できます。


Key ancestorKey = KeyFactory.createKey(ImmutableDatastoreEntity.class, consistentId);
List<ImmutableDatastoreEntity> versions = ofy().load()
.kind(ImmutableDatastoreEntity.class)
.filter("consistentId", consistentId)
.ancestor(ancestorKey)
.list();

課題

以上の設計により、私たちは、デバッグしやすく、ニュースフィード風の機能を開発しやすい、ほぼイミュータブルなエンティティを実装するという目標を達成できました。しかし、この方法にはいくつか課題もあります。

  1. エンティティを取得するには必ずクエリを実行する必要がある : 特定の論理エンティティを取得するには、前述したようにクエリを実行しなければなりません。Cloud Datastore では、これはキーによる従来の “取得” よりも時間のかかる操作です。さらに、Objectify はビルトイン キャッシング機能を提供しますが、イミュータブル エンティティの 1 つを取得しようとするときは、この機能は使えません(Objectify はクエリをキャッシュできないからです)。この課題の対策としては、パフォーマンス上の問題が発生したら独自のキャッシングを memcache で実装することです。
  2. エンティティの取得をバッチで実行する方法がない : 各クエリは、整合性を確保するために 1 つのエンティティ グループを対象にしなければならないので、複数の論理エンティティの最新のデータストア エンティティを、1 回のデータストア操作でフェッチすることはできません。この問題に対処するため、私たちは複数の非同期クエリを実行し、それらがすべて完了するのを待ちます。この方法は理想的でもクリーンでもありませんが、実用上はかなりうまくいきます。ただし、App Engine で RPC を同時に呼び出す場合、RPC の発行数は 30 までに制限されていることに留意する必要があります。そのため、この対処方法は暫定的なものと言わざるをえません。
  3. エンティティを実装する初期コストが高い : 私たちは、上で説明した設計の大部分を抽象化し、イミュータブル エンティティを今後は低コストで実装できるようにしました。しかし、エンティティを最初に実装するのは容易なことではありませんでした。さまざまな問題をすべて解決するにはかなりの時間を要しました。こうした手間のかかる実装を行う価値があるのは、イミュータビリティを切実に必要としている場合か、もしくは実装をさまざまなユースケースに活用し、その多くの受益者に実装コストを “広く薄く” 負担してもらう場合に限られます。
  4. エンティティが実際には削除されない : 設計上、私たちはイミュータブル エンティティを削除しません。しかし、ユーザーの側では、私たちのアプリで何かを削除したら、私たちがそのデータを実際に削除することを期待するかもしれません。一部の規制対象業種(ヘルスケアなど)でも、そうしたことが求められる可能性があります。私たちのユースケースではそうした配慮は不要でしたが、お客様によっては、データセットを監視し、論理エンティティが削除されたのを見つけたら、バッチ タスクで定期的に、それらを表すデータストア エンティティをすべて削除するシステムを開発したほうがよいかもしれません。


次のステップ

私たちは、イミュータブル エンティティを本番環境で短期間しか運用していません。そのため、これから未知の問題に直面することもあるでしょう。また、イミュータブル エンティティとして実装するデータセットがさらにいくつか増えれば、実装のコストや労力に見合った効果が出ているかどうかを明確に判断できるようになるはずです。

最新情報をお知りになりたい方は、ぜひ私たちのブログをご覧ください。

今回紹介したようなデータ インフラストラクチャに興味を持たれた方は、ぜひご連絡ください。なお、私たちはバックエンド チームのメンバーも募集しています。私たちの人材募集ページで詳しい情報をご覧ください。

ディスカッションは Hacker News でどうぞ。

1 これは MVCC(https://en.wikipedia.org/wiki/MultiVersion_Concurrency_Control)の考え方と非常に似ています。MVCC は、多くの現代的なデータベースでトランザクションやロールバックの実装に使用されています。


- Posted by Aleem Mawani, Co-Founder, Streak.com


List<ImmutableDatastoreEntity> results = ofy().load()
.kind(ImmutableDatastoreEntity.class)
.filter("isTip", true)
.filter(/** apply other filters here */)
.list();


ニュースフィード クエリを実行


私たちの目標の 1 つは、論理エンティティが時間とともにどのように変わってきたかを示すことでした。そのためには、チェーン内のすべてのデータストア エンティティをクエリできなければなりません。

これはかなりシンプルなクエリです。consistentId でクエリし、結果をタイムスタンプで並べるだけです。そうすれば、論理エンティティのすべてのバージョンが得られます。各データストア エンティティについて、前のデータストア エンティティとの差分を取れば、ニュースフィードに必要なデータを生成できます。


Key ancestorKey = KeyFactory.createKey(ImmutableDatastoreEntity.class, consistentId);
List<ImmutableDatastoreEntity> versions = ofy().load()
.kind(ImmutableDatastoreEntity.class)
.filter("consistentId", consistentId)
.ancestor(ancestorKey)
.list();

課題

以上の設計により、私たちは、デバッグしやすく、ニュースフィード風の機能を開発しやすい、ほぼイミュータブルなエンティティを実装するという目標を達成できました。しかし、この方法にはいくつか課題もあります。

  1. エンティティを取得するには必ずクエリを実行する必要がある : 特定の論理エンティティを取得するには、前述したようにクエリを実行しなければなりません。Cloud Datastore では、これはキーによる従来の “取得” よりも時間のかかる操作です。さらに、Objectify はビルトイン キャッシング機能を提供しますが、イミュータブル エンティティの 1 つを取得しようとするときは、この機能は使えません(Objectify はクエリをキャッシュできないからです)。この課題の対策としては、パフォーマンス上の問題が発生したら独自のキャッシングを memcache で実装することです。
  2. エンティティの取得をバッチで実行する方法がない : 各クエリは、整合性を確保するために 1 つのエンティティ グループを対象にしなければならないので、複数の論理エンティティの最新のデータストア エンティティを、1 回のデータストア操作でフェッチすることはできません。この問題に対処するため、私たちは複数の非同期クエリを実行し、それらがすべて完了するのを待ちます。この方法は理想的でもクリーンでもありませんが、実用上はかなりうまくいきます。ただし、App Engine で RPC を同時に呼び出す場合、RPC の発行数は 30 までに制限されていることに留意する必要があります。そのため、この対処方法は暫定的なものと言わざるをえません。
  3. エンティティを実装する初期コストが高い : 私たちは、上で説明した設計の大部分を抽象化し、イミュータブル エンティティを今後は低コストで実装できるようにしました。しかし、エンティティを最初に実装するのは容易なことではありませんでした。さまざまな問題をすべて解決するにはかなりの時間を要しました。こうした手間のかかる実装を行う価値があるのは、イミュータビリティを切実に必要としている場合か、もしくは実装をさまざまなユースケースに活用し、その多くの受益者に実装コストを “広く薄く” 負担してもらう場合に限られます。
  4. エンティティが実際には削除されない : 設計上、私たちはイミュータブル エンティティを削除しません。しかし、ユーザーの側では、私たちのアプリで何かを削除したら、私たちがそのデータを実際に削除することを期待するかもしれません。一部の規制対象業種(ヘルスケアなど)でも、そうしたことが求められる可能性があります。私たちのユースケースではそうした配慮は不要でしたが、お客様によっては、データセットを監視し、論理エンティティが削除されたのを見つけたら、バッチ タスクで定期的に、それらを表すデータストア エンティティをすべて削除するシステムを開発したほうがよいかもしれません。


次のステップ

私たちは、イミュータブル エンティティを本番環境で短期間しか運用していません。そのため、これから未知の問題に直面することもあるでしょう。また、イミュータブル エンティティとして実装するデータセットがさらにいくつか増えれば、実装のコストや労力に見合った効果が出ているかどうかを明確に判断できるようになるはずです。

最新情報をお知りになりたい方は、ぜひ私たちのブログをご覧ください。

今回紹介したようなデータ インフラストラクチャに興味を持たれた方は、ぜひご連絡ください。なお、私たちはバックエンド チームのメンバーも募集しています。私たちの人材募集ページで詳しい情報をご覧ください。

ディスカッションは Hacker News でどうぞ。

1 これは MVCC(https://en.wikipedia.org/wiki/MultiVersion_Concurrency_Control)の考え方と非常に似ています。MVCC は、多くの現代的なデータベースでトランザクションやロールバックの実装に使用されています。


- Posted by Aleem Mawani, Co-Founder, Streak.com
Share on Twitter Share on Facebook