無気力生活 (ノ ´ω`)ノ ~゜

脱力系エンジニア。てきとーに生きてます。

開発環境(mac)を:beers:まみれにするためにやること

https://assets-cdn.github.com/images/icons/emoji/unicode/1f37b.png

やるたびに忘れるので、個人用メモ程度に。

Homebrew

自家醸造しないと始まりません。サクッといれる。
rubyとcommand line tools for xcodeが必要らしい。RubyはデフォルトでOK。
command line tools for xcodeは導入課程でインストールが要求されてた気がする。まあダメだったら入れる感じで。

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

インストール後、以下コマンド実行。なにか問題あるならエラーなり警告がわかりやすく表示されるので解消しておく

brew doctor

こんな感じで使います。

brew install git

インストールしたモジュールは、/usr/local/Cellar/配下に置かれる(変更はできる)
また、/usr/local/bin配下にシンボリックリンクが置かれる

Homebrew-Cask

brewコマンドで、Chromeのようなアプリケーションを入れられるようになるやつ。
brewコマンドでインストール

brew install caskroom/cask/brew-cask

# アプリインストール
brew cask install google-chrome

インストールしたアプリケーションは、デフォルトだと/opt/homebrew-cask/Caskroom/に配置される。パスは通っているらしく open -a アプリ名 とかで起動できる。

caskroom/versions

Homebrew-Caskはアプリを入れてくれるけども、英語しかない。ユトラーなので日本語ないとつらい。そこでcaskroom/versions。 brew caskの別バージョンアプリをインストールできるようになるやつ。 *1
これを導入することで、日本語パッケージがリポジトリに含まれる。

brew tap caskroom/versions
brew cask install thunderbird-ja

デジタルマーケティグ普及の旗手となるかっ!? 株式会社テクロコへ行ってきました

私は、株式会社テクロコ を応援しています
https://www.wantedly.com/companies/techloco



こんにちわ! 最近、いろんな会社さんのお話を聞きに回っております。 事業の話や今後の目標等のお話、その会社さんの熱意に触れられる。そうところを楽しみに聞かせて頂いてます。

さて、もちろん、そういう良い話だけでなく、困っているお話も伺うこともあります。 よく話題になるのが、 エンジニア不足 の問題です。


近頃、個人でもいろいろサービスを開始できる環境が整ってきたこともあり、様々な企業さんが参入しています。
ただ、優秀なエンジニアは、いろんな企業さんで取り合いになってしまい、なかなか確保できません。
どの企業さんも、人材確保には躍起になっていまして、
ソーシャルでの採用活動を行ったり、エンジニアによりよい環境を用意したり、等、いろいろな試みをしています。

そういった、エンジニアにやさしい環境 をつくった or つくろうとしている企業さんを応援するべく、

勝手に記事を書いていこう

という企画です。 ※掲載許可は頂いております
今後、定期的に会社見学して、いろんな企業さんの紹介をやっていこうと思っています。


さて、この企画、第一号です。
株式会社テクロコ!!

先週の、大雨があった日に行ってきましたorz 油断して傘持ってこなかったせいで、道中コンビニに全力ダッシュするハメになったのは秘密(´・ω・`)

テクロコさんは、
Web広告業界の大手企業、株式会社オプト さんのグループ企業です。
他のグループ企業さんに、マーケティングツールを開発して卸す事業をしています。
その卸したツールは、グループ企業さんが導入支援した上で、ユーザー企業さんが使われています。

アドテク業界は、今後大きくなっていく業界だと言われています。
参考: http://www.meti.go.jp/statistics/toppage/report/bunseki/pdf/h19/h4a0803j2.pdf
これまで、CMや紙ベースだった企業さんが、より手軽に打て、高い効果が期待できるネット広告に流入しています。 そうすると、その広告を配信する企業や、効果を測定する企業の需要が高くなります。

テクロコさんも、自社開発の分析ツールにおいて、ユーザーさんが順調に増えており、今後さらに導入が広がっていくと思われます。 自分の作ったサービス、ツールがたくさんの人に使われていく。そういう体験はすごく嬉しいものだと思います。

さて、このテクロコさんですが、
今後、マーケティングツール以外にも、様々なサービスを行っていきたいとのこと。
そのためのエンジニア、を募集しているんですが、採用活動に苦慮しているそうです。

どうしても、

  • 目立つサービスを作っている企業
  • スーパーエンジニアがいる企業

に、行ってしまい、なかなか応募が来てくれないんだそうです。

現在、所属するエンジニアさんは、数名程で、組織を作っている途中とのこと。
その組織を引っ張っていけるコアメンバーを募集しているそうです。

一から、会社を育てて見たい人、環境を作ってみたい人には、 大変やりがいがある環境だと思います。

テクロコさんの、エンジニアの私から見て、良い所を上げてみます。

  1. 残業が少ない
    最近、このような募集が増えてきています。
    長く残業して開発するより、早く帰って自主学習する。それを仕事に活かしてもらったほうが、意義があると考える企業が増えているようです。
    テクロコさんも、同じ考えなんだそうです。
  2. 福利厚生が充実
    広告系サービスの会社ですからね。そこらの企業より充実しています。
  3. 今後、大きく伸びる業界
    企業が生産活動を行い、ユーザーさんに届けるため、広告は必要不可欠。ゆえに、今後なくならない業界だと思います。
    手堅い業界は強い!

この記事をみて興味が湧いてきましたら、
次に自分が戦っていくフィールドに、選んでみてはいかがでしょうか?
http://www.green-japan.com/job/27133

第二回ゲームサーバー勉強会に参加してきた

7/19(土)に開催された、ゲームサーバーに特化した勉強会についてのメモです。

広くてきれいな場を提供していただいたGREEさん、ありがとうございました。 そういえばGREEさんに入るのは、今回が初めてですね( ・ω・)

今回の勉強会では、以下のようなお話を頂きました。

  • データベースの再入門
    (@nsega様 )
  • 分割と整合性をがんばる話 ソーシャルゲームの整合性対策
    (株式会社gumi 小林様)
  • MMOのサーバーについて「剣と魔法のログレス 〜いにしえの女神〜」の実装例 (株式会社Aiming 山藤様)

スライド資料はまだ公開されてない模様でしたが、一部共有をして頂けるとの事だったので、公開され次第リンク貼っておきます。
今回、書いているメモは、あくまで私個人のメモから抜粋しているので、正確でない部分があるかもしれません。その部分はご指摘いただければと思います。( ・`ω・´)

結構、分量が多くなってしまったことを反省…その分濃い勉強会でした。

データベースの再入門

初心者しかいないと仮定した説明をします、との前置きがありました。内容もDBを使うにあたっての基本的なお話が中心でした。

nsegaさんは、MongoDBの人で有名な方です サーバーサイドの開発、直近だとネイティブもやってるそうです。 DBはPosgtre、Mysqlをよく使うそうです。

2014/08/27
資料が公開されている旨いただきましたので、貼っつけておきます。

ここからメモ

データベースについて

データベースを扱うためには、データの定義を明確にする必要がある。
論理的、物理的問わず、最初に定義を固めておく。

DBMSと、問い合わせするためのSQLには、以下のような種類があり、目的が異なる。

  • DDL (Create等の)データ定義言語
  • DML (Insert等の)データ操作言語
  • DCL (Rollback等の) データ制御言語

複数人で同時に操作する、壊れたら大変なデータ、を扱うときはDB。
DBを使うケース = 検索性重視、障害時のリカバリを迅速に行う、整合性を保証したい場合

必要なデータを探すときは、インデックスがパフォーマンスにかなり影響する。DBで使われるインデックスの特性を理解すること

  • B+Treeインデックス
  • ハッシュインデックス
トランザクションを重視する理由
  • データ更新の並列性を保つ
  • データの整合性を保障する
レプリケーション
  • DBのデータを複製できる。障害が発生しても、ある程度、データが元に戻せる。
  • マスタ-スレーブ構成。Update等の更新は、マスタに対して行う。
    マスタの変更は随時、スレーブに配信する、アプリからのReadはスレーブから。

RDBMSとNoSQLについて

  • RDBMS

    • データの一貫性保つことが得意。SELECTでの複数条件を使った柔軟な検索ができる。
    • 苦手
      • たくさんの通信があるとつらい。
      • インデックス作成などの、構成変更で時間がかかる
      • カラムのパターンが、固定しづらいケースだと苦手
      • 汎用的に使おうとすると、予備カラムが増殖してやばい
      • 結果を早く返すこと苦手(トランザクション効くとどうしても)
  • NoSQL

    • 何種類かある(KV型、ドキュメントベース型、カラムファミリ型)
      • データ分散しやすい。大量データもOK。
      • スケールアウトさせやすい(分割が楽)
      • 安いサーバーでも十分
    • 苦手

お互いが不得意なことを、無理に置き換える必要はない 。適材適所が大事。DBかKVSの選択は、要件を解決するための手札でしかない。

KVSの使いどころは、タイムライン表示とか、リアルタイムランキング。 セッションステートとしても良い感じ 。

データベースを使った使用事例

データモデリング大事。あとで矛盾があっても、手戻りは基本できない。
これから勉強する人は、IPAデータベーススペシャリストの勉強が、おすすめできる。

  • データの種類と管理方法

    • マスタ系データ
      アイテムとかモンスターそのもののデータ。頻繁にかわることはあまりない
      • M_xxxのようなプレフィックスつけて管理してる
    • トランザクション系データ
      ユーザーデータ。頻繁に更新追加が行われるもの
      • T_xxxのようなプレフィックスをつけて管理してる
  • ER図自動生成
    ジークレストではEclipse使っているので、ERMaster使って、ER図からクエリ自動生成してる

Tips

  • ER図レビュー、ソースレビュー、クエリレビューやる

    • 実行計画を見る
    • リクエスト回数が多すぎないか(ORM使っているとある)
    • 事前に事故防止ができる
    • わかってるエンジニアのアサインが必須になる
  • レプリケーション設計

    • 最初からDB負荷を分散できる
    • レプリケーション遅延を見越して設計する必要ある。マスタ反映後スレーブ反映しているので、若干遅延が出てしまう。タイミングによって、変更が反映されていない情報が取れる問題が。
    • そのため、時にはせっかくスレーブに向けてたSelectクエリを、Master側に向ける必要も出てくる
  • シャーディング

    • 水平分割: レコード単位で別DBに向ける
    • 垂直分割: 1テーブル内の、更新が多い項目だけを別テーブルに切り出す。
      シャーディングすることによって、DB性能、管理しやすさ、可用性に優しくなる。ただ、テーブルJoinが難しく…設計で考慮することが、増える。
  • 開発

    • フロントとサーバーサイド分けずに、一人でやったほうが効率いい
    • API定義書とかつらい。全部自分で作ることで、コミュニケーションレスでできる。楽に。
    • ただし、両方できる人は貴重…

分割と整合性をがんばる話 ソーシャルゲームの整合性対策

gumiの清水さんのお話でした。ソーシャルゲームの運用を通して、いろいろ工夫されたことを中心に、話されてました。

gumiさんは、python使ってることで有名な、SAPですね。 最近、大口の資金調達で話題になっていたりもしました。

ここからメモ

負荷対策

新規サービスが大ヒットして、負荷が限界に…
当時の、AWS最高インスタンスでもダメだったので、単純なスケールアップでは対応できなかった。サービス側で色々改修した。

  • Player系データを、単独のDBサーバーに。
  • 機能単位で、DB先を変更していたものを、Master、Trade、Guild、Friendをそれぞれ別サーバーに分割する方法に変更(垂直分割)
    • 性能限界にぶち当たるたびに試行錯誤してた。
    • 外部キーを外して、別DBに移す作業をひらすら実施。
  • 一つの機能に負荷が集中して、対処不可能に
    • KVSにも、じゃんじゃん流す

複数ユーザーが、同時に使う機能は、分割することが難しい - Player情報系は負荷が多く、分割難しい - ロックの粒度で負荷変わらない... なので、Player毎に、接続先DBを変更する、水平分割を行って解決。
ユーザー増えたらサーバー増やす→ 性能限界の問題は解消できた。

しかし、複数DBをまたがせると、

  • 多発する不具合
  • 消えた更新、消えたカード
    トレード機能で、カードを他のユーザー所有に変更するとき、カードから、ユーザーのヒモ付を消すようにしていた。
    → このユーザーが、分割キーだったので、分割キーを消すことで、このカードはどのDBに置くべきか、判断つかなくなった。
    結果、他のユーザーの資産が影響受ける問題に。
    → 水平分割した時は、分割キーは消しちゃいけない

トランザクション

  • 不整合と戦う
    一から抜本的に対応

    • 負荷は水平分割で対処
    • XA Transactionによる一貫性担保
    • ロックによる排他制御
  • 水平分割を前提とした構成にする

    • プレイヤーデータはPlayer用のShardにまとめる。
    • ただし、ギルドテーブルだけは、全ユーザに対する網羅的なアクセスが発生するので、これは1DBサーバーにまとめるようにした。
    • マスタデータはJsonにして、デプロイ時にメモリ上に展開するような方法に。
  • DBのみで実装する

    • プレイヤーのデータはすべてDBに
    • 自動回復系ステータスもDB
       いままではKVSに格納→Redisを水平分割してた→ 人が動くたびにデータが生成されるので、サーバーを都度増やす自体に、つらい。
       DBだけ更新、KVSだけ更新が発生していて、どちらかが、漏れる事故があった。
    • 何か問題が起こると、ユーザーに特になる場合は裏技として2chで祭られ、ユーザーが損する場合は、CSが爆発。
    • なので、トランザクションを重要視してた。
    • 正規化を徹底

XA Transaction

分散トランザクション

  • XAに参加するいずれかのDBで問題起これば、ロールバック可能
  • 複数DBをまたいだトランザクションいける
  • フレームワーク側が対応していなかったので自社開発
  • Preapared後のデータコミット時に、コミット途中で死んだら?
    • 裏でCron回して、コミットされていないやつを、解除するタスクを回そうとしていた。
    • DBのバージョンアップで、Prepared状態で固まっていると、自動でロールバックする対応が入ったので、結局使わなかった。
    • が、DBが死んだ際に、復旧のため使った

デッドロック

  • トランザクション掛けた、Updateが2回、クロスしたりする起きる。 解決できないので、サービス側でレコードロックをするようにした。
  • innoDBはインデックス使ってレコードロックかけれる
  • Whereで抽出する際に、インデックスが張っていれば、レコードが特定されてそこだけ行ロックできる
  • インデックスがないと、行が特定できないのでテーブルロックが走る

発生した事例では、テーブルにインデックス貼ってなかったせいで、テーブルロックがかかる。そのため、デッドロックで、DBサーバーのCPUが張り付く問題が発生した。
また、無駄インデックスが残っていると、意図しないインデックスが使われて、思いもよらないロックが取られることがあった。

回避するためには、処理時に

  • ロックの順番を統一すること
    • DBまたがってる場合、DB順もソート
    • 別のテーブルにまたがってる場合、テーブルもソート
  • 参照に、更新処理まぜない(あればSelect、なければInsertSelect)のケース

MYSQLは親切。同じDB内のデッドロックを検知して解除してくれる

  • 片方をロールバックして、いい感じにしてくれる
  • DB分割している場合、他のDBのデッドロックは、検知できないので自力でロック解除できない

まとめ

  • KVSに移すのは問題の先延ばしにしかならない
  • デッドロック対策の前に適切なインデックスを
  • インデックスショットガン、ダメ絶対
  • プロファイラ大事

MMOのサーバーについて「剣と魔法のログレス 〜いにしえの女神〜」の実装例

Aimingの、山藤さんのお話です。

近頃、ランキングで目立ってきている、あのログレスの、実装についての内容でした。
今、目立つタイトルだけに、会場の期待度もかなり大きい印象でした。

MMOのタイトルらしく、通信周りの工夫の話が、大きくウェイト割かれていたように思います。

ここからメモ

ログレスのサーバー

フロントエンド側のサーバー、バックエンド側のサーバーを、それぞれ、階層分けて冗長化している。 WANを縦につなぐ、同階層での接続はしていない。

フロントエンドサーバー

  • ユーザークライアントが、直接接続するサーバー
  • 通信を2種類使いわけている。

バックエンドサーバー

  • ユーザークライアントは接続しないサーバー。
  • フロントエンドサーバー間の、データやりとりを、Socketで行っている。
    サーバー中では、DBとのやりとりも行っていた。
  • サーバーはC++で実装している

Socket

  • サーバープッシュが必要な箇所で使用。
  • レスポンス速度が要求される、常時接続、差分更新
  • 利点
    • オペレーション都度の、接続コストが発生しない
    • 一回の、送受信量を少なくできる
  • 欠点
    • バッテリー消費(セッション維持するとどうしてもつらい)
    • 回線切れに弱い
    • ソフトウェアで対応しないといけないことが増える
    • セッション維持している関係上、ロードバランサー使ったスケールアウト難しい

HTTP

  • サーバープッシュがいらないところ
  • レスポンス速度を要求しないところ
  • 必要都度、通信、切断、
  • 一括更新

実装例

  • キャラクタの移動

    • 歩けない場所の制御、等あるため、サーバーでも管理する
    • キャラクタが動くと
      • 描画範囲外で、見えなかったものが見えるように
      • 見えなかったユーザーも見えるように
  • 見えなかったものが、見えると、どうなる

    • 自分の行動を他のユーザーにも反映しないといけない
    • 見えてる人がとった行動を、自分に反映しないといけない 人が増えることによってやりとりするデータが増えていく
  • 移動すると、

    • 描画通信範囲の更新を繰り返す
    • 移動フロー
    • クライアントで移動開始
    • サーバー側に目的値と到達点を送信
    • サーバー側で移動の妥当性を検証
    • 周辺のプレイヤーに送る

移動の都度、サーバー介すると反応が悪くなるので、いろいろと工夫が必要。

  • 他の人は多少遅れても気にならない
  • クライアントだけで移動させてしまうと、通信範囲の計算できない
  • クライアントだけで移動させると、マップの当たり判定無視できてしまう。
  • チート問題が付きまとうので、サーバー側の妥当性は検証必須

チャット

文字ベースコミニュケーション

  • キャラクタの、チャット送信でのポップアップはSocketで表示させている。
    • チャットの吹き出しは見える人だけ見えればいよね
    • 吹き出しは発言後なるべく早く画面にだしたい
  • チャット履歴はHTTPで
    • チャットログは、オフライン時のやつも見れる必要がある
    • コミニュケーションの途切れを防ぐ

実際に起こった問題と対応

  • 一台のサーバーにログインできるプレイヤー数が限られる
    • エリア毎に別サーバーで割り当て。で分散。
  • クライアントは、裏で、フロントエンドサーバー間の接続を、切り替えながら動いている
    • この切替時のサーバー負荷が大きい
    • ユーザー移動が大量に起こると、バックエンドが時間かかってローディングが終わらない
      • サーバーをラウンドロビンして、解決
      • 影響範囲はバックエンドとフロントエンドの通信部分だけ。
        クライアントには影響なしで修正できた。構成が分離されていることによるメリット。

RoslynかわいいよRoslyn

サンプル見てて大層感動したので、いじってみた。
解説は後日。

using System;
using System.Collections.Generic;
using System.Linq;
using Roslyn.Compilers.CSharp;
namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            SyntaxTree tree = SyntaxTree.ParseCompilationUnit(
                @"
                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Text;

                namespace Roslyn_Sample
                {
                    public class Person
                    {
                        public string Name { get; private set; }
                        public Person(string name)
                        {
                            Name = name;
                        }

                        public string Speak()
                        {
                            return string.Format(""Hello My Name is {0}"", Name);
                        }
                    }
                }");

            // 外部ファイルから読み込む用
            // var code = new StreamReader("../../Person.cs").ReadToEnd();
            // SyntaxTree tree = SyntaxTree.ParseCompilationUnit(code);

            var root = (CompilationUnitSyntax)tree.GetRoot();
            root.Usings.ForEach(x => Console.WriteLine("Using Block: {0}", x.Name));
            root.Members.ForEach(member =>
            {
                if (member is NamespaceDeclarationSyntax) (member as NamespaceDeclarationSyntax).Members.ForEach(nsM => {
                    if (nsM is ClassDeclarationSyntax) (nsM as ClassDeclarationSyntax).Members.ForEach(csM => {

                        if (csM is ConstructorDeclarationSyntax)
                            Console.WriteLine("Constructor:\n " + (csM as ConstructorDeclarationSyntax).GetText());
                        if (csM is PropertyDeclarationSyntax)
                            Console.WriteLine("Property:\n " + (csM as PropertyDeclarationSyntax).GetText());
                        if (csM is MethodDeclarationSyntax)
                            Console.WriteLine("Method:\n" + (csM as MethodDeclarationSyntax).GetText());
                        if (csM is FieldDeclarationSyntax)
                            Console.WriteLine("Field:\n" + (csM as FieldDeclarationSyntax).GetText());
                    });
                });
            });
            Console.ReadKey();
        }
    }

    // foreachなんて書いてられっかヽ(`Д´)ノ
    public static class Extentions
    {
        public static void ForEach<T>(this IEnumerable<T> src, Action<T> func)
        {
            IEnumerator<T> enumrator = src.GetEnumerator();
            while (enumrator.MoveNext()) func(enumrator.Current);
        }
    }
}

Hadoopハンズオンセミナーに参加してきました。

黄色いゾウさんすげー!な体験です(`・ω・´)
昨日04/14に開催されました、Hadoop初心者向けハンズオンセミナーに参加してきました。

セミナーでは、前半にHadoopについての説明。後半から実際にHadoopを使ったプログラミングを行いました。
後半のプログラミングでは事前に提示されていた準備があったのですが、事前準備のメールが来ていないことに到着してから気づき、会場についてから必死で準備していたのは私です。
ええ、UbuntuJavaも準備出来ていませんでしたよと。モウシワケナイ・・・
メール来なかったのは、メールアドレス間違えてたこちらのミスでした。大変お手数をおかけしました。快く主催さんのサーバー環境貸して頂き、なんとかハンズオン中に動くものができました。感謝してもしきれません。
主催のAcroquest Techonology株式会社様。貴重な体験をさせて頂き大変勉強になりました。ありがとうございました。

セミナーではHadoopの動作の中身といった詳しいお話もあり、初めて触れたHadoopでしたが、概要は理解できました(・ω・)
Hadoopについて知ったことを書いてみたいとおもいます。

そもそも、Hadoopとはなんぞや?

Hadoopとは、ある巨大なデータを複数のマシンで分散処理しより高速に分析を行うことができるフレームワークで、Googleが提唱したMapReduceJavaで実現したものです。Apacheのトップレベルプロジェクトの一つとして位置づけられています。2007/9/04に最初の版がリリースされています。思っていたより昔ですね。
Hadoopの用途としてよく聞くのが、ログやデータの分析や大量データを扱うバッチ処理ですね。多くのユーザーを抱える企業では殆ど使われているんじゃないんでしょうか?

Hadoopはノードを追加するだけで処理をスケールアウトすることができます。性能を上げたければその辺に転がっている古いPCでも、たくさん集まれば処理性能は高くなります。セミナーで聞いたところ、4000台を使ってスケールアウトした事例もあるらしいです。Hadoop自体の限界は、現在開発版の0.23で10000台を見込んでいるらしいですね。

Hadoopの仕組みについて

Hadoopを構成する要素は、大きく分けて2つあります。

  1. HDFS
  2. MapReduce
HDFS

HDFS(Hadoop Distributed File System)とは、Hadoopが持つ独自のファイルシステムです。複数のサーバーを使って分散的にデータを管理することができます。
HDFSは、"Name Node"、"Data Node"の2つで構成されており、Data Nodeはファイル自体を管理し、Name NodeはData Nodeを管理します。*1

ある大きなデータをHadoopで処理するとき、どのように分散するんでしょうか?
説明のためName Nodeを"管理ノード"、Data Nodeを"ノード"として説明します。

まず、管理ノードがお仕事します。クライアント側で持っているデータを64MB程度のブロックに分割し各ノードに渡します。
この時、ブロックのコピーを複数のノードに割り当ててレプリケーションしたりします。
管理ノードはブロックをどのノードに渡したかを管理し、処理のマスターして機能します。各ノードに指示を発行するのはこの管理ノードの役割です。

MapReduce

もう一つのMapReduceは、"複数のマシンで並列処理を実行する仕組み"です。Hadoopの実処理部分は、このMapReduceが請け持っています。
MapReduceには、処理全体を管理する"JobTracker"(以下、マスターノード)と、処理を実行する"TaskTracker"(以下、スレーブノード)があります。
HDFSと連携してデータを各スレーブに割り当て、"各スレーブ毎に"分析処理を行います。
"各スレーブ毎に"がキモです。マスターノードが各スレーブに指示して処理を実行するわけではないんですね。
2012/04/17削除
なにか処理を実行するとき、マスタノードからスレーブノードに対して、分析開始指示を行います。
指示を受けたスレーブノードは、自身にあるHDFSのDataNodeからデータを読み出して、以下の順序でデータを処理します。

  • 1.Mapステップ

処理を実行する前処理にあたります。スレーブノードに渡されたデータをKeyとValueの形式に変えて、入力を作ります。
キモになるのが、入力はKey-Valueのセットであるということです。どの値を入力に使うかは、利用者が自分で調整しなければなりません。
入力値の整形は、開発者側が実装して行います。

  • 2.Shuffleステップ

Mapステップで整形した入力値を、Keyでグルーピングし、実処理(Reduceステップ)を行うワーカーに渡します。
データをグルーピングすることによって、高速に処理する準備をするらしい。

  • 3.Reduceステップ

Shuffleステップで渡されたグルーピング済みのデータを処理します。どのような処理をするかは、開発者が実装して行います。

上記処理を実行した後は、全スレーブノードの処理結果をマスターノードに渡してまとめ、最終的な処理結果をクライアントに返します。
これがMapReduceの動きの概要になります。

並列処理をする黄色いゾウにも弱点があった。

そんなHadoopですが、パフォーマンスを発揮できないケースが存在します。

  • 小さなファイルがいっぱい存在する

Hadoopは内部で64MBごとにデータを配置していく方法をとっています。そのため小さなファイルが多量に存在する場合、そのファイルをまとめてブロック化しなければなりません。Name Nodeの管理が複雑になってしまうことが想像されます。

  • 短時間で終わる処理

Hadoopは前処理に時間がかかります。詳しいことは調べきれてませんが、各ノードの整合性や、データの破損状況をチェックしたりしているらしく、どうしても時間がかかります。
短時間で終わる処理(数分)程度だと、前処理時間 > 処理時間となるため、Hadoop使わずに処理した方が早くなります。
Hadoopがその力を発揮できるのは、膨大なデータがあり、処理時間が数時間以上かかる場合に限られます。

Hadoopはどう使うの?

長くなりそう+日を跨ぎそうなので、また後日纏めてエントリ上げます。更新するまで暫くお待ち下さいな。

おまけ

自宅に帰って調べてみたら、NTTデータさんの詳しい資料がありました。
http://www.meti.go.jp/policy/mono_info_service/joho/downloadfiles/2010software_research/clou_dist_software.pdf
Hadoopのチューニングをコード付きで提示されており、これだけでも十分勉強できそうです。
気になる方はぜひ一読をおすすめします。

*1:"Secoundary Name Node"と呼ばれるName Nodeのコピーを持つことができ、冗長化のために使われることもある

ソーシャルゲームを調べるにあたって必要な用語を纏めてみた

勢い凄いですよね、ソーシャルゲーム
様々な方面でソーシャルゲーム関連の記事を目にすることが多いのですが、
略称ばっかで分かりにくいと感じていたため、用語を纏めておくことにします。

非業界人の個人的なメモです。認識が間違っていることもあるため、鵜呑みは厳禁で(汗

ソーシャルゲームっていうかビジネス用語

  • KPI(Key Performance Indicator)

重要業績評価指標のこと。企業毎に定義した目標を達成したかどうか、定量的に判断するための指標を示す。
ソーシャルビジネス介在では、新規獲得ユーザー、アクティブユーザー、課金ユーザーと課金率で算出されることが多いのかな?
似たものとして、KGI(重要目標達成指数)というものがありますが、KPIは目標を達成していく要素を指すのに対し、 こちらは目標を達成したとみなす条件を指します。

  • KGI(Key Goal Indicator)

重要目標達成指数のこと。ビジネスを成功させる為の目標を指し、名前通り事業の"ゴール"を示します。
売上高や、購入件数等がこれに当たります。この数値を見れば成功か失敗かが分かるものがKGIです。
KGIを向上させるために、どのようなKPIを実現していけばよいのか?が基本的なビジネスの考え方ですかね。
これはソーシャルビジネスに限らない、企業で共通した意識になります。

  • CSF / KSF

ビジネス用語ですね。前者がCritical Success Factor、後者がKey Success Factorと呼ばれ、 共に「主要成功要因」と呼ばれます。
このCSFとKSFを集めていくことで、KPIが構成されていきます。つまり、CSFとKSFを積み上げていくことでKPIが向上し、KGIを達成することができます。

  • NDA(Non Disclosure Agreement)

秘密保持契約のことですね。この業界に限らずすべての企業にあるものです。
これは知ってた。
開発中の商品の情報を、社外に漏らしちゃいけない。とか、マスコミ等にリークしちゃいけないってことですね。エンドユーザーの個人情報保護も含まれます。

  • マネタイズ

サービスの収益化を指します。
如何にしてビジネスからお金を得ることができるか、ターゲットを想定して絞り込むことで、より多くの効果を上げることができます。
ただし、最初から売上ありきでサービス構築すると、Web広告まみれになってしまうことが多く、新規ユーザーをなかなか獲得できません。
ある程度サービスが大きくなってから、マネタイズを考える事が望ましいらしいです。

  • IP(Intellectual Property)

知的財産のこと。自社IPって使い方が多そうです。
ソーシャルビジネスにおいて、新しいモデルのサービスを始めてみると、他社でも同様なことを始めます。
顕著な例では、ソーシャルゲーム業界に多いですね。MobageGREEに乱立するカードゲーム見てもらえば分かるかと。
猫も杓子もカードゲーム。モデルを真似ることで比較的容易に作れて利益出せることに繋がるので、気持ちが分からなくもありませんが...*1

IP関連の問題で、大きくクローズアップされたのがGREEMobageの訴訟合戦ですかね。
http://gigazine.net/news/20120131-dena-gree/

ソーシャルゲーム同士の問題以外に、既存のコンテンツを丸パクリしたと思われるような事案もありました。
http://getnews.jp/archives/115930

ガジェ通記事なので、確かなソースと言えるがどうか分かりませんが、雰囲気はよく似てますよね。
果たして、ここまで似せる必要性はあったのだろうか...
ともかく、知的財産は大事にしたいものです。

むしろ広告業界用語

  • グロス金額

どうやら広告業界の用語らしい。
ググると、広告で売り上げた金額の全てを指すもの、と出てきます。
商品の提供単価を算出する上で、かかった経費等も含めた価格が考慮されますが、これがグロス金額となるようです。
ソーシャルビジネスで言うと、広報料や、サービスを載せるプラットフォーム使用料などを、含めて算出された金額が該当します。似た言葉にでネット金額というものがあります。

  • ネット金額

グロス金額とは異なり、かかった経費を除いた金額を指すもののようです。
広報料や、プラットフォーム使用料を除いた、純粋な売上をネット金額とするそうです。

  • CRM(Customer Relationship Management)

顧客関係管理のこと。元々は、「ITを使って顧客データを分析し、顧客毎に最適なサービスを提供することで顧客との信頼を深める」手法として使われていました。パーソナライズ化とかあの辺の考え方ですかね?
ソーシャルビジネスにおけるCRMは、インターネットを通して受け取ったエンドユーザーの声を拾い上げて、サービスの向上を進めていくのに使えそうです。FacebookTwitter等に企業が進出しているのは、このCRMにあたると考えています。

  • インプレッション

広告がユーザーに見られた回数を指します。大抵、「月間IMP」とした月単位の総数が使用されます。
広告主からの広告料は、この数値で計算され支払われるんでしょうか?

  • PV

これは説明不要ですかね。ページビューです。
ページにアクセスされた総数を計上します。

  • LP(Landing Page)

Web広告を開いた時に、商品説明のためのページが表示されますよね?
ランディングページと呼ばれ、Webマーケティングの一手法として用いられています。
広告主体で収益を得ることが多いソーシャルビジネスでは扱うことが多い用語だと考えられます。
このLPを最適化して、アクセスからの収益を得る割合を高めることを、LPO(Langing Page Optimiztion)と呼んでいます。

  • CVR(Conversion Rate)

広告業界の用語で、サイトに訪れたユーザーのうち実際に購入を行った比率を指します。
これが高い程、より多くの広告効果があったと判断できます。

CVR = 購入者 / ビジター総数

価格が低いもの程購入の障壁が下がるため、その分CVRが高くなりがちです。価格が高いものは逆に作用します。

  • CPA(Cost Per Acquisition)

顧客獲得単価のこと。もともとはアフェリエイト広告によって商品購入に至ったユーザー一人あたりの売上を指します。
ソーシャルビジネスでは、顧客を一人捕まえるのにかかったコストを示します。
例えば、CMを500万くらいで打って1万人ユーザーを得ると、CPA = 500万 / 1万 = 500円/人となります。
この指標を用いて、行なっている集客方法の効果を比較し測定することができます。

  • CPC(Cost Per Click)

お馴染みのクリック単価です。もともとはアフェリエイト広告をクリックした際の料金を指します。
ソーシャルビジネスでは、1クリックされるのにかかったコストを示します。
似たものにCPI(Cost Per Install)と呼ばれるものがあります。こちらはその名の如く1インストールされるのにかかったコストを示します。
CPA、CPCが低ければ低い程、集客のコストパフォーマンスが優れていることを示します。

ここからソーシャルビジネス用語

  • SAP(Social Applipcation Providor)

ソーシャルアプリを提供している企業のことを指します。ソーシャルゲーム企業にも使われているようですが、SGP(Social Game Providor)と呼ぶ動きもあるようです。
http://blogs.itmedia.co.jp/sakamoto/2010/08/sgpsap-81e6.html

今現在はどっち使ってるんでしょうね?SGPは聴いたこと無いから、今現在もSAPと呼ばれているんでしょうか?

  • インストールUU

実際にアプリをインストールしたユーザー数を指すのかな?UUは、Unique Userだと思う。
この数値は実際にアプリを利用していない場合でも、インストールさえされてしまえば計上されるようです。 このインストールUUに、実際の利用率を乗算することで利用UUが算出できます。
更に利用UUにエンドユーザーの課金率を乗算すると課金UUが出され、これに後述する「ARPU」を乗算すると最終的な売上が計上できるようです。

  • MAU(Monthly Active Users)

まんまですね。月間のアクティブなユーザー総数のことです。
アクティブユーザーの定義は企業によって差がありますが、MAUはひと月で一回以上サービスを使ったユーザーをアクティブユーザーとして計上します。
似たものに、DAUっていうのがあります。こちらはDaily Acitive Usersのことで、一日でサービスを一回以上使ったユーザー数が計上されます。
MAUにおけるDAUの割合が高ければ高い程賑わっているサービスを示すそうです。Twitterがそうですね。

  • LTV(Life Time Value)

顧客生涯価値を指します。ここで言われる「生涯」とは、エンドユーザーがソーシャルサービスを使う残存期間を意味しています。TwitterFacebook等、ユーザーが長く使うサービスはLTVが高いです。
一方、ソーシャルゲームのように、短期でユーザーが離れていく傾向にあるものはLTVが低くなります。
長い間ユーザーがサービスを使用することでコンテンツの購入可能性が増えるため、これを重視するサービスも多くありそうです。

  • 課金率

利用ユーザーが、サービスの対して課金しているかどうかを表します。これはソーシャルゲーム運営会社が注視する指標ですね。
ちなみに、国内の代表的なソーシャルゲームプラットフォーマー(MobageGreeMixi)の課金率は、それぞれ、 11.3%、14.2%、6.39%となっています。Greeが少し抜け、広告収入主体のmixiが落としているようです。
http://mmd.up-date.ne.jp/news/detail.php?news_id=609

  • 継続率

利用ユーザーが、サービスの利用を続けている割合を示すもので、主に一定期間経過した後もユーザーがサービスを利用しているかどうかを調べるために使われます。
新規ユーザーが多くても継続率が低ければ、売上は見込めないことになります。
ソーシャルゲームでは頻繁にイベント打つことがありますが、あれは継続率を維持するためのものだと思っていたりします。長く使われてこそ!ですね。

  • ARPU(Average Revenue Per User)

ユーザー一人辺りの課金金額平均を指す。元々は携帯電話業の加入者一人辺りの月間売上高を指していた。
課金金額合計 / ユーザー数 = ARPU となります。後述するARPPUとは異なって課金ユーザー一人あたりの金額ではありません。広告ARPUや、販売ARPUなど複数の種類があります。
ARPUが高ければ高い程、そのサービスは収益を生んでいることになります。

  • ARPPU(Average Revenue Per Paid User)

課金ユーザー一人辺りの課金金額平均を表します。ARPUとはその名の通り、課金ユーザーか、ユーザー全体かで使い分けられます。ARPPUが高い程、コンテンツに多くの金額を払うユーザーがいる=ヘヴィーユーザーが多数であることが分かります。
これが顕著に高いのは、Mobageアイマスですかね。重課金の人の話を聞くととんでもない額を注ぎ込んでいるっぽい...

意外と知らない用語があった

まだ聞いたこと無い用語ありましたが、重要なところはカバー出来てると思います。
改めて調べてみると、ソーシャルゲーム関連固有の用語ってそれほど多くない印象ですね。広告業界関連の用語が思った以上にあったのが意外でした。

しかし、知らない単語がこんなにあったとは...この辺の記事を読む上での必須知識なので、これを契機に覚えてしまいたいです(`・ω・´)

*1:カードゲームが主になるのは、ハード的に複雑なことができないって理由もあります。

Visual Studio 2008でASP.NET MVCを使う

VS2010では標準で対応しているASP.NET MVCですが、VS2008では追加パッケージを導入しないと使用することができません。
VS2010を購入すれば早い話ではあるのですが、現在手元にはVS2008しかない*1ので、VS2008で開発環境を整える方法まとめておきます。

ASP.NET MVCの追加パッケージは以下から取得します。VS2008で使える最新版はMVC2なので、それ用を取得しましょう。
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=22079
[AspNetMVC2_VS2008.exe]を選択して、インストーラをダウンロードしましょう。

ダウンロードしたインストーラを実行すると、実行エラーを示すダイアログが表示されることがあります。
[Detail]で詳細な情報を確認すると、VS2008のSP(サービスパック)のインストールが要求されているようです。

調べてみて分かったのですが、VS2008のSPはWindows Updateで入ってきません。そのため、別途導入する必要があります。
SPのパッケージは以下から取得できます。
http://www.microsoft.com/downloads/ja-jp/details.aspx?familyid=fbee1648-7106-44a7-9649-6d9f6d58056e
インストーラを叩いて暫く待てば、SP導入が完了します。
SPを導入したら、Windows Updateを実行して、SP1の修正パッチ等を当てておきます。
ここまでで、導入の準備となります。

導入の準備が終わったら、ダウンロードしておいた[AspNetMVC2_VS2008.exe]を実行して、ASP.NET MVCを導入します。
exe実行時に、同意を得る画面が表示されるので、Acceptを選択してインストールを継続します。
インストールが終了したらVS2008を開き、新規プロジェクトからMVCプロジェクトが作成できるか確認してみます。

はい、追加されていますね。
MVCを選択してプロジェクトを作成すると、メッセージを表示するだけの画面が作られます。

後は、好きな用にコーディング進めれば問題ありません。

今回はここまで。

*1: はやく2010に更新したい(´;ω;`)