第三回ライブドア・テクニカルセミナーに行ってきました

クラウド時代のWebストレージ/データベース戦略

自己紹介
クラウド
  • SaaS
  • PaaS
  • laaS
  • パブリック
利用者から見て
  • 物理的なサーバ、ネットワークを意識しない
  • 高可用性
  • 柔軟な課金体系
  • Amazon S3,CloudFiles...
提供者から見て
  • 高価な機器に依存しない=>スケールアウト
  • リソース有効活用でコスト効率
  • 管理、運用の手間の効率化
ライブドアの考え
  • 物理サーバリソースは投資済み
  • 提供しているサービスはSaaS的なもの
  • さらにコスト効率をあげたい
  • (l|P)aaS的なクラウド環境を自分達で付くって自分達で使う
実例
  • Webサービスのメディアストレージ
  • 安価に容量を拡張可能
  • データの冗長化/高可用性
  • 実際の構成は"あまり"意識したくない
    • アプリとストレージ双方でちょっとくらい意識した方が良い
名前
  • なかなか決まらない、最初のクラス名が決まらなくて2時間とか...
  • STFに決定
    • Step over Toled with Facelock?
  • STorage Farm
  • HTTPを利用した分散ストレージ
  • 参考にしたプロダクト
特徴
  • シンプルなkey-value
  • クライアントからは巨大なストレージプールとして見れる
  • 普通のサーバを使用して拡張可能
  • データのレプリケーション
  • apacheモジュールベース
Cons
  • ファイルシステムとしてマウントできない
    • コードの書き換えが必要
    • FUSEとかつかったらだめかな
  • すでにあるオブジェクトに追記できない
Design
REST
  • GET/PUT/DELETE
  • Bucketの作成/削除
  • Objectの取得/作成/更新/削除
  • レプリカの作成数はヘッダで指定
    • オリジナル画像は3つくらいレプリカが必要
    • サムネイルは再コンバートできるから2つでいいかとか
Example

PUT /ikebe/picture.jpg HTTP/1.1
X-Replication-Count: 3
Content-Length: 10240<内容>

基本戦略
CAP定理
  • Consistency
  • Availability
  • Partition Tolerance
  • 一貫性を捨てる
MySQL

Dual Masterが使えるようにAutoIncrement等使ってなくて
PerlのロジックをCにコピペして実装

MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.18 その他の関数
UUID は、スペースおよび時間においてグローバルに一意の数字としてデザインされています。UUID() へのふたつの呼び出しは、互いに接続されていない別々のコンピュータ上で行った場合でも、それぞれ異なるふたつの値を生成することが想定されます。

  • URI->実態のマッピング/メタ情報
  • テーブル
    • strage ストレージノドマスタ
    • bucket バケット
    • object URI<->オブジェクトID
    • entity オブジェクトID<=>ファイル実態
mod_stf.c
  • バックエンドストレージへのリクエストディスパッチゃー
mod_stf_strage.c
  • mod_dav_fileに似ている
  • GET/PUT/DELETE メソッドを受け付けてファイルの読み書き
  • GETはdefault-handlerに任せ
  • PUTはRecursiveにディレクトリを作成
  • 同一ファイル名での上書きはできない
    • 更新は一回消して内部的には別ファイルを作成
TODO
  • MySQL依存からの脱却
  • 特定のノードの使用(SSD対応)
    • Webなんて、最新と人気なものが高速に返せればよい
  • オープンソースでの公開
質問
  • ストレージのサイズはどのくらい?
    • MAX:20TB-30TB位
    • 運用:10T程度
    • 月に1Tづつ増える
  • mogile FSでは何がダメでSTFなのか

ライブドアクラウド風サービス

概要

ライブドア、“クラウド的”サービスを3月開始へ - ITmedia NEWS

  • クラウドをやってみよう
    • ライブドアの強みを生かしたサービスにしたい
      • 自社色をだしたい
      • 安価に
  • ライブドア流とは
    • Webサービスに強い
    • DataHotelというデータセンターを運用している
      • 回線、インフラを自社で運用している
利点

※AmazonEC2の利用中の企業は大部分はExtraLargeを契約しているらしい

    • 強いサーバが必要?

ニーズ

  • Webフロントサーバをクラウドにする
    • サービス規模に応じて、短時間のリソース増減が可能
  • バックエンドは専用サーバ
実装決定までの試行錯誤
技術
目指すもの
  • スケールアップ,スケールアウト
    • ユーザ操作で即時に行うことが
  • なぜ?
    • 急激なトラフィック増加があるサービスへの対応
    • スモールスタートの規模を最小にとどめて個人開発者の支援
    • 人的リソース温存
TODO
  • LVS DSR構成
  • Auto Scalling
    • Auto Scaleも今後対応予定
  • PC3?
質問
  • DSRでも裁けなくなったらどうする?
    • 1顧客の量を制限
    • 現状はLVSには余裕があるが、今後増えてきた場合はセットごと追加
  • APIを公開することは?
    • 今後は必須の条件になってくる
  • お値段は?
    • EC2よりも性能良くて(メモリ1GB)5,000-6,000
    • EC2はネットワーク従量課金であるが、PC2は?
      • 社内で賛否両論
  • インスタンス監視
  • インスタンスは月額?時間課金?
    • まだ話がいっていない
    • ログをとっているので1秒単位でも1時間単位でもできる
      • お客さまの都合により柔軟に
  • インスタンスの重複
  • Migration先はシステムが勝手に決める?
    • 決めてない
    • お客さんに選んでいただいてもよいかな?

livedoor Readerの新機能とは?

自己紹介
Livedoor ReaderのStreaming API

livedoor Readerサービス終了のお知らせ

  • livedoor readerのクロールしているフィードの更新情報をリアルタイムに取得
  • キーワードに絞りこみ
ポイント
  • 外部ドメインでも動く
  • 非公開フィードの記事はでない
リアルタイム
  • Readerがクロールしたタイミング
Streaming APIのサーバサイド実装
  • クローラ
  • apache
    • nginx+Plackに変更予定
    • 5+2台
  • mysql
  • memcached
  • perl
  • Q4M
    • ジョブ管理
    • MySQL(64bit)*2台
  • TokyoTyrant
    • memcachedの代替
    • HashDB*7台
    • キャッシュ
  • InnoDBPlugin
    • 改良されたInnoDB
    • データを圧縮してメモリ利用効率向上
  • Nginx
    • ロシア生まれのWebサーバ
    • Streaming APIのフロント
    • long-pollコネクション可
  • PSGI/Plack
  • 負荷試験ツール
    • Coroで作られたDoSツール
    • 大量のコネクションを張る
  • 記事データサイズ
    • テキストだけで1TB
    • 過去記事の削除->やってない
      • 件数不明
  • 対象:180Mフィード
  • 更新があるフィードは約1時間
  • クローラ
    • 4台
クローラの処理
  • Q4Mをつかってバケツリレー
  • daemontoolsで管理
  • Broker
    • cronで1分置きに起動
    • 必要なデータを予めmemcached
    • クロール対象のfeedをQ4M
  • Fetcher
    • Coroを使った並列処理
    • ドメイン毎に同時接続数を制限
    • URLにたいしてHTTPでとってくる
  • Parser
    • 解析する
    • XML::LibXML+XML::Liberal+独自
    • CPUパワーに依存
  • Updator
    • 更新されたものを見付けてアップデータ
    • データベースの処理速度に依存
    • 並列数は1台あたり10
Front (古いブラウザ)
Front (IE)
  • window.name+IFRAME間送信

ニフティクラウドの紹介と今後の展望

Loading...

クラウドをやる理由
  • 大規模で継続したサービスを提供可能な資金
  • お客さんをいっぱいもっている
  • いままでの技術をうまく流用できる
内部基板

VMWare+L2網+IPストレージ

  • 思想
  • 機器
    • マルチベンダー
    • 数百TB
疎結合
  • アプリの部分はモジュール化されており、基板自体を意識していない
  • ネットワーク、ストレージ、サーバ、仮想OSはお互いをほぼ意識すること無くメンテナンス構成変更が可能
  • 物理サーバはメモリとCPU箱 DISKは不要
  • ラックにサーバをいれればCloud Ready
規模の経済
  • ユーザ毎や環境ごとに特殊なことはしない
  • 大量、一括購入によるコスト削減
  • ニフティと一体の基板
  • 運用が物理台数や、仮想マシン数に比例しない

Android/XPERIA勉強会にいってきた

Xperiaの紹介とSEMCによる開発者支援活動(ソニー・エリクソン様)

  • Android有償で売って良い国は11ヶ国
  • Symbianは22ヶ国
  • 日経BPのコンテストで優秀な人は、海外の人ともやりとりできる
  • 4月中に発売予定!!

モバイルの祭典Mobile World Congress2010(バルセロナ)レビューとメディアからみたAndroidの魅力(日経BP

  • 世界最大のモバイルイベント
  • 2010/2/15-18
  • バルセロナ スペイン
  • 49,000人の来場
  • 出展1,300
  • LTE Long Term Evolution 新しい通信サービス

Androidアプリ開発 vs iPhoneアプリ開発(リクルート様)

スピーカー
各言語
iPhoneアプリ
  • hotpepperのiPhoneアプリ
    • 2008/7 Web版
    • 2008/9 AppVer0.3
      • WebViewを付けただけ
    • 2009/9 AppVer1.0
Androidアプリ
  • もうすぐリリース予定(HotPapperアプリ?)
    • 2009/12末〜勉強
    • 2009/01 Xperia発表会 デモ
    • 2009/03 リリース予定
    • Twidroidと連携か?
アプリ間連携
  • Android
    • 複数アプリが同時に動く
    • 他のアプリいいって、戻ってくることができる
      • iPhoneに比べるとすごくよい仕組み
    • 他のアプリからのインテントを受け付けることができる
  • Android
    • ひとつのアプリが動く
ユニットテスト
メモリ
  • Andoroid
    • Javaのメモリ管理
    • エラーがわかる
  • iPhone
    • シビア、無言で落ちる
解像度
  • iPhone
    • ひとつの解像度
  • Android
    • 解像度が複数存在
    • pxではなく、dipを使おう
    • 縦横比が違うのは厳しい
UIガイドライン
ストア
開発環境
  • iPhone
    • Mac必須
    • 実機テストい$99
  • Android
    • つないだだけで実機にInstall可能
    • つないだだままでDebug
iPhone vs Android!?

開発者には楽しい状況

Androidアプリ開発体験記(テックファーム様)

自己紹介
セカイカメラに関して
シンプルがぶちささる
  • ユーザが一目でこれってこういうアプリだというのが伝わるアプリ
    • マーケットでも3行説明で理解できる
UIは実際描いてみる
  • 853x480の紙を用意する
  • バイスに貼っ付ける
  • シャーペンを用意する
  • 画面を描いてみる
  • ピクトリズムは全部で50枚位描いた?

機能ごとに理由を付ける
  • 何故?を繰り返す
    • 無駄な機能を減らす
    • なんでこの機能が必要なのか?
PlayNow(ソニーエリクソンさんのPlayNow)

Xperiaタッチ&トライ



BPStudy#30 Django vs Rails

Intruduction to Rails

Akira Matsuda (@a_matsuda) | Twitterさん
Opinioned Software

特に2つの思想

  • DRY,CoC

DHHがイケメン天才プログラマ
Rails3ではViewがHTML5採り入れる

Railsを使っているうちに筋の良い習慣や技術が自然に身につく

Head First Railsがお薦め

O/Rマッピング

ActiveRecord
  • モデルのクラスとテーブルが1対1
  • モデルのクラスのなまえとテーブルの名前が勝手に紐付く
  • カラム名がクラスのattributeと対応、クラスの中身が空でもアプリが動く
  • Djangoはモデルからスキーマを作る
  • Railsはモデル中心主義
  • DjangoはFormはFormで別
  • Validation
    • RailsはモデルでValidation
    • DjangoはForm回りでValidation
    • Djangoは複数の画面から同一モデルをいじる場合に問題では?
      • Formの継承でなんとかなるのでは
    • Rails3ではモデルじゃないフォームも対応
      • 全てRESTで表せない事もある

テンプレート

  • Djangoはテキストテンプレートエンジン
    • Django専用のエンジン
    • 基本的にプログラマブルな記述は使えない
    • テンプレートはロジックを絶対に含ませない
    • じゃロジックが必要なときは?
      • コントローラでがんばる
      • テンプレートタグを自作する
    • テンプレートタグの作りやすさ
      • 支援APIがある
      • 2,3行とか
  • テンプレート継承ができる
  • Djangoテンプレートエンジン以外もOK
  • Djangoテンプレートエンジンの残念な点
    • Pythonなのに閉じタグが必要
      • デザインなとの協業
    • 代替テンプレートエンジンは?
      • Jinja:Templateがテンプル(寺)だから神社
    • コンパイル済みのものを使えない
  • Rails erb
    • HTMLっぽいテキストだが、なんでもあり
      • 一歩間違えるとPHPみたいに...
    • erb以外のテンプレートエンジンは?
      • 20世紀っぽい
      • hamlとかある

デプロイ

  • Railswsgiがなかった
    • rackが最近作られた
    • Railsはrackの上で動く
    • mod_rack(Passenger)がメジャー
      • nginxでもapacheのモジュールでもコンパイルできる
      • 動作を安定していて、導入も簡単
    • fcgiでも遅い
  • Djangofcgiを結構使う
  • fcgiが落ちたときとかめんどい

開発環境

Django
  • easy_installでもいける
  • Windowsでも全然動く
    • Windows2003サーバで動かしている人も
  • DB
Rails
  • gem install railsだけでいける(3 words!!)
  • ruby安定系1.9.1は使ってはならないRuby Railsが動かない
    • 日本人にとっては動かない
    • 動く地域の人もある
  • ruby1.8.7がよい
  • Windowが推奨できない
  • まずはMacを買うことから!!
  • DB
    • MySQL第一DB
      • 本番はこっちが推奨
    • 最近SQLite3
      • 開発のときには便利
    • PostgreSQLでも動く
    • Oracleとかはイバラ道
      • Rails1まではサポート
      • Rails2.0からはずされる
      • Rails3ではまたSupported
エディター
  1. Vim
  2. テキストエディット?
  3. emacs
  4. aptana(eclipse)
    1. 動きがもっさりしている
  5. NetBeans(IDEのうちでは一押し)
  1. emacs
  2. pyscripter
  3. py-dev
ローカライズ
  • Django
    • 設定すれば管理画面も日本語化
      • gettext
      • gettext関連のツールが使える
      • gettext使っている歴史も長いし
  • Rails
    • 英語をしゃべる人のフレームワーク
    • Rails i18nプロジェクトが加わって2.2から世界のフレームワーク
      • gettextではなくてyaml
      • gettextは難しい、コンパイル
      • fuzzyという概念はない
      • YY/MM/DDとか国によって日付の違いもLocaleでみて切替える
    • 翻訳ツールとかあるの?
      • 便利なジェネレータがある

プラグイン

  • Rails
    • プラグイン
      • いろんな人が後から追加できる柔軟な機構が用意されている
      • ちょっと作ったらなんでもgithub
    • 開発者が多い
  • Django
    • 管理画面
      • デバッグなどもアプリケーションがたくさんある
    • bitbucketかgithubを探せばDjangoもなんでもある

マイグレーション

設計思想、開発サイクル

  • Rails 3.0
    • バージョンアップが頻繁
      • 仕事で使うにはバージョンアップに付いていく
    • 後方互換
      • 身軽
  • Django 1.1

SocialWeb Conference vol.5 〜OpenSocial Night #2〜 に行ってきました

GAEとソーシャルアプリの話

  • @tmatsuoさんの話

AppEngineを使ったソーシャルアプリの開発と運用 by Takashi Matsuo on Prezi

GAEの良い点
  • ほとんど落ちない
  • アクセスが増えたら勝手に分散してくれる
  • BigTableが使える
    • データが増えても参照速度が変わらない
      • シャーディングやパーティショニング不要
  • 値段
KayFrameworkの利点
  • GAEにはDjangoがあるがKayの差別点
    • Djangoそのままでは動かない
      • patchを当てないといけない
    • 機能が多すぎ
    • Django GAE上でcold-start upが重い
    • DjangoRDB用に作られている

Django-nonrel - NoSQL support for Django | All Buttons Pressed

OpenSocialHost

OpenSocial-Host.pdf - Google Drive
HeartRails - ハートレイルズ - 新規事業開発のエキスパート

  • HeartRailsの人
  • HeartRailsはスタッフが全て在宅勤務!!
  • OpenSocialHost
JavaScript API(PC/Mobile)
ファイル,KVS
オートスケーリング,有人対応
管理コンソール
    • 単一機能のみ利用可能
    • 課金モデル
      • 従量課金
      • JSのみのGAEライク
    • 対応サービス
今後
    • OpenSocialの課金/決裁プラットフォームの提供(今週中)
    • Cron機能
      • サーバサイドのJavaScriptを割り当てる
    • 国際化
    • アプリケーションテンプレート
      • アプリの雛型を提供
      • 管理コンソール上でカスタマイズ可能
    • 汎用PaaS
質問
  • KVSの正体はなに?
    • 現在はHaertRails内のハイスペックサーバ
    • 実はRDB
  • ファイルAPIも課金?
実績
  • 数万User程度
    • サーバの1/100のリソースも使ってない

大規模SNSにおけるソーシャルアプリの運用マネタイズ

直接課金
  • mixiポイントやモバコインでお買物
  • おもしろさ
    • 成長
ゲームのソーシャルならではの強み
  • 友達
  • 他ユーザ
時間消費型成長
  • モンスターを戦って経験値を積む
金銭消費型成長
  • お金を払うことによって手に入れるもの
マネタイズに必要な安定稼働
  • ゲームにもっとも重要な事絶対安定
  • 一度落ちたゲームへの復帰はかなり難しい
巨大SNSならでは
  • 想定すべき負荷がすごい
  • 数秒以内に200返却MUST
  • アクセス数のピーク
    • リリース直後がお祭り
    • イベント直後、日付変更直後、定時アイテム配布時
  • ソーシャル、信じられない位ユーザが
  • ec2
    • 西海岸にある
    • 西海岸<->日本で2秒
  • うまレーシング
    • うまを撫でる機能
    • MySQLでは耐えられずTTに移行

appengine ja night #5に いってきました

Kayの人

@tmatsuo

正規化しすぎるとだめ

class Tag(db.Model)
  name = db.StringProperty()
  count = db.IntegerProperty()

class Post(db.Model)
  tags = db.ListProperty(db.Key)
  body = db.TextProperty()

JOINが使えないので検索はこんな感じ...

t =Tag.get_by_key_name(tag_input)
if t is None:
  raise Http404
posts = Post.all().filter("tags = ",t.key()).fetch(200)

上記の場合はPostモデルにStringListを持った方が、無難

  • 質問
    • Q:タグ名を変更する場合は全Postをなめて変更するのか?、
    • A:TaskQueueかRemoteAPIで全部を変更するか,Modelにバージョンを持つ
      • 最近1.3.1でクエリが早くなった->複数クエリを発行することに躊躇する必要はなくなった?
      • GETとQueryは変わらない
      • KeyでGETは18msec程度
      • KeyでQueryは23msec程度(ヒットが1つの場合)
      • 場合場合によってモデル設計を考える

不要なIndexを付けないように

db.StringPropertyはデフォルトでIndexが付いてしまう

class Foo(db.Model)
  prop1 = db.StringProperty()
  prop2 = db.StringProperty()
  prop3 = db.StringProperty()
  prop4 = db.StringProperty()

インデックスを付けない

class Foo(db.Model)
  prop1 = db.StringProperty(indexed=false)
  prop2 = db.StringProperty(indexed=false)
  prop3 = db.StringProperty(indexed=false)
  prop4 = db.StringProperty(indexed=false)

インデックス名を短くする

class Foo(db.Model)
  prop1 = db.StringProperty(name="p1")
  prop2 = db.StringProperty(name="p2")
  prop3 = db.StringProperty(name="p3")
  prop4 = db.StringProperty(name="p4")

GQLを書いた場合kindが必要だが
kind名を短くする

@classmethod
def kind(cls)
  return "z"

参考
http://code.google.com/intl/ja/appengine/docs/python/datastore/gqlreference.html

  • 無料で保存できるデータ容量は限られているのでこれらをできるだけ短い名前にする
    • app engineの管理ツールでDBのうちどれくらいがメタデータかを見ることができる

ログイン - Google アカウント

  • モデルにIndexが何個あるかによってもパフォーマンスが変わる 1個Indexが追加される毎に16msec(cpu time)
  • 検索に使わないのであればIndexを無駄に張らない

db.StringProperty(indexed=false)
から
db.StringProperty(indexed=true)
に変更したばあいfalse時代のものは検索に反映されない!!
http://code.google.com/intl/ja/appengine/docs/python/datastore/queriesandindexes.html

Exploding Index

q = MyModel.all().filter("contents ="."word1").¥
                  filter("contents ="."word2").¥
                  filter("contents ="."word3").¥
                  order("-created")
entries = q.fetch(10)

このクエリにたいしてcontents,contents,contents,createdというインデックスを作ろうとする
content数xcontent数xcontent数xcreated数 の膨大なIndexを作ってしまう(Max 5,000件)

q = MyModel.all().filter("contents ="."word1").¥
                  filter("contents ="."word2").¥
                  filter("contents ="."word3").¥
                  finter("created_month=".this_month)

entries = q.fetch(1000)
entries.sort(cmp=lmbda x,y: cmp(x.created,y.created)

on memoryでsortするように心がける
Composite Indexを作ると危険!!

  • イデア
    • Keyに時刻を埋め込むとorderが不要になる
      • marge joinの仕様でsortされることがおそらく保証されている
  • 質問
    • Q.1000件を越えるInmemory sortは?
    • A.ヒープ領域(100M程度)が許す限りin memoryで可能

Greedy module loading

  • 一部でしか使用しないモジュールは遅延ロードするべき
    • スピンアップはなるべく短く
# -*- coding: utf-8 -*-

from kay.utils import render_to_response

import hoge_utils
import fuga_utils
import moge_utils

def index(request)
  return render_to_response('myapp/index.html',{'message':'hello'})

def hoge(request)
  hoge_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

def fuga(request)
  fuga_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

def moge(request)
  moge_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

先頭でimportしている
apache+mod_pythonの場合はこの方が効率が良い
GAEでは以下の用に 遅延ロードしたほうがよい
許されるスピンアップは10秒程度

# -*- coding: utf-8 -*-

from kay.utils import render_to_response


def index(request)
  return render_to_response('myapp/index.html',{'message':'hello'})

def hoge(request)
  import hoge_utils
  hoge_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

def fuga(request)
  import fuga_utils
  fuga_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

def moge(request)
  import moge_utils
  moge_utils.get_entries()
  return render_to_response('myapp/index.html',{'message':'hello'})

参考

1.3.1の新機能紹介

Transactional Task Queue

http://pixiv.cc/mix3/archives/51343747.html
DBのTransacion内にTaskQueueを積む動作を入れておく
commitが成功した場合にのみ積まれる
不整合が起きにくい

  • 質問
    • Q.TaskQueueは一時間後とか指定できる
    • A.できる etaかcount downで指定可能 正確とは限らないけど。
    • Q.TaskQueueのQueueのサイズに上限がある?
    • A.なし、ただしスピードは同時に秒間20タスクが上限
Cursor

Pagingに使えそう
任意ページに飛んだり、戻るにはもう一捻り

Appstats(Python版のみ)

http://blog.shehas.net/2009/12/11/Kay-appstats

  • 以下のYSlow的なものが見える
    • RPCの統計
    • URLアクセス統計
    • Requestの履歴

app.yaml

  • url: /sats_*

ひがやすをさん

複数のエンティティグループに跨ったTransaction(グローバルトランザクション)

エンティティグループはできるだけ小さく作る

2phase commit

複数のDBに跨るようなTransactionのプロトコル
分散トランザクションに挑戦しよう!

  1. ジャーナルに書きだし
  2. 内部コミット
  3. ジャーナルの適応

appengine ja night #4 Transaction Puzzlers

MacOSXでCUIからアプリケーションを起動する

http://straitmouth.jp/blog/setomits/682が非常に参考になった
このようなエラーがでたので少しだけ書き換えた

$ . .apprc 
-bash: alias: `Address Book.app': invalid alias name

http://gist.github.com/301137