AWS運用における3種の神器

こんにちは。matsです。

 

IMは膨大な量のデータを扱うビッグデータカンパニーでありますが、それと同時にAWSをゴリゴリつかうオートスケールカンパニー(?)でもあります。

ほぼ全てのサーバをオートスケールによって運用しており、高い対障害性と運用の効率化を実現しております。今回はAWSのオートスケールを使って数百台規模のサーバを運用する際に、非常に便利な3つのサービスをご紹介したいと思います。

 

1. Mackerel

mackerel

Mackerelはクラウド型のモニタリングサービスです。最近はサーバのリソースだけでなく、スクリプトによる監視も行えるようになっています。

各サーバで稼働するエージェントにより監視を行うプッシュ型のサービスのため、オートスケールとの相性が非常によく、台数の増加に伴う運用負荷の増加が殆どありません。同様のサービスではDataDogがありますが、SearviceとRoleでサービスを分類・管理出来るという点と、ボリュームディスカウントが効く点からMackerelを採用しております。

また、SearviceとRoleでサービスを分類するというやり方は、残りの2つのサービスでも採用しているため弊社においては非常に重要な概念になります。

 

 

2. Papertrail

papertrail

日本ではあまり聞かないサービスですが、PapertrailはGitHubなどの採用実績のあるログの集約・監視を行うサービスになります。

リモートSyslog形式で投げ込むことにより、複数のサーバのログをまとめてブラウザ上からほぼリアルタイムに見ることが出来ます。(まとめる単位はMackerelのSearviceとRoleに合わせています。)サーバ台数が多いと、各サーバに入ってログを確認するということだけでも大変になってくるので重宝しています。

特定文字列の監視を設定し、Slack等にアラートを飛ばすことも可能です。

また、集めたログはS3に日別で自動アーカイブすることが可能なので、IMではほぼ全てのログをPapertrailに投げ込んでいます。(PT側の保存期間を短くして、S3にアーカイブするといった使い方も可能)

これだけ至れり尽せりな仕様でありながら、数十ドル/月で利用可能です。(検索可能な期間と月間に受信するログの量で変動します)

正直、何でコレが流行っていないのか理解に苦しむレベルのネ申サービスです。

 

 

3. Rundeck

 

rundeck-logotype-512

RundeckはOSSのタスクスケジューラーになります。ブログなどでcronの代替として紹介されていることが多いですが、AWSとの連携により真の力を発揮することが出来ます。

Rundeckはプラグインにより、EC2のインスタンスの一覧を取得可能で、その際に付与されているタグも識別することが出来ます。

Mackerelなどで利用しているSearviceとRoleを適切にタグに設定していれば、そのグルーピング単位でジョブの実行やソースコードのデプロイを行うことが可能です。これにより、ホスト名やIPで個々のサーバを管理する必要がなくなります。

また、アドホックにコマンドを発行することも可能なので、全台のOpenSSLのバージョンを調べるといった使い方も出来たりします。

 

 

PapertrailとRundeckは国内の事例が少ないようなので、別途記事を書こうかと思います。

mackerelのスクリプトによる監視を使ってみる

こんにちはmatsです。

 

以前、こんな記事を投稿しました。

http://tech.im-dmp.net/archives/632

 

強引かつ(´・ω・`)ショボイ方法で監視をしていたのですが、はてなさんが神アップデートをしてくれたので、試したいと思います。

http://help-ja.mackerel.io/entry/custom-checks

nagios-pluginを使ったプロセス監視

 

今回はnagios-pluginsの中にある、「check_procs」モジュールを使ってelasticsearchのプロセス監視を行ってみたいと思います。

 

nagios-pluginのインストール

 

AWS環境(AmazonLinux)なので、yumでいれます。(CentOS等はepelだったかと)

$ sudo yum install -y nagios-plugins-all

 

これで「/usr/lib64/nagios/plugins/」配下にモジュールがインストールされます。

 

mackerel-agentの設定

設定は次のように mackerel-agent.conf に記載するだけです。

 

/etc/mackerel-agent/mackerel-agent.conf

apikey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
roles = [ "service:role" ]

[plugin.checks.elasticsearch]
command = "/usr/lib64/nagios/plugins/check_procs -w 1:1 -c 1:1 -u elasticsearch -C java"

 

アラートの判定ロジックはnagiosを踏襲しているので、コマンド自体はそのままでいけます。

監視状況はmackerel上でこんな感じに確認できます。

mackerel_proc

 

 

気になる点としては、一回エラーを検知すると即発報してしまうのでnagiosのような柔軟な監視設計ができないところくらいでしょうか。

特に問題はないのですが、EC2のAutoScalingでサーバがterminateされる時にプロセスの終了とmackerelの退役処理の間に監視が差し込まれたりして、アラートがあがったりしてしまうことがありました。(nagios等だと即発報とかにはしないので気にならないのですが)

コレに関しては、停止順を精査すればいいだけのことではありますが。

 

mackerelスゲーというお話でした。

PythonでTreasureDataにBulkImportした話

こんにちは、g0eです。

mats氏によって「中の人」の紹介記事が勝手に書かれていることに最近気づきました。javaはもう忘れました。

 

弊社では各種ローデータの収集や一次加工にTreasureData(以下:TD)を活用しています。

tresuredata

そして、アプリケーションは主にpythonで書いていまして、tdコマンドの中を覗く(lessする)とruby派っぽい雰囲気が伝わってくるんですが、pythonでも結構戦えたので紹介したいと思います。

今回のお題は、pythonでTDにtsvとかcsvのファイルをbulk_importした、という話です。 男らしくtdコマンドをsubprocessで叩けばいいんじゃないか、と思わなくもないですが、ちょっとややこしい環境で動かそうとしてうまくいかなかったので、td-client-pythonを使うことにしました。

このライブラリ、コードとコメントを読むと実は結構色々なことが出来るみたいで、そもそも最初はbulk_importの機能も実装されている事に気づきませんでした。

 

TDの環境設定とかtdコマンドの設定とかは既に終わっている前提で、まずはさくっとpipでインストールします。

(今回の記事は td-client==0.2.0 をベースに書いています)

$ pip install td-client

 

サンプルコード

pythonのコード的には↓みたいな感じで動くはず (既に動いているコードから切り貼りしてきただけなんで、エラー出たら教えて下さい)

# -*- coding: utf-8 -*-
import tdclient
import time

TD_APIKEY = "XXXX" # TDのAPIキー
TD_DB = "hoge" # TDのデータベース名
TD_TB = "piyo" # TDのテーブル名
TSV_FILE ="/path/to/hoge.tsv" # bulk_importしたいtsvファイル

cl = tdclient.Client(TD_APIKEY)
ts = int(time.time()) # timestamp

# bulk_importするtsvファイル(tdコマンドでimport:auto出来るフォーマットで)
f = open(TSV_FILE,"r")

# bulk_import用のセッション名
# ユニークになればOKっぽいのでファイル名とtimestampを使ってみる
# ただ、/か.かを含んでいるとエラーになったっぽいので除去
session_name = f.name.split("/")[-1].replace(".","") + "_" + str(ts)

# bulk_import用のsessionを生成
bulk = cl.create_bulk_import(session_name,TD_DB,TD_TB)

# ファイルをアップロード
bulk.upload_file(session_name,"tsv",f)

# ファイルの追加・変更がないことを通知するっぽい
# freezeしないと先に進めないのでおまじない的に
bulk.freeze()

# TDのUIからJobsを確認するとこの段階でMap-Reduceが走っている様子
# wait=Trueにして処理が完了するまで待たないとcommitでエラーが出ます
bulk.perform(wait=True)

# この処理が終わって、やっとUI上で追加されたデータを確認できる
bulk.commit(wait=True)

# 処理に成功した件数とエラーになった件数はこんな感じで取得できる
print("valid_records:" + str(bulk.valid_records))
print("error_records:" + str(bulk.error_records))

# 後処理
bulk.delete()
f.close()

 

freezeとかperformとかcommitとかの概念はBulk Import Internalsに書いているみたいなんで、気になる方は見てみて下さい。

以上

Elasticsearch勉強会に登壇してきました

こんにちは、matsです。

 

6/1に行われていた第10回Elasticsearch勉強会に登壇してきました。

内容としては、AWS上にAutoScallingを利用して大規模なクラスターを組んでますよという事例紹介がメインになります。

1.5ヶ月でリリースまで持っていったこともあり、パフォーマンス(構成)の考察などはサービス提供上問題ないレベルであればOKを出していたので、正確性に欠けているな・・というのをまとめながら考えていました。

半分くらいは当たり前の内容を書いているつもりでしたが、意外に反響が大きかったのを見ると他社の事例というのは需要が大きいのかなぁといったところです。

 

また、他のESユーザの方のお話を伺うと、QPSやレイテンシなどを気にしている方が多いのが印象的でした。

IMの場合は、4億弱のdocumentに対して激しい集計をかけるような重いクエリが多く、どうしても数秒はかかってしまっているのでミリ秒レベルのチューニングの話はあまり意識したことがなかったので正直わかりませんでした。(台数を並べていることもあり、単純なキーワードマッチであれば数msで返ってはきますが。。)

 

また機会があれば、今度はその集計まわりのお話をしようかなと思っています。

 

引き続きエンジニアを募集中ですので、ElasticsearchやAerospikeなどを用いた大規模なデータ処理に興味のある方いらっしゃいましたらご連絡頂ければと思います。

採用ページはこちら

Aerospikeを採用した話2

こんにちは。社内でApple Watchをイジられているmatsです。

 

少し前に、

http://tech.im-dmp.net/archives/421

このような記事を書きましたが、今回はその続きになります。

プレスリリースや前回の記事では他社とのID連携の部分にフォーカスしていましたが、実は弊社が保有する3億超のIDに紐づく属性データもAerospike上で扱っています。今回はその辺りについて触れていこうかと思います。

 

Aerospikeのパフォーマンス

億件レベルのデータを扱うためにはAeorspikeのパフォーマンスが必要不可欠です。

例えばですが、1件取り出すのを1msで行えるとしても、3.6億件を取り出すのに単純計算で

36万秒 = 6000分 = 100時間

かかります。実際の処理の場合には並列で処理を行うのですが、Aerospikeのパフォーマンスを最大限に引き出すためには、結構な多重度でリクエストを送る必要があります。

相応のスペックのサーバを用意することとアプリケーションの作りこみが必要なのでなかなか大変なのですが、IMでは16〜32coreぐらいのサーバを用いて数百多重で処理を回すことで実現しています。

aerospike_blog

Aerospikeのパフォーマンスには単純なレスポンスの速さの他に、高多重なリクエストに対する耐性が担う部分も大きいので導入の際は、用途にマッチしているかを検討されるといいと思います。また、パフォーマンスを出しきるためにはクライアント側もそれ相応のパワーが必要になりますので、クライアント側でかかるコストについても注意が必要です。

 

IMでのデータの持ち方

1つのsetに全ての属性データが格納されていれば、前述のように1リクエストでそのIDに紐づく情報を取得できるのですが、IMではそのようなデータの持ち方はしておりません。

※ namespace : MySQLでいうデータベース

※ set : MySQLでいうテーブル

各setの主キーは全て弊社のIDに統一していますが、

  • セグメント
  • アクセス元IP
  • ユーザエージェント

など内容に応じてsetを分けて保持しており、データを参照する際にジョインして利用しております。

aerospike_join

これにより、Aerospikeに対するリクエストの数は爆増してしまいますが、それぞれのデータを独立して更新できるようになるため、より柔軟なデータの持ち方が出来るようになります。

 

Embulk

少し話がそれますが、少し前にトレジャーデータ様がEmbulkというツールをリリースおり、個人的に非常に注目しています。

http://www.publickey1.jp/blog/15/embulkfluentd.html

どこに注目しているかというと、embulkは実行環境のリソースに応じて並行処理することが出来るところです。仕組み的にaerospikeと非常に親和性が高いと思っており、これを使ってS3やelasticsearchと繋いでデータを出し入れできると非常に捗る気がするのですが、僕自身がjavarubyも得意でないので実現するのはもうしばらくかかりそうです。。(誰か一緒にやってくれないかな)

 

 

話がそれましたが、ID連携以外でもAerospikeをゴリゴリ使っているという話でした。

AzureのWordpressを無料で使い倒す

こんにちは。イマイチ5月病のビッグウェーブに乗り切れていないmatsです。

 

IMではインフラ基板にAWSを採用していますが、本ブログを含めいくつかのwebサイトではMicrosoft Azureを利用しております。

azure

メインのプロダクト以外は極力マネージドのサービスを利用して、運用負荷を軽減するといったことを目的にAzureを選定いたしました。

(同じPaaSであるherokuでも可能ではあるのですが、Wordpressの管理画面からテーマやプラグインをインストール出来ないためAzureをオススメしております。)

今回はそのAzureにてWordpressほぼ無料で運用するためのポイントと運用上の注意点をご紹介したいと思います。

 

基本的に欧米リージョンのみ

Azure上で使用できるMySQLであるClearDBを立てられるのが欧米リージョンのみとなっています。

データベースとのレイテンシを考慮し同じリージョンに立てると、必然的に欧米リージョンを使用することになります。(IMは米国西部がメインです)

cleardb

ただし、webアプリにはClearDB1インスタンス分の無料枠がついており、1サイト目の構築の際のウィザードにそって作った場合のみ国内に立てることが出来ます。

(ClearDB自体にも無料プランがあるのでややこしいです。。)

 

DBの容量は20MBまで

ClearDB(MySQL)の無料プランで利用できる容量は 20MB になります。

普通にWordpressを運用していると直ぐにオーバーしてしまう容量ですが、実際に必要な容量はそれほど多くありません。

大部分が投稿記事の編集履歴であったりするので、IMでは「WP-Optimize」というプラグインを使って定期的に削除しています。

https://wordpress.org/plugins/wp-optimize/

(Optimizeすると大体1〜2MBくらいになります。)

 

アップロードできるファイルは1GBまで

無料プランでは使用できるディスクの容量は1GBになります。

そのため、安定運用するためにはメディアファイルを外部に移すことをオススメしています。

IMでは、プラグインの「WP Read-Only」を使ってS3上にメディアファイルを移しています。

https://wordpress.org/plugins/wpro/

似たようなプラグインはいくつかあるのですが、Wordpress上にファイルを残さず直接アップロード出来るものを選んで下さい。

 

独自ドメインの利用にはCDNが必要

無料プランではAzure上で独自ドメインを利用することが出来ず、 *.azurewebsites.net の様なドメインしか使用することが出来ません。

そのため、IMではAWSのCDNであるCloudFrontを用いて独自ドメインの実装をしております。

※ これにより、高トラフィック対策と欧米リージョン対策も合わせてできていたりします。

cf_azure

CDNの設定にあたりいくつか注意事項があるのでご紹介しておきます。

(CloudFrontの設定方法になるので、他CDNの場合は読み替えて下さい)

 

①POSTを許可する

CDNがフォワードするmethodにPOSTがないと、ログインや記事の投稿が出来なくなります。

CloudFront_Method

 

②フォワードするヘッダーにUser-Agentを追加する

これをしないと、投稿画面のリッチテキストエディタなど一部の表示が正常に動作しなくなります。

CloudFront_header

 

③管理画面のキャッシュを無効にする

/wp-admin 配下のコンテンツのTTLを0秒に設定し、キャッシュを無効化します。

※ その他のコンテンツについては、お好みで設定して下さい。

 

また、CloudFront側のTTLが優先されるようにAzure側のヘッダーのCache-Controlを変更して下さい。

web.config に次のように記載することでキャッシュを無効化できます。

<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

 

④GA関連のCookie以外をフォワードする

Google Analyticsを導入の際に、GA関連のCookieをOriginにフォワードしてしまうと正常に動作しないので、Wordpress関連のものに絞ってフォワードします。

CloudFront_Cookie

 

 

 

いかがでしょうか。S3とCloudFrontを利用しているため完全無料とはいきませんが、価格帯の割には非常に拡張性のある構成になっているのではないかと思います。また、S3とCloudFrontの利用料もAWSの無料枠内に収まるケースの方が多いかと思います。

 

Azureは国内事例が少ないのですが、PaaS領域は先進的なプロダクトが多いと思うので興味があればトライしてみてください。

Mackerelのカスタムメトリックをechoで取得する

mackerel

どうもmatsです。

みなさんはサーバの監視は何をお使いでしょうか?

IMではリソースの監視にmackerelを、サービス監視にNagiosを採用しております。

100台超のサーバ群を監視するのにmackerekは非常に便利かつ強力なのですが、問題はNagiosです。

 

IMではほとんどのサーバをオートスケールにて起動しており、そことの相性が非常に悪く超重要なサーバ以外はNagiosに設定を入れていない状況です。

Sensu等も検討したのですが、ものによってはプラグインによって値をmackerelに送れば事足りるものも多いので今回はそちらで対応することにしました。

 

カスタムメトリックの投稿

mackerelのヘルプによると、

http://help-ja.mackerel.io/entry/advanced/custom-metrics

これの通りやると、好きなメトリックをmackerelに投げつけることが出来るみたい。しかしですよ、

プラグイン書くのが面倒くさい!(笑)

 

いや、面倒くさいは言いすぎですが、オートスケールの起動時に余計なデプロイ手順を踏むことになるのがイヤだったので考えました。

(端折りますが、cloud-initを使ってデプロイしているので容量制限があるのです)

 

プラグインを書かずにメトリックスを投稿する

 

よくドキュメントを読むと、プラグインと言っても実行結果が次の形式で標準出力されていれば何でもよくて、golangとかで書く必要はない模様。

 

{metric name}t{metric value}t{epoch seconds}

 

監視対象のメトリックス名: {metric name}

値: {metric value}

実行時のunixtime: {epoch seconds}

すごいミスリードを生みそうな書き方なんですが、3つのパラメータをタブ(t)区切りで出せばいいようで、{}とかは要らないみたいです。(むしろ怒られました。。)

実は echo でいけるんじゃないかと思い、nginxのプロセス数を取得するコマンドを書いてみました。

 

echo "proc_sum.nginxt$(ps -f -u nginx | grep worker | grep -v grep | wc -l)t$(date -u +%s)"

 

監視対象のメトリックス名:  proc_sum.nginx

値(プロセス数):  ps -f -u nginx | grep worker | grep -v grep | wc -l

実行時のunixtime:  date -u +%s

これを実行すると

proc_sum.nginx  3  1430552578

みたいな感じで、標準出力がかえってきます。

これをmackerelの設定ファイルに書いてみます。

※ ダブルクオーテーションをエスケープするところに注意

 

[plugin.metrics.proc_sum_nginx]
command = "echo "proc_sum.nginxt$(ps -f -u nginx | grep worker | grep -v grep | wc -l)t$(date -u +%s)""

 

こんな感じで、mackerel.conf に書いて mackerel-agent を再起動すればmackerel上にグラフが描画されるはずです。

あとはプロセス数が規定値を下回っていたらアラートを上げるようにしてあげれば監視の出来上がりです。簡単ですね。

 

プロセス以外の監視

基本的にワンライナーでパラメータを取得できるものであれば、同じ方法で監視を行うことが出来ます。

例えばですが、弊社の他のところではaerospikeのDISK使用量の監視なども同じ方法で行っております。

※ aerospikeはファイルシステムを介さずに直接ブロックデバイスに書き込むので、OSからDISK使用量を取得することが出来ません。

※ DISK使用量などの情報取得には asinfo という独自コマンドが必要です。

 

[plugin.metrics.used_ssd_ns1]
command = "echo "used_ssd.ns1t$(asinfo -v 'namespace/ns1' -l | grep ^used-bytes-disk | sed -e "s/used-bytes-disk=//g")t$(date -u +%s)""