工場長のブログ

日々思ったことを書いてます。

ソリューションアーキテクトという仕事について

ex-mixi Advent Calander 2017の12/12分のポストです。みんなエモいことを書いているのでわたしもエモいことを書くことにします。

 

ちなみに今日はわたしの結婚記念日で、嫁とはmixiで出会いました(物理)。

 

で、テーマはソリューションアーキテクト(以下、SAと略します)という仕事について。もっとみんなにSAって何なのかというのを知ってもらいたいなと思ってます。SAってめっちゃ面白いよ!ってのを叫びたいのです。なお、本ポストではわたしがAWSでSAをやっていたときの話をしますが、あくまで経験や「わたしはこうやっていた」という話であって、AWSを代表する見解ではないことをご理解ください。

 

mixiには2010/2から2012/7までの約2.5年在籍していて、ずっと広告関連のアプリケーション開発をやっていました。自分のなかではものすごく体感時間長かったんですが、振り返ってみるととても短いですね。で、わたしはその後AWS、Hortonworks、SORACOMと会社は変わりながらですが、ずっとSAをやってます。

 

一緒に仕事したことあるひとから見ると、恐らくセールスエンジニアとか、場合によってはエバンジェリストのような仕事に見えてると思っていて、それはそれで合っています。が、実はそれだけではないので、そのあたりをみなさんにぜひ知ってもらいたいな、と。とてもおもしろい仕事なので、エンジニアのキャリアパスのひとつとして広まったら嬉しいなと思っています。

 

何をやる仕事なの?

 

AWSは馴染みが深い人が多いと思うので、そのときの話を例に話をすすめていきます。AWSのSAが何をする人かというと、お客さんのビジネスを成功させるため/困り事を解決するために、AWSを「うまく」つかってもらう、そのためにあらゆる技術サポートを提供するというのがお仕事です。

 

AWSを使うのがはじめてのひとが相手であれば「AWSで構築する○○(例えばWeb)アプリケーションのよくある構成」みたいなのを説明します。やりたいことはあるんだけどアプリケーションの設計がぼんやりしているお客さんに対しては、ホワイトボードを使ってアーキテクティングをしたりします。設計まで固まってきているお客さんであれば、その設計をもとにレビューをしたりベターなアーキテクチャを目指したディスカッションをしたりします。

 

MySQLの性能が出なくて困っているのであれば、問題がどこにあるのかを突き止めるためのサポートをしつつ、見えてきた問題に対してAWS的にそれをうまく解決するための方法を提案します。もちろん、アプリケーションやクエリの問題だったということがわかるということもよくあります。

 

ここらへんがSAの面白いところなんですが「あー、それはアプリケーションの話なんでそちらで解決してくださいね」みたいな話にはしないんです。アプリケーションの作りやクエリの中身、クエリの投げ方みたいなところまで突っ込んで議論をして、どうすれば問題が解決するのかというのがわかるまでしっかりDeep Diveします。問題の根本原因を見つけて、お客さんと共通の認識を持ち、それに対するアクションを作っていきます。もちろん、いきなり根本解決できればベストなんですが、動いているアプリケーションをいきなりドラスティックに変えることができないということもよくある話です。まずは暫定的にインスタンスサイズのアップだったりリードレプリカの追加、ストレージのIOをより速いものにしたりという対処をしつつ、アプリケーションの改修のディスカッションなんかをしたりします。

 

他にも、必要な性能や機能を満たせるかどうかの検証のためにアプリケーションを書いたり、関連するオープンソースソフトウェアのソースコードや、プロトコルRFCをがっつり読んだりなんてこともします。場合によっては、お客さんの利用料や利用傾向を見て「それ、アプリケーションをこういうふうに直したらもっと安いインスタンスタイプでも全然まわりますよ」なんて提案することもあります。

 

Do the right things的といいますか、お客さんのアプリケーションがより安定的に運用できるようになることであれば、正しいと信じられること/共感を得られることであればJust do itな感じであります。

 

なんでこんなことをするんでしょうか?それは「サステイナブルにプラットフォーム(例えばAWS)を使ってもらう」ということがとても大事だからです。AWSのようなサービスは売り切り型ではなくストック型のビジネスなので、一瞬の売上の高さをあげることよりも、長く使ってもらうことにより、高さだけでなく長さを掛けた面積を最大化することが重要です。

 

ニワトリタマゴな話なんですが、こういうビジネスであるからこそ、SAは技術者として全力でお客さんのヘルプができるというところがあるのです。理論的には、助ければ助けるだけお客さんのアプリケーションやビジネスは安定して、結果としてより長く、スケーラブルに使ってもらえるようになるので。

 

(いちお、誤解のないように補足をすると、AWSは有償のコンサルティングサービスも提供していて、様々なお客さんが、それぞれ必要とする形に合わせた最適なサポートを提供できるようになっています。)

 

SAの仕事をするなかでよく、お客さんからのTechnical Credibility(技術的信頼度)を得るのがとても大事だよねという話が出てきます。みなさんも、あまりよくしらない人にデータベースの選択やプログラミング言語の選択について相談しませんよね?SAは、お客さんからこういった相談をしてもらえるように、(言葉選びが難しいですが)尊敬されるエンジニアであることが必要です。さらにこの信頼度パラメータが高くなってくると「新しい○○という感じの事業を考えてるんだけど、どんな感じに作ったらいいすかね?」なんて相談を受けて「いいっすね!ちょっとホワイトボード使ってディスカッションしますかー」なんていう隠しイベントが発生する確率が上がってきます。

 

この信頼度パラメータをあげるためには、常に最新の技術事情にキャッチアップをしているのはもちろん大事なんですが、それとともに得意な専門分野を持っていることがとても大事です。わたしの場合mixiで広告配信をやっていたので「ハイトラフィックウェブアプリケーション、アドテク、Hadoop」みたいなキーワードが経験の主戦場で、AWSではゲームやアドテク関連の事業をしているお客さんたちを担当していました。

 

こういうのをアメリカの会社っぽくいうとArea Of Depth(AOD)と呼んだりします。AODにおいてはお客さんに対してリアクティブにアドバイスをするだけじゃなくって「あー、これってきっとこの辺りで困ってますよね?ですよね?そこはこういうパターンの実装をするのがベストプラクティスなんですよー(ドヤ」みたいな感じやっていくことが期待されます。

 

このAODを獲得できたのはまさにmixiのときの経験のおかげで、とても感謝してます。2010〜2012当時のmixiはとてもウェブのトラフィックが多くて、そこに対して安定的に広告を配信するアプリケーションを書いていたというのがすごくいい経験になりました。特に在籍期間の後半では「このゲームはあなたのマイミクの○○さんもプレイしてるよ!」みたいな、いまは当たり前になったソーシャル広告の開発をやってました。これって、広告(1ページにいくつも表示される)ごとにソーシャルグラフを始めとする、mixiの様々な箇所からデータを取ってくる必要がありました。コード的な依存関係を最小化し、かつ負荷的にもできるだけ影響を切り離しつつ、いかに高頻度でデータを取得できるか、みたいなことに毎日頭を悩ませてました。あとは、配信した広告をどれだけ早くレポート出せるかみたいなことにも毎日頭を抱えてました。コンソールに流れるmap reduceの進捗状況を「成功してくれ〜。落ちないでくれ〜。これ落ちたらレポート間に合わないんだよ〜。営業に殺されるよ〜。」と祈りながらよく眺めてました。こんな経験があったからこそ、「あるある」なハマりどころやツボをしっかり自分のこととして語り、負荷の高いウェブアプリケーションにおけるアーキテクティングのアドバイスみたいなことができるようになったのかなと。

 

と、なんか昔語りになっちゃいましたが、こういった経験や知識をもとにお客さんとガチでアプリケーションアーキテクチャのディスカッションをするというのがSAのしごとです。ゲームやアドテクの業界のお客さんは普段から○○千QPS、○○万QPSをさばいているひとたちなので、ガチです。

 

最後になんでSAになったのか、ソフトウェアエンジニアからジョブチェンジしてどうだったのかという点にも触れておきたいなと。やっぱり、はじめてSAになる瞬間はとても悩みました。「コード書けなくなってもいいのか?」みたいなことをすごく悩んで、ウジウジ悩んで、嫁に怒られて泣いたりしてました。最終的にはあんまりロジカルな理由はなくて、転職に対してサポーティブだった嫁のPushと「Amazonで働ける」というミーハーな動機で転職しました。

 

で、コードを書かなくなったかというとぜんぜんそんなことはありません。ガチなエンジニアや、ガチなビジネスのプレイヤーを相手にするということは、提案しているプロダクトやサービスについてお客さんと同じ目線で証明を提供することが必要です。それが場合によっては性能を実証のためのコードであったり、アプリケーションのプロトタイプだったりします。

 

サービスやプロダクトを開発するソフトウェアエンジニアとの違いとしては、お客さんの必要なものを汲み取りながら少ない時間で検証コードを書いて動かして見せて理解をしてもらうというサイクルを回すことが多いので、スプリンターのようにコードを書くことが求められることが多いです。(まあこれは好き嫌いあると思いますが)

 

と、つらつらと書いてしまいましたが、これがSAのしごとです。一文にまとめるなら、お客さんのビジネスややりたいことをよしなに(いい意味でいってる)、クイックに汲み取りつつ、それを成功させるために必要な「あらゆる」技術的サポートをするよ、という感じでしょうか。

 

いまはSORACOMというIoTのための通信プラットフォームを提供している会社でSAをやっています。これまではクラウドとかビッグデータ関連の技術をメインに触っていましたが、IoTでは「物理」とか「無線」とか、わたしにとって未知の世界が多くて四苦八苦してますw

 

SAワークとしては、プロトタイピングする対象がソフトウェアだけじゃなくてデバイスなんかも入ってきて、総合格闘技感あって最高です。楽しくやってます。(35才過ぎて、初めて真面目にシリアルとかUARTとか勉強したw)

広告に関するなにか: RedshiftでAttribution分析の実装

職場の同僚のドッグさん(語尾は上げる)「パイセン、Redshiftとか使ってイイカンジにAttribution分析するならどんなかんじなんすかね〜」って言われたので考えた。

Attribution分析とは

「あるコンバージョンに対して貢献のあった広告の表示やクリックなどの、要因分析」という感じだと思っている。例えば下記のような導線をたどった場合を考えてみる。

banner impression(1)
banner impression(2)
banner click
paid_search impression
paid_search click

このときにconversionに対して貢献度を下記のように割り振るイメージ。割り振りは適当。適当なんだけど、この数値の精度をいかに上げていくのかというのが恐らく一番大事な話なんだと思う。

banner impression(1): 5%
banner impression(2): 10%
banner click: 20%
paid_search impression: 15%
paid_search click: 50%

こうすると、ひとつのコンバージョンに対して複数の広告やクリック以外のアクションの貢献度を数値化することができ、より精度の高い広告の予算配分が可能になりますよという考え方。

「より」というのはどういうことかというと、よくAttribution分析と比べられる手法として、より昔からあったLast Click分析というのがある。この手法で先ほどの導線を分析すると以下のようになる。

banner impression(1): 0%
banner impression(2): 0%
banner click: 0%
paid_search impression: 0%
paid_search click: 100%

コンバージョン前の最後のクリックに対しての貢献度を100%としておくということになるが、この分析手法だと「search adの効果がよかったので、banner adの出稿を減らしてsearch adに予算を集中させましょう」ということになる。実際にはbanner adもこのコンバージョンに対しての貢献をしているにもかかわらず。

ではなぜAttribution分析が新しいかという話だが、理由はいろいろあると思うのだけれど、システム屋てきな発想としては、impressionまで分析対象にすることのシステムコストが大きな原因のひとつであると思う。

たとえばクリックだけを分析対象にするのと比べて、インプレッションまで分析の対象にすると処理するデータの量(ログの行数)だけで1,000倍くらいにになる。(広告のクリックレートを0.1%で計算した場合)更にラストクリックと違い、ひとつのコンバージョンに対しての貢献があるイベントを時系列に並べて、更に貢献度の時間的減衰を計算して・・・みたいなことをやるととても計算コストが高くなる。ログの行数だけで1,000倍なので、総コストで見ると1,000倍を軽く超えるはず。

実装を考える

前置きが長くなってしまったけれど、これの実装を考えてみる。

スキーマ

ログのスキーマはこんな感じとする。ものすごく単純化してるので注意。もっとたくさんアトリビュートはあるはずだし、一般的にはアクションごとにログを分けちゃうはず。

少しでも計算を楽にするためにログにsession_idという概念を取り入れてみる。広告への初回接触時にsession_idを払い出す感じ。で、conversionしたら破棄、もしくは時間が経ったらexpire、みたいな感じ。

{
  action:    '{impression|click|conversion}' // ユーザーのアクションのタイプ
  campaign_id:     'string',       // 広告のキャンペーンを一意に識別するID
  ad_id:  'string'      // 広告を一意に識別するID
  ad_type:   '{banner|listing}',     // 広告の種類
  uid:   'string',     // ユーザーのID
  session_id: 'string' // ひとつのコンバージョンに至るまでの一連のセッションにふられたID
  timestamp: 'timestamp' // アクションのタイムスタンプ
}

さっきの導線をログにしてみるとこんなかんじ。

{"action":"impression", "campaign_id":"123", "ad_type":"banner","uid":"abc","timestamp":"2015-01-01T12:34:56Z"}
{"action":"impression", "campaign_id":"123", "ad_type":"banner","uid":"abc","timestamp":"2015-01-01T12:45:21Z"}
{"action":"click", "campaign_id":"123", "ad_type":"banner","uid":"abc","timestamp":"2015-01-01T12:45:36Z"}
{"action":"impression", "campaign_id":"123", "ad_type":"listing","uid":"abc","timestamp":"2015-01-01T13:01:01Z"}
{"action":"click", "campaign_id":"123", "ad_type":"listing","uid":"abc","timestamp":"2015-01-01T13:01:21Z"}
{"action":"conversion", "campaign_id":"123","uid":"abc","timestamp":"2015-01-01T13:10:12Z"}

出力

とりあえずこんな感じのテーブルにデータを出力してあげたらあとはいろいろ計算できるはず

CREATE TABLE attributions (
  `campaign_id` CHAR(20),
  `ad_id`       CHAR(20),
  `ad_type`     CHAR(20),
  `action`      CHAR(20),
  `score`       REAL,
  `timestamp`   TIMESTAMP
);

計算の大まかな流れを確認する

では、上記のような出力をつくるためにはどんな計算をしたらいいんだろうということでRubyっぽい擬似コードを書いてみる。なんかMapReduceっぽくなった。これそのまま実装すりゃいいじゃんw

actions = [...] #すべてのログへの参照を持つとする
actions
  .group_by{|action| action[:session_id]} #session_idでgrouping。Map処理。
  .each_value{|grouped_actions| #Shuffle & Sort
    grouped_actions.each{|action| #Reduce
      puts    1/actions.size
              * action_factor(action[:action])
              * type_factor(action[:ad_type])
              * recency_factor(actions[-1][:timestamp] - action[:timestamp])
    }
  }

def action_factor
  #クリックやインプレッションなど、ユーザーのアクションによる係数を計算する
end

def type_factor
  #bannerやListingなど、広告の種類による係数を計算する
end

def recency_factor
  #コンバージョンを起点として、アクションのRecencyによる係数を計算する
end

あくまでここで書いているのは計算の流れであってアルゴリズムではない。上記のサンプル内の*_factorの精度をどうやってあげていくのか、というのが非常に重要なポイントであり、アルゴリズムの話。

SQLで実装しなおす

で、計算の流れに戻ると・・・actions.size....?

!!!

これはアレだ。ひとつの計算をするために複数行のデータを参照しなきゃいけないアレだ。Window関数が必要になってくる感じ。あんまり効率のいいSQLにならなそう。

ひとまず書いてみるとこんな感じだろうか。現状、RedshiftにはUDFを取り扱う機能はないが、めんどくさいのでとりあえず擬似コード的にUDFを使って書く。

SELECT
  campaign_id,
  ad_id,
  ad_type,
  action,
  (1/ COUNT(*) OVER (PARTITION BY sessiond_id)) * action_factor(action) * type_factor(ad_type) * recency_factory(LAST_VALUE(timestamp) OVER (PARTITION BY sessiond_id) - timestamp) AS score,
  timestamp
FROM actions;

UDFほしい

・・・はい。UDFほしいですね。いまのところだと、それぞれの*_factor関数をSQLにベタ書きで展開してcase文とか使ったら書けると思う。

しかしそれではメンテナンス性が低い。アルゴリズムの調整をするたびにSQLを修正しなきゃいけないというのはちょっとアレな感じ。去年のre:InventでUDF対応するよって言ってたので、期待して待つのがよさげ。

アルゴリズム

もう長くなってきたので、というのと集中力が切れてきたのでアルゴリズムについてはまた今度考えてみることにする。いちおう、今回の記事を書くのにあたって、いろいろ記事やらなにやらを掘ってみたんだけど、Quoraのこのスレッドがわかりやすくまとまっていてよかった。

What is a conversion attribution model in online advertising?

主に議論の対象になっているのは - バナーなのかリスティングなのか - クリックなのかインプレッションなのか - 3rd Partyのデータもいかすべき

みたいな話なんだけど、とりわけいい話だなと思ったのは下記のコメント。

It's important to distinguish between data-driven and user-driven models. By this I mean that some attribution solutions simply consist of user-assigned weights for each type of touch point. If you think that Search is 2X as good as Display, you can set that weight, and the results you get will be tilted towards search. This type of "model" is easy to implement, but not very objective since it relies on the marketer's existing intuition. Data-driven models, on the other hand, rely on statistical algorithms and extract the value of each channel from the data.

たとえばクリックだったらインプレッションの2倍みたいなアナログな手法よりも、もっとデータドリブンでやるべきということを主張している。

具体的には先程の*_factorな関数たちの係数を決めるためのパラメータを実際のデータから計算しようという話になるんだと思う。ではそれを実現するためにはどうしたらいいのか。例えば以下のようなデータを集めることが想像できる。 - 係数を分散させた複数の広告を出稿して、実際に効果のよさそうな係数設定を探っていく - 流れている広告主の出稿データと結果から係数の精度を上げていく

このあたりはまた今度ふかく考えてみることにする。

まとめ

ありません。次回(いつになるかは・・・)に続く!

広告に関するなにか: Top 5 Trends in Digital Out of Home

IABのブログポスト、Top 5 Trends in Gigital Out of Homeを読んだ。DOOHというのは初めて聞いた言葉だったのでちょっと記事を拾ってみた。

「IABが考える、2015に掴んでおきたい5つのトレンド」的な記事。

DOOHとは

Digital Out of Home (or “DOOH” as the channel is commonly referred) encompasses a variety of screen shapes, sizes, and levels of interactivity. From digital billboards and signs on taxis, to digital signage at airport gates and gyms and waiting rooms, these varieties underline a necessary bridge between context and location in relevance and favorable recall - vital components of any media campaign.

上記の記事からの引用部分を読んでみるとDOOHは様々なサイズや形のスクリーンが含まれる。デジタルビルボード(渋谷の駅前のあれとか)、タクシーの屋根についている(これはニューヨークの話)デジタルなサイネージから、空港やジムなどにあるデジタルサイネージなどがそれである的なことが書いてあるので、ニュアンス的にはデジタルサイネージよりも広い意味を込めて使われていることがわかる。更にこれらの特徴としてコンテキストとロケーションの間をうまく橋渡しをしてくれるというようなことが書いてあるので、ただの電子掲示板みたいなものとは区別されている。ただし、ここでいうコンテキストが消費者個人のコンテキストを指すものなのか、もう少し大きなシチュエーション的なコンテキスト(たとえばジムであればそこにいる人々は何かしら健康に興味があるというコンテキストが得られる)のことを指すのかは書かれていない。

Trend1: Corss-platform trageting opportunities are on the rise

ユーザーが持ち歩いているモバイルデバイスがリッチになってきているので、DOOHはより高度にパーソナライズができるようになるであろうと。NFCやビーコンなどを使って、ユーザーのデバイスから情報を受け取ってDOOH側で最適な広告を提供する、というようなストーリーが書かれている。

Trend2: DOOH will provide increasingly relevant messages in locations that matter.

これとかこれによると、ひとは家にいるよりも、外出中のほうが様々なメッセージに対する受容性が高くなるというレポートがあるようだ。この特性をうまく活かし、デジタルサイネージのような既存のスクリーンを使いつつも、DOOH的なロケーション&コンテキストアウェアな広告を提供することによって、ユーザーの関心度を高めることができるようになっていくであろう、もしくはそういう取り組みが増えていくであろうという感じだろうか。

このパートを読んでいてデジタルサイネージとDOOHの違いがなんとなくイメージついてきた。デジタルサイネージはあくまでスクリーンであって、DOOHは屋外にあるスクリーンを利用したコンテキスト&ロケーションアウェアな広告手法、ということなんだろうと思う。

Trend3: Data is (literally) where it's at, locally and programmatically.

DOOHもRTBで買えるようになるであろうという話が書かれている。パーミッションやIDのフラグメンテーション問題はいったん置いとくとたしかに

iphone -(nfcとか?)-> デジタルサイネージ-(internet)-> ssp -> dsp

な感じの流れの結果、落札された広告をデジタルサイネージに表示、みたいなことができるという論理が成り立つ。

しかし、↑の図では、ibeaconだとスマホ側からサーバーに通信しなくてはならないので、という理由でなんとなくnfcと書いてみたものの、nfcでほんとにできるんだろうか。というのは若干疑問が残る。(nfcを調べてみれば済む話なんだけれども)

Trend4: Out of Home creates a unique canvas for top-notch creativity.

いままでにない新しい体験をユーザーに対してもたらすことができるであろうという話。いきなり話が雑になったきがするがw

Trend5: There is a rise of new measurement and addressability opportunities in DOOH.

これも若干雑な話で「これからこの分野は成長性していくぜ!」という話w

タイトルにあるnew measurementとかaddressability opportunitiesというのは広告事業者や技術者としてすごく興味をひかれたり期待を寄せたりするのは、すごくわかる。

おわりに

DOOHとは?最近のトレンドとは?という記事だった。実際、IABではDOOH Taskforceというのを立ち上げたと書かれている。活動内容は明記されていないけれども。

パーソナライズされた広告がデジタルサイネージに表示される・・・って、昔見たSF映画みたいな世界でドキドキ感がある。

広告に関するなにか:Spotifyのパーソナライゼーションの話

Personalization at Spotify using Cassandra

広告の話ではないけど、Spotifyのパーソナライゼーションの話ということで。Cassandraを使って大量のデータをベース多くのユーザーに低レイテンシな、プレイリストのパーソナライゼーションを提供してますよ。その裏側を少し紹介しますよという話。

プレイリストのレコメンデーションの難しさの一例として、メタルが好きな2人のひとがいて、再生している楽曲やプレイリストは全く同じだとしても、片方のひとは子供がいるから夜や家ではメタルは聴きたくない。もう片方のひとはそんなこと気にせずいつでもメタルを聴きたい。みたいなケースでレコメンデーションの挙動をいかに最適化するのか、という話が挙げられている。そこで出てくるのがレコメンデーションのパーソナライゼーションでしょうと。

で、中身を読んだんだけど、実際にはパーソナライゼーションの話ではなくてそのためのアーキテクチャやデータベースのモデリングの話だったのであしからず。

アーキテクチャ

見づらいけど・・・

Log ▶▶ Kafka -> HDFS  ->  Apache Crunch 
          ▼                      ▼
          ▼   <- Cassandra(Entity Metadata Store)
          ▼                      ▼
        Storm -> Cassandra(User Profile Store)
  

Kafkaにユーザーのイベントログを流し込み、そこから2つの経路に分岐。

  1. HDFSにデータを流し込みApache CrunchMapReduceして結果をEntity Metadata StoreとUesr Profile Storeに格納。いわゆるバッチレイヤ。特にEntity(楽曲などのデータ)は、一度生成されたらめったに変わるものではないのでバッチで問題ない、ということらしい。
  2. Stormにデータを流し込み、Entity Metadata Storeのデータを利用しながらリアルタイムにUesr Profile Storeの内容を更新していく。いわゆるスピードレイヤ。ユーザーの状態は比較的リアルタイムに移り変わっていくのでこういう対応にしていると書いてある。

なぜCassandra?

はあんまり興味がないのでちょろっとだけ。スケーラビリティとジオレプリケーションが主なポイントと書いてある。あとはHDFSとかからのバルクデータロードとかもポイントらしい。

データモデル

ここが一番おもしろかった。ここで利用されているようなデータの特徴として、 - アトリビュート(いわゆるカラム)は自在に増えたり減ったり - クエリされるためにすべてのアトリビュートが必要なわけではない

という特徴がある。行型よりもカラムナ型やドキュメント型のデータベースがマッチしそうな雰囲気。しかし、どちらもすべての要件を満たすわけではない。そこで彼らの考えたスキーマ

こうじゃなくて

CREATE TABLE entitymetadata (
  entityid text,
  feature1 text,
  feature2 text,
  feature3 text,
  -- 続く
  PRIMARY KEY (entityid, featurekey)
  )
  
CREATE TABLE userprofilelatest (
  userid text,
  feature1 text,
  feature2 text,
  feature3 text,
  -- 続く
  PRIMARY KEY (userid, featurename)
)

こういうふうにアトリビュートごとにアイテム(行)を分割するという実装にしたと書いてある。

CREATE TABLE entitymetadata (
  entityid text,
  featurename text,
  featurevalue text,
  PRIMARY KEY (entityid, featurekey)
  )
  
CREATE TABLE userprofilelatest (
  userid text,
  featurename text,
  featurevalue text,
  PRIMARY KEY (userid, featurename)
)

で、更に柔軟性を持たせるために、さらにこう改善されていった。

CREATE TABLE entitymetadata (
  entityid text,
  featurename text,
  featurevalue list<text>,
  PRIMARY KEY (entityid)
)

このモデルはAdRollのDynamoDBでも同じような構成が取られている。以前も紹介したスライドだけど、この20枚目に同じような話が書いてある。

ということで

直接レコメンデーションやパーソナライゼーションどうこうという話よりは、アーキテクチャモデリングの話になってしまったけど、このあたりの業界ではLambdaアーキテクチャは当たり前になっているし、さらに拡張しやすい柔軟なモデルもある程度形が固まっているという話をまとめとして終わります。

広告に関するなにか(2015/1/14): Apache Lens at Hadoop meetup

inmobiのレポートシステムでLensを使っているよという話。

 

Generation 1 : RDBMS

Architecture

  • RDBMSで1.5TBくらいのデータを扱っていた。

Challenges

  • データロードに24時間近くかかったり3ディメンションくらいしか現実的にはクエリできなかったり・・・いろいろ辛かった。
  • 誰もが通る道だよね。でもinmobiもそれやってたって話を聞くとなんか安心するw

Generation 2 : Hadoop + Columnar DB

Architecture

  • Hadoop + Columnar DB
  • 集計済みのデータ: Columnar DBにいれてダッシュボード利用
  • 生に近いデータ: Hadoopにいれてアドホッククエリ。
  • Columnar DBに8TB。Hadoopに250TBくらいデータ入れてた。

Challenges

  • 2つのシステム(Columnar DBとHadoop)をメンテナンスするつらさ
  • データの食い違い
  • スキーマのメンテ
  • 学習コストの高さ
  • 2つの重複データを管理するのもつらいしもったいない

Generation 3 : Apache Lens

Architecture

  • Apache Lens使い始めた。
  • これを使うと複数のデータソースをOLAPで抽象化できる。しかもマルチディメンションなCUBEっぽく使える。
  • メタデータは1箇所で集中管理できる。
  • 新しいワークロードに合わせてRedshiftやSpark、Tezも取り入れ始めた。

Generation 4 (Future) : Machine learning workflow in Apache Lens using Apache Spark

をやりたいと思っている。以上。という感じ笑

Apache Lensについて

Apache Lens

http://lens.incubator.apache.org/ から引用

  • OLAP Cube QL which is a high level SQL like language to query and describe data sets organized in data cubes.
  • A JDBC driver and Java client libraries to issue queries, and a CLI for ad hoc queries.
  • Lens application server - a REST server which allows users to query data, make schema changes, scheduling queries and enforcing quota limits on queries.
  • Driver based architecture allows plugging in reporting systems like Hive, Columnar data warehouses, Redshift, Impala etc.
  • Cost based engine selection - allows optimal use of resources by selecting the best execution engine for a given query based on the query cost. The following diagram shows Lens architecture.

実際のデータストアレイヤを抽象化して、横断的にクエリできるようにしてくれるソフトウェア。という感じだろうか。たぶん、個々のクエリを最適化しなきゃいけないような場面だとつらい気もするけど、アドホックなクエリでいろいろやりたい、という場面にはとても便利そう。

広告に関する何か 2015/1/9

Beating the Speed of Light with Your Infrastructure

 

AWS Re:Invent 2014でのAdRollの発表のスライド。AdRollと言えばAWSてきにはDynamoDBの事例でよく話題にあがる会社。ちょっと内容をつまみ食いしてみる。

扱っているトラフィックの量

  • 150TB/Day
  • 5ms以内にレスポンス(サーバー内だけの話のはず)
  • グローバルで100万request/sec超え(Dailyでは600億requestsくらいの模様)
  • 1兆(!)を超えるアイテム(DBのレコード数だと思う)

アーキテクチャ

アーキテクチャ設計のPrincipleとして下記の2つへの言及がされている。

ひとつめ。

Essentially it means accepting now that in a few years time you'll (hopefully) need to throw away what you're currently building.

-Martin Fowler

ふたつめ。

Ensure your design works if scale changes by 10X or 20X but the right solution for X often not optimal for 100X

-Jeff Dean, Google

どちらも、現実的なところで折り合いを付けましょうというか、ひとつのアーキテクチャを後生大事に引き回すなというか状況に併せてアーキテクチャは作りなおしていこうぜという話。(ざっくり意訳しすぎか)

で、気になるアーキテクチャ

Biddingは当然データに基いて行われるわけだけど、そのデータ収集から利用までの流れを表したのが下記のフロー図。BatchレイヤとSpeedレイヤ。Lamdaアーキテクチャですかね。

Data Collection(Process) -> Data Storage(Store) -> Global Distribution(Process) -> Bid Storage(Store) -> Bidding(Process) という具合に、ひとつずつの処理にあとにデータストアを置いてチェックポイントをつくることが重要という話が強調されている。 Lambda* 冒頭のスライドより抜粋

こちらはデータ収集部分の話ですね。バッチレイヤ側。トラッキングサーバーで集めたユーザーのログをKinesisとS3に放り込んで、Storm経由で各リージョンのBid Storageに配布している。 Lambda3* 冒頭のスライドより抜粋

ここからは完全に想像だけど、Bidderだけじゃなくてトラッキングサーバーも各リージョンにあると思うので、このグローバルなデータ配布って

Tracker:Bidder=1:n

ではなくて

Tracker:Bidder=n:n

でやっている気がする。グローバルに地理分散しつつ中心のないアーキテクチャ、ということになりそう。かっこいい。

そしてこちらは実際のBidderのアーキテクチャ。超シンプル。 Lamda2* 冒頭のスライドより抜粋

Bidderの中身。Erlang使ってるね!TrackerからDynamoDBまで運ばれてきたデータをもとにBiddingしていくわけね。Blackboxというのは、彼ら独自のMachine Learningアプリケーションぽい。 architecture* 冒頭のスライドより抜粋

DynamoDBに至るまで

DynamoDBの選定経緯みたいなのも語られていたのでまとめてみた。

  • Cassandra, Redis, Memcached, HBaseを比べた。
  • 最終的にはコスト面でDynamoDBを選択。
  • 上記の4つと比較するとDynamoDBは唯一オープンソースではなかった。当然ロックイン問題も考慮した。
  • しかしアプリケーションの開発スピードを優先した結果の選択。

まとめ:もっと中身の話が知りたい

AdRollのスライドをざっとまとめてみた。非常にきれいにまとまっていて読みやすかった。でもアーキテクチャだけじゃなくて、もっと中身のアルゴリズムの話とか知りたいよね。でもまあそんなに中身の話を公開している企業があるわけはないので、このへんはKDDの論文とかをあさってみようと思う。で、それをまとめてまたブログに・・・したいんだけど論文は読むのに骨が折れるんだよね・・・

広告に関するなにか 2015/1/7

Could Programmatic Branding Have a Breakthrough Year?

パフォーマンス系、獲得系の広告だけじゃなくてブランディング系の広告においてプログラマティックが利用されるようになっていくのかという話。書いているのがDMPのセールスのひとなのである程度バイアスはかかっているものの、基本に立ち返るいいポスト。

The most fundamental problem with digital branding is that it is truly a one-to-one marketing exercise. If we dream of the “right message, right person, right time,” then matching a user with her devices is table stakes for programmatic branding. How do I know that Sally Smith on desktop is the same as Sally Smith on tablet? Cross-device identity management is the key. Device IDs must be mapped to cookies, other mobile identifiers and Safari browser signals to get a sense of who’s who. Once you unlock user identity, many amazing things become possible.

ということで、ブランディング広告においても"right message, right person, right time"が大事ですと。そしてそれを実現するためにはクロスデバイスなユーザートラッキングが絶対に必要になりますよね。という話。もう一歩話を進めると、以下の3つのAchievementが必要でしょうと。

  1. Global Frequency Capping
    • まずはひとの特定をしたうえで、グローバルなフリークエンシーキャップをかけましょうという話。フリークエンシーキャップって広告主から見ると広告費用の無駄を削ってくれるのでとても大事だと思うんだけど、広告を見るユーザー側からしても、同じ広告との過度な接触を減らすことになるので、ユーザーから見たインターネットの品性を上げてくれるという意味でも大事だと思う。最近、リターゲティングの広告がどこまでもいつまでも追いかけてきて、辟易なことも多いしね。。
  2. Sequencial Messaging
    • で、ユーザーの特定ができてフリークエンシーキャップが掛けられるようになったら、次にストーリーを持って広告を出していきましょうと。カスタマージャーニーという表現も使われている。
  3. Cross-Channel Attribution
    • うえのカスタマージャーニーの話とかぶっている部分も多い気もするが、アトリビューション(分析というよりは、アトリビューションを利用したカスタマージャーニー?)も当然重要ですよねという話。

こんな感じに見てみると、兎にも角にも「クロスデバイスでユーザーをいかにトラッキングしていくのか」がいかに重要かという話が浮き彫りになってくるね。何か論文探してアルゴリズムの話を探してみようっと。。。