初めに
CYBIRDエンジニア Advent Calendar 2015 1日目担当の @gotyoooo です。
CYBIRDでゲームインフラ部という部署に所属しています。
今年もアドベントカレンダーをやることになり、カレンダーを事前に埋めるためにとっておいたらそのまま1日目担当になることになり、非常に焦りながらこの記事を書いてます。
最初に
- 弊社のモバイルゲームにおけるインフラ環境について赤裸々に語ります
- 浅く広く環境の紹介がメイン
前提
- ここ1年ぐらいで新規リリースしたゲームの商用環境のインフラ周りの構成や構築情報を紹介
- もちろん1人でやっているわけではないので、私以外の担当領域も含まれます
構成
オンプレミス?クラウド?
- どちらもあります。以下の様なメリット/デメリットを見て選択
オンプレミス | クラウド | |
---|---|---|
構築(Bootstrap) | ☓ ラッキングや配線・OSインストールなどのスケジュールも考慮する必要がある | ◯ インスタンスを立てるだけ |
運用 | ☓ 機器自体の故障なども踏まえた運用が必要になる | △ 自動化が進めば楽 |
コスト | ◯ クラウドに比べて高性能なサーバが安い | ☓ リザーブドインスタンス等を使いコストを抑える方法もあるが、転送量が結構高い |
スケール性 | ☓ 物理サーバを購入するには時間がかかる | ◯ 足りなければすぐ作れる |
オンプレミスを選択するとき
- トラフィックをある程度事前に予測できるゲーム
- (例)量産型ゲームや、シリーズ物
クラウドを選択するとき
- トラフィックが読みにくいゲーム
- (例)完全新規開発ゲーム
- 日本以外へリリースするゲーム
LAMP+αの環境
監視
- Zabbix
- デフォルトの監視項目はもちろんのこと、自作した監視スクリプトやローレベルディスカバリ等を駆使し、わりと細かく数値を取って閾値を決めている
- アラート発生時はメール送信、CahtWorkでメッセージ通知で知らせるようにしている
- MONyog
- ボトルネックがMySQLであることがほとんどなので、MySQLに対する監視を深くするため利用
- また障害発生時のプロファイリングもしやすく、困ったときに利用
- NewRelic
- サーバサイドのパフォーマンス監視用途
- こちらも困ったときや負荷試験時に重宝することが多い
他の特徴
GlusterFS
- 複数サーバでの画像共有
- あるサービスで画像合成をして、その画像を保存するような処理が存在
- 「この画像が既に存在するか?」を確認後、なければ合成処理が行われる
- 処理にある程度CPUやメモリリソースが必要なため、複数台のサーバが必要
- 複数のサーバで同じ画像を合成するのを防ぐために保存先にGlusterFSで作成したVolumeを利用
- NASストレージが利用できない環境のためのプラン
- 1年半ほど運用しているが、大きな障害は発生していない
- ファイルがなくなっても処理でなんとかなるので「Distributed Volume」を利用
- 容量が大きいストレージを持ったサーバのリソースを効率よく利用
- オンプレ環境の各コンテンツに1台は3TB超えのストレージを持ったサーバが存在
- MySQLのダンプファイルや、ログの置き場として利用するがバックアップさせつつ、さらに大きなストレージとするために「Distributed Striped Replicated Volume」を利用
Fluentd(td-agent)
Docker
- FluentdでログをAmazon S3に転送しているが、各サーバ単体でそれぞれ別でやらせるとポートが枯渇する問題があり中継サーバとして利用
- 受信ポートを分けるために複数コンテナを起動し、1サーバで複数のtd-agentを起動させてコンテンツごとの中継先にしている
- Chefレシピ等のTDD用途にも利用(後述)
Serf
- 各サーバのServerspecテストのためにロールを持ったり、色々情報もたせたりしてる(後述)
-
内部DNS設定がめんどくさいからhost名で名前解決するために/etc/hostsファイルにSerfクラスタに入っているサーバ情報を記述
LVS
- オンプレミス環境のロードバランサー
- アプライアンス製品は使ってません
- Heartbeat + Pacemaker + ldirectord
- 構築後SplitBrainで問題になったことがありPacemakerのSTONITH機能も利用
構築
Chef/Serverspec
Cookbook/Roleの方針
- Cookbookはほとんど内製開発
- Chef Supermarketのものもあるが、ラップしたようなCookbookも作っている
- Recipeにロジックを入れない
- 管理が煩雑になってしまうのを防ぐ
- 広く使えるようなものではなく、わかりやすいことを優先している(多種OSに対応するようなものにはしていない)
- インストールするソフトウェアのバージョンや各種パラメータはRoleで管理
- data_bagを利用し暗号化
- Roleを見ればどのような環境であるか一目瞭然になる
- 以下はRoleのイメージ
TEST_ROLE.json
{
"name": "TEST_ROLE",
"description": "とある開発用WEBサーバのRole",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
"user": {
"user_list": {
"test": {
"password": "暗号化したパスワード"
}
}
},
"visudo": {
"sudoers_d": {
"test": "test ALL=(ALL) ALL",
}
},
"httpd" : {
"httpd_conf": {
"prefork" : {
"start_servers" : 8,
"min_spare_servers" : 5,
"max_spare_servers" : 20,
"server_limit" : 256,
"max_clients" : 256,
"max_requests_per_child" : 1000
}
},
"application" : {
"hoge.jp.conf": {
"listen_port": 80,
"contents_user": "test",
"document_root": "/home/test/app/current/public",
"server_name": "hoge.jp",
"server_alias": ["hoge.jp", "www.hoge.jp"]
},
}
},
"php" : {
"version" : "php55",
"packages" : ["php", "php-cli", "php-common", "php-devel", "php-gd", "php-mbstring", "php-pear", "php-pdo", "php-opcache", "php-mysqlnd"],
"php_ini": {
"date_timezone": "Asia/Tokyo"
}
},
"serf": {
"tags": {
"chef_role": "TEST"
}
},
"zabbix_agent": {
"version" : "2.2.10-1.el6",
"zabbix_server_ip": "ZabbixサーバのIP"
}
},
"chef_type": "role",
"run_list": [
"user",
"sshd",
"visudo",
"php",
"httpd",
"zabbix_agent",
"serf"
],
"env_run_lists": {
}
}
構築はknife-soloで
- Jenkinsでknife-solo用のJOBを作り実行している
- Serverspecでテストを行うようにしている
Chef開発環境
- GitHub上でPull Request開発
- Pull Request時にServerspecテストが走る
- テストが通った時点でレビュー依頼->OKならマージ
- Serverspecテストが実行される流れ
- Jenkinsの「GitHub pull request builder plugin」でhook
- 新規Dockerコンテナ起動(空のCentOS)
- 2に対してknife-solo実行(roleはbranch名をつけたテスト用roleを作成している)
- 3に対してServerspec実施(3のロールのAttributeを読み込みテスト)
- テスト結果をGitHubに通知
毎日Serverspecテスト
- 運用中のサーバにも毎日Serverspecテストが走る
- 適用するChefのロール名をSerfのタグに持たせている
- そのロールを元にテスト実行、失敗したらChatWorkへメッセージ通知
Kickstart
- オンプレミスの物理サーバに対して、OSインストールからknife-soloを実行できるようにするまでを担当
- PXEネットワークブートさせて実行
未来へ向けて考えていること
HTTP/2への移行
- APIでJSON返すだけならそこまでいらないが、いわゆるWEBサイトなら効果絶大なはず
- nginxもHTTP/2サポートしたので今こそ!という気持ち
chef-soloからchef-zeroへ
- まぁ・・・ね。
- 今Chef開発環境はChefZeroでやっていたりするが、それを商用環境でも適用したい。というかやりましょう。
Chefによる単体のサーバごとの構成管理だけではなく、全体構成管理も
- Terraformかな。
負荷試験方法の進化
- 現状はJMeterを利用
- テストシナリオを作るのは大変
- JMeterProxyを利用する手もあるが、それでは事足りない
- リリース前の本番環境に負荷をかけているので、運用中に実施は実質不可能
- ここはまだまだ模索中
ここまでのまとめ
- 変わったことはあんまりしていない
- 導入・運用に対するコストを踏まえて適切に選ぶことを重要視している
最後に
投稿日前日に書くと辛いのでみんな計画的に書きましょう・・・
CYBIRDエンジニア Advent Calendar 2015 明日は、 @keitarou の「JavaScriptにおける非同期処理の歴史」です。
@keitarou は後輩でありながら、プログラムに関しては私の先生になってくれてるすごい奴です。
乞うご期待!