tag:blogger.com,1999:blog-68125543691153355502024-03-14T16:00:52.253+09:00memorycraft更新とか絶対忘れるから。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comBlogger143125tag:blogger.com,1999:blog-6812554369115335550.post-80459175648669378532014-03-07T09:46:00.001+09:002014-03-07T09:47:51.501+09:00ELBってなんじゃ?(アクセスログがやってきた)<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-wzHUWAwNq6U/UxkM-ytK-iI/AAAAAAAAFRY/QiHkjDZvBqg/s1600/Untitled(2).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-wzHUWAwNq6U/UxkM-ytK-iI/AAAAAAAAFRY/QiHkjDZvBqg/s1600/Untitled(2).png" height="280" width="320" /></a></div>
<br />
<br />
ELBにアクセスログ機能が搭載されたので、試してみました。<br />
<br />
まず、AWSコンソールのELBのの画面をみてみますが、ここで、古いバージョンのコンソールだとアクセスログの設定ができないので、ヘッダ上部のお知らせアイコンから新しいバージョンに切り替えます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-6ubKWBqrYbA/UxkNMw0CmsI/AAAAAAAAFRg/f2PW8zsbncc/s1600/EC2+Management+Console+2014-03-07+08-44-18+2014-03-07+08-44-39.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-6ubKWBqrYbA/UxkNMw0CmsI/AAAAAAAAFRg/f2PW8zsbncc/s1600/EC2+Management+Console+2014-03-07+08-44-18+2014-03-07+08-44-39.png" /></a></div>
<br />
<br />
<br />
任意のELBを選択して、下部ペインのDescriptionタブの最下段に、「Access Logs」という項目が追加されているのが分かります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-MHx9VC09J0o/UxkPwZe6fUI/AAAAAAAAFSM/KYtiU_xccDE/s1600/EC2+Management+Console+2014-03-07+08-46-07+2014-03-07+08-46-37+2014-03-07+09-14-53+2014-03-07+09-15-47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-MHx9VC09J0o/UxkPwZe6fUI/AAAAAAAAFSM/KYtiU_xccDE/s1600/EC2+Management+Console+2014-03-07+08-46-07+2014-03-07+08-46-37+2014-03-07+09-14-53+2014-03-07+09-15-47.png" height="504" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<br />
最初はDisabledになっています。Editのリンクを押下すると、以下のようなダイアログが表示されます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-C-9dPJEWcpw/UxkOCCum0hI/AAAAAAAAFRw/3hWYYZHGNVg/s1600/EC2+Management+Console+2014-03-07+08-49-01+2014-03-07+08-49-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-C-9dPJEWcpw/UxkOCCum0hI/AAAAAAAAFRw/3hWYYZHGNVg/s1600/EC2+Management+Console+2014-03-07+08-49-01+2014-03-07+08-49-02.png" /></a></div>
<br />
<br />
ここで、「Enable Access Logs」にチェックを入れ、<br />
<ul>
<li><b>Interval</b>:ログ出力間隔(現状5分か60分)</li>
<li><b>S3 Location</b>:ログ出力先のS3ロケーション(Create the location for meをチェックすると自動でつくられる)</li>
</ul>
を入力し、「Save」をクリックします。<br />
<br />
<br />
<br />
しばらくすると、指定したS3のロケーションに、ログが出力されます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ZtXxM561Kgk/UxkO7k6NRRI/AAAAAAAAFR8/CrKj4y6YVFs/s1600/S3+Management+Console+2014-03-07+08-59-25+2014-03-07+08-59-26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-ZtXxM561Kgk/UxkO7k6NRRI/AAAAAAAAFR8/CrKj4y6YVFs/s1600/S3+Management+Console+2014-03-07+08-59-25+2014-03-07+08-59-26.png" height="106" width="640" /></a></div>
<br />
<br />
<br />
中身をみてみると、以下のようになっています。<br />
<pre class="cmdprint">2014-03-06T23:50:37.819662Z manage 54.248.248.218:60123 10.156.231.23:80 0.00008 0.002195 0.000074 403 403 0 5039 "GET https://mng.cloudpack.jp:443/ HTTP/1.1"
2014-03-06T23:54:42.332009Z memory 219.117.233.241:43172 10.156.231.23:80 0.000068 2.234742 0.000065 200 200 0 129832 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account HTTP/1.1"
2014-03-06T23:54:45.898722Z memory 219.117.233.241:43172 10.156.231.23:80 0.000069 0.142097 0.000058 200 200 0 766319 "GET https://memory.cloudpack.jp:443/cloudpack/admin HTTP/1.1"
2014-03-06T23:55:05.069736Z memory 219.117.233.241:43172 10.156.231.23:80 0.000082 0.767399 0.000083 200 200 0 129832 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account HTTP/1.1"
2014-03-06T23:55:09.530026Z memory 219.117.233.241:43172 10.156.231.23:80 0.000078 0.701585 0.000067 200 200 0 133234 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/2 HTTP/1.1"
2014-03-06T23:55:11.639899Z memory 219.117.233.241:43172 10.156.231.23:80 0.000088 0.70764 0.000099 200 200 0 133341 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/3 HTTP/1.1"
2014-03-06T23:55:13.555633Z memory 219.117.233.241:43172 10.156.231.23:80 0.000076 0.698172 0.000095 200 200 0 131071 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/4 HTTP/1.1"
2014-03-06T23:55:15.414292Z memory 219.117.233.241:43172 10.156.231.23:80 0.000075 0.885828 0.00009 200 200 0 129831 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/1 HTTP/1.1"
2014-03-06T23:55:20.774540Z memory 219.117.233.241:43172 10.156.231.23:80 0.000075 0.68001 0.000083 200 200 0 23283 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/index?search=miura HTTP/1.1"
2014-03-06T23:55:25.478841Z memory 219.117.233.241:43172 10.156.231.23:80 0.000076 0.817105 0.000061 200 200 0 233574 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account/doc/miura@cloudpack.jp HTTP/1.1"
2014-03-06T23:55:31.467146Z memory 219.117.233.241:43172 10.156.231.23:80 0.000072 0.142359 0.00011 200 200 0 766319 "GET https://memory.cloudpack.jp:443/cloudpack/admin HTTP/1.1"
2014-03-06T23:55:35.995594Z memory 219.117.233.241:43172 10.156.231.23:80 0.000077 0.768791 0.000101 200 200 0 129832 "GET https://memory.cloudpack.jp:443/cloudpack/admin/account HTTP/1.1"
2014-03-06T23:55:37.699927Z memory 54.248.248.218:36526 10.156.231.23:80 0.000064 0.001333 0.000062 403 403 0 5039 "GET https://memory.cloudpack.jp:443/ HTTP/1.1"</pre>
<br />
<br />
ログのフォーマットは、以下のような構成だそうです。<br />
<table border="0" cellspacing="0" style="border-spacing: 0px; border: 1px solid rgb(204, 204, 204); color: black; font-family: verdana, arial, sans-serif; font-size: 13.333333015441895px;"><thead>
<tr><th style="background-color: #eeeeee; border: 1px solid rgb(204, 204, 204); color: #333333; font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">フィールド名</th><th style="background-color: #eeeeee; border: 1px solid rgb(204, 204, 204); color: #333333; font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">説明</th><th style="background-color: #eeeeee; border: 1px solid rgb(204, 204, 204); color: #333333; font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">例</th></tr>
</thead><tbody>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">タイムスタンプ</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">クライアントにレスポンスを返したUTC時刻</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">2014-02-15T23:39:43.945958Z</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELB名</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELBの名前</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">my-test-loadbalancer</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">クライアントポート</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">リクエストしたクライアントのIP</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">192.168.131.39:2817</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">バックエンドポート</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">このリクエストを処理したインスタンスのIP</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">10.0.0.0.1</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">リクエスト処理時間</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELBがリクエストをうけとってからインスタンスに渡すまでの経過時間(秒)</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">0.000073</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">バックエンド処理時間</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">インスタンスに渡してからレスポンスヘッダを返し始めるまでの経過時間<span style="font-size: 12px;">(秒)</span></td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">0.001048</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">レスポンス処理時間</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELBがインスタンスからレスポンスヘッダを受け取りクライアントにレスポンスヘッダを返し初めてからの経過時間(秒)<br />
処理時間にはELBのキューイング時間とインスタンスへの接続要求時間も含まれています。</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">0.000057</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELBステータスコード</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ELBからクライアントへ返されるHTTPステータスコード (HTTPのみ)</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">200</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">バックエンドステータスコード</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">インスタンスからELBへ返されるHTTPステータスコード (HTTPのみ)</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">200</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">受信バイト数<br />
<br /></td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">クライアントからのリクエストのサイズ(バイト)<br />
HTTPリクエストではボディのみでヘッダのサイズは含まれません<br />
TCPリクエストではヘッダのサイズも含まれます</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">0</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">送信バイト数</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">クライアントへのレスポンスのサイズ(バイト)<br />
HTTPリクエストではボディのみでヘッダのサイズは含まれません<br />
TCPリクエストではヘッダのサイズも含まれます</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">29</code></td></tr>
<tr><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><span style="font-size: 12px;">"リクエスト"</span><br />
</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;">ダブルクォーテーションで囲まれたクライアントからのリクエスト行。フォーマットは<br />
HTTPメソッド + プロトコル://ホスト:ポート + パス + HTTPバージョン<br />
<br />
TPCリクエストでは"- - -"のようになります。</td><td style="border: 1px solid rgb(204, 204, 204); font-size: 12px; margin: 0px; padding: 5px; vertical-align: top;"><code class="code" style="font-family: 'Courier New', Courier, mono; font-size: 12px;">"GET http://www.example.com: 80/HTTP/1.1"</code></td></tr>
</tbody></table>
<br />
<br />
ELBは自動でスケールするので、漏れ無くロギングできるかどうかは怪しいところですが、簡単にアクセスログをとるには便利そうです。<br />
<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-79709511901582387012014-03-06T18:16:00.000+09:002014-03-06T20:17:02.118+09:00TreasureDataってなんじゃ?(Googleスプレッドシートで簡易ダッシュボード)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-poxHI4ChuKM/Uxg56xGPy3I/AAAAAAAAFQM/OTDMDN66NO0/s1600/bootstrap-marketing-customer-logo-Treasure-data.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-poxHI4ChuKM/Uxg56xGPy3I/AAAAAAAAFQM/OTDMDN66NO0/s1600/bootstrap-marketing-customer-logo-Treasure-data.jpg" height="322" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<a href="http://memocra.blogspot.jp/2014/02/treasuredata.html" target="_blank">前回</a>、TrasureDataでデータのロードとクエリの実行を行いましたが、今回は結果をTreasureDataの外に出してみます。<br />
<br />
まず、Google Spreadsheetで空のスプレッドシートを作成します。<br />
名前は適当に、「TreasureDataTest」シートは「dashboard1」と名づけます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-J2TukW1awyc/Uxg6vNb66uI/AAAAAAAAFQc/bKa8Rng4UFE/s1600/TreasureDataTest+2014-03-06+17-55-30+2014-03-06+17-55-31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-J2TukW1awyc/Uxg6vNb66uI/AAAAAAAAFQc/bKa8Rng4UFE/s1600/TreasureDataTest+2014-03-06+17-55-30+2014-03-06+17-55-31.png" height="331" width="400" /></a></div>
<br />
<br />
<br />
<br />
また、Googleでパスワードに2段階認証を掛けている場合、TreasureDataがGoogle Spreadsheetへアクセスできないので、予めGoogleアカウントでアプリ用のパスワードを作成しておきます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/--7HYKtL2eGs/Uxg6X5JPl4I/AAAAAAAAFQY/wqtiY9keyfQ/s1600/%25E3%2582%25A2%25E3%2582%25AB%25E3%2582%25A6%25E3%2583%25B3%25E3%2583%2588%25E6%2583%2585%25E5%25A0%25B1+2014-03-06+17-57-58+2014-03-06+17-58-00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/--7HYKtL2eGs/Uxg6X5JPl4I/AAAAAAAAFQY/wqtiY9keyfQ/s1600/%25E3%2582%25A2%25E3%2582%25AB%25E3%2582%25A6%25E3%2583%25B3%25E3%2583%2588%25E6%2583%2585%25E5%25A0%25B1+2014-03-06+17-57-58+2014-03-06+17-58-00.png" /></a></div>
<br />
<br />
<br />
<br />
ここまでできたら、TreasureDataの画面に移ります。「New Query」の「Result Output」のプルダウンで出力先の選択肢が表示されますので、今回はGoogleSpreadsheetを選びます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-r1f8a2nYmkk/Uxg50TANgjI/AAAAAAAAFQE/BQoPovfs9Vs/s1600/+2014-03-06+18-00-45+2014-03-06+18-00-57.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-r1f8a2nYmkk/Uxg50TANgjI/AAAAAAAAFQE/BQoPovfs9Vs/s1600/+2014-03-06+18-00-45+2014-03-06+18-00-57.png" height="360" width="400" /></a></div>
<br />
<br />
<br />
すると、Google Speardsheet用の設定項目が表示されます。<br />
先ほどつけた、ファイル名、シート名、取得したアプリ用のパスワードなどを指定し、クエリをつくって実行します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-36xvNo-fKvU/Uxg72osb2hI/AAAAAAAAFQo/zOkSyw-UT9w/s1600/Treasure+Data+2014-03-06+17-39-21+2014-03-06+17-40-42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-36xvNo-fKvU/Uxg72osb2hI/AAAAAAAAFQo/zOkSyw-UT9w/s1600/Treasure+Data+2014-03-06+17-39-21+2014-03-06+17-40-42.png" height="578" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
実行がおわると、指定したスプレッドシートに解析結果のデータが表示されます。<br />
そのデータを元に、GoogleSpreadsheetのグラフ機能でグラフを作って簡易ダッシュボードが完成です。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-9a4KeRnwBQU/UxhZIa3owVI/AAAAAAAAFRA/PalLp5GHLsQ/s1600/TreasureDataTest+2014-03-06+17-54-26+2014-03-06+17-54-28+2014-03-06+20-15-09+2014-03-06+20-16-25.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-9a4KeRnwBQU/UxhZIa3owVI/AAAAAAAAFRA/PalLp5GHLsQ/s1600/TreasureDataTest+2014-03-06+17-54-26+2014-03-06+17-54-28+2014-03-06+20-15-09+2014-03-06+20-16-25.png" height="592" width="640" /></a></div>
<br />
<br />
<br />
実行のスケジューリングなどもできますので、定期的に内容のかわるスプレッドシートをつくることもできるでしょう。<br />
<br />
以上です。<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-11270000136740938692014-02-24T10:30:00.000+09:002014-02-24T10:30:00.886+09:00Dockerってなんじゃ?(docker+nginxで複数コンテナにWEBサーバーをたてる)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-eil6pFGKQYk/Uwo2YfvwpMI/AAAAAAAAFNU/ztPYw4C9Ylk/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-eil6pFGKQYk/Uwo2YfvwpMI/AAAAAAAAFNU/ztPYw4C9Ylk/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
dockerを使って複数のWEBサーバーを立ててみたいと思います。<br />
複数の外部ポートを使うため、プロキシとしてnginxと併用してみます。<br />
<br />
今回は2つのWEBサーバーのコンテナを立て、1つにはwordpress on apache、もう一つは素のnginxを入れてみます。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-xKQB9zaJ1LM/Uwp2FSjUH5I/AAAAAAAAFOM/p8WOFD-vbCE/s1600/Untitled(1)+(2).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-xKQB9zaJ1LM/Uwp2FSjUH5I/AAAAAAAAFOM/p8WOFD-vbCE/s1600/Untitled(1)+(2).png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
コンテナにはそれぞれ<br />
<br />
<ul>
<li>memorycrat.cloudpack.jp</li>
<li>tenkaippin.cloudpack.jp</li>
</ul>
<br />
というドメインを割り当てます。<br />
また、sshも立ちあげます。<br />
<br />
今回はDockerfileを使ってイメージを構築します。<br />
それぞれのコンテナのDockerfileとsupervisorの設定ファイルテンプレートは以下の様にホスト側に配置しておきます。<br />
<pre class="cmdprint"> $ tree .
.
└── templates
├── memorycraft
│ └── conf
│ ├── Dockerfile
│ └── supervisor.conf
└── tenkaippin
└── conf
├── Dockerfile
└── supervisor.conf
</pre>
<br />
<br />
<br />
<h1>
wordpressコンテナの設定</h1>
<br />
memorycraftコンテナでは、httpdとsshのサービスを立ちあげます。<br />
また、wordpressをダウンロードし、RDSに接続するように設定ファイルを書き換えます。
<br />
<br />
./templates/memorycraft/conf/Dockerfile<br />
<script src="https://gist.github.com/memorycraft/9175045.js"></script>
<br />
./templates/memorycraft/conf/supervisor.conf<br />
<script src="https://gist.github.com/memorycraft/9175064.js"></script>
コンテナをビルドします。
<br />
<pre class="cmdprint">docker build --no-cache --rm -t memorycraft/wordpress templates/memorycraft/conf/
</pre>
<br />
できたら、起動します。
<br />
<pre class="cmdprint">docker run -p 80 -p 22 -d memorycraft/wordpress /usr/bin/supervisord
</pre>
<br />
<br />
<br />
<h1>
nginxコンテナの設定</h1>
<br />
tenkaippinコンテナでは、nginxとsshのサービスを立ちあげます。<br />
<br />
./templates/tenkaippin/conf/Dockerfile<br />
<script src="https://gist.github.com/memorycraft/9175072.js"></script>
./templates/tenkaippin/conf/supervisor.conf<br />
<script src="https://gist.github.com/memorycraft/9175086.js"></script>
コンテナをビルドします。
<br />
<pre class="cmdprint">docker build --no-cache --rm -t tenkaippin/nginx templates/tenkaippin/conf/
</pre>
<br />
できたら、起動します。
<br />
<pre class="cmdprint">docker run -p 80 -p 22 -d tenkaippin/nginx /usr/bin/supervisord
</pre>
<br />
<br />
<br />
<h1>
ホスト側nginxの設定</h1>
<br />
まず、プロキシ用にnginxをインストールします。<br />
<pre class="cmdprint"># rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# yum install nginx -y
</pre>
<br />
ここで一度コンテナの起動状況を調べてみます。
<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5499f267f670 tenkaippin/nginx:latest /usr/bin/supervisord About an hour ago Up About an hour 0.0.0.0:49185->22/tcp, 0.0.0.0:49186->80/tcp determined_shockley
9b361ac4aaef memorycraft/wordpress:latest /usr/bin/supervisord 5 hours ago Up 5 hours 0.0.0.0:49173->22/tcp, 0.0.0.0:49174->80/tcp loving_nobel
</pre>
<br />
これで、<br />
<ul>
<li>memorycraft:80 → 49174 </li>
<li>tenkaippin:80 → 49186 </li>
</ul>
<br />
というマッピングになっているのが分かります。(起動時にホスト側のIPを指定することも出来ます。)
<br />
<br />
次に、仮想サーバごとにプロキシ設定します。まずプロキシの基本設定です。<br />
<br />
/etc/nginx/conf.d/proxy.conf<br />
<script src="https://gist.github.com/memorycraft/9175103.js"></script>
<br />
次に、仮想サーバーで、memorycraft.cloudpack.jpとtenkaippin.cloudpack.jpの設定をします。<br />
プロキシの転送先ポートとして、先ほど調べたポートを指定します。
<br />
<br />
/etc/nginx/conf.d/virtual.conf<br />
<script src="https://gist.github.com/memorycraft/9175112.js"></script>
<br />
<br />
<br />
<h1>
DNSの設定</h1>
<br />
次にRoute53で、2つのサブドメインでこのサーバーに向けたAレコードを登録します。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-7Q9nx8hgcZs/UwpDhchff5I/AAAAAAAAFNk/zbo3pPbsOY4/s1600/Route+53+Management+Console+2014-02-24+03-53-01+2014-02-24+03-53-21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-7Q9nx8hgcZs/UwpDhchff5I/AAAAAAAAFNk/zbo3pPbsOY4/s1600/Route+53+Management+Console+2014-02-24+03-53-01+2014-02-24+03-53-21.png" height="60" width="640" /></a></div>
<br />
これで作業は完了です。<br />
<br />
<br />
<h1>
確認</h1>
<br />
それでは、SSH確認してみます。<br />
<br />
<br />
<b>memorycraft.cloudpack.jp</b><br />
<br />
まずは、ホストサーバでssh接続してみます。<br />
<pre class="cmdprint"># ssh memorycraft@127.0.0.1 -p 49173
The authenticity of host '[127.0.0.1]:49173 ([127.0.0.1]:49173)' can't be established.
RSA key fingerprint is a2:c9:81:fb:f5:84:57:ee:06:db:8b:18:7e:3c:2a:2e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49173' (RSA) to the list of known hosts.
memorycraft@127.0.0.1's password:
[memorycraft@9b361ac4aaef ~]$
[memorycraft@9b361ac4aaef ~]$
</pre>
接続出来ました。
<br />
<br />
次に、ブラウザを確認します。
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-7-Sse889bdo/UwpEgT81sqI/AAAAAAAAFNw/9LXTM82Ks7g/s1600/WordPress+%E2%80%BA+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB+2014-02-24+03-00-53+2014-02-24+03-00-55.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-7-Sse889bdo/UwpEgT81sqI/AAAAAAAAFNw/9LXTM82Ks7g/s1600/WordPress+%E2%80%BA+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB+2014-02-24+03-00-53+2014-02-24+03-00-55.png" height="640" width="626" /></a></div>
<br />
おお!接続出来ました!
<br />
<br />
<br />
<br />
<b>tenkaippin.cloudpack.jp</b><br />
<br />
ssh接続してみます。<br />
<pre class="cmdprint"># ssh tenkaippin@127.0.0.1 -p 49175
ssh: connect to host 127.0.0.1 port 49175: Connection refused
[root@ip-10-157-38-165 ~]# ssh tenkaippin@127.0.0.1 -p 49185
The authenticity of host '[127.0.0.1]:49185 ([127.0.0.1]:49185)' can't be established.
RSA key fingerprint is c3:87:55:75:0b:d4:ce:f3:5c:0a:e9:71:e1:0f:fd:ca.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49185' (RSA) to the list of known hosts.
tenkaippin@127.0.0.1's password:
[tenkaippin@5499f267f670 ~]$
[tenkaippin@5499f267f670 ~]$
</pre>
接続出来ました。<br />
<br />
ブラウザを見てみます。
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zw7i2OEpue4/UwpF-FxaR1I/AAAAAAAAFN8/6lPqCjldew0/s1600/Welcome+to+nginx!+2014-02-24+03-01-31+2014-02-24+03-01-34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-zw7i2OEpue4/UwpF-FxaR1I/AAAAAAAAFN8/6lPqCjldew0/s1600/Welcome+to+nginx!+2014-02-24+03-01-31+2014-02-24+03-01-34.png" height="224" width="640" /></a></div>
<br />
<br />
<br />
ちゃんと表示されています!
<br />
<br />
このように、サーバー資源が限られていてユーザースペースを確実に分離したい場合などには、複数コンテナをつかうと便利かもしれません。<br />
<br />
以上です。
Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-61959855958761457692014-02-18T23:02:00.000+09:002014-08-18T15:35:22.273+09:00Dockerってなんじゃ?(S3プライベートレジストリ) <div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
<a href="http://memocra.blogspot.jp/2014/02/docker_17.html" target="_blank">前回</a>に引き続き、プライベートレジストリです。<br />
<br />
前回の方法では、レジストリのコンテナを載せたサーバー自体が落ちてしまったときに登録されたコンテナイメージが全てなくなってしまいます。<br />
<a href="https://github.com/dotcloud/docker-registry" target="_blank">dockerのregistryコンテナ</a>には、設定ファイルが存在し、永続化のオプションとしてバックエンドにS3を使うことができます。<br />
<br />
それでは早速試してみます。<br />
<br />
<br />
<h1>
レジストリ側の設定</h1>
<br />
レジストリのコンテナをbashで起動します。<br />
<pre class="cmdprint">$ docker run -t -i registry /bin/bash
</pre>
<br />
レジストリに入ったら設定ファイルがある<i>/docker-registry/config/</i>フォルダに移動します。<br />
S3用のサンプルがあるのでそれを<i>config.yml</i>として使います。<br />
<br />
dockerのレジストリでは設定ファイルに<i>_env:VARIABLENAME</i>となっている部分があり、環境変数をセットしている部分です。起動時に-eオプションでその環境変数をコンテナに渡すことが出来ます。<br />
<br />
このS3用のファイルは、AWSキーやバケット名などに環境変数をセットできるようになっているので起動時にパラメータ渡しが可能です。今回はそのまま変更なしで使います。<br />
<pre class="cmdprint"># cd /docker-registry/config
# mv config.yml config.yml.org
# cp config_s3.yml config.yml
# cat config.yml
~(略)~
prod:
storage: s3
boto_bucket: _env:AWS_BUCKET
s3_access_key: _env:AWS_KEY
s3_secret_key: _env:AWS_SECRET
s3_bucket: _env:AWS_BUCKET
s3_encrypt: true
s3_secure: true
secret_key: REPLACEME
s3_encrypt: true
s3_secure: true
storage_path: /images
</pre>
<br />
<br />
接続を終了し、コミットします。<br />
<pre class="cmdprint"># exit;
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e1e890b9647 registry:0.6.5 /bin/bash 6 minutes ago Exit 0 grave_wozniak
# docker commit 1e1e890b9647 memorycraft/registry
</pre>
<br />
<br />
コミットしたS3用のレジストリイメージを起動します。その際前述のように、-eオプションでAWSキーやバケット名などを環境変数として渡します。<br />
また、<i>SETTINGS_FLAVOR</i>環境変数は、<i>config.yml</i>のprodと対応しています。これによって設定ファイルの各モードを起動時に選択することができます。<br />
<pre class="cmdprint"># docker run -p 5000:5000 -e SETTINGS_FLAVOR=prod -e AWS_KEY=XXXXXXX -e AWS_SECRET=YYYYYYYYY -e AWS_BUCKET=memorycraft-docker-registry -d memorycraft/registry
#
#
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e1e890b9647 registry:0.6.5 /bin/bash 6 minutes ago Exit 0 grave_wozniak
413aa68a3ad1 memorycraft/registry:latest /docker-registry/run 9 hours ago Up 9 hours 0.0.0.0:5000->5000/tcp prickly_davinci
</pre>
<br />
これで、S3対応のレジストリができました。<br />
<br />
<br />
<br />
<br />
<h1>
S3レジストリへの登録</h1>
<br />
それではクライアント側からこのレジストリにpushしてみます。流れは前回の記事と同じです。<br />
<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee60c633c8f9 memorycraft/centos:latest /usr/bin/supervisord 3 days ago Up 3 days 0.0.0.0:49189->22/tcp, 0.0.0.0:49190->80/tcp happy_brattain
c118bcc97b1e 539c0211cd76 /bin/bash 5 days ago Exit 0
# docker commit ee60c633c8f9 176.34.16.242:5000/memorycraft/centos
b939188f4672b83d03e90ad12c4ad9e2ccdfa66d2f50fd44ae18ef314eee5c5b
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
176.34.16.242:5000/memorycraft/centos latest b939188f4672 14 seconds ago 443.8 MB
memorycraft/centos latest d0c94b943ba2 4 days ago 437.9 MB
# docker push 176.34.16.242:5000/memorycraft/centos
The push refers to a repository [176.34.16.242:5000/memorycraft/centos] (len: 1)
Sending image list
Pushing repository 176.34.16.242:5000/memorycraft/centos (1 tags)
539c0211cd76: Image successfully pushed
380423464fbc: Image successfully pushed
dc52da789c75: Image successfully pushed
b2ab60219415: Image successfully pushed
52b555115035: Image successfully pushed
a149f9038d0e: Image successfully pushed
3897f6889349: Image successfully pushed
bd1a450e0e46: Image successfully pushed
da6f1a424b7c: Image successfully pushed
4a8d2a1dab88: Image successfully pushed
af06476dc08c: Image successfully pushed
65ec465a844b: Image successfully pushed
318326461017: Image successfully pushed
fc6935aadec7: Image successfully pushed
9022a04f5b3f: Image successfully pushed
4787e46941f7: Image successfully pushed
30f9368972bb: Image successfully pushed
dc6de6feb9a9: Image successfully pushed
d0c94b943ba2: Image successfully pushed
b939188f4672: Image successfully pushed
Pushing tags for rev [b939188f4672] on {http://176.34.16.242:5000/v1/repositories/memorycraft/centos/tags/latest}
</pre>
<br />
<br />
無事にpushできたようです。<br />
それではS3バケットを覗いてみると、リポジトリのメタデータやイメージなどがアップされているのがわかります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-7s7m4aERD2Q/UwNGQjOXgbI/AAAAAAAAFL4/O0OFdsY5sNQ/s1600/S3+Management+Console+2014-02-18+20-37-43+2014-02-18+20-38-08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-7s7m4aERD2Q/UwNGQjOXgbI/AAAAAAAAFL4/O0OFdsY5sNQ/s1600/S3+Management+Console+2014-02-18+20-37-43+2014-02-18+20-38-08.png" height="242" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-qSilM1-iHz4/UwNGQlx8kDI/AAAAAAAAFL8/vUdBkWF7yMM/s1600/S3+Management+Console+2014-02-18+20-38-58+2014-02-18+20-38-59.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-qSilM1-iHz4/UwNGQlx8kDI/AAAAAAAAFL8/vUdBkWF7yMM/s1600/S3+Management+Console+2014-02-18+20-38-58+2014-02-18+20-38-59.png" height="628" width="640" /></a></div>
<br />
<br />
<br />
<h1>
レジストリを消してみる</h1>
<br />
ここで、一度、レジストリ側のサーバーが壊れてしまった。もしくはインスタンスが消えてしまった場合を想定して、0から別のサーバーにレジストリを立てて見たいと思います。<br />
<br />
<pre class="cmdprint"># docker run -t -i registry /bin/bash
# cd /docker-registry/config
# mv config.yml config.yml.org
# cp config_s3.yml config.yml
# cat config.yml
# exit
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
927bb1ccf9dc registry:0.6.5 /bin/bash About a minute ago Exit 0 trusting_mccarthy
# docker commit 927bb1ccf9dc memorycraft/registry
# docker run -p 5000:5000 -e SETTINGS_FLAVOR=prod -e AWS_KEY=XXXXXXXXXXXXXXXX -e AWS_SECRET=YYYYYYYYYYYYYYYY -e AWS_BUCKET=memorycraft-docker-registry -d memorycraft/registry /docker-registry/run.sh
</pre>
<br />
<br />
<br />
<h1>
S3からpull</h1>
<br />
念のためクライアント側もイメージもコンテナも消した状態で、S3レジストリを指定してrunしてみます。<br />
<pre class="cmdprint"># docker run -t -i 176.34.16.242:5000/memorycraft/centos /bin/bash
Unable to find image '176.34.16.242:5000/memorycraft/centos' (tag: latest) locally
Pulling repository 176.34.16.242:5000/memorycraft/centos
b939188f4672: Download complete
da6f1a424b7c: Download complete
dc6de6feb9a9: Download complete
af06476dc08c: Download complete
b2ab60219415: Download complete
65ec465a844b: Download complete
4a8d2a1dab88: Download complete
3897f6889349: Download complete
a149f9038d0e: Download complete
539c0211cd76: Download complete
30f9368972bb: Download complete
52b555115035: Download complete
bd1a450e0e46: Download complete
318326461017: Download complete
4787e46941f7: Download complete
380423464fbc: Download complete
dc52da789c75: Download complete
d0c94b943ba2: Download complete
9022a04f5b3f: Download complete
fc6935aadec7: Download complete
bash-4.1#
</pre>
<br />
ちゃんと取得できて、コンテナを立ち上げることが出来ました。<br />
これで、S3の高い堅牢性可用性をバックエンドにしたレジストリができました。<br />
<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-10730347195554804992014-02-17T10:30:00.000+09:002014-02-26T01:28:19.226+09:00Dockerってなんじゃ?(プライベートレジストリ)<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
<br />
<a href="http://memocra.blogspot.jp/2014/02/dockerdocker-index.html" target="_blank">前回の記事</a>で、Docker Indexというパブリックレジストリについて書きましたが、プライベートなレジストリを作ることも出来ます。それによって社外に出したくない資産などを管理することが出来ます。<br />
<br />
Docker Indexには、プライベートレジストリ用のリポジトリが提供されていて、それをpullしてコンテナとしてプライベートレジストリとして使うことが出来るようになっています。<br />
<br />
それでは、早速試してみたいと思います。<br />
localhostでも構いませんが、今回はレジストリ専用のサーバーを用意してみます。<br />
<a href="http://memocra.blogspot.jp/2014/02/docker.html" target="_blank">最初の記事</a>のようにレジストリサーバー上で、Dockerをインストールしておきます。<br />
<br />
<br />
<h1>
レジストリのインストールと起動</h1>
<br />
そして、Docker Indexのregistoryというリポジトリからpullしてきいます。<br />
<pre class="cmdprint"># docker pull registry</pre>
<br />
あとはこれを立ち上げるだけです。レジストリの内部ポートは5000番が使用されます。今回は外部ポートも5000番で指定します。<br />
<pre class="cmdprint"># docker run -d -p 5000:5000 registry</pre>
<br />
<br />
<br />
<h1>
commit</h1>
<br />
そしていままでのコンテナサーバー側で、コンテナをコミットしますが、指定の仕方が異なります。<br />
<pre class="prettyprint"><i>docker commit <コンテナID> <レジストリサーバーIP>:<レジストリポート>/<リポジトリ名></i>
</pre>
のようにします。<br />
<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b033c1821a7 centos:6.4 /bin/bash 38 minutes ago Exit 0
# docker commit 7b033c1821a7 176.34.16.242:5000/memorycraft
a2a360e08ee87d8fd3c98f08701ce0e4d681164e50432ff032890108eded996c
</pre>
<br />
<br />
すると以下のようにタグ付けされたイメージが保存されます。<br />
<pre class="cmdprint"># docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
176.34.16.242:5000/memorycraft latest a2a360e08ee8 12 seconds ago 360.4 MB
</pre>
<br />
<br />
<br />
<h1>
push</h1>
<br />
そしてこれをpushしてみます。pushもコミットと同様の指定の仕方になります。<br />
<pre class="cmdprint"># docker push 176.34.16.242:5000/memorycraft
The push refers to a repository [176.34.16.242:5000/memorycraft] (len: 1)
Sending image list
Pushing repository 176.34.16.242:5000/memorycraft (1 tags)
539c0211cd76: Image successfully pushed
a2a360e08ee8: Image successfully pushed
Pushing tags for rev [a2a360e08ee8] on {http://176.34.16.242:5000/v1/repositories/memorycraft/tags/latest}
</pre>
<br />
うまく自前のレジストリにむけてpushされたようです。<br />
<br />
<br />
<br />
<h1>
確認</h1>
<br />
次に、ローカルのイメージを削除してみます。<br />
<pre class="cmdprint"># docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
176.34.16.242:5000/memorycraft latest a2a360e08ee8 3 minutes ago 360.4 MB
# docker rmi a2a360e08ee8
Untagged: a2a360e08ee87d8fd3c98f08701ce0e4d681164e50432ff032890108eded996c
Deleted: a2a360e08ee87d8fd3c98f08701ce0e4d681164e50432ff032890108eded996c
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
</pre>
<br />
<br />
改めて、自前のレジストリから起動してみます。<br />
<pre class="cmdprint"># docker run -t -i 176.34.16.242:5000/memorycraft /bin/bash
Unable to find image '176.34.16.242:5000/memorycraft' (tag: latest) locally
Pulling repository 176.34.16.242:5000/memorycraft
539c0211cd76: Download complete
a2a360e08ee8: Download complete
bash-4.1#
bash-4.1#
</pre>
<br />
<br />
おお!無事起動しました。<br />
<br />
このように、自前のレジストリを用意すると、公開したくないコンテナイメージを社内やシステム内に限定して共有することができます。<br />
<br />
以上です。<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-16068808848006585932014-02-15T19:16:00.000+09:002014-02-26T01:28:46.855+09:00Dockerってなんじゃ?(Docker Index レジストリ)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJY/omQaYV3OalY/s1600/Homepage+-+Docker%253A+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
いままでのDockerの記事にも登場してきましたが、<br />
Dockerにはリポジトリという概念があります。<br />
<br />
<blockquote class="tr_bq">
A repository is a hosted collection of tagged images that together create the file system for a container. The repository’s name is a tag that indicates the provenance of the repository, i.e. who created it and where the original copy is located.<br />
<br />
<a href="http://docs.docker.io/en/latest/use/workingwithrepository/" target="_blank">working with repogistry</a></blockquote>
<br />
<br />
<h1>
リポジトリ</h1>
<br />
リポジトリというのはコンテナのファイルシステム(AUFS)を構成するタグ付けされたイメージのホストされた集合です。リポジトリ名は、例えば作成者とオリジナルコピーがどこにあるかなど、リポジトリの由来となるようなタグとして利用します。<br />
<br />
<br />
<br />
<h1>
レジストリ</h1>
<br />
リポジトリはレジストリ上に存在します。デフォルトではレジストリは<a href="http://index.docker.io/" target="_blank">Docker Index</a>というDockerがホストしているパブリックレジストリになります。Docker自身が提供しているトップレベルリポジトリもアカウント上に作られるユーザーリポジトリもあります。Docker IndexはgitでいうところのGithubのようなものになります。<br />
<br />
<br />
<br />
<h1>
アカウントを作成</h1>
<br />
Docker Indexを使うにはアカウントを作成してみます。まず、Dockerのサイトを開きます。<br />
sign upのローカルナビのリンクをクリックするとサインアップ画面が表示されるので、情報を入力して登録します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-9F0M0NdWzDY/Uv6ilO5UgmI/AAAAAAAAFJ4/j4K486i4RpE/s1600/Signup+-+Docker+2014-02-15+01-52-49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-9F0M0NdWzDY/Uv6ilO5UgmI/AAAAAAAAFJ4/j4K486i4RpE/s1600/Signup+-+Docker+2014-02-15+01-52-49.png" height="500" width="640" /></a></div>
<br />
<br />
確認メールが届くのでアクティベーションすると、登録完了します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-MExRbgg5ROo/Uv6it9TxZwI/AAAAAAAAFKA/X2aJXyq7O1I/s1600/Welcome+to+Docker+-+Docker+2014-02-15+01-53-36.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-MExRbgg5ROo/Uv6it9TxZwI/AAAAAAAAFKA/X2aJXyq7O1I/s1600/Welcome+to+Docker+-+Docker+2014-02-15+01-53-36.png" height="356" width="640" /></a></div>
<br />
<br />
マイページのAuthorized Serviceを開いてDocker Indexの「Go to application」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-tk2s0omy_t4/Uv6i8HVGJxI/AAAAAAAAFKQ/qf3DoN9XNgA/s1600/Docker+Services+-+Docker+2014-02-15+01-59-11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-tk2s0omy_t4/Uv6i8HVGJxI/AAAAAAAAFKQ/qf3DoN9XNgA/s1600/Docker+Services+-+Docker+2014-02-15+01-59-11.png" height="284" width="640" /></a></div>
<br />
<br />
すると、Docker Index画面が開くので、ログインします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-HJjl55ZxqhY/Uv6jYa_C-rI/AAAAAAAAFKg/-d50mheKv6M/s1600/Login+%7C+Docker+Index+2014-02-15+01-59-43.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-HJjl55ZxqhY/Uv6jYa_C-rI/AAAAAAAAFKg/-d50mheKv6M/s1600/Login+%7C+Docker+Index+2014-02-15+01-59-43.png" height="332" width="640" /></a></div>
<br />
<br />
Docker Indexの画面が表示され、自分のリポジトリ一覧画面が開かれますが、最初はなにもありません。<br />
これからここにリポジトリをアップしてみたいと思います。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-jZhq2-m8Log/Uv6jex_27YI/AAAAAAAAFKo/7r9G_seYajk/s1600/View+Public+Profile+%7C+Docker+Index+2014-02-15+02-00-03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-jZhq2-m8Log/Uv6jex_27YI/AAAAAAAAFKo/7r9G_seYajk/s1600/View+Public+Profile+%7C+Docker+Index+2014-02-15+02-00-03.png" height="372" width="640" /></a></div>
<br />
<br />
<br />
<h1>
リポジトリの操作</h1>
<br />
<br />
<b>login</b><br />
<br />
いったんブラウザを離れて、コマンドライン上でDocker Indexにログインします。<br />
ユーザー名、Eメール、パスワードを聞かれるので、先ほど登録したアカウントの情報を入力します。<br />
<pre class="cmdprint"># docker login
Username: memorycraft
Password:
Email: memorycraft@gmail.com
Login Succeeded
</pre>
<br />
これでdockerのコマンドラインとアカウントが紐付きました。<br />
<br />
<br />
<br />
<b>search</b><br />
<br />
<a href="http://memocra.blogspot.jp/2014/02/docker.html" target="_blank">最初のDocker記事</a>で使用したcentosというリポジトリは公式のリポジトリです。<br />
ユーザーはまず、Docker Indexレジストリ上にある公式または任意のユーザーの公開リポジトリを使用してコンテナを作っていきます。<br />
<br />
レジストリからリポジトリを探す場合は以下のようにします。<br />
<pre class="cmdprint"># docker search centos
NAME DESCRIPTION STARS OFFICIAL TRUSTED
tianon/centos CentOS 5 and 6, created using rinse instea... 6
centos 27
tutum/centos CentOS Docker image with SSH access 5
hnakamur/centos CentOS 6.5 x86_64 base image 1
zwxajh/centos centos 6 base system. 1
kalefranz/centos 2 [OK]
goyalankit/centos Bare centos repo 1
blalor/centos Bare-bones base CentOS 6.5 image 0 [OK]
backjlack/centos This repository contains the following ima... 0
.......
</pre>
<br />
このようにリポジトリ名などが出てきます。<br />
(centosはDocker Index上ではオフィシャルですが、なぜかCI上だとOFFICIALに印がありません)<br />
TRUSTEDはTrusted RepositoryというGitHubのリポジトリと連携してホストされている特殊なリポジトリです。これについてはまたの機会に触れてみたいと思います。<br />
<br />
<br />
<br />
<b>pull</b><br />
<br />
searchで目的のリポジトリが見つかったらこれを手元に持ってきて使います。<br />
<br />
たとえば<br />
<pre class="cmdprint"># docker pull centos</pre>
とすると、Dockerのレジストリからcentosリポジトリをローカルイメージとしてpullしてきます。<br />
また、<br />
<pre class="cmdprint"># docker run -t -i centos /bin/bash</pre>
とすると、ローカルにある場合はローカルのcentosのイメージを、なければDockerのレジストリからcentosのリポジトリからイメージをpullして、そのままコンテナを起動します。<br />
<br />
<br />
<br />
<b>commit</b><br />
<br />
いままでの記事にあったように、コンテナでいろいろ作業をしていくうちに、作業内容をコミットする場合があります。<br />
コミットはコンテナをイメージに変換して保存します。その場合イメージ名は"ユーザー名/イメージ名"のようにつけます。Docker Indexのアカウントのユーザー名にしておくとDocker Indexのレジストリに登録するときにわかりやすいです。<br />
<pre class="cmdprint"># docker commit <container_id> <username>/<imagename></pre>
<br />
<br />
<br />
<b>push</b><br />
<br />
pushをするとイメージをリポジトリに保存することができます。<br />
gitのpushと同じイメージです。pushする先がデフォルトの場合、レジストリはDocker Indexに登録されます<br />
<pre class="cmdprint"># docker push <username>/<repo_name></pre>
<br />
<br />
ここで、Docker Indexを見てみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-zS_0kSfXm2k/Uv6lGZBiPZI/AAAAAAAAFK8/H85ZnjVxlE4/s1600/View+Public+Profile+%7C+Docker+Index+2014-02-15+08-22-12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-zS_0kSfXm2k/Uv6lGZBiPZI/AAAAAAAAFK8/H85ZnjVxlE4/s1600/View+Public+Profile+%7C+Docker+Index+2014-02-15+08-22-12.png" height="380" width="640" /></a></div>
<br />
<br />
先ほどのリポジトリ一覧に、pushしたリポジトリが1つ表示されるようになりました!<br />
<br />
レジストリを使用することで、dockerのサーバが壊れた時の復旧や、環境を移行したり増やしたりする場合などに便利です。<br />
<br />
今回は以上です。<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-90781838203429493812014-02-13T15:40:00.000+09:002014-02-13T15:42:35.653+09:00Dockerってなんじゃ?(Dockerfileでビルド)<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJU/EehBj70H1pc/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-YZ81cKPBhCs/UvxpSd7XBWI/AAAAAAAAFJU/EehBj70H1pc/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="307" width="640" /></a></div>
<br />
<br />
DockerにはDockerfileというものがあります。<br />
docker buildを行うと、指定したパスからDockerfileを探し、コンテナを新規作成し記述されたステップを実行した後、コミットをしてコンテナイメージの作成までを自動で行います。<br />
<br />
たとえば<br />
<pre class="cmdprint">$ docker build -t hoge/moge /path/to/contxt/</pre>
とすると、/path/to/contxt/ディレクトリにあるDockerfileを元にステップ実行したコンテナをhoge/mogeというリポジトリ名で保存するところまでを自動で行ってくれます。<br />
<br />
Dockerfileの記述フォーマットは、基本的に<br />
<pre class="prettyprint">命令 引数</pre>
という形式で記載します。<br />
<br />
<br />
<br />
<h1>
命令</h1>
<br />
<br />
命令には以下のものがあります。<br />
<br />
<b>FROM</b><br />
<br />
コンテナの元になるベースイメージの指定をします<br />
<pre class="prettyprint">FROM <image></pre>
<br />
<b>MAINTAINER</b><br />
<br />
生成されるイメージのAuthorフィールドの指定をします<br />
<pre class="prettyprint">MAINTAINER <name></pre>
<br />
<b>RUN</b><br />
<br />
ビルドステップ内で実行されるコマンドです<br />
<pre class="prettyprint"># /bin/sh -cでのコマンドとして実行されます
RUN <command>
# 実行プログラムを直接指定します
RUN ["executable", "param1", "param2"]</pre>
<br />
<b>CMD</b><br />
<br />
作成されたコンテナ起動時のデフォルトコマンドです<br />
<pre class="prettyprint"># 実行プログラムを直接指定します
CMD ["executable","param1","param2"]
# ENTRYPOINTのデフォルトパラメータを定義します
CMD ["param1","param2"]
# シェルとして実行されます
CMD command param1 param</pre>
<br />
<b>EXPOSE</b><br />
<br />
指定されたポートを開放します。指定するのはコンテナ内部からみたポート番号です<br />
<pre class="prettyprint">EXPOSE <port> [<port>...]</pre>
<br />
<b>ENV</b><br />
<br />
環境変数をセットします<br />
<pre class="prettyprint">ENV <key> <value></pre>
<br />
<b>ADD</b><br />
<br />
コンテナ外のファイルをコンテナ内に配置します<br />
<pre class="prettyprint">ADD <src> <dest></pre>
<br />
<b>ENTRYPOINT</b><br />
<br />
作成されたコンテナ起動時のコマンドです<br />
CMDと異なり、docker runで引数が与えられた場合、コマンド自体が上書きされず、パラメータとして扱います<br />
<pre class="prettyprint"># 実行プログラムを直接指定します
ENTRYPOINT ["executable", "param1", "param2"]
# シェルとして実行されます
ENTRYPOINT command param1 param2</pre>
<br />
<b>VOLUME</b><br />
<br />
外部からボリュームとしてマウントする際のマウントポイントです<br />
<pre class="prettyprint">VOLUME ["/data"]</pre>
<br />
<b>USER</b><br />
<br />
コンテナを起動する際のユーザー名またはUIDです<br />
<pre class="prettyprint">USER daemon</pre>
<br />
<b>WORKDIR</b><br />
<br />
CMDが実行される時のワークディレクトリを指定します<br />
<pre class="prettyprint">WORKDIR /path/to/workdir</pre>
<br />
<b>ONBUILD</b><br />
<br />
ビルド完了後に実行される命令です<br />
他の命令と同じタイミングではまだ実行できないような命令の場合、全てのビルドが終わってから実行されます<br />
<pre class="prettyprint">ONBUILD [INSTRUCTION]</pre>
<br />
以上、これらの命令を組み合わせて、コンテナの中身を組み上げていきます。<br />
<br />
<br />
<br />
<br />
<h1>
Dockerfileの作成</h1>
<br />
<br />
前回の記事でつくったsshdとhttpdをsupervisordで起動するコンテナを、上記の命令を組み合わせてDockerfileを記述して作ってみると以下のようになります。<br />
<br />
<pre class="prettyprint"># centosがベース
FROM centos
# 作成者
MAINTAINER memorycraft
# yumでいろいろインストール
RUN yum install sudo passwd openssh openssh-clients openssh-server httpd vim python-setuptools -y
# sshdの設定
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config
# キーの生成
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
# sshでログインするユーザーを用意
RUN useradd memorycraft
RUN echo 'memorycraft:memorycraft_password' | chpasswd
RUN echo 'memorycraft ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/memorycraft
# httpdのトップページ
RUN echo 'moge' > /var/www/html/index.html
# supervisordのインストール
RUN easy_install supervisor
# supervisordの設定
RUN echo_supervisord_conf > /etc/supervisord.conf
RUN echo '[include]' >> /etc/supervisord.conf
RUN echo 'files = supervisord/conf/*.conf' >> /etc/supervisord.conf
RUN mkdir -p /etc/supervisord/conf/
ADD templates/memorycraft/conf/supervisor.conf /etc/supervisord/conf/service.conf
# ポート開放
EXPOSE 22 80
# 起動時にsupervisordを実行
CMD ["/usr/bin/supervisord"]
</pre>
<br />
<br />
<br />
<h1>
ビルドの実行</h1>
<br />
それでは、このDockerfileをビルドしてコンテナイメージを作成します。
ポイントは--rmです。<br />
デフォルトでは1つの命令が実行されるごとにコミットが行われ、沢山のコンテナが出来てしまいますがこのオプションをつけることで、ビルドが成功した後に中間コンテナを全て消してくれます。
<br />
<pre class="cmdprint"># docker build --no-cache --rm -t memorycraft/centos .
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
memorycraft/centos latest d0c94b943ba2 2 minutes ago 437.9 MB
centos 6.4 539c0211cd76 10 months ago 300.6 MB
centos latest 539c0211cd76 10 months ago 300.6 MB
</pre>
<br />
作成には成功しているようです。<br />
続けて、このイメージでコンテナを起動してみます。<br />
<pre class="cmdprint"># docker run -d -p 22 -p 80 memorycraft/centos /usr/bin/supervisord
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d4a403c44c5 memorycraft/centos:latest /usr/bin/supervisord 44 seconds ago Up 43 seconds 0.0.0.0:49185->22/tcp, 0.0.0.0:49186->80/tcp goofy_darwin
c118bcc97b1e centos:6.4 /bin/bash 18 hours ago Exit 0
</pre>
<br />
<br />
<br />
<h1>
確認</h1>
<br />
<br />
それでは、このコンテナに前回同様アクセスしてみたいと思います。sshのユーザー/パスワードはDockerfileで指定したものを使います。
<br />
<pre class="cmdprint"># ssh memorycraft@127.0.0.1 -p 49185
The authenticity of host '[127.0.0.1]:49185 ([127.0.0.1]:49185)' can't be established.
RSA key fingerprint is ea:46:dd:dd:07:64:89:6e:b6:e4:38:73:41:82:32:b7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49185' (RSA) to the list of known hosts.
memorycraft@127.0.0.1's password:
[memorycraft@1d4a403c44c5 ~]$
</pre>
<br />
無事接続出来ました!
<br />
<br />
また、ブラウザにもアクセスしてみます。
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-WjXB4leM4Po/Uvxkh0gqsMI/AAAAAAAAFJE/Is0IdUiTqyM/s1600/54.250.80.31:49186+2014-02-13+15-22-05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-WjXB4leM4Po/Uvxkh0gqsMI/AAAAAAAAFJE/Is0IdUiTqyM/s1600/54.250.80.31:49186+2014-02-13+15-22-05.png" height="200" width="400" /></a></div>
<br />
<br />
表示されてます!<br />
これで、Dockerfileのコーディングによるインフラ管理ができるようになります。
<br />
<br />
今回は以上です。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-60414344657579418162014-02-13T00:22:00.000+09:002014-02-13T12:37:56.889+09:00Dockerってなんじゃ?(Supervisorで複数のサービス起動)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Lp4eWuu9O70/UvuRUD5bjyI/AAAAAAAAFIo/coh0IHhDdRM/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Lp4eWuu9O70/UvuRUD5bjyI/AAAAAAAAFIo/coh0IHhDdRM/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
Dockerネタです。<br />
<a href="http://memocra.blogspot.jp/2014/02/docker.html" target="_blank">前回の記事</a>で、DockerでSSHサーバとして起動しましたが、通常いろいろなサービスを起動したコンテナを使うことの方が多いと思います。<br />
<br />
Dockerでは起動時に1つのCMDしか指定できないようで、前回のやり方では1つのサービスしか起動できません。
このような場合は、Supervisorを利用するといいようです。
<br />
<br />
たとえば、sshdとhttpdをサービス起動したコンテナの場合、コンテナ内のsupervisordがsshdとhttpdを管理し、dockerがsupervisordを使ってサービス起動するというイメージです。
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-B8np0mxTARk/UvuDlIpNzvI/AAAAAAAAFIQ/azhcpEBepbA/s1600/Untitled(1)+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-B8np0mxTARk/UvuDlIpNzvI/AAAAAAAAFIQ/azhcpEBepbA/s1600/Untitled(1)+(1).png" /></a></div>
<br />
<br />
それでは早速試してみます。<br />
コンテナは前回と同じcentosをつかいます。<br />
<br />
<br />
<br />
<h1>
コンテナの起動</h1>
<br />
コンテナを立ちあげてコンソールにアクセスします。
<br />
<pre class="cmdprint"># docker run -t -i centos /bin/bash
</pre>
<br />
<br />
<br />
<h1>
sshとhttpdのインストール</h1>
<br />
コンテナに入ったらまず、必要なsshdやhttpd、supervisorインストール用のeasy?installなどのプログラムを準備します。
<br />
<pre class="cmdprint">-bash-4.1# yum install passwd openssh openssh-clients openssh-server httpd vim python-setuptools -y
</pre>
<br />
<br />
sshdの設定をします。
<br />
<pre class="cmdprint">-bash-4.1# vim /etc/ssh/sshd_config
</pre>
<pre class="prettyprint">#UsePAM no
UsePAM yes
↓
UsePAM no
#UsePAM yes
</pre>
<br />
<br />
rootユーザのパスワードを設定します。
<br />
<pre class="cmdprint">-bash-4.1# passwd
</pre>
<br />
<br />
httpdのインデックスページを用意します。
<br />
<pre class="cmdprint">-bash-4.1# -bash-4.1# echo moge > /var/www/html/index.html
</pre>
<br />
<br />
<h1>
Supervisorのインストール</h1>
<br />
supervisorをインストールします。
<br />
<pre class="cmdprint">-bash-4.1# easy_install supervisor</pre>
<br />
<br />
supervisorの起動スクリプトを用意します。
<br />
<pre class="cmdprint">-bash-4.1# vim /etc/init.d/supervisord
</pre>
<pre class="prettyprint">#!/bin/sh
#
# /etc/rc.d/init.d/supervisord
#
# Supervisor is a client/server system that
# allows its users to monitor and control a
# number of processes on UNIX-like operating
# systems.
#
# chkconfig: - 64 36
# description: Supervisor Server
# processname: supervisord
# Source init functions
. /etc/init.d/functions
RETVAL=0
prog="supervisord"
pidfile="/tmp/supervisord.pid"
lockfile="/var/lock/subsys/supervisord"
start()
{
echo -n $"Starting $prog: "
daemon --pidfile $pidfile supervisord
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}
}
stop()
{
echo -n $"Shutting down $prog: "
killproc -p ${pidfile} /usr/bin/supervisord
RETVAL=$?
echo
if [ $RETVAL -eq 0 ] ; then
rm -f ${lockfile} ${pidfile}
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $prog
;;
restart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
;;
esac
</pre>
<pre class="cmdprint">
# chmod 755 /etc/init.d/supervisord
</pre>
<br />
<br />
<br />
<h1>
Supervisorの設定</h1>
<br />
supervisorの設定ファイルを用意します。
<br />
<pre class="cmdprint">-bash-4.1# echo_supervisord_conf > /etc/supervisord.conf
-bash-4.1# echo "[include]" >> /etc/supervisord.conf
-bash-4.1# echo "files = supervisord/conf/*.conf" >> /etc/supervisord.conf
-bash-4.1# mkdir -p /etc/supervisord/conf/
</pre>
<br />
<br />
設定を記載します。
ここでポイントは、supervisord自身のnodaemon=trueという項目です。<br />
これによって、supervisordがフォアグラウンド起動します。
<br />
<pre class="cmdprint">-bash-4.1# vim /etc/supervisord/conf/service.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true
[program:httpd]
command=/usr/sbin/httpd -c "ErrorLog /dev/stdout" -DFOREGROUND
redirect_stderr=true
</pre>
<br />
<br />
ここで、コンテナを抜けます。
<br />
<pre class="cmdprint">-bash-4.1# exit
</pre>
<br />
<br />
<br />
<h1>
コンテナイメージの作成</h1>
<br />
ホスト側で、一度コミットします。
<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c118bcc97b1e centos:6.4 /bin/bash 3 hours ago Exit 0
# docker commit c118bcc97b1e memorycraft/centos
</pre>
<br />
<br />
<br />
<h1>
コンテナの起動</h1>
<br />
それでは、コミットしたイメージで新しいコンテナを起動してみます。<br />
このとき、起動するコマンドに/usr/bin/supervisordを指定し、開放ポートに22と80を2つ指定します。
<br />
<pre class="cmdprint"># docker run -d -p 22 -p 80 memorycraft/centos /usr/bin/supervisord
</pre>
<br />
<br />
<br />
<h1>
確認</h1>
<br />
それではコンテナに対してsshとhttpでアクセスしてみます。<br />
docker ps -aで、ポートマッピングの状況がわかります。
<br />
<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
337f5660c4d0 memorycraft/centos:latest /usr/bin/supervisord 47 minutes ago Up 47 minutes 0.0.0.0:49173->22/tcp, 0.0.0.0:49174->80/tcp stoic_bell
c118bcc97b1e centos:6.4 /bin/bash 3 hours ago Exit 0 sad_torvalds
</pre>
<br />
<br />
マッピングされたポートをつかってsshアクセスしてみます。
<br />
<pre class="cmdprint"># ssh root@127.0.0.1 -p 49173
The authenticity of host '[127.0.0.1]:49173 ([127.0.0.1]:49173)' can't be established.
RSA key fingerprint is 59:de:98:f5:21:15:bc:40:c1:29:8d:76:84:eb:59:05.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49173' (RSA) to the list of known hosts.
root@127.0.0.1's password:
</pre>
<br />
アクセスできました!<br />
<br />
続けて、httpです。<br />
マッピングされたポートをつかってブラウザアクセスしてみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-AiBMkZ4sn-c/UvuQzVegzYI/AAAAAAAAFIg/2gsZ1Sf9ak0/s1600/54.250.80.31:49174+2014-02-12+23-38-17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-AiBMkZ4sn-c/UvuQzVegzYI/AAAAAAAAFIg/2gsZ1Sf9ak0/s1600/54.250.80.31:49174+2014-02-12+23-38-17.png" height="147" width="400" /></a></div>
<br />
<br />
<br />
おお!確認できました!<br />
<br />
これで複数のサービスが起動したコンテナを作れます。<br />
今回は、以上です。<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-26725719117429866342014-02-11T08:09:00.000+09:002014-02-11T08:09:15.126+09:00Node.jsってなんじゃ?(gm:GraphicsMagickで画像合成)今回はnode.jsを利用して、画像合成をしてみたいと思います。<br />
この手の画像生成にはImageMagickがよく使われますが、ImageMagickから派生した<a href="http://www.graphicsmagick.org/index.html" target="_blank">GraphicMagick</a>がImageMagickよりもパフォーマンスが優れているのでこちらの方を利用します。<br />
<br />
node.js内からは、GraphicMagick/ImageMagickを使用できる<a href="http://aheckmann.github.io/gm/" target="_blank">gm</a>というモジュールを利用します。<br />
<br />
今回node.jsは久しぶりなので、nodeのインストールから始めてみたいと思います。<br />
他のLL言語などでもそうですが、nvmやenv系などインストール環境管理ツールが乱立しているようです。<br />
今回はnodebrewが便利そうなので、<a href="https://github.com/hokaccha/nodebrew" target="_blank">nodebrew</a>を使ってみました。<br />
<br />
<br />
<h1>
GraphickMagickのインストール</h1>
<br />
yumでインストールします。<br />
<pre class="cmdprint"># yum install gcc-c++ GraphicsMagick -y
</pre>
<div>
<br /></div>
<br />
<br />
<h1>
nodebrewを使ったnode.jsとモジュールのインストール</h1>
<br />
nodebrewでは、インストール実行した場所だけにファイルが作られるようで環境を汚さず、rootでなくともインストールが可能なことが特徴のようです。<br />
インストールを行い、PATHを通すだけで完了なので、とても簡単です。
<br />
<pre class="cmdprint"># cat /etc/profile.d/nodebrew.sh
#!/bin/bash
export NODE_PATH=$HOME/.nodebrew/current/node_modules
export PATH=$HOME/.nodebrew/current/bin:$PATH
$ source /etc/profile
$ cd ~/
$ curl https://raw.github.com/hokaccha/nodebrew/master/nodebrew | perl - setup
$ nodebrew install latest
$ nodebrew use latest
$ node -v
v0.11.11
$ npm install gm
$ npm install argv
</pre>
<br />
<br />
<br />
<h1>
実装</h1>
<br />
<br />
<b>image.js</b>
<br />
<br />
画像合成のメイン処理です。引数の画像URLをダウンロードして画像合成します。<br />
<br />
<script src="https://gist.github.com/memorycraft/8925088.js"></script>
<br />
<br />
<b>gmcomposite.js</b>
<br />
<br />
合成を子プロセスで実行する箇所をモジュール化したものです。<br />
<br />
<script src="https://gist.github.com/memorycraft/8925118.js"></script>
<br />
<br />
<h1>
画像部品の配置</h1>
<br />
<br />
今回の合成ではfacebookのプロフィール写真がどうにも無愛想なので、かわいくしてみたいと思います。
合成素材用のディレクトリ、合成後の出力先のディレクトリを作成します。
<br />
<pre class="cmdprint">$ mkdir -p assets rslt/convert rslt/composite rslt/download
$ tree ~/
/home/memorycraft/
|-- assets
| `-- frame.png //合成素材(マスク+ベース兼用)
|-- gmcomposite.js
|-- image.js
|-- node_modules
| |-- argv
| `-- gm
|-- rslt
| |-- composite
| |-- convert
| `-- download
`-- tmp
</pre>
<br />
また、httpdサーバのドキュメントルートから出力先ディレクトリにリンクします。
<br />
<pre class="cmdprint"># chmod 755 /home/memorycraft/
# cd /var/www/html
# ln -s /home/memorycraft/rslt rslt
</pre>
<br />
<br />
assetsディレクトリにマスク素材を配置します。<br />
<br />
<b>frame.png</b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1aUp-wyuPBU/UvlQtyUAUSI/AAAAAAAAFHU/O7m1Qn6fUxQ/s1600/frame.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1aUp-wyuPBU/UvlQtyUAUSI/AAAAAAAAFHU/O7m1Qn6fUxQ/s400/frame.png" height="320" width="318" /></a></div>
<br />
<br />
<br />
<h1>
実行</h1>
<br />
<br />
それでは実行します。
オプション引数にfacebookの画像URLと、facebook ID(画像名につかうだけなので何でも良い)を渡します。
<br />
<pre class="cmdprint">$ node image.js -u http://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-prn1/t1/1525482_10202990719234672_615625235_n.jpg -f memocra
create complete !
</pre>
無事出力できたようです。
<br />
<br />
<br />
<br />
<h1>
確認</h1>
<br />
それでは出力された画像をブラウザで確認してみます。
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-H3Si0Hq32jQ/UvlZfiaf89I/AAAAAAAAFHw/44NdwX9ooac/s1600/memocra.jpg+(800%C3%97800)+2014-02-11+07-55-35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-H3Si0Hq32jQ/UvlZfiaf89I/AAAAAAAAFHw/44NdwX9ooac/s1600/memocra.jpg+(800%C3%97800)+2014-02-11+07-55-35.png" height="640" width="571" /></a></div>
<br />
<br />
。。。。ちょっと思った感じと違いますが、とりあえず合成できたのでよしとします。<br />
今回は以上です。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-77165688623256982212014-02-10T10:00:00.000+09:002014-02-10T10:00:03.597+09:00TreasureDataってなんじゃ?<a href="https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCkQFjAA&url=http%3A%2F%2Fwww.treasuredata.com%2F&ei=uur3UsOxBoj4kAXyxoG4DA&usg=AFQjCNHJHDO6EV_-kwba9-_1_BYjdfQyaQ&sig2=O46Y5sVzA4T_J4UluKIt7g&bvm=bv.60983673,d.dGI" target="_blank">Treasure Data</a>はデータの収集、保存、管理、処理、可視化などを行えるログ解析の基盤サービスで、fluentdを使ってデータを収集し、hadoopで解析を行います。<br />
自分も<a href="http://memocra.blogspot.jp/2014/02/kibanakibana3-elasticsearch-fluentd.html" target="_blank">以前の記事</a>で書きましたが、よくelasticsearch + kibanaや、splunkなどの部分がサービス化されているようなイメージです。<br />
<br />
Treasure Dataについては、中の人が<a href="http://doryokujin.hatenablog.jp/entry/2014/01/10/165221" target="_blank">非常に詳しくブログで書かれています</a>。<br />
<br />
それでは実際に触ってみます。<br />
<br />
<br />
<h1>
ユーザー登録&ログイン</h1>
<br />
<a href="http://www.treasuredata.com/jp/products/try-it-now.php">http://www.treasuredata.com/jp/products/try-it-now.php</a><br />
にアクセスして、サインアップのリンクをクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-zvAJPRSnHqw/Uvffr7LvWyI/AAAAAAAAFGc/27s6ZIb9U3A/s1600/%E3%83%88%E3%83%AC%E3%82%B7%E3%82%99%E3%83%A3%E3%83%BC%E3%83%86%E3%82%99%E3%83%BC%E3%82%BF+%7C+%E4%BB%8A%E3%81%99%E3%81%8F%E3%82%99%E7%84%A1%E6%96%99%E7%89%88Treasure+Data+Service%E3%82%92%E3%81%8A%E8%A9%A6%E3%81%97%E3%81%8F%E3%81%9F%E3%82%99%E3%81%95%E3%81%84+2014-02-10+03-10-02.png+2014-02-10+05-05-57.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-zvAJPRSnHqw/Uvffr7LvWyI/AAAAAAAAFGc/27s6ZIb9U3A/s1600/%E3%83%88%E3%83%AC%E3%82%B7%E3%82%99%E3%83%A3%E3%83%BC%E3%83%86%E3%82%99%E3%83%BC%E3%82%BF+%7C+%E4%BB%8A%E3%81%99%E3%81%8F%E3%82%99%E7%84%A1%E6%96%99%E7%89%88Treasure+Data+Service%E3%82%92%E3%81%8A%E8%A9%A6%E3%81%97%E3%81%8F%E3%81%9F%E3%82%99%E3%81%95%E3%81%84+2014-02-10+03-10-02.png+2014-02-10+05-05-57.png" height="562" width="640" /></a></div>
<br />
<br />
<br />
サインアップ画面が表示されるので、必要な情報を入力して登録します。<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-5BRaaY0NA44/UvfeYH2LP_I/AAAAAAAAFFA/aVAzrrHaDuY/s1600/Sign+Up+2014-02-10+03-10-59.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-5BRaaY0NA44/UvfeYH2LP_I/AAAAAAAAFFA/aVAzrrHaDuY/s1600/Sign+Up+2014-02-10+03-10-59.png" height="640" width="408" /></a></div>
<br />
<br />
<br />
登録が終わると、確認メールが送られてくるので、確認リンクをクリックして登録完了です。<br />
また、ログインする場合は、以下のような画面でログインすることになります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-fdZh0rJDNIo/UvfeYFrUmVI/AAAAAAAAFE8/TfZcbkVKMF0/s1600/Sign+In+2014-02-10+03-11-38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-fdZh0rJDNIo/UvfeYFrUmVI/AAAAAAAAFE8/TfZcbkVKMF0/s1600/Sign+In+2014-02-10+03-11-38.png" height="640" width="492" /></a></div>
<br />
<br />
<br />
<br />
<h1>
ログの送信</h1>
<br />
<br />
ログの収集対象となるサーバーで、apacheのログデータをTreasure Dataに送信するように設定します。<br />
まず、ログのあるサーバーでtd accountコマンドを使って先ほど登録したメールアドレスとパスワードを設定して、アカウントを紐付けます。<br />
<br />
<pre class="cmdprint"># td account
Enter your Treasure Data credentials.
Email: miura@cloudpack.jp
Password (typing will be hidden):
Authenticated successfully.
Use 'td db:create <db_name>' to create a database.
</pre>
<br />
<br />
次に、Treasure Dataに送信する時のAPIキーを取得するために、td apikey:showコマンドを実行します。<br />
(APIキーは伏せてあります。)<br />
<pre class="cmdprint"># td apikey:show
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</pre>
<br />
<br />
次に、/etc/td-agent/td-agent.confで、sourceをapacheアクセスログのtailを、matchで今のAPIキーを使ったtdlogを設定します。tdlogがTreasure Dataにログを送信するためのプラグインになります。<br />
auto_create_tableを設定しておくと、自動的にログ用のテーブルがTreasure Data側に用意されます。<br />
<br />
<pre class="prettyprint"> <source>
type tail
format apache
path /var/log/httpd/access_log
pos_file /tmp/access.log.pos
tag td.apache.access
</source>
<match td.*.*>
type tdlog
apikey XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
auto_create_table
buffer_type file
buffer_path /var/log/td-agent/buffer/td
use_ssl true
</match>
</pre>
<br />
<br />
設定したら、td-agentを起動します。<br />
<pre class="cmdprint">/etc/init.d/td-agent start
</pre>
<br />
ログ収集対象のサーバーの設定は以上です。<br />
<br />
td tablesコマンドを使用すると、Treasure Data側で作成されたテーブルの一覧が表示されます。<br />
<br />
<pre class="cmdprint"># td tables;
+-----------+------------+------+-------+--------+---------------------------+---------------------------+----------------------------------------------------------------------------------------------------------+
| Database | Table | Type | Count | Size | Last import | Last log timestamp | Schema |
+-----------+------------+------+-------+--------+---------------------------+---------------------------+----------------------------------------------------------------------------------------------------------+
| apache | access | log | 26 | 0.0 GB | 2014-02-10 04:01:49 +0900 | 2014-02-10 04:00:17 +0900 | host:string, path:string, method:string, referer:string, code:long, agent:string, user:string, size:long |
| sample_db | www_access | log | 5,000 | 0.0 GB | 2014-01-30 16:43:07 +0900 | 2013-09-07 10:13:45 +0900 | host:string, path:string, method:string, referer:string, code:long, agent:string, user:string, size:long |
+-----------+------------+------+-------+--------+---------------------------+---------------------------+----------------------------------------------------------------------------------------------------------+
2 rows in set
</pre>
<br />
<br />
Treasure Dataのアカウントを作成すると、デフォルトでsample_dbというデータベースが用意されていますが、ログが保存され始めると、apacheデータベースのaccessテーブルというのが作られています。<br />
DB名、テーブル名はsourceのtagを元に作成されます。<br />
<br />
<br />
<h1>
Treasure Dataでの集計</h1>
<br />
Treasure Dataの管理画面のDatabasesにも、apacheデータベースが追加されていることがわかります。<br />
ドリルダウンしていくと、登録されているログデータが構造化されているのを見ることができます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-skmES0UnoW4/UvfeahfxJqI/AAAAAAAAFF0/DegniZFnun4/s1600/Treasure-Data+2014-02-10+04-06-33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-skmES0UnoW4/UvfeahfxJqI/AAAAAAAAFF0/DegniZFnun4/s1600/Treasure-Data+2014-02-10+04-06-33.png" height="212" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Rbt_oIXPWBg/UvfnAvAgoMI/AAAAAAAAFGs/227aYpKs3wk/s1600/Treasure-Data+2014-02-10+05-37-09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Rbt_oIXPWBg/UvfnAvAgoMI/AAAAAAAAFGs/227aYpKs3wk/s1600/Treasure-Data+2014-02-10+05-37-09.png" height="344" width="640" /></a></div>
<br />
<br />
<br />
左ペインのNew Queryで集計の設定をおこないます。<br />
データベースはapacheを選択し、今回はQuery typeはHiveを選択します。<br />
Queryに集計するためのHiveクエリを書き、あとはそのままで「Submit」をクリックすると、Jobの実行が開始されます。Job実行はスケジューリングすることもできます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-ODf-mfo8jyc/UvfebfdLFOI/AAAAAAAAFGE/I13Kub4T7tc/s1600/Treasure-Data+2014-02-10+04-12-15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-ODf-mfo8jyc/UvfebfdLFOI/AAAAAAAAFGE/I13Kub4T7tc/s1600/Treasure-Data+2014-02-10+04-12-15.png" height="540" width="640" /></a></div>
<br />
<br />
<br />
Copy result toでMySQLやS3など結果を保存する先を指定することもできます。<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-q5yOea43PqA/UvfowIN-IvI/AAAAAAAAFG4/MkswZOe3JQs/s1600/Treasure-Data+2014-02-10+04-06-04.png+2014-02-10+05-44-37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-q5yOea43PqA/UvfowIN-IvI/AAAAAAAAFG4/MkswZOe3JQs/s1600/Treasure-Data+2014-02-10+04-06-04.png+2014-02-10+05-44-37.png" height="220" width="640" /></a></div>
<br />
<br />
<br />
Jobの実行が終わると、Jobリストとして結果が表示されます。<br />
今回は、結果の保存先を特に指定していないので、この結果画面にそのまま結果が表示されます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-0ibyKY9U-nA/Uvfeb9CrRKI/AAAAAAAAFGU/y3SiOTSSOMU/s1600/Treasure-Data+2014-02-10+04-16-42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-0ibyKY9U-nA/Uvfeb9CrRKI/AAAAAAAAFGU/y3SiOTSSOMU/s1600/Treasure-Data+2014-02-10+04-16-42.png" height="504" width="640" /></a></div>
<br />
<br />
<br />
ざっとですが、td-agentを使ったログの収集、Treasure Dataの管理コンソールでのログの確認、集計をさらってみました。<br />
<br />
今回は以上です。<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-74265915503115930722014-02-06T22:41:00.000+09:002014-02-06T23:37:45.289+09:00Kibanaってなんじゃ?(kibana3 + elasticsearch + fluentd)ずんぶん前に<a href="http://memocra.blogspot.jp/2013/04/kibanakibanaelasticsearchfluentd.html" target="_blank">Kibanaの記事</a>を書きましたが、時がたちKibana3がとても感じがよいと巷で評判なので、再入門してみます。<br />
<br />
<h1>
インデックスサーバー側</h1>
<br />
<h2>
準備</h2>
インデックスサーバー側のポートは80,22の他に、fluent用に9200番ポートを開けておきます。<br />
また、インデックスは最終的に大きくなるので、容量の大きなストレージに入れておきます。<br />
<br />
<pre class="cmdprint"># yum install xfsprogs httpd java-1.7.0-openjdk -y
# mkfs.xfs /dev/xvdf
# mount -t xfs /dev/xvdf /mnt/ebs/0
</pre>
<br />
<br />
<h2>
Kibana3のインストール</h2>
Kibanaはv3になってから、rubyではなくhtmlになりました。DocumentRoot下に置いてhttpdを起動するだけでOKです。<br />
<br />
<pre class="cmdprint"># cd /var/www/
# curl -OL http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip
# unzip kibana-latest.zip
# mv html html.org
# mv kibana-latest html
# /etc/init.d/httpd start
</pre>
<br />
<br />
<h2>
ElasticSearchのインストール</h2>
<pre class="cmdprint"># cd /mnt/ebs/0/
# curl -OL https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.11.tar.gz
# tar xzvf elasticsearch-0.90.11.tar.gz
# cd elasticsearch-0.90.11/
# ./bin/elasticsearch start
</pre>
<br />
これで、インデックスサーバー側は準備ができました。<br />
<br />
<br />
<br />
<h1>
ログ送信サーバー側</h1>
<br />
apacheのログを送信するとして、ここではfluentdの設定はin:tailとout:elasticsearchプラグインを使います。<br />
<br />
<pre class="cmdprint"># yum install td-agent -y
# vim /etc/td-agent/td-agent.conf
</pre>
<pre class="prettyprint"><source>
type tail
format apache2
path /var/log/httpd/access_log
pos_file /tmp/access.log.pos
tag server1.apache.access
</source>
<match server1.apache.access>
type_name apache
type elasticsearch
include_tag_key true
tag_key @log_name
host XXX.XXX.XXX.XXX
port 9200
logstash_format true
flush_interval 10s
</match>
</pre>
<br />
<br />
<pre class="cmdprint"># /etc/init.d/td-agent start
</pre>
<br />
これでログの送信設定は完了です。<br />
<br />
<br />
<br />
<h1>
確認</h1>
<br />
<br />
ここまで設定できたらkibanaの画面を見てみます。<br />
これがデフォルトのトップ画面です。<br />
右側の[Logstash Dashboard]というリンクをクリックすると、ダッシュボード画面に遷移します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-hrf7T68aG7c/UvOJiaJSnwI/AAAAAAAAFDM/AxXW6DLbNeg/s1600/Kibana+3+2014-02-05+19-54-48.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-hrf7T68aG7c/UvOJiaJSnwI/AAAAAAAAFDM/AxXW6DLbNeg/s1600/Kibana+3+2014-02-05+19-54-48.jpg" height="260" width="640" /></a></div>
<br />
<br />
<br />
ダッシュボードでは、fluentdから送られてきたログがひな形のダッシュボードに表示されていることがわかります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8NvgdZxCEng/UvOJ7Z7h_kI/AAAAAAAAFDY/R9012NgoZ_M/s1600/Kibana+3+2014-02-06+18-57-47.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-8NvgdZxCEng/UvOJ7Z7h_kI/AAAAAAAAFDY/R9012NgoZ_M/s1600/Kibana+3+2014-02-06+18-57-47.jpg" height="416" width="640" /></a></div>
<br />
<br />
<br />
<br />
<h2>
クエリの追加</h2>
クエリフィールドはフィールドの「+」ボタンでいくつも登録できます。<br />
クエリの書式は<a href="http://lucene.apache.org/core/2_9_4/queryparsersyntax.html" target="_blank">luceneの書式</a>が基本となっているようです。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-AK5EMbYOq_o/UvOMXnAguWI/AAAAAAAAFDg/IZg0uutvX48/s1600/Kibana+3+2014-02-06+22-16-48.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-AK5EMbYOq_o/UvOMXnAguWI/AAAAAAAAFDg/IZg0uutvX48/s1600/Kibana+3+2014-02-06+22-16-48.jpg" height="74" width="640" /></a></div>
<br />
<br />
<br />
<h2>
パネルの追加</h2>
ダッシュボードはグリッド上にできており、基本的に行(ROW)にパネルを追加していきます。<br />
パネルはひとつまたは複数のクエリを使用します。<br />
<br />
ROWにある「Add Panel」ボタンでパネルを追加します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-yVXkKQRAMzU/UvOMjBYiWHI/AAAAAAAAFDo/7VG_p52O3Mo/s1600/Kibana+3+2014-02-06+22-15-20.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-yVXkKQRAMzU/UvOMjBYiWHI/AAAAAAAAFDo/7VG_p52O3Mo/s1600/Kibana+3+2014-02-06+22-15-20.jpg" height="428" width="640" /></a></div>
<br />
<br />
<br />
パネル追加画面では、パネルのタイプや使用するクエリや、その他パネル固有のパラメータを設定します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-hfH-t3sP4oY/UvOMwn6AXfI/AAAAAAAAFDw/EF_nL-Ing90/s1600/Kibana+3+2014-02-06+22-14-18.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-hfH-t3sP4oY/UvOMwn6AXfI/AAAAAAAAFDw/EF_nL-Ing90/s1600/Kibana+3+2014-02-06+22-14-18.jpg" height="268" width="640" /></a></div>
<br />
<br />
いくつかのクエリとパネルを組み合わせて目的に会ったダッシュボードを造ります。<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-E14JLitC8XU/UvONshSRYwI/AAAAAAAAFEE/3Feq6NPusPk/s1600/Kibana+3+2014-02-06+22-26-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-E14JLitC8XU/UvONshSRYwI/AAAAAAAAFEE/3Feq6NPusPk/s1600/Kibana+3+2014-02-06+22-26-27.jpg" height="564" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
作成したら、名前をつけてダッシュボードを保存することで、リロードしても保持されるようになります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-x-dVy6FNyww/UvONskZh73I/AAAAAAAAFEI/e9e7cf8Gfcc/s1600/Kibana+3+2014-02-06+22-26-51.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-x-dVy6FNyww/UvONskZh73I/AAAAAAAAFEI/e9e7cf8Gfcc/s1600/Kibana+3+2014-02-06+22-26-51.jpg" height="180" width="640" /></a></div>
<br />
<br />
以前と比べてかなりいろいろなデータを表示できるようになってきました。<br />
細かいところはまた今度。<br />
<br />
以上です。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-40889133156245367452014-02-05T11:00:00.000+09:002014-02-05T11:00:06.400+09:00EMRってなんじゃ?(ImpalaでCloudfrontの爆速ログ集計)<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ufkaqbv2Omo/Uu_kl2i14cI/AAAAAAAAFCc/cuO62REpmyQ/s1600/impala-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /><img border="0" src="http://2.bp.blogspot.com/-ufkaqbv2Omo/Uu_kl2i14cI/AAAAAAAAFCc/cuO62REpmyQ/s1600/impala-logo.png" height="320" width="170" /></a></div>
<br />
<br />
EMRが<a href="https://github.com/cloudera/impala" target="_blank">Impala</a>をサポートするようになりました。Impalaは<a href="http://www.cloudera.com/" target="_blank">Cloudera</a>が提供するオープンソースのクエリエンジンで、Hiveより断然速いそうです。<br />
<br />
例として、Cloudfrontのログを、タイムスタンプをJSTに直して1時間ごとのアクセス数の集計をしてみます。<br />
<br />
<br />
<h1>
ログバケットの確認</h1>
<br />
まずCloudFrontのログが以下のS3にたまっているとします。<br />
s3://memorycraft-impala-input/cf/logs<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8NiPH5ei794/Uu6ffLzRaGI/AAAAAAAAFAs/ROErBlsYue4/s1600/S3+Management+Console+2014-02-03+04-40-00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-8NiPH5ei794/Uu6ffLzRaGI/AAAAAAAAFAs/ROErBlsYue4/s1600/S3+Management+Console+2014-02-03+04-40-00.jpg" height="244" width="640" /></a></div>
<br />
<br />
<br />
<br />
<h1>
EMRクラスタの起動</h1>
<br />
次に、EMRクラスタを起動します。<br />
EMRのダッシュボードで「Create Cluster」をクリックし、新規クラスタ作成画面を表示します。<br />
<br />
<h2>
Cluster Configuration</h2>
Cluster nameに適当なクラスタ名を入力します。また、今回はEMRのログは出力しないのでLoggingのチェックはOFFなんかにしておきます。起動したインスタンスの名前をつける場合は、TagsのNameとしてインスタンス名をつけておきます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-iq4KMS-qlWI/Uu6f9TnX6OI/AAAAAAAAFA0/q-NCeKLa_nI/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-35-23.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-iq4KMS-qlWI/Uu6f9TnX6OI/AAAAAAAAFA0/q-NCeKLa_nI/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-35-23.jpg" height="316" width="640" /></a></div>
<br />
<br />
<h2>
Software Configuration</h2>
Hadoopのバージョンとアプリケーションのリストを設定します。<br />
Applications to be installedのリストにはデフォルトでHiveとPigが追加されていますが、<br />
AMI versionは現時点で最新の3.0,2を選ぶち、下のAdditional applicationsのドロップダウンでImpalaが選択できるようになります。<br />
Impalaを選択し、「Configure and add」をクリックして追加します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1kBTEa9ZtNQ/Uu6hAD1IuYI/AAAAAAAAFBA/0x4mSTkQ6yk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-35-51.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1kBTEa9ZtNQ/Uu6hAD1IuYI/AAAAAAAAFBA/0x4mSTkQ6yk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-35-51.jpg" height="284" width="640" /></a></div>
<br />
<br />
<h2>
Hardware Configuration</h2>
ここでVPCやゾーンやインスタンス数を設定します。<br />
ここでは、EC2-Classicで、ゾーンはA、インスタンス数はデフォルトにしてみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Rzossbt-PtE/Uu6iG758hsI/AAAAAAAAFBM/gBTUVeCjyjk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-36-24.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-Rzossbt-PtE/Uu6iG758hsI/AAAAAAAAFBM/gBTUVeCjyjk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-36-24.jpg" height="234" width="640" /></a></div>
<br />
<br />
<h2>
Security and Access</h2>
EC2 key pairで、hadoopインスタンスに接続するときのキーペア名を設定します。<br />
ここが未定義だと、インスタンスに接続できないので注意が必要です。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-bzxcYoLF6Z8/Uu6igoZ5dhI/AAAAAAAAFBU/Jgw0FahiqYk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-36-40.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-bzxcYoLF6Z8/Uu6igoZ5dhI/AAAAAAAAFBU/Jgw0FahiqYk/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-36-40.jpg" height="156" width="640" /></a></div>
<br />
<br />
<h2>
Bootstrap Actions & Steps</h2>
ここでは、起動した後の挙動や起動パラメータなどを定義します。<br />
今回は未設定のままでOKです。<br />
最後に「Create cluster」ボタンをクリックして、クラスタを作成します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-IzkZan3_350/Uu6i6aN1D2I/AAAAAAAAFBc/cDmnMLZL6Iw/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-37-04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-IzkZan3_350/Uu6i6aN1D2I/AAAAAAAAFBc/cDmnMLZL6Iw/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-37-04.jpg" height="392" width="640" /></a></div>
<br />
<br />
<br />
<br />
<h1>
EMRのインスタンスへの接続</h1>
<br />
起動完了するとクラスタ詳細画面で、Master public DNSに、マスタインスタンスのPublicDNSが表示されます。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-NdTAMcrwymc/Uu6kPULpzDI/AAAAAAAAFBo/BePsGIHaMTA/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-59-05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-NdTAMcrwymc/Uu6kPULpzDI/AAAAAAAAFBo/BePsGIHaMTA/s1600/Elastic+MapReduce+Management+Console+2014-02-03+04-59-05.jpg" height="216" width="640" /></a></div>
<br />
<br />
そのPublicDNSに対して、先ほど選択した鍵を使ってhadoopユーザーでSSH接続します。<br />
<pre class="cmdprint">$ ssh -i ~/.ssh/keys/memorycraft.pem hadoop@ec2-54-199-41-72.ap-northeast-1.compute.amazonaws.com
The authenticity of host 'ec2-54-199-41-72.ap-northeast-1.compute.amazonaws.com (54.199.41.72)' can't be established.
RSA key fingerprint is 0f:ac:d5:8d:50:2b:7c:92:6a:ad:74:5e:f3:d1:52:05.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ec2-54-199-41-72.ap-northeast-1.compute.amazonaws.com,54.199.41.72' (RSA) to the list of known hosts.
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/
13 package(s) needed for security, out of 46 available
Run "sudo yum update" to apply all updates.
--------------------------------------------------------------------------------
Welcome to Amazon Elastic MapReduce running Hadoop and Amazon Linux.
Hadoop is installed in /home/hadoop. Log files are in /mnt/var/log/hadoop. Check
/mnt/var/log/hadoop/steps for diagnosing step failures.
The Hadoop UI can be accessed via the following commands:
ResourceManager lynx http://localhost:9026/
NameNode lynx http://localhost:9101/
--------------------------------------------------------------------------------
$
</pre>
接続が完了しました。
<br />
<br />
<br />
<br />
<h1>
S3データのコピー</h1>
<br />
現状、ImpalaでExternalテーブルにS3のパスを直接指定するとエラーになってしまいました。方法がわからなかったため、S3DistCpでHDFS上の/input/にコピーしてきます。<br />
<pre class="cmdprint">$ vim ./import.sh
</pre>
<pre class="prettyprint">#!/bin/bash
. /home/hadoop/impala/conf/impala.conf
hadoop jar /home/hadoop/share/hadoop/common/lib/EmrS3DistCp-1.0.jar -Dmapreduce.job.reduces=30 --src s3://memorycraft-impala-input/cf/logs/ --dest hdfs://$HADOOP_NAMENODE_HOST:$HADOOP_NAMENODE_PORT/input/ --outputCodec 'none'</pre>
<br />
<pre class="cmdprint">$ chmod 755 ./import.sh
$ ./import.sh
14/02/02 20:12:41 INFO s3distcp.S3DistCp: Running with args: -Dmapreduce.job.reduces=30 --src s3://memorycraft-impala-input/cf/logs/ --dest hdfs://172.31.0.95:9000/input/ --outputCodec none
14/02/02 20:12:41 INFO s3distcp.S3DistCp: S3DistCp args: --src s3://memorycraft-impala-input/cf/logs/ --dest hdfs://172.31.0.95:9000/input/ --outputCodec none
14/02/02 20:12:45 INFO s3distcp.S3DistCp: Using output path 'hdfs:/tmp/8f7379de-1ebf-4f31-be50-bd17aa54f2d5/output'
14/02/02 20:12:46 INFO s3distcp.S3DistCp: GET http://169.254.169.254/latest/meta-data/placement/availability-zone result: ap-northeast-1a
14/02/02 20:12:46 INFO s3distcp.S3DistCp: Created AmazonS3Client with conf KeyId XXXXXXXXXXXXXX
〜(中略)〜
<span class="Apple-tab-span" style="white-space: pre;"> </span>Combine output records=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_LENGTH=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_MAP=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_REDUCE=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>File Input Format Counters
<span class="Apple-tab-span" style="white-space: pre;"> </span>Bytes Read=3406
<span class="Apple-tab-span" style="white-space: pre;"> </span>File Output Format Counters
<span class="Apple-tab-span" style="white-space: pre;"> </span>Bytes Written=0
14/02/02 20:13:37 INFO s3distcp.S3DistCp: Try to recursively delete hdfs:/tmp/8f7379de-1ebf-4f31-be50-bd17aa54f2d5/tempspace
</pre>
<br />
コピーの実行が終わりました。HDFSの内容を見ると、コピーされているのが分かります。<br />
<pre class="cmdprint">$ hadoop fs -ls /input/
Found 20 items
-rw-r--r-- 1 hadoop supergroup 1728 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.21fcnUK5
-rw-r--r-- 1 hadoop supergroup 1726 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.9jiEU8sU
-rw-r--r-- 1 hadoop supergroup 1477 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.9pD0UZAy
-rw-r--r-- 1 hadoop supergroup 4996 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.CECpH1q4
-rw-r--r-- 1 hadoop supergroup 3636 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.DmeAD298
-rw-r--r-- 1 hadoop supergroup 979 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.GhmYMPjI
-rw-r--r-- 1 hadoop supergroup 1915 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.IvAE5n9h
-rw-r--r-- 1 hadoop supergroup 1853 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.K3Crm40n
-rw-r--r-- 1 hadoop supergroup 6120 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.KILmQ81g
-rw-r--r-- 1 hadoop supergroup 969 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.KdRXIw4s
-rw-r--r-- 1 hadoop supergroup 1731 2014-02-02 20:13 /input/E2KNLXPGJLJRRQ.2014-01-30-07.MIAnZGc4
.....
</pre>
<br />
<br />
<br />
<h1>
Impalaの実行</h1>
<br />
Impalaはimpala-shellというコマンドで専用のプロンプトを起動して使います。hiveのhiveコマンドと同じようなものです。<br />
<pre class="cmdprint">$ impala-shell
Starting Impala Shell without Kerberos authentication
Connected to ip-10-146-59-193.ap-northeast-1.compute.internal:21000
Server version: impalad version 1.2.1 RELEASE (build 8c1da7709727f3545974009a4bb677a0004024ec)
Welcome to the Impala shell. Press TAB twice to see a list of available commands.
Copyright (c) 2012 Cloudera, Inc. All rights reserved.
(Shell build version: Impala Shell v1.2.1 (8c1da77) built on Sun Dec 1 20:57:24 PST 2013)
[ip-10-146-59-193.ap-northeast-1.compute.internal:21000] >
</pre>
<br />
まずは、入力テーブルをつくります。ファイルの場所はS3DistCpのコピー先に指定した/input/を指定します。<br />
<pre class="cmdprint">[ip-10-146-59-193.ap-northeast-1.compute.internal:21000] >
CREATE EXTERNAL TABLE IF NOT EXISTS input (
cf_date STRING,
cf_time STRING,
x_edge_location STRING,
sc_bytes INT,
c_ip STRING,
cs_method STRING,
cs_host STRING,
cs_uri_stem STRING,
sc_status STRING,
cs_referrer STRING,
cs_user_agent STRING,
cs_uri_query STRING,
cs_cookie STRING,
x_edge_result_type STRING,
x_edge_request_id STRING,
x_host_header STRING,
cs_protocol STRING,
cs_bytes INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION '/input/';
</pre>
<br />
それでは、クエリを実行してみます。<br />
<pre class="cmdprint">[ip-10-146-59-193.ap-northeast-1.compute.internal:21000] >
SELECT
w.jsttime,
count(mydata)
FROM
(
SELECT
SUBSTR(
CAST(
FROM_UTC_TIMESTAMP(
FROM_UNIXTIME(
UNIX_TIMESTAMP(CONCAT(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')
), 'JST'
) as STRING
), 1, 13
) AS jsttime,
'AAA' AS mydata
FROM
input
WHERE
cf_date NOT LIKE '#%'
) w
GROUP BY
w.jsttime
;
Query: select w.jsttime, count(mydata) from (select substr(cast(from_utc_timestamp(from_unixtime(unix_timestamp(concat(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')), 'JST') as STRING), 1, 13) as jsttime, 'AAA' as mydata from input where cf_date not like '#%') w group by w.jsttime
+---------------+---------------+
| jsttime | count(mydata) |
+---------------+---------------+
| 2014-01-30 16 | 95 |
| 2014-01-30 17 | 33 |
+---------------+---------------+
Returned 2 row(s) in 0.88s
</pre>
1秒かかりませんでした。<br />
<br />
<br />
<br />
<h1>
Hiveとの速度比較</h1>
<br />
これと同じ集計をHiveで行ってみます。<br />
<pre class="cmdprint">Total MapReduce jobs = 1
Launching Job 1 out of 1
Number of reduce tasks not specified. Estimated from input data size: 1
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapred.reduce.tasks=<number>
Starting Job = job_1391362544864_0002, Tracking URL = http://10.132.128.116:9046/proxy/application_1391362544864_0002/
Kill Command = /home/hadoop/bin/hadoop job -kill job_1391362544864_0002
Hadoop job information for Stage-1: number of mappers: 2; number of reducers: 1
2014-02-02 17:46:18,013 Stage-1 map = 0%, reduce = 0%
2014-02-02 17:46:29,536 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:30,585 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:31,646 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:32,707 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:33,773 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:34,822 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:35,872 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:36,925 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 4.92 sec
2014-02-02 17:46:37,975 Stage-1 map = 100%, reduce = 100%, Cumulative CPU 6.85 sec
2014-02-02 17:46:39,034 Stage-1 map = 100%, reduce = 100%, Cumulative CPU 6.85 sec
2014-02-02 17:46:40,083 Stage-1 map = 100%, reduce = 100%, Cumulative CPU 6.85 sec
MapReduce Total cumulative CPU time: 6 seconds 850 msec
Ended Job = job_1391362544864_0002
Counters:
MapReduce Jobs Launched:
Job 0: Map: 2 Reduce: 1 Cumulative CPU: 6.85 sec HDFS Read: 58636 HDFS Write: 34 SUCCESS
Total MapReduce CPU Time Spent: 6 seconds 850 msec
OK
2014-01-30 16<span class="Apple-tab-span" style="white-space: pre;"> </span>95
2014-01-30 17<span class="Apple-tab-span" style="white-space: pre;"> </span>33
Time taken: 40.334 seconds, Fetched: 2 row(s)
</pre>
40秒も掛かりました。いかにImpalaが速いかがわかります。<br />
<br />
<br />
<br />
<h1>
8億レコードでやってみた</h1>
<br />
上と全く同じ内容のクエリを使って、8億レコードのCloudFrontログ解析をImpala上で実行してみました。<br />
<br />
<h2>
データコピー(S3→HDFS)</h2>
<pre class="cmdprint">$ . /home/hadoop/impala/conf/impala.conf
$
$ hadoop jar /home/hadoop/share/hadoop/common/lib/EmrS3DistCp-1.0.jar -Dmapreduce.job.reduces=30 --src s3://cloudfront-big-log/logs/cf/ --dest hdfs://$HADOOP_NAMENODE_HOST:$HADOOP_NAMENODE_PORT/input/ --outputCodec 'none'
14/02/03 05:21:10 INFO s3distcp.S3DistCp: Running with args: -Dmapreduce.job.reduces=30 --src s3://cloudfront-big-log/logs/cf/ --dest hdfs://172.31.0.95:9000/input/ --outputCodec none
14/02/03 05:21:10 INFO s3distcp.S3DistCp: S3DistCp args: --src s3://cloudfront-big-log/logs/cf/ --dest hdfs://172.31.0.95:9000/input/ --outputCodec none
14/02/03 05:21:14 INFO s3distcp.S3DistCp: Using output path 'hdfs:/tmp/9dc925c6-0f4e-4043-a19a-f21930f89b6b/output'
14/02/03 05:21:15 INFO s3distcp.S3DistCp: GET http://169.254.169.254/latest/meta-data/placement/availability-zone result: ap-northeast-1a
14/02/03 05:21:15 INFO s3distcp.S3DistCp: Created AmazonS3Client with conf KeyId XXXXXXXXXXXXXXXXXXXXXXXX
14/02/03 05:21:16 INFO s3distcp.S3DistCp: Skipping key 'logs/cf/' because it ends with '/'
14/02/03 05:21:16 INFO s3distcp.FileInfoListing: Opening new file: hdfs:/tmp/9dc925c6-0f4e-4043-a19a-f21930f89b6b/files/1
14/02/03 05:21:57 INFO s3distcp.S3DistCp: Created 1 files to copy 211761 files
14/02/03 05:21:57 INFO s3distcp.S3DistCp: Reducer number: 29
〜(中略)〜
<span class="Apple-tab-span" style="white-space: pre;"> </span>CPU time spent (ms)=16164160
<span class="Apple-tab-span" style="white-space: pre;"> </span>Physical memory (bytes) snapshot=18180935680
<span class="Apple-tab-span" style="white-space: pre;"> </span>Virtual memory (bytes) snapshot=53996851200
<span class="Apple-tab-span" style="white-space: pre;"> </span>Total committed heap usage (bytes)=14206107648
<span class="Apple-tab-span" style="white-space: pre;"> </span>Shuffle Errors
<span class="Apple-tab-span" style="white-space: pre;"> </span>BAD_ID=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>CONNECTION=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>IO_ERROR=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_LENGTH=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_MAP=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>WRONG_REDUCE=0
<span class="Apple-tab-span" style="white-space: pre;"> </span>File Input Format Counters
<span class="Apple-tab-span" style="white-space: pre;"> </span>Bytes Read=39560891
<span class="Apple-tab-span" style="white-space: pre;"> </span>File Output Format Counters
<span class="Apple-tab-span" style="white-space: pre;"> </span>Bytes Written=0
14/02/03 06:30:50 INFO s3distcp.S3DistCp: Try to recursively delete hdfs:/tmp/9dc925c6-0f4e-4043-a19a-f21930f89b6b/tempspace
</pre>
<br />
<br />
<h2>
入力テーブル作成(input)</h2>
<pre class="cmdprint">$ impala-shell
>
> CREATE EXTERNAL TABLE IF NOT EXISTS input (
> cf_date STRING,
> cf_time STRING,
> x_edge_location STRING,
> sc_bytes INT,
> c_ip STRING,
> cs_method STRING,
> cs_host STRING,
> cs_uri_stem STRING,
> sc_status STRING,
> cs_referrer STRING,
> cs_user_agent STRING,
> cs_uri_query STRING,
> cs_cookie STRING,
> x_edge_result_type STRING,
> x_edge_request_id STRING,
> x_host_header STRING,
> cs_protocol STRING,
> cs_bytes INT
> )
> ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
> LOCATION '/input/';
Query: create EXTERNAL TABLE IF NOT EXISTS input ( cf_date STRING, cf_time STRING, x_edge_location STRING, sc_bytes INT, c_ip STRING, cs_method STRING, cs_host STRING, cs_uri_stem STRING, sc_status STRING, cs_referrer STRING, cs_user_agent STRING, cs_uri_query STRING, cs_cookie STRING, x_edge_result_type STRING, x_edge_request_id STRING, x_host_header STRING, cs_protocol STRING, cs_bytes INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/input/'
Returned 0 row(s) in 266.06s
</pre>
<br />
<br />
<h2>
入力件数</h2>
<pre class="cmdprint">> select count(*) from input;
Query: select count(*) from input
+-----------+
| count(*) |
+-----------+
| 820545673 |
+-----------+
Returned 1 row(s) in 642.03s
</pre>
<br />
<br />
<h2>
出力テーブル作成(output)</h2>
<pre class="cmdprint">> CREATE EXTERNAL TABLE IF NOT EXISTS output_pv (
> dth STRING,
> cnt BIGINT
> )
> ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
> LOCATION '/output_pv/';
Query: create EXTERNAL TABLE IF NOT EXISTS output_pv ( dth STRING, cnt BIGINT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/output_pv/'
Returned 0 row(s) in 2.23s
</pre>
<br />
<br />
<h2>
解析(input→output)</h2>
<pre class="cmdprint">> insert into output
> select w.jsttime, count(mydata) from
> (select substr(cast(from_utc_timestamp(from_unixtime(unix_timestamp(concat(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')), 'JST') as STRING), 1, 13) as jsttime, 'AAA' as mydata from input where cf_date not like '#%') w
> group by w.jsttime
> ;
Query: insert into output select w.jsttime, count(mydata) from (select substr(cast(from_utc_timestamp(from_unixtime(unix_timestamp(concat(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')), 'JST') as STRING), 1, 13) as jsttime, 'AAA' as mydata from input where cf_date not like '#%') w group by w.jsttime
Inserted 759 rows in 14940.46s
</pre>
<br />
<br />
<style>
table.sample1 {border: solid 1px #000000; border-collapse: collapse;}
td.sample {border: solid 1px #000000;padding:5px}
</style>
<br />
<h2>
結果</h2>
<table class="sample1">
<tbody>
<tr>
<td class="sample">データのコピー(S3→HDFS)</td><td class="sample">約1時間</td>
</tr>
<tr>
<td class="sample">テーブル作成(input)</td><td class="sample">約4分</td>
</tr>
<tr>
<td class="sample">テーブル作成(output)</td><td class="sample">約2秒</td>
</tr>
<tr>
<td class="sample">解析(input→output)</td><td class="sample">約4時間</td>
</tr>
</tbody></table>
<br />
想像していたより全然速いです。<br />
<br />
<br />
ちなみに、特定のURIに絞ってクエリを実行したら15分ほどで終わってしまいました。
<br />
<pre class="cmdprint">> insert into output_pv
> select w.jsttime, count(mydata) from
> (select substr(cast(from_utc_timestamp(from_unixtime(unix_timestamp(concat(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')), 'JST') as STRING), 1, 13) as jsttime, 'AAA' as mydata from input where cf_date not like '#%' and (cs_uri_stem = '/' or cs_uri_stem = '/index.html')) w
> group by w.jsttime
> ;
Query: insert into output_pv select w.jsttime, count(mydata) from (select substr(cast(from_utc_timestamp(from_unixtime(unix_timestamp(concat(cf_date, " ", cf_time), 'yyyy-MM-dd HH:mm:ss')), 'JST') as STRING), 1, 13) as jsttime, 'AAA' as mydata from input where cf_date not like '#%' and (cs_uri_stem = '/' or cs_uri_stem = '/index.html')) w group by w.jsttime
Inserted 755 rows in 852.34s
</pre>
<br />
今回はHiveで8億レコードは試せませんでしたが、いままでHiveを使用していた感覚からするとImpalaは異常なほどの速さです。<br />
これからEMRでクエリを使用する場合はImpala一択になりそうです。<br />
<br />
以上です。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-69086230585395163222014-02-04T08:30:00.000+09:002014-02-04T08:30:02.595+09:00Dockerってなんじゃ?<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-e87nWEii9SU/Uu_jXBDXOoI/AAAAAAAAFCI/3eZKePQ2t3c/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-e87nWEii9SU/Uu_jXBDXOoI/AAAAAAAAFCI/3eZKePQ2t3c/s1600/Homepage+-+Docker:+the+Linux+container+engine+2014-02-04+03-43-27.jpg" height="308" width="640" /></a></div>
<br />
<br />
またまた今更ですが、<a href="http://www.docker.io/" target="_blank">Docker</a>を触ってみました。<br />
Dockerについては<a href="http://www.slideshare.net/slideshow/embed_code/30608792" target="_blank">このスライド</a>がこれ以上ないくらいに、わかりやすく説明してくれています。<br />
<br />
今回は、Docker内にCentOSを立ちあげて、SSH接続するまでをやってみます。<br />
<br />
<h1>
Dockerのインストールと起動</h1>
<br />
docker-ioだと少し古いので、epel-testing というリポジトリからインストールします。<br />
<pre class="cmdprint"># yum install --enablerepo=epel-testing docker-io-0.7.6-2.el6
</pre>
<br />
<br />
docker searchコマンドでcentosのベースイメージを探します。<br />
<pre class="cmdprint"># docker search centos
NAME DESCRIPTION STARS
tutum/centos CentOS Docker image with SSH access 5
tianon/centos CentOS 5 and 6, created using rinse instea... 6
centos 23
.......
</pre>
<br />
centosというのが一般的なものらしいので、それを使ってコンテナを起動します。<br />
<pre class="cmdprint"># docker run -t -i centos /bin/bash
</pre>
<br />
<br />
すると、起動したコンテナ内のbashコンソールに自動的に接続されます。<br />
ここからはゲストOSの世界です。<br />
あとで、sshでログインするために、rootのパスワードを設定します。<br />
<pre class="cmdprint">-bash-4.1# passwd
</pre>
<br />
<br />
ここで、まずコンテナ内にopensshをインストールします。<br />
<pre class="cmdprint">-bash-4.1# yum install openssh openssh-clients openssh-server vim -y
</pre>
<br />
<br />
次に、sshd_configで、PAMを使用しないように設定します。(CentOSの場合)<br />
<pre class="cmdprint">-bash-4.1# vim /etc/ssh/sshd_config</pre>
<pre class="prettyprint">#UsePAM no
UsePAM yes
↓
UsePAM no
#UsePAM yes
</pre>
<br />
ここまで設定したら、いったんコンテナを抜けてホストOSの世界に戻ってきました。<br />
<pre class="cmdprint">-bash-4.1# exit
</pre>
<br />
<br />
<br />
<h1>
SSH用コンテナの起動</h1>
<br />
docker ps -aで、現在起動しているゲストOSの一覧を確認します。<br />
centosのコンテナが1つあります。コンテナには一意のID(9c4fd33c4786)がついていて、状態はExitになっています。<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c4fd33c4786 centos:6.4 /bin/bash About a minute ago Exit 0 kickass_pare
</pre>
<br />
<br />
ここで、この9c4fd33c4786のコンテナをdocker commitコマンドで、イメージ化します。<br />
イメージのリポジトリ名はsshd/centosとします。<br />
<pre class="cmdprint"># docker commit 9c4fd33c4786 sshd/centos
4e3f5f7e23b22900df3d3752ba4644f2282a5d07176b472b03753bf4ed1bd191
</pre>
<br />
<br />
そして、SSH用に、いま作ったsshd/centosのイメージで改めて起動しますが、先ほどとは違い、-dオプションでデーモン化し、sshのポート番号と起動フォアグラウンドプロセスを指定します。それによってsshが起動した状態でコンテナが起動します。<br />
<pre class="cmdprint"># docker run -d -p 22 sshd/centos /usr/sbin/sshd -D
76451b30b156e0ebb9003152eae0dbe41aa7252d27451fb30a00cdb011ad5e20
</pre>
<br />
<br />
<br />
<br />
<h1>
SSH接続</h1>
<br />
起動したSSH用のコンテナは、docker内部では22番ポートですが、ホストOSに対しては別のポートで開いています。docker port コマンドで、コンテナの22番ポートに接続するためのポート番号を調べます。<br />
<pre class="cmdprint"># docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4485f95b6c81 sshd/centos:latest /usr/sbin/sshd -D 25 minutes ago Up 25 minutes 0.0.0.0:49158->22/tcp drunk_curie
9c4fd33c4786 centos:6.4 /bin/bash About a minute ago Exit 0 kickass_pare
#
#
# docker port 4485f95b6c81 22
0.0.0.0:49158
</pre>
<br />
どうやら49158ポートにフォワードされるようです。<br />
また、ifconfigをみると、docker0というインターフェースでアクセス先のipが分かります。<br />
<pre class="cmdprint"># ifconfig
docker0 Link encap:Ethernet HWaddr FE:9D:BA:61:73:4F
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:20164 errors:0 dropped:0 overruns:0 frame:0
TX packets:44290 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1155381 (1.1 MiB) TX bytes:64015506 (61.0 MiB)
</pre>
<br />
これで、このコンテナは172.17.42.1の49158でSSHに接続できることが分かりました。<br />
早速接続してみます。<br />
<pre class="cmdprint"># ssh root@172.17.42.1 -p 49158
The authenticity of host '[172.17.42.1]:49158 ([172.17.42.1]:49158)' can't be established.
RSA key fingerprint is f2:72:a0:0d:65:58:bf:c9:d1:3f:10:6c:9e:1c:de:9a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[172.17.42.1]:49158' (RSA) to the list of known hosts.
root@172.17.42.1's password:
-bash-4.1#
</pre>
<br />
うまくつながりました!<br />
とりあえず今回は以上です。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-14036691192817763932014-02-03T13:04:00.000+09:002014-02-03T13:04:54.893+09:00Splunkってなんじゃ?(IISのログをSplunkで解析)久しぶりのsplunkです。<br />
WindowsのIISのアクセスログをsplunkで解析してみました。<br />
<br />
fluentdを使おうかと思いまいしたが、Windowsにfluentdを入れるのは大変なので、Splunk Universal Forwarderを使います。これはSplunkが提供している専用の送信ツールです。<br />
ここでは、splunkのインデックスサーバーは既に起動しているものとして、IISとSplunk Universal Forwarderのインストール&設定を行ってみます。<br />
<br />
<br />
<br />
<h1>
IISのインストール</h1>
<br />
まずはWindowsを立ちあげます。EC2のWindows 2008 R2 Baseです。<br />
起動したらRDPで接続し、サーバーマネージャーをクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-_hjNVYAEl-w/Uu1Qp3-7RXI/AAAAAAAAE6Q/ul4FuVNf7dI/s1600/54.249.129.34+2014-01-31+20-26-25.jpg+2014-01-31+20-29-57.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-_hjNVYAEl-w/Uu1Qp3-7RXI/AAAAAAAAE6Q/ul4FuVNf7dI/s1600/54.249.129.34+2014-01-31+20-26-25.jpg+2014-01-31+20-29-57.jpg" height="522" width="640" /></a></div>
<br />
<br />
<br />
枠割の追加をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-PcHk-7WxLw4/Uu1Qts_11wI/AAAAAAAAE6Y/6LQES10nzdo/s1600/54.249.129.34+2014-01-31+20-28-46.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-PcHk-7WxLw4/Uu1Qts_11wI/AAAAAAAAE6Y/6LQES10nzdo/s1600/54.249.129.34+2014-01-31+20-28-46.jpg" height="464" width="640" /></a></div>
<br />
<br />
<br />
<br />
「開始する前に」は「次へ」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-8xJMgvpQvnQ/Uu1RerwSV-I/AAAAAAAAE6g/uYR5CEt5sW0/s1600/54.249.129.34+2014-01-31+20-30-45.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-8xJMgvpQvnQ/Uu1RerwSV-I/AAAAAAAAE6g/uYR5CEt5sW0/s1600/54.249.129.34+2014-01-31+20-30-45.jpg" height="464" width="640" /></a></div>
<br />
<br />
<br />
「サーバーの役割の選択」では「Webサーバー(IIS)」を選択して、「次へ」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-QSJRMAvoQyQ/Uu1RtYQm8MI/AAAAAAAAE6o/I82G3IUqrNc/s1600/54.249.129.34+2014-01-31+20-31-13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-QSJRMAvoQyQ/Uu1RtYQm8MI/AAAAAAAAE6o/I82G3IUqrNc/s1600/54.249.129.34+2014-01-31+20-31-13.jpg" height="460" width="640" /></a></div>
<br />
<br />
<br />
「Webサーバー(IIS)」では「次へ」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zu45tO51BoM/Uu1R8-M2RPI/AAAAAAAAE6w/GJWNxakdh9Q/s1600/54.249.129.34+2014-01-31+20-31-55.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-zu45tO51BoM/Uu1R8-M2RPI/AAAAAAAAE6w/GJWNxakdh9Q/s1600/54.249.129.34+2014-01-31+20-31-55.jpg" height="464" width="640" /></a></div>
<br />
<br />
<br />
「役割サービス」でASPなどを使用する場合は、ここで選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-LWE_MCYSQpw/Uu1S0b8THoI/AAAAAAAAE7A/dfinTQbYkaY/s1600/54.249.129.34+2014-01-31+20-33-43.jpg+2014-01-31+20-34-07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-LWE_MCYSQpw/Uu1S0b8THoI/AAAAAAAAE7A/dfinTQbYkaY/s1600/54.249.129.34+2014-01-31+20-33-43.jpg+2014-01-31+20-34-07.jpg" height="460" width="640" /></a></div>
<br />
<br />
<br />
確認ダイアログでは「必要な役割サービスを追加」をクリックします<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-47BPVh94VSU/Uu1SkKM0GbI/AAAAAAAAE64/0siDWdLVB-k/s1600/54.249.129.34+2014-01-31+20-33-17.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-47BPVh94VSU/Uu1SkKM0GbI/AAAAAAAAE64/0siDWdLVB-k/s1600/54.249.129.34+2014-01-31+20-33-17.jpg" height="460" width="640" /></a></div>
<br />
<br />
<br />
「確認」では「インストール」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-W4AQ7rOdzAY/Uu1VV_vINuI/AAAAAAAAE7I/oCAGO87l_sQ/s1600/54.249.129.34+2014-01-31+20-34-31.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-W4AQ7rOdzAY/Uu1VV_vINuI/AAAAAAAAE7I/oCAGO87l_sQ/s1600/54.249.129.34+2014-01-31+20-34-31.jpg" height="464" width="640" /></a></div>
<br />
<br />
<br />
これで、IISがインストールされ、サービスが起動したようです。<br />
ローカルのブラウザからWindowsインスタンスのIPアドレスでアクセスしてみます。<br />
もちろん、80番は開放しています。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Y-aHAZHLczA/Uu1Vh3kzRnI/AAAAAAAAE7Q/VcXVHB7j-oQ/s1600/IIS7+2014-01-31+20-39-12.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Y-aHAZHLczA/Uu1Vh3kzRnI/AAAAAAAAE7Q/VcXVHB7j-oQ/s1600/IIS7+2014-01-31+20-39-12.jpg" height="368" width="640" /></a></div>
<br />
正常にアクセスすることが出来ました。<br />
<br />
<br />
<br />
<h1>
Splunk Universal Forwarderのインストール</h1>
<br />
次に、Universal Forwarderのインストールです。<br />
ホーム画面で、「データの追加」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IlN59gvb4vs/Uu1Z6lBg5dI/AAAAAAAAE9w/QMg3PAQk-rM/s1600/%E3%83%9B%E3%83%BC%E3%83%A0+%7C+Splunk+2014-01-31+20-56-36.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-IlN59gvb4vs/Uu1Z6lBg5dI/AAAAAAAAE9w/QMg3PAQk-rM/s1600/%E3%83%9B%E3%83%BC%E3%83%A0+%7C+Splunk+2014-01-31+20-56-36.jpg" height="348" width="640" /></a></div>
<br />
<br />
<br />
「IISログ」を選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-vShi0OzVlFo/Uu1Z7BHuXoI/AAAAAAAAE-Q/Ep5wCG82MeI/s1600/%25E8%25A8%25AD%25E5%25AE%259A+%257C+Splunk+2014-01-31+20-57-00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-vShi0OzVlFo/Uu1Z7BHuXoI/AAAAAAAAE-Q/Ep5wCG82MeI/s1600/%25E8%25A8%25AD%25E5%25AE%259A+%257C+Splunk+2014-01-31+20-57-00.jpg" height="276" width="640" /></a></div>
<br />
<br />
<br />
「他のサーバーからログを転送する」のリンクを開き、URLをコピーします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ee7DC2re4kU/Uu1Z72CIoII/AAAAAAAAE-M/7NAoXqBzzuM/s1600/%25E8%25A8%25AD%25E5%25AE%259A+%257C+Splunk+2014-01-31+20-57-26.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-ee7DC2re4kU/Uu1Z72CIoII/AAAAAAAAE-M/7NAoXqBzzuM/s1600/%25E8%25A8%25AD%25E5%25AE%259A+%257C+Splunk+2014-01-31+20-57-26.jpg" height="267" width="640" /></a></div>
<br />
<br />
<br />
Windows側でURLを開きます。<br />
すると、Splunk Universal Forwarderのダウンロード画面が表示されます。<br />
その際、このsplunkサイトでログインしている必要があります。<br />
Windowsの環境に合わせてリンクをクリックして、ダウンロード、実行します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-hZ0U2Z-HXlM/Uu1ZuzjjHrI/AAAAAAAAE70/r1RJQOe3I2Y/s1600/54.249.129.34+2014-01-31+21-01-01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-hZ0U2Z-HXlM/Uu1ZuzjjHrI/AAAAAAAAE70/r1RJQOe3I2Y/s1600/54.249.129.34+2014-01-31+21-01-01.jpg" height="448" width="640" /></a></div>
<br />
<br />
<br />
<br />
するとインストーラが立ち上がるので、「Next」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-TK0P8lLH9iA/Uu1ZxiVh-cI/AAAAAAAAE8c/M_lfeHdZYSQ/s1600/54.249.129.34+2014-01-31+21-10-08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-TK0P8lLH9iA/Uu1ZxiVh-cI/AAAAAAAAE8c/M_lfeHdZYSQ/s1600/54.249.129.34+2014-01-31+21-10-08.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
<br />
ライセンスに同意し次に進みます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-e0Yq7VhvGBs/Uu1Zx24UI7I/AAAAAAAAE8g/bxrisoX034g/s1600/54.249.129.34+2014-01-31+21-10-29.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-e0Yq7VhvGBs/Uu1Zx24UI7I/AAAAAAAAE8g/bxrisoX034g/s1600/54.249.129.34+2014-01-31+21-10-29.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
<br />
インストール場所はそのままでOKです。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Z2x_rszaAGA/Uu1Z10s2QCI/AAAAAAAAE9I/MQ9ci0_nWuc/s1600/54.249.129.34+2014-01-31+21-10-50.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-Z2x_rszaAGA/Uu1Z10s2QCI/AAAAAAAAE9I/MQ9ci0_nWuc/s1600/54.249.129.34+2014-01-31+21-10-50.jpg" height="484" width="640" /></a></div>
<br />
<br />
<br />
「Deployment Server」は空欄のまま進みます。<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-X27zoL4oO2o/Uu1Z1GuOfSI/AAAAAAAAE9E/Y7r10cPbPts/s1600/54.249.129.34+2014-01-31+21-12-47.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-X27zoL4oO2o/Uu1Z1GuOfSI/AAAAAAAAE9E/Y7r10cPbPts/s1600/54.249.129.34+2014-01-31+21-12-47.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
<br />
「Recieving Indexer」では、splunkのインデックスサーバーのIPを入力し、ポートは「9997」とします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-GqG5ObWFMug/Uu1Z1ZxhVeI/AAAAAAAAE9A/MJRir6jT0zA/s1600/54.249.129.34+2014-01-31+21-16-58.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-GqG5ObWFMug/Uu1Z1ZxhVeI/AAAAAAAAE9A/MJRir6jT0zA/s1600/54.249.129.34+2014-01-31+21-16-58.jpg" height="476" width="640" /></a></div>
<br />
<br />
<br />
<br />
SSLに関しては、今回はそのままです。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-bCQ0Jpb1IwY/Uu1Z5bwm21I/AAAAAAAAE9s/erkmelGtfUw/s1600/54.249.129.34+2014-01-31+21-17-53.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-bCQ0Jpb1IwY/Uu1Z5bwm21I/AAAAAAAAE9s/erkmelGtfUw/s1600/54.249.129.34+2014-01-31+21-17-53.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
<br />
送信データじゃ「Local Data Only」を選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vD3vFA6Sakc/Uu1Z3AywXFI/AAAAAAAAE9c/WdcLPP0fFpk/s1600/54.249.129.34+2014-01-31+21-21-33.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-vD3vFA6Sakc/Uu1Z3AywXFI/AAAAAAAAE9c/WdcLPP0fFpk/s1600/54.249.129.34+2014-01-31+21-21-33.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
送信内容の画面では、「Path to monitor」で、「Directory」をクリックして、「C:¥inetpub¥logs¥LogFiles¥W3SVC1」を選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-bgPr-nQrIdQ/Uu1nALFdQuI/AAAAAAAAE-w/CnaATuo0CLM/s1600/54.199.91.254+2014-01-31+22-53-40.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-bgPr-nQrIdQ/Uu1nALFdQuI/AAAAAAAAE-w/CnaATuo0CLM/s1600/54.199.91.254+2014-01-31+22-53-40.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
<br />
「Splunk Tecnology」では、上のラジオを選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-eNV-BjFiXSs/Uu1Z47JuXgI/AAAAAAAAE9k/PAUT91qAV2w/s1600/54.249.129.34+2014-01-31+21-30-34.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-eNV-BjFiXSs/Uu1Z47JuXgI/AAAAAAAAE9k/PAUT91qAV2w/s1600/54.249.129.34+2014-01-31+21-30-34.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
最後に「Install」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-0l1ha48LObc/Uu1Z7Z2Bb2I/AAAAAAAAE-A/2xNFcuPhYhE/s1600/54.249.129.34+2014-01-31+21-30-55.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-0l1ha48LObc/Uu1Z7Z2Bb2I/AAAAAAAAE-A/2xNFcuPhYhE/s1600/54.249.129.34+2014-01-31+21-30-55.jpg" height="480" width="640" /></a></div>
<br />
<br />
<br />
すると、完了画面になるので、「Finish」で閉じます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-1s4-m4aNs0w/Uu1Z53VvuLI/AAAAAAAAE90/jow53zzUqto/s1600/54.250.95.3+2014-01-31+23-48-47.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-1s4-m4aNs0w/Uu1Z53VvuLI/AAAAAAAAE90/jow53zzUqto/s1600/54.250.95.3+2014-01-31+23-48-47.jpg" height="482" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<h1>
Splunk Universal Forwarderの設定</h1>
<br />
これだけではログの送信ができません。<br />
まずは、splunkのサーバーにセキュリティグループで9997ポートにアクセスできるようにしておきます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-y0DJZlQTmNw/Uu1qPgQc0lI/AAAAAAAAE-8/Z3Mq8A-1Lv0/s1600/EC2+Management+Console+2014-02-02+06-42-06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-y0DJZlQTmNw/Uu1qPgQc0lI/AAAAAAAAE-8/Z3Mq8A-1Lv0/s1600/EC2+Management+Console+2014-02-02+06-42-06.jpg" /></a></div>
<br />
<br />
次に、Splunk Forwarderの設定です。<br />
いまのところIISのログの場所を指定しただけで、IISのログフォーマットなどを指定していません。<br />
以前では、ヘッダの指定などもしなければいけませんでしたが、最近のsplunkにはIISのsourcetype定義が含まれているため、<br />
C:¥Program Files¥S@lunkUniversalForwarder¥etc¥system¥local¥inputs.conf<br />
に以下の記述を追記するだけで済むようになりました。<br />
<br />
<pre class="prettyprint">[monitor://C:\inetpub\logs\LogFiles\W3SVC1]
sourcetype=iis
</pre>
<br />
<br />
そして、SplunkForwarderを再起動します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ZZJjx_gjjjs/Uu1riCcw3dI/AAAAAAAAE_I/7QcnK6YINb0/s1600/54.250.95.3+2014-02-02+06-46-20.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-ZZJjx_gjjjs/Uu1riCcw3dI/AAAAAAAAE_I/7QcnK6YINb0/s1600/54.250.95.3+2014-02-02+06-46-20.jpg" /></a></div>
<br />
<br />
<br />
<br />
<h1>
Splunkサーバーの設定</h1>
<br />
一方、Splunkのインデックスサーバーでは先ほどForwarderで設定した9997番ポートを受け付けるように設定する必要があります。<br />
<br />
Splunkのサーバーのグローバルヘッダから「設定」メニューの 「データ > 転送と受信」を選択します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-m5qxsOozK7U/Uu5O4OVD8qI/AAAAAAAAFAI/gBoMRxXlp4Q/s1600/%E3%83%9B%E3%83%BC%E3%83%A0+%7C+Splunk+2014-02-02+22-56-12.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-m5qxsOozK7U/Uu5O4OVD8qI/AAAAAAAAFAI/gBoMRxXlp4Q/s1600/%E3%83%9B%E3%83%BC%E3%83%A0+%7C+Splunk+2014-02-02+22-56-12.jpg" height="488" width="640" /></a></div>
<br />
<br />
<br />
転送と受信画面では、「データの受信 > 新規追加」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-aeATVq2BFMU/Uu5PUCH2qLI/AAAAAAAAFAQ/gQMbPDX2Y9M/s1600/%E8%A8%AD%E5%AE%9A+%7C+Splunk+2014-02-02+22-56-47.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-aeATVq2BFMU/Uu5PUCH2qLI/AAAAAAAAFAQ/gQMbPDX2Y9M/s1600/%E8%A8%AD%E5%AE%9A+%7C+Splunk+2014-02-02+22-56-47.jpg" height="300" width="640" /></a></div>
<br />
<br />
<br />
新規追加画面で、9997を入力して「保存」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9DySunXiE90/Uu5Pj9aGEwI/AAAAAAAAFAY/emY3BJHNhlI/s1600/%E8%A8%AD%E5%AE%9A+%7C+Splunk+2014-02-02+22-57-13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-9DySunXiE90/Uu5Pj9aGEwI/AAAAAAAAFAY/emY3BJHNhlI/s1600/%E8%A8%AD%E5%AE%9A+%7C+Splunk+2014-02-02+22-57-13.jpg" height="212" width="640" /></a></div>
<br />
<br />
これで、Splunk Universal Forwarderの9997からデータを受信することができるようになりました。<br />
<br />
<br />
<br />
<h1>
確認</h1>
<br />
<br />
少し待ってから、splunkのサーチ画面でデータサマリーを見てみると、、、<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-2KUjGulqA9M/Uu1sQcGHkCI/AAAAAAAAE_Q/UBYoks6UW94/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-50-25.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-2KUjGulqA9M/Uu1sQcGHkCI/AAAAAAAAE_Q/UBYoks6UW94/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-50-25.jpg" height="220" width="640" /></a></div>
<br />
おお、「WIN-SEL3V5P943V」というホスト名のデータが新たに登録されてきているのがわかります。<br />
<br />
<br />
<br />
そのままホスト名のリンクをクリックして、中身を見てみると、投入されたログデータが表示されており、左のフィールド欄をみると、正しくスプリットされていることが分かります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1euU44_MqgQ/Uu1suGyDICI/AAAAAAAAE_Y/U8ArwVOxaRg/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-52-25.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1euU44_MqgQ/Uu1suGyDICI/AAAAAAAAE_Y/U8ArwVOxaRg/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-52-25.jpg" height="402" width="640" /></a></div>
<br />
<br />
<br />
そこで、フィールド欄で、アクセスログによくあるフィールドを表示選択して、一覧の項目を整理すると以下のようにそれらしくなります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-R7OYbgeOZcs/Uu1uU_W-CGI/AAAAAAAAE_k/tHaXCQI2IF0/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-59-20.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-R7OYbgeOZcs/Uu1uU_W-CGI/AAAAAAAAE_k/tHaXCQI2IF0/s1600/%E3%82%B5%E3%83%BC%E3%83%81+%7C+Splunk+2014-02-02+06-59-20.jpg" height="412" width="640" /></a></div>
<br />
<br />
<br />
これを簡単なクエリをいくつか使ってダッシュボードを作ってみると以下のようになります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-5xq2gtFiF0c/Uu1zcjmndmI/AAAAAAAAE_0/VvQAPsVLF-c/s1600/IIS+%7C+Splunk+2014-02-02+07-20-45.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-5xq2gtFiF0c/Uu1zcjmndmI/AAAAAAAAE_0/VvQAPsVLF-c/s1600/IIS+%7C+Splunk+2014-02-02+07-20-45.jpg" height="524" width="640" /></a></div>
<br />
<br />
<br />
このような感じで、IISのログも統計をとることができました。<br />
途中のダイアログにもありましたが、IISだけではなく、Windowsのイベントログなども取得可能です。<br />
<br />
今回は以上です。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-8287309513139030182014-01-31T17:03:00.000+09:002014-01-31T18:06:41.373+09:00Chefってなんじゃ?<blockquote class="tr_bq">
「男もすなるChefといふものを、女もしてみむとてするなり。」<br />
−紀貫之</blockquote>
<br />
ということで、いまさらすぎますがChefです。<br />
<br />
とっても有名な入門書「<a href="http://www.amazon.co.jp/gp/product/B00BSPH158/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B00BSPH158&linkCode=as2&tag=memorycraft-22">入門Chef Solo - Infrastructure as Code</a><img alt="" border="0" src="http://ir-jp.amazon-adsystem.com/e/ir?t=memorycraft-22&l=as2&o=9&a=B00BSPH158" height="1" style="border: none !important; margin: 0px !important;" width="1" />」にだいたいのことが書いてあります。<br />
<br />
Chefはサーバーの設定をしたりソフトウェアをインストールしたりする管理ツールとのことで、rubyのDSLでレシピを書いて実行するとサーバーの状態が変更されるので、セットアップが自動化できるとのことです。<br />
<br />
他にChef Serverというのもあるようですが、ここでは割愛してChef Soloだけで進めます。<br />
まずはインストールです。<br />
前回インストールしたvirtual box内のローカルにchef soloをインストールしてみます。<br />
<br />
<br />
<h1>
rbenvのインストール</h1>
<br />
今回はrbenvからrubyを入れるためrbenvからインストールします。<br />
rubyを直接インストールする場合は、これは必要ありません。<br />
また、全ユーザで参照できるように、/etc/profileにrbenvのパスを設定しておきます。<br />
<pre class="cmdprint">$ sudo yum install -y openssl-devel git vim tree
$ cd /usr/local/
$ sudo git clone git://github.com/sstephenson/rbenv.git rbenv
$ sudo groupadd staff
$ sudo chgrp -R staff rbenv
$ sudo chmod -R g+rwxXs rbenv
$ sudo mkdir /usr/local/rbenv/plugins
$ cd /usr/local/rbenv/plugins
$ sudo git clone git://github.com/sstephenson/ruby-build.git
$ sudo chgrp -R staff ruby-build
$ sudo chmod -R g+rwxs ruby-build
$ sudo su -
# vim /etc/profile.d/rbenv.sh
export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# source /etc/profile
</pre>
<br />
<br />
<br />
<h1>
rubyのインストール</h1>
<br />
rubyをインストールします。<br />
sudoでchefが呼び出せるように、/etc/sudoersにパスの設定をしておきます。<br />
<pre class="cmdprint"># rbenv install --list
# rbenv install -v 2.0.0-p353
# rbenv global 2.0.0-p353
# ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
# exit
$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
$ gem -v
2.0.14
$ sudo visudo -f /etc/sudoers.d/rbenv
Defaults !secure_path
Defaults env_keep += "PATH RBENV_ROOT"
</pre>
<br />
<br />
<h1>
chefとknife soloのインストール</h1>
<br />
gemでインストールします。<br />
<pre class="cmdprint">$ sudo gem install chef
$ sudo gem install knife-solo
$ sudo rbenv rehash
</pre>
<br />
<br />
<br />
<h1>
chefリポジトリの作成</h1>
<br />
knife configureコマンドでknife設定を初期化します。これは初回だけでOKです。<br />
そのあとknife solo initで初期ディレクトリ群を作成し、ついでにgit管理しておきます。<br />
<pre class="cmdprint">$ knife configure
$ knife solo init myfirstkitchen
$ tree myfirstkitchen/
myfirstkitchen/
|-- cookbooks
|-- data_bags
|-- environments
|-- nodes
|-- roles
`-- site-cookbooks
6 directories, 0 files
$ cd myfirstkitchen/
$ git init
$ git add .
$ git commit -m 'first commit'
</pre>
<br />
<br />
<br />
<h1>
クックブックの作成</h1>
<br />
knife cookbook createで新規にクックブック(レシピ集)を作成します。<br />
自分のクックブックはsite-cookbooks内に置くのが習わしのようです。<br />
<pre class="cmdprint">$ knife cookbook create myfirstcookbook -o site-cookbooks
** Creating cookbook myfirstcookbook
** Creating README for cookbook: myfirstcookbook
** Creating CHANGELOG for cookbook: myfirstcookbook
** Creating metadata for cookbook: myfirstcookbook
$ tree .
.
|-- cookbooks
|-- data_bags
|-- environments
|-- nodes
|-- roles
`-- site-cookbooks
`-- myfirstcookbook
|-- CHANGELOG.md
|-- README.md
|-- attributes
|-- definitions
|-- files
| `-- default
|-- libraries
|-- metadata.rb
|-- providers
|-- recipes
| `-- default.rb
|-- resources
`-- templates
`-- default
</pre>
<br />
<br />
<br />
<h1>
レシピの作成</h1>
<br />
まずは設定。chef-soloの実行時に、クックブックの場所がわかるように以下の内容をファイルに記述します。<br />
クックブックの場所はcookbooksとsite-cookbooksを指定します。<br />
<pre class="cmdprint">$ cat ./solo.rb
file_cache_path "/tmp/chef-solo"
cookbook_path ["/home/vagrant/myfirstkitchen/cookbooks", "/home/vagrant/myfirstkitchen/site-cookbooks"]
</pre>
<br />
次に実行時にどのクックブックのレシピを実行するかをjsonファイルで指定できます。<br />
<pre class="cmdprint">$ cat localhost.json
{
"run_list": [
"recipe[myfirstcookbook]"
]
}
</pre>
<br />
やっとレシピの作成に入ります。空のdefaultレシピが配置されているので、ここに記述します。<br />
httpdとphpをインストールし、サービス起動するように設定します。<br />
<pre class="cmdprint">$vim site-cookbooks/myfirstcookbook/recipes/default.rb</pre>
<pre class="prettyprint"># Cookbook Name:: myfirstcookbook
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
# install httpd & php
%w{httpd php}.each do |pkg|
package pkg do
action :install
end
end
# make /etc/init.d/httd and start httpd
service "httpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
</pre>
<br />
<br />
<br />
<h1>
実行</h1>
<br />
それでは実行です。実行時に、先ほど作ったsolo.rbとlocalhost.jsonを指定します。<br />
<pre class="cmdprint">$ sudo chef-solo -c solo.rb -j localhost.json
Starting Chef Client, version 11.8.2
Compiling Cookbooks...
Converging 3 resources
Recipe: myfirstcookbook::default
* package[httpd] action install
- install version 2.2.15-29.el6.centos of package httpd
* package[php] action install
- install version 5.3.3-27.el6_5 of package php
* service[httpd] action enable
- enable service service[httpd]
* service[httpd] action start
- start service service[httpd]
Chef Client finished, 4 resources updated
</pre>
<br />
実行が正常に終わったようです。<br />
<br />
<br />
<br />
<h1>
確認</h1>
<br />
/etc/httpdにインストールされています。<br />
<pre class="cmdprint">$ ls -l /etc/httpd/
total 8
drwxr-xr-x 2 root root 4096 Jan 31 06:08 conf
drwxr-xr-x 2 root root 4096 Jan 31 06:09 conf.d
lrwxrwxrwx 1 root root 19 Jan 31 06:08 logs -> ../../var/log/httpd
lrwxrwxrwx 1 root root 29 Jan 31 06:08 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx 1 root root 19 Jan 31 06:08 run -> ../../var/run/httpd
</pre>
<br />
<br />
/etc/init.d/httpdがつくられています。<br />
<pre class="cmdprint">$ ls -l /etc/init.d/httpd
-rwxr-xr-x 1 root root 3371 Aug 13 17:30 /etc/init.d/httpd
</pre>
<br />
起動しています!<br />
<pre class="cmdprint">$ ps -ax | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
25266 ? Ss 0:00 /usr/sbin/httpd
25268 ? S 0:00 /usr/sbin/httpd
25269 ? S 0:00 /usr/sbin/httpd
25270 ? S 0:00 /usr/sbin/httpd
25271 ? S 0:00 /usr/sbin/httpd
25272 ? S 0:00 /usr/sbin/httpd
25273 ? S 0:00 /usr/sbin/httpd
25274 ? S 0:00 /usr/sbin/httpd
25275 ? S 0:00 /usr/sbin/httpd
25356 pts/0 S+ 0:00 grep httpd
</pre>
<br />
どうやらyumでインストールされたようです。<br />
<pre class="cmdprint">$ sudo yum list installed | grep httpd
Failed to set locale, defaulting to C
httpd.x86_64 2.2.15-29.el6.centos
httpd-tools.x86_64 2.2.15-29.el6.centos
</pre>
<br />
<br />
PHPのindexをつくってみます。<br />
<pre class="cmdprint"># vim /var/www/html/index.php
<?php phpinfo();?>
</pre>
<br />
<br />
ブラウザで確認すると、、、<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-t3POMPWS3C8/UutUqy9y_BI/AAAAAAAAE50/XG93wBBbRlI/s1600/phpinfo()+2014-01-31+15-52-16.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-t3POMPWS3C8/UutUqy9y_BI/AAAAAAAAE50/XG93wBBbRlI/s1600/phpinfo()+2014-01-31+15-52-16.jpg" height="570" width="640" /></a></div>
<br />
<br />
おお、ちゃんとphpも動いてます!<br />
<br />
<br />
<br />
<h1>
保存</h1>
<br />
ここまでできたら、再度コミットしておきます。<br />
<pre class="cmdprint">$ git add .
$ git commit -am "add httpd&php"
</pre>
<br />
<br />
<br />
このように、レシピを追加して、その状態をgit管理することでサーバーの状態をバージョン管理することができて便利なのだそうです。<br />
今後もっとchefに触れていきたいと思います。以上です。
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-88672619357661740172014-01-29T10:30:00.000+09:002014-01-29T14:41:07.566+09:00Vagrantってなんじゃ?VagrantはVirtual Boxという仮想環境のコマンドインターフェースのようなものです。<br />
VirtualBoxをつかえば、手元に簡単にテスト環境を用意できます。<br />
<br />
<br />
<h1>
VirtualBoxのインストール</h1>
<br />
<a href="https://www.virtualbox.org/wiki/Downloads" target="_blank">VirtualBox</a>をダウンロードしてインストールします。<strike>この時点のvagrantの最新がVirtualBox 4.2までの対応だったようなので、ここでは4.2をインストールします。</strike>(Vagrantをgemではなく、パッケージインストーラの最新版から入れたらVirtualBoxの最新版に対応していました。)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-wMFJmRmi8Cw/UueA9ag6pTI/AAAAAAAAE30/p0RSS_j7g7o/s1600/Downloads+%25E2%2580%2593+Oracle+VM+VirtualBox+2014-01-28+19-05-28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-wMFJmRmi8Cw/UueA9ag6pTI/AAAAAAAAE30/p0RSS_j7g7o/s1600/Downloads+%25E2%2580%2593+Oracle+VM+VirtualBox+2014-01-28+19-05-28.png" height="504" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
インストーラなので、そのままインストールします。<br />
<br />
<br />
<br />
<h1>
Vagrant のインストール</h1>
<br />
インストールが完了したら次は<a href="http://www.vagrantup.com/downloads.html" target="_blank">vagrant</a> のインストールです。<br />
vagrantは、最近のバージョンはGemではなくPackageインストーラでインストールします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-fSDVzy0NOCs/UuedKR9ZJKI/AAAAAAAAE4Y/CyZJEikPAtQ/s1600/Download+Vagrant+-+Vagrant+2014-01-28+21-05-54.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-fSDVzy0NOCs/UuedKR9ZJKI/AAAAAAAAE4Y/CyZJEikPAtQ/s1600/Download+Vagrant+-+Vagrant+2014-01-28+21-05-54.jpg" height="536" width="640" /></a></div>
<br />
vagrantのインストールが完了したら、vagrantをつかって仮想環境をつくります。VirtualBoxでは仮想環境を固めたものをboxと呼ぶようです。<br />
今回はCentOSのboxを追加します。各boxが、<br />
<br />
<a href="http://www.vagrantbox.es/" target="_blank">http://www.vagrantbox.es/</a><br />
<br />
に公開されているので、以下のようなコマンドでURLを追加します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-FNqHAJ5qPvQ/UufH_dRnOKI/AAAAAAAAE5E/cvzmK_Fax1g/s1600/A+list+of+base+boxes+for+Vagrant+-+Vagrantbox.es+2014-01-28+20-06-06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-FNqHAJ5qPvQ/UufH_dRnOKI/AAAAAAAAE5E/cvzmK_Fax1g/s1600/A+list+of+base+boxes+for+Vagrant+-+Vagrantbox.es+2014-01-28+20-06-06.jpg" height="586" width="640" /></a></div>
<br />
<br />
boxには名前をつける必要があるので、ここでは myfirstbox という名前をつけてみます。<br />
<pre class="cmdprint">$ vagrant box add myfirstbox https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box
</pre>
これで、インストールが完了しました。<br />
<br />
<br />
<br />
<h1>
仮想環境の起動</h1>
<br />
適当なディレクトリをつくって、vagrant initをすると、Vagrantfileが出来ます。<br />
<pre class="cmdprint">$ mkdir virtualbox
$ cd virtualbox/
$ vagrant init
$ ls -l
total 16
-rw-r--r-- 1 memorycraft staff 4668 1 28 22:27 Vagrantfile
</pre>
<br />
Vagrantfileを開いて、2点だけ修正します。<br />
・box名を先ほどつけたmyfirstboxへ変更する<br />
・ネットワーク設定をプライベートIPの192.168.33.10に設定する<br />
IPは他のIPでも構いません<br />
<br />
<b>Vagrantfile</b><br />
<br />
<pre class="prettyprint">config.vm.box = "base"
↓
config.vm.box = "myfirstbox"
#config.vm.network :private_network, ip: "192.168.33.10"
↓
config.vm.network :private_network, ip: "192.168.33.10"
</pre>
<br />
<br />
これで起動の準備が整ったので、起動してみます。起動はvagrant upをつかいます。<br />
起動のログ出力が正常に終わると、起動完了です。<br />
<pre class="cmdprint">$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'myfirstbox'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Configuring and enabling network interfaces...
[default] Mounting shared folders...
[default] -- /vagrant
</pre>
<br />
<br />
起動した環境にsshログインしてみます。<br />
<pre class="cmdprint">$ vagrant ssh-config --host myfirstbox >> ~/.ssh/config</pre>
<pre class="cmdprint">$ ssh myfirstbox
[vagrant@vagrant-centos65 ~]$
[vagrant@vagrant-centos65 ~]$ pwd
/home/vagrant
[vagrant@vagrant-centos65 ~]$ ls -la
total 24
drwx------. 3 vagrant vagrant 4096 Dec 5 14:18 .
drwxr-xr-x. 3 root root 4096 Dec 5 14:18 ..
-rw-r--r--. 1 vagrant vagrant 18 Jul 18 2013 .bash_logout
-rw-r--r--. 1 vagrant vagrant 176 Jul 18 2013 .bash_profile
-rw-r--r--. 1 vagrant vagrant 124 Jul 18 2013 .bashrc
drwx------. 2 vagrant vagrant 4096 Dec 5 14:18 .ssh
[vagrant@vagrant-centos65 ~]$
</pre>
<br />
<br />
おお、入れました。<br />
それでは、ここにhttpdをインストールしてWEBサーバーを立ちあげてみましょう。<br />
<pre class="cmdprint">$ sudo yum install -y httpd
$ sudo /etc/init.d/httpd start
</pre>
<br />
<br />
<br />
<h1>
確認</h1>
<br />
そしてブラウザで、さきほどVagrantFileに記述したIPにアクセスしてみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-3dB5IBcoHj0/Uue-Oy9m-TI/AAAAAAAAE4w/teQB8hE8pV8/s1600/Apache+HTTP+Server+Test+Page+powered+by+CentOS+2014-01-28+23-18-33.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-3dB5IBcoHj0/Uue-Oy9m-TI/AAAAAAAAE4w/teQB8hE8pV8/s1600/Apache+HTTP+Server+Test+Page+powered+by+CentOS+2014-01-28+23-18-33.jpg" height="488" width="640" /></a></div>
<br />
<br />
簡単にWEBサーバーが出来てしまいました。<br />
これで他に開発環境とかもつくれてしまいますね。<br />
<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-82036431243801929062014-01-16T17:13:00.001+09:002014-02-12T22:20:21.815+09:00SQSってなんじゃ?(supervisordでSQS)いまさらですが、SQS+supervisordです。<br />
<br />
supervisorはプログラムの起動監視と、自動起動/復帰などを行ってくれるツールです。<br />
これをつかってSQSの受信処理プログラムをワーカーとして管理してみます。<br />
<br />
<br />
<h1>
受信テスト用のスクリプトを作成</h1>
<br />
メッセージの受信は、一度に最大の10件まで、ポーリング20秒で受信したメッセージをログファイルに出力するようにします。<br />
また、今回はログの出力タイミングがわかりやすいように、1回のポーリング後10秒間sleepしています。<br />
<pre class="cmdprint">$ vim /home/ec2-user/svsqs.rb
</pre>
<pre class="prettyprint">#!/usr/local/bin/ruby
require 'aws-sdk'
require 'logger'
access_key = 'XXXXXXXXXXXXXXXX'
secret_key = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
queue_url = 'https://sqs.ap-northeast-1.amazonaws.com/ZZZZZZZZZZZ/svsqs'
log = Logger.new("/home/ec2-user/test.log");
AWS.config(:access_key_id => access_key,
:secret_access_key => secret_key,
:region => "ap-northeast-1")
sqs = AWS::SQS.new
while true
messages = sqs.queues[queue_url].receive_message({:limit => 10, :wait_time_seconds => 20}).map do |m|
json = JSON.parse(m.body)
log.debug("#{$$} #{json['msg']}")
m.delete()
end
log.debug("#{$$} -------")
sleep 10
end
</pre>
<pre class="cmdprint">$ chmod 755 /home/ec2-user/svsqs.rb
</pre>
<br />
<br />
<br />
<h1>
supervisorのインストールと設定</h1>
<br />
次に、supervisorをインストールして、上記のスクリプトの起動管理するように設定します。<br />
<pre class="cmdprint"># easy_install supervisor
# vim /etc/init.d/supervisord
</pre>
<br />
次にsupervisor自体の起動スクリプトをつくってサービス登録します。<br />
<pre class="prettyprint">#!/bin/sh
#
# /etc/rc.d/init.d/supervisord
#
# Supervisor is a client/server system that
# allows its users to monitor and control a
# number of processes on UNIX-like operating
# systems.
#
# chkconfig: - 64 36
# description: Supervisor Server
# processname: supervisord
# Source init functions
. /etc/init.d/functions
RETVAL=0
prog="supervisord"
pidfile="/tmp/supervisord.pid"
lockfile="/var/lock/subsys/supervisord"
start()
{
echo -n $"Starting $prog: "
daemon --pidfile $pidfile supervisord
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}
}
stop()
{
echo -n $"Shutting down $prog: "
killproc -p ${pidfile} /usr/bin/supervisord
RETVAL=$?
echo
if [ $RETVAL -eq 0 ] ; then
rm -f ${lockfile} ${pidfile}
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $prog
;;
restart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
;;
esac
</pre>
<pre class="prettyprint">
</pre>
<br />
<pre class="cmdprint"># chmod 755 /etc/init.d/supervisord
# chkconfig --add supervisord
# chkconfig supervisord on
# chkconfig --list</pre>
<br />
<br />
<br />
<h1>
監視対象プロセスの設定</h1>
<br />
<h2>
子設定ファイルの読込み設定</h2>
主設定ファイルの末尾に、アプリケーションごとの設定ファイルをインクルードするように設定しておきます。<br />
<pre class="cmdprint"># echo_supervisord_conf > /etc/supervisord.conf
# echo "[include]" >> /etc/supervisord.conf
# echo "files = supervisord/conf/*.conf" >> /etc/supervisord.conf
</pre>
<br />
<h2>
子設定ファイルの作成</h2>
svsqsという名前で最初に書いたスクリプトの起動設定をします。
自動起動や、自動復帰をONにします。<br />
<pre class="cmdprint"># mkdir -p /etc/supervisord/conf/
# vim /etc/supervisord/conf/svtest.conf
</pre>
<pre class="prettyprint">[program:svsqs]
command = /home/ec2-user/svsqs.rb
process_name = svsqs
autostart = true
autorestart = true
</pre>
<br />
<br />
<br />
<h1>
supervisorのデーモン起動</h1>
<br />
ここまで設定できたらsupervisord自体を起動します。<br />
<pre class="cmdprint"># service supervisord start
</pre>
<br />
<br />
<br />
<h1>
supervisorのコンソールでstop/startテスト</h1>
<br />
supervisorctlというコマンドで管理対象プロセスの操作や状態確認が簡単にできます。<br />
supervisorが起動すると、autostartがONになっているため対象のスクリプトも起動していることが分かります。<br />
<pre class="cmdprint"># supervisorctl
svtest RUNNING pid 18770, uptime 15:44:07
supervisor> stop svtest
svtest: stopped
supervisor> status
svtest STOPPED Jan 16 05:12 AM
supervisor> start svtest
svtest: started
supervisor>
supervisor>
supervisor> status
svtest RUNNING pid 10876, uptime 0:00:03
supervisor>
supervisor>
supervisor> exit
</pre>
<br />
<br />
<br />
<h1>
自動復帰の確認</h1>
<br />
プロセスを強制的に落としてみます。<br />
するとsupervisorにより、新しいプロセスとして自動復帰します。<br />
<pre class="cmdprint"># ps -ax | grep svtest
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
10876 ? S 0:00 /bin/sh /home/ec2-user/svsqs.rb
10892 pts/0 D+ 0:00 grep svtest
# kill -9 10876
# ps -ax | grep svtest
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
10898 ? S 0:00 /bin/sh /home/ec2-user/svsqs.rb
10901 pts/0 S+ 0:00 grep svtest
</pre>
<br />
<br />
<br />
<h1>
メッセージの確認</h1>
<br />
このプログラムで扱うSQSのキューに対し、いくつかメッセージを送ってみると、受信できているのがわかります。<br />
<pre class="cmdprint"># tail -1000f test.log
D, [2014-01-16T07:02:28.085909 #13119] DEBUG -- : 10898 aaaaaa
D, [2014-01-16T07:02:28.176748 #13119] DEBUG -- : 10898 -------
D, [2014-01-16T07:02:38.347694 #13119] DEBUG -- : 10898 bbbbbbb
D, [2014-01-16T07:02:38.364416 #13119] DEBUG -- : 10898 cccccccc
D, [2014-01-16T07:02:38.414742 #13119] DEBUG -- : 10898 ddddddd
D, [2014-01-16T07:02:38.466001 #13119] DEBUG -- : 10898 -------
D, [2014-01-16T07:02:48.655003 #13119] DEBUG -- : 10898 eeeeeee
D, [2014-01-16T07:02:48.666323 #13119] DEBUG -- : 10898 ffffffff
D, [2014-01-16T07:02:48.718459 #13119] DEBUG -- : 10898 gggggggg
D, [2014-01-16T07:02:48.771584 #13119] DEBUG -- : 10898 -------
D, [2014-01-16T07:02:58.947327 #13119] DEBUG -- : 10898 hhhhhhhh
D, [2014-01-16T07:02:58.957724 #13119] DEBUG -- : 10898 iiiiiii
D, [2014-01-16T07:02:59.023820 #13119] DEBUG -- : 10898 -------
D, [2014-01-16T07:03:09.171886 #13119] DEBUG -- : 10898 jjjjjjj
</pre>
<br />
<br />
<br />
<h1>
複数プロセス</h1>
<br />
次に、このプログラムを並列で複数のワーカーとして起動管理するようにしてみます。<br />
<pre class="cmdprint"># vim /etc/supervisord/conf/svsqs.conf
</pre>
<br />
複数のプロセスとして管理するには、numprocsというパラメータを2以上に設定します。<br />
また、このときprocess_nameにはワーカーの番号を含める必要があるため、<br />
supervisorの特殊変数 <i>%(program_name)</i>と<i>%(process_num)</i>を利用します。<br />
<pre class="prettyprint">[program:svsqs]
command = /home/ec2-user/svsqs.rb
process_name = %(program_name)s_%(process_num)02d
numprocs = 2
autostart = true
autorestart = true
</pre>
<br />
設定を変えたので再起動し、プロセスを見てみると、2つ起動しているのが分かります。
<br />
<pre class="cmdprint"># /etc/init.d/supervisord restart</pre>
<br />
supervisorctlでは、先ほど設定した名前でワーカー名が動的に付与されているのが分かります。
<br />
<pre class="cmdprint">[root@ip-10-160-79-47 ec2-user]# supervisorctl
svsqs:svsqs_00 RUNNING pid 14286, uptime 0:36:24
svsqs:svsqs_01 RUNNING pid 14287, uptime 0:36:24
</pre>
<br />
プロセスを落としてみると、自動で2プロセスにもどります。
<br />
<pre class="cmdprint">#
# ps -ax | grep rb
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
14286 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb
14287 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb
14516 pts/0 S+ 0:00 grep rb
#
# kill -9 14286
#
# ps -ax | grep rb
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
14287 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb
14526 ? Rl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb
</pre>
<br />
また、ログをみてみると、2つのプロセスできちんと動作しているようです。<br />
<pre class="cmdprint"># tail -1000f test.log
D, [2014-01-16T07:25:13.175073 #14287] DEBUG -- : 14287 -------
D, [2014-01-16T07:25:23.311352 #14286] DEBUG -- : 14286 aaaaaaaa
D, [2014-01-16T07:25:23.326240 #14286] DEBUG -- : 14286 bbbbbbbb
D, [2014-01-16T07:25:23.393122 #14286] DEBUG -- : 14286 ccccccc
D, [2014-01-16T07:25:23.441076 #14286] DEBUG -- : 14286 -------
D, [2014-01-16T07:25:28.144026 #14287] DEBUG -- : 14287 ddddddd
D, [2014-01-16T07:25:28.153058 #14287] DEBUG -- : 14287 -------
D, [2014-01-16T07:25:33.682118 #14286] DEBUG -- : 14286 eeeeeee
D, [2014-01-16T07:25:33.735474 #14286] DEBUG -- : 14286 fffffff
D, [2014-01-16T07:25:33.827446 #14286] DEBUG -- : 14286 -------
D, [2014-01-16T07:25:42.971976 #14287] DEBUG -- : 14287 ggggggg
D, [2014-01-16T07:25:42.986925 #14287] DEBUG -- : 14287 -------
D, [2014-01-16T07:25:44.555526 #14286] DEBUG -- : 14286 hhhhhhh
D, [2014-01-16T07:25:44.606725 #14286] DEBUG -- : 14286 -------
D, [2014-01-16T07:25:53.106090 #14287] DEBUG -- : 14287 jjjjjjjj
D, [2014-01-16T07:25:53.118289 #14287] DEBUG -- : 14287 -------
D, [2014-01-16T07:26:01.609948 #14286] DEBUG -- : 14286 kkkkkkkk
D, [2014-01-16T07:26:01.738742 #14286] DEBUG -- : 14286 -------
D, [2014-01-16T07:26:04.564231 #14287] DEBUG -- : 14287 llllllll
D, [2014-01-16T07:26:28.385778 #14287] DEBUG -- : 14287 -------
D, [2014-01-16T07:26:34.210485 #14526] DEBUG -- : 14526 mmmmm
D, [2014-01-16T07:26:34.301180 #14526] DEBUG -- : 14526 -------
D, [2014-01-16T07:26:39.204945 #14287] DEBUG -- : 14287 nnnnn
D, [2014-01-16T07:26:39.224593 #14287] DEBUG -- : 14287 -------
</pre>
<br />
こんな感じで、仮にプログラムがエラーでオチたりした場合でも、常に指定したプロセス数に起動しなおしてくれると助かります。<br />
<br />
以上です。<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-47166121676212723882013-12-11T08:00:00.000+09:002013-12-11T08:00:58.836+09:00AutoScalingってなんじゃ?(AutoScalingがAWSマネージメントコンソールで管理可能に!)ついにAWSの管理コンソールからAutoScalingが管理可能になりました。<br />
<br />
早速触ってみます。<br />
<br />
EC2のコンソールの左ペインの最下部にAutoScaling(以下AS)の項目が追加されています。<br />
選択してみると、左側に概要が表示されるので、「Create Auto Scaling Group」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-DayW2w2E4nc/UqeO9JMaXtI/AAAAAAAAEs0/HZNBpdn8vZY/s1600/2013-12-11+at+6.26+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="436" src="http://2.bp.blogspot.com/-DayW2w2E4nc/UqeO9JMaXtI/AAAAAAAAEs0/HZNBpdn8vZY/s640/2013-12-11+at+6.26+2.png" width="640" /></a></div>
<br />
<br />
<br />
<h1>
Launch Configuration の作成</h1>
<br />
<br />
既存のLaunchConfiguration(以下LC)を使うか、新規にLCを作るかを聞かれるので、今回は新規LCを選びます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-uLIwHzTR7zU/UqePyEleNeI/AAAAAAAAEs8/YnieUGtaeCY/s1600/2013-12-11+at+6.29.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="392" src="http://1.bp.blogspot.com/-uLIwHzTR7zU/UqePyEleNeI/AAAAAAAAEs8/YnieUGtaeCY/s640/2013-12-11+at+6.29.png" width="640" /></a></div>
<br />
すると、LC作成ウィザードに切り替わり、インスタンスの起動にまつわる設定が始まります。<br />
<br />
<br />
<h2>
AMI</h2>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-eaOwUxmKvpE/UqeQqdSIcHI/AAAAAAAAEtQ/uu7GhaI8L3s/s1600/2013-12-11+at+6.30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="384" src="http://3.bp.blogspot.com/-eaOwUxmKvpE/UqeQqdSIcHI/AAAAAAAAEtQ/uu7GhaI8L3s/s640/2013-12-11+at+6.30.png" width="640" /></a></div>
<br />
<h2>
インスタンスタイプ</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-xKpaSDlf77g/UqeQqSPo1pI/AAAAAAAAEtU/Z3PizYRNLi8/s1600/2013-12-11+at+6.30+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="394" src="http://4.bp.blogspot.com/-xKpaSDlf77g/UqeQqSPo1pI/AAAAAAAAEtU/Z3PizYRNLi8/s640/2013-12-11+at+6.30+2.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
詳細設定</h2>
<br />
ここで、LC名を入力します。<br />
それ以外はインスタンス起動の詳細設定と同じです。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-VG_98NxhD8s/UqeQ1JnXLKI/AAAAAAAAEtg/u_GkU_6adko/s1600/2013-12-11+at+6.31.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="384" src="http://3.bp.blogspot.com/-VG_98NxhD8s/UqeQ1JnXLKI/AAAAAAAAEtg/u_GkU_6adko/s640/2013-12-11+at+6.31.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
ストレージ</h2>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-tAZlro4vf04/UqeQ1GPdD8I/AAAAAAAAEtk/dgHSd0wurDM/s1600/2013-12-11+at+6.31+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="388" src="http://4.bp.blogspot.com/-tAZlro4vf04/UqeQ1GPdD8I/AAAAAAAAEtk/dgHSd0wurDM/s640/2013-12-11+at+6.31+2.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
セキュリティグループ</h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ikWsXFmkppw/UqeRZ8OjIzI/AAAAAAAAEtw/UiKqVYbMpVI/s1600/2013-12-11+at+6.32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="388" src="http://3.bp.blogspot.com/-ikWsXFmkppw/UqeRZ8OjIzI/AAAAAAAAEtw/UiKqVYbMpVI/s640/2013-12-11+at+6.32.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
確認画面</h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-g_ucHSGGZdM/UqeRqaNgS7I/AAAAAAAAEt4/CGaKKM0nrGw/s1600/2013-12-11+at+6.32+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="388" src="http://1.bp.blogspot.com/-g_ucHSGGZdM/UqeRqaNgS7I/AAAAAAAAEt4/CGaKKM0nrGw/s640/2013-12-11+at+6.32+2.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<h2>
キーの選択</h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-5DKtoJakFFA/UqeR3MIIxxI/AAAAAAAAEuA/Lj4tGUO_Xvo/s1600/2013-12-11+at+6.33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="394" src="http://4.bp.blogspot.com/-5DKtoJakFFA/UqeR3MIIxxI/AAAAAAAAEuA/Lj4tGUO_Xvo/s640/2013-12-11+at+6.33.png" width="640" /></a></div>
<br />
<br />
ここでLCで設定する鍵を選択して「Create launch configuration」をクリックすると、LCの作成は終了で、自動的にASの作成に移ります。<br />
<br />
<br />
<br />
<h1>
Auto Scaling Groupの作成</h1>
<br />
<br />
<h2>
基本設定</h2>
<br />
AS作成画面では、先に新規作成したLCまたは既存から選択したLCがセットされ、AS名やサイズ、起動場所(VPCやゾーン)、バランサのヘルスチェックなどを入力します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-1qsM7-DxOZg/UqeTOjnxhoI/AAAAAAAAEuU/hNyZG2uKymA/s1600/2013-12-11+at+6.34.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="392" src="http://4.bp.blogspot.com/-1qsM7-DxOZg/UqeTOjnxhoI/AAAAAAAAEuU/hNyZG2uKymA/s640/2013-12-11+at+6.34.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
スケーリングポリシー</h2>
<br />
次にスケーリングポリシーを設定します。<br />
アラームや増減の限界値や単位を設定します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vfgzIoT9W3E/UqeUQ21VmMI/AAAAAAAAEug/kJwx_cYr0ps/s1600/2013-12-11+at+6.35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="http://3.bp.blogspot.com/-vfgzIoT9W3E/UqeUQ21VmMI/AAAAAAAAEug/kJwx_cYr0ps/s640/2013-12-11+at+6.35.png" width="640" /></a></div>
<br />
<br />
「Add new alarm」でその場でアラーム設定が可能です。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-D_RlKcWBerM/UqeUnUhkGqI/AAAAAAAAEuo/J1FoSl0ijRI/s1600/2013-12-11+at+6.37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="516" src="http://2.bp.blogspot.com/-D_RlKcWBerM/UqeUnUhkGqI/AAAAAAAAEuo/J1FoSl0ijRI/s640/2013-12-11+at+6.37.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
通知</h2>
<br />
通知の設定をします。ASのイベントとそれが発生した時の通知先を設定します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-lX6495bB9Fs/UqeVJT5lu2I/AAAAAAAAEu8/ZLhf5toOTLQ/s1600/2013-12-11+at+6.41.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="520" src="http://3.bp.blogspot.com/-lX6495bB9Fs/UqeVJT5lu2I/AAAAAAAAEu8/ZLhf5toOTLQ/s640/2013-12-11+at+6.41.png" width="640" /></a></div>
<br />
<br />
<br />
<h2>
確認画面</h2>
<br />
最後に確認画面で内容をチェックし、「Create auto scaling group」をクリックして設定を終えます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-7CB7PHwekT8/UqeU4llnFdI/AAAAAAAAEuw/VbGv4Yt5mFY/s1600/2013-12-11+at+6.41+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="http://2.bp.blogspot.com/-7CB7PHwekT8/UqeU4llnFdI/AAAAAAAAEuw/VbGv4Yt5mFY/s640/2013-12-11+at+6.41+2.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<h1>
Auto Scaling Groupの確認</h1>
<br />
<br />
<h2>
設定の変更</h2>
<br />
一覧画面に作成したばかりのASが表示されます。<br />
また、ASを選択すると、下部ペインの「Details」タブなどで詳細が確認でき、<br />
「Edit」で設定の変更が可能です。<br />
<br class="Apple-interchange-newline" />ここで、DesiredCapacityの変更もできるので、min=1, max=5, desired=1にして、1つインスタンスを起動してみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Uya3sO5-ro0/UqeVn7pPOWI/AAAAAAAAEvA/lXWgntHJ6P8/s1600/2013-12-11+at+6.48.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="432" src="http://4.bp.blogspot.com/-Uya3sO5-ro0/UqeVn7pPOWI/AAAAAAAAEvA/lXWgntHJ6P8/s640/2013-12-11+at+6.48.png" width="640" /></a></div>
<br />
<br />
<br />
すると、「ScalingHistory」タブでスケーリングイベントの履歴が確認できます。<br />
失敗イベントはその理由も記述されているので簡単なデバッグも行えます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-pLbe3XuNQY0/UqeXMvD486I/AAAAAAAAEvM/1Cj7KaJIwb8/s1600/2013-12-11+at+6.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-pLbe3XuNQY0/UqeXMvD486I/AAAAAAAAEvM/1Cj7KaJIwb8/s640/2013-12-11+at+6.49.png" width="640" /></a></div>
<br />
<br />
<br />
インスタンス一覧を見てみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-FxNyjHPW3lc/UqeXeuhVkOI/AAAAAAAAEvU/vuryNlscrQA/s1600/2013-12-11+at+6.54.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="http://4.bp.blogspot.com/-FxNyjHPW3lc/UqeXeuhVkOI/AAAAAAAAEvU/vuryNlscrQA/s640/2013-12-11+at+6.54.png" width="640" /></a></div>
<br />
<br />
正常に起動しているようです。<br />
<br />
<br />
いままでASはコンソールからはまったく見えませんでしたが、これで視認性がよくなりました。<br />
これからもコマンドライン等で設定を行うという人も、状態の確認などはコンソールを使うと便利かもしれません。<br />
<br />
<br />
以上です。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-48427602810737209872013-12-09T14:40:00.003+09:002013-12-09T14:40:46.544+09:00CDPってなんじゃ?(Kinesisでstream chain)この記事は「<a href="http://www.zusaar.com/event/1120006" target="_blank">CDP Advent Calendar 2013</a>」12/9用の記事です。<br />
<br />
<a href="http://memocra.blogspot.jp/2013/12/kinesisjava.html">前回</a>、<a href="http://memocra.blogspot.jp/2013/12/kinesis.html">前々回</a>でKinesisを触りました。<br />
<br class="Apple-interchange-newline" />
資料などみていく中で、ストリームの終端になりえるものに、Redshift, S3, EMR, DynamoDBなどの他に、別のKinesisストリームもありえるということを知りました。<br />
<br class="Apple-interchange-newline" />
処理の内容が単純、高速であったり、データ数が少ない場合には1つのConsumerで事足りると思いますが、あまりにも大量であったり、処理の幾つかに非常に時間の掛かるものがあったり、複合的な処理が必要な場合には、複数のストリームを使うと全体の効率が上がる場合があるかと思います。<br />
<br />
これは、<a href="http://aws.clouddesignpattern.org/" target="_blank">CDP</a>の<a href="http://aws.clouddesignpattern.org/index.php/CDP:Queuing_Chain%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3" target="_blank">Queuing Chainパターン</a>の派生的なものになるかと思います。<br />
そこで、別のKinesisストリームに流すにはどういう場合が有効かを考えてみました。<br />
<br />
<h1>
Stream Chianパターン</h1>
<br />
・統計的な処理を連続して行う場合、Producerが投入したデータ単位と、1つ目の処理が終わったデータ単位が異なる場合があります。その場合も1つ目が終わったときに別のストリームを使います。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-T_4Z8Eksjso/UqVKPsWBcHI/AAAAAAAAErU/0r0Z7T2PL9c/s1600/Untitled+(3).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="264" src="http://1.bp.blogspot.com/-T_4Z8Eksjso/UqVKPsWBcHI/AAAAAAAAErU/0r0Z7T2PL9c/s640/Untitled+(3).png" width="640" /></a></div>
<br />
<br />
・処理全体の中で、負荷の高い部分と低い部分を分けて別に処理を行うことで、コストの最適化を行うことも考えられます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-7PJDKYvSURM/UqVOz66tVKI/AAAAAAAAEro/WEiAbyD5xCo/s1600/Untitled+(9).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="http://1.bp.blogspot.com/-7PJDKYvSURM/UqVOz66tVKI/AAAAAAAAEro/WEiAbyD5xCo/s640/Untitled+(9).png" width="640" /></a></div>
<br />
<br />
<br />
・共通処理もあるが、データの種類によって個別の処理が必要という時も別のストリームを使える場合があります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-iu5ZvYLe2ss/UqVVWDp2TnI/AAAAAAAAEsQ/E7S2dkWrNNs/s1600/Untitled+(11).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="356" src="http://3.bp.blogspot.com/-iu5ZvYLe2ss/UqVVWDp2TnI/AAAAAAAAEsQ/E7S2dkWrNNs/s640/Untitled+(11).png" width="640" /></a></div>
<br />
<br />
<br />
・おまけ:JettyをProducerにして、3つストリームのチェーンを使うと、ジェットストリームアタックになります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ty6xaI3Yu1s/UqVPtBzYGaI/AAAAAAAAEr4/VTffKBedgak/s1600/Untitled+(8).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="http://3.bp.blogspot.com/-ty6xaI3Yu1s/UqVPtBzYGaI/AAAAAAAAEr4/VTffKBedgak/s640/Untitled+(8).png" width="640" /></a></div>
<br />
<br />
<br />
<br />
最後のが言いたかっただけでした。<br />
以上です。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-88861704346229970042013-12-04T14:16:00.000+09:002013-12-05T16:45:55.449+09:00Kinesisってなんじゃ?(Java実装編)<a href="http://memocra.blogspot.jp/2013/12/kinesis.html" target="">前回</a>からの続きです。<br />
<br />
このストリームをつかってイベント処理を行うアプリケーションを実装します。<br />
Kinesisを扱うには、現時点でJavaのSDKとKinesisのクライアントライブラリ(KCL)が利用可能です。<br />
<br />
今回のサンプルとなるシステムですが、以下のように定義してみました。<br />
<ul>
<li>Producerはユーザーの出発地点(0, 0)からの到達位置(x, y)を日時ごとにJSONとしてストリームに入力していきます。</li>
<li>ConsumerAではストリームからデータを受け取り、ログとしてS3のバケットに保存していきます。</li>
<li>ConsumerBでは同じくストリームからデータを受け取り、ユーザーごとの総移動距離をDynamoDBにインクリメント保存していきます。</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-P376HcJpIJo/Up2UOP3dsNI/AAAAAAAAEpE/pv3dIos1jLM/s1600/Untitled+%25283%2529.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="368" src="http://4.bp.blogspot.com/-P376HcJpIJo/Up2UOP3dsNI/AAAAAAAAEpE/pv3dIos1jLM/s640/Untitled+%25283%2529.png" width="640" /></a></div>
<div>
<br /></div>
<div>
これを、限定公開用にKinesis対応されたJavaのSDKとKinesisのクライアントライブラリ(KCL)を使って実装してみます。SDKにはサンプルコードなどが付属しているため、それを参考に実装してみます。</div>
<div>
また、KCLはシャードの管理のために裏側でConsumerごとにDynamoDBテーブルを使用します。</div>
<div>
<br />
JDKの1.7とantがインストールされていることが前提です。<br />
<br />
<br />
<h1>
Producer</h1>
<br />
以下のツリー図の通り、SDKのサンプルコードの一部として他のサンプルと同じようにMemoKinesisというサンプルをつくりました。<br />
<br />
<pre class="cmdprint">/usr/local/src/aws-java-sdk-1.6.4/
├── lib
│ ├── aws-java-sdk-1.6.4.jar
│ ├── aws-java-sdk-1.6.4-javadoc.jar
│ ├── aws-java-sdk-1.6.4-sources.jar
│ ├── aws-java-sdk-flow-build-tools-1.6.4.jar
│ ├── <span style="color: blue;">commons-lang-2.6.jar</span>
│ ├── <span style="color: blue;">joda-time-2.3-dist.tar.gz</span>
│ ├── <span style="color: blue;">joda-time-2.3.jar</span>
│ └── <span style="color: blue;">jsonic-1.3.0.jar</span>
├── samples
│ └── <span style="color: red;">MemoKinesis</span>
│ ├── <span style="color: red;">AwsCredentials.properties</span>
│ ├── <span style="color: red;">build.xml</span>
│ ├── <span style="color: red;">Hoge.java</span>
│ └── <span style="color: red;">MemorycraftKinesisProducer.java</span>
└── third-party
</pre>
<br />
配下のbuild.xmlは他サンプルと同様に、../../lib, ../../third-partyにクラスパスを通して、コンパイル→実行するようなターゲットになっているため、クラス名だけ変更してそのまま利用しています。<br />
AwsCredentials.propertiesには自分のアカウントのキー情報を入力してあります。<br />
また、このコードで必要なライブラリは../../libディレクトリに追加してあります(<span style="color: blue;">青字</span>)。</div>
<br />
また、コードは以下の通りです。<br />
<br />
<b>MemorycraftKinesisProducer.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783381.js"></script>
<br />
<b>Hoge.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783395.js"></script>
<br />
Producerでは、testuser_[A-Z]の26人のユーザーIDと、日時、ランダムなx,y をJSON化してストリームに投入しつづけます。<br />
AmazonKinesisClientを初期化し、PutRecordRequestを使ってputRecordします。<br />
実行すると以下のように投入され続けていくことがわかります。
<br />
<pre class="cmdprint">[root@ip-10-154-154-57 MemoKinesis]# ant
Buildfile: /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml
run:
[javac] /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml:12: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1 source file to /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis
[javac] warning: Supported source version 'RELEASE_6' from annotation processor 'com.amazonaws.eclipse.simpleworkflow.asynchrony.annotationprocessor.AsynchronyDeciderAnnotationProcessor' less than -source '1.7'
[javac] 1 warning
[java] Dec 03, 2013 10:08:23 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:22","user_id":"testuser_F","x":"66.41701160878385","y":"85.85361518485006"}
[java] Dec 03, 2013 10:08:23 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:23","user_id":"testuser_D","x":"64.19880893804586","y":"26.65513499028829"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:23","user_id":"testuser_T","x":"59.34696505060783","y":"85.54404394674596"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_N","x":"76.26154448594934","y":"67.74843698818461"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_Z","x":"29.457789127237753","y":"18.48254643961956"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_Z","x":"9.91729666668798","y":"18.193714091252332"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_M","x":"98.54843645906183","y":"83.25335740427954"}
[java] Dec 03, 2013 10:08:24 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_F","x":"22.2596852199308","y":"39.49631977033009"}
[java] Dec 03, 2013 10:08:25 AM MemorycraftKinesisProducer main
[java] INFO: {"datetime":"2013-12-03 10:08:24","user_id":"testuser_W","x":"35.34360225385589","y":"7.982969346289337"}
.......
</pre>
<br />
<br />
<br />
<h1>
Consumer A</h1>
<br />
次はConsumerです。これも同じように他のサンプルコードとほぼ同じ構成で実装しました。<br />
<br />
<pre class="cmdprint">/usr/local/src/aws-java-sdk-1.6.4/
├── lib
│ ├── aws-java-sdk-1.6.4.jar
│ ├── aws-java-sdk-1.6.4-javadoc.jar
│ ├── aws-java-sdk-1.6.4-sources.jar
│ ├── aws-java-sdk-flow-build-tools-1.6.4.jar
│ ├── <span style="color: blue;">commons-lang-2.6.jar</span>
│ ├── <span style="color: blue;">jsonic-1.3.0.jar</span>
│ └── <span style="color: blue;">KinesisClientLibrary.jar</span>
├── samples
│ └── <span style="color: red;">MemoKinesis</span>
│ ├── <span style="color: red;">AwsCredentials.properties</span>
│ ├── <span style="color: red;">build.xml</span>
│ ├── <span style="color: red;">ConfigKeys.java</span>
│ ├── <span style="color: red;">MemorycraftKinesisLoggingConsumer.java</span>
│ ├── <span style="color: red;">MemorycraftKinesisLoggingProcessorFactory.java</span>
│ └── <span style="color: red;">MemorycraftKinesisLoggingProcessor.java</span>
└── third-party
</pre>
<br />
Consumer Aのインスタンス群では、ストリームに流れているデータを抽出して、順次S3にログとして保存していきます。<br />
ConsumerではKCLを使用します。<br />
<br />
構成としては、MemorycraftKinesisLoggingConsumerからIRecordProcessorFactoryを実装したMemorycraftKinesisLoggingProcessorFactoryを初期化してワーカーとして実行します。<br />
実際の処理はIRecordProcessorを実装したMemorycraftKinesisLoggingProcessorのprocessRecordsメソッド内部に記述します。<br />
<br />
<br />
<b>MemorycraftKinesisLoggingConsumer.java</b><br />
<script src="https://gist.github.com/memorycraft/7783412.js"></script>
<br />
<b>MemorycraftKinesisLoggingProcessorFactory.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783417.js"></script>
<br />
<b>MemorycraftKinesisLoggingProcessor.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783449.js"></script>
<br />
実行してみます。<br />
<pre class="cmdprint">[root@ip-10-118-97-158 MemoKinesis]# ant
Buildfile: /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml
run:
[javac] /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml:12: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 4 source files to /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis
[javac] warning: Supported source version 'RELEASE_6' from annotation processor 'com.amazonaws.eclipse.simpleworkflow.asynchrony.annotationprocessor.AsynchronyDeciderAnnotationProcessor' less than -source '1.7'
[javac] 1 warning
..........
[java] INFO: Successfully published 3 datums.
[java] Dec 03, 2013 11:58:06 AM com.amazonaws.services.kinesis.metrics.impl.DefaultCWMetricsPublisher publishMetrics
[java] INFO: Successfully published 18 datums.
[java] Dec 03, 2013 11:58:14 AM com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker$WorkerLog info
[java] INFO: Current stream shard assignments: shardId-000000000001, shardId-000000000000
[java] Dec 03, 2013 11:58:14 AM com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker$WorkerLog info
[java] INFO: Sleeping ...
[java] Dec 03, 2013 11:58:16 AM com.amazonaws.services.kinesis.metrics.impl.DefaultCWMetricsPublisher publishMetrics
[java] INFO: Successfully published 20 datums.
[java] Dec 03, 2013 11:58:16 AM com.amazonaws.services.kinesis.metrics.impl.DefaultCWMetricsPublisher publishMetrics
[java] INFO: Successfully published 3 datums.
[java] Dec 03, 2013 11:58:18 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: process record [21269323576357670914947437401207537664]
[java] Dec 03, 2013 11:58:18 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: saved [json]={"datetime":"2013-12-03 08:41:05","user_id":"testuser_G","x":"54.504733903095726","y":"27.966324048617963"}
[java] Dec 03, 2013 11:58:18 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: process record [21269323576357720993054772957520920576]
[java] Dec 03, 2013 11:58:19 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: saved [json]={"datetime":"2013-12-03 08:41:05","user_id":"testuser_W","x":"12.256118907591883","y":"63.004577908019634"}
[java] Dec 03, 2013 11:58:19 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: process record [21269323576357794417499720660453949440]
[java] Dec 03, 2013 11:58:19 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: saved [json]={"datetime":"2013-12-03 08:41:05","user_id":"testuser_O","x":"69.81831906353719","y":"31.571006624423724"}
[java] Dec 03, 2013 11:58:19 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: process record [21269323576357840331291814692712415232]
[java] Dec 03, 2013 11:58:19 AM MemorycraftKinesisLoggingProcessor process
[java] INFO: saved [json]={"datetime":"2013-12-03 08:41:04","user_id":"testuser_F","x":"19.924814432111905","y":"41.65256488223227"}
..........
</pre>
<br />
<br />
うまく拾えているようです。<br />
S3のバケットを見てみます。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-W1eizUifOiQ/Up3oxo1WGrI/AAAAAAAAEpk/xNTqztTnH8I/s1600/2013-12-03+at+23.18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="329" src="http://4.bp.blogspot.com/-W1eizUifOiQ/Up3oxo1WGrI/AAAAAAAAEpk/xNTqztTnH8I/s640/2013-12-03+at+23.18.png" width="640" /></a></div>
<br />
おお、次から次へとファイルが保存されていくのがわかります。<br />
そのうちの一つをダウンロードして、中身を見てみます。<br />
<pre class="prettyprint">{"datetime":"2013-12-03 08:44:17","user_id":"testuser_H","x":"79.49199108301805","y":"2.4829017202529724"}
</pre>
中身もうまく入っているようです。
<br />
<br />
<br />
<h1>
Consumer B</h1>
<br />
<br />
次はConsumerBです。<br />
<br />
<pre class="cmdprint">/usr/local/src/aws-java-sdk-1.6.4/
├── lib
│ ├── aws-java-sdk-1.6.4.jar
│ ├── aws-java-sdk-1.6.4-javadoc.jar
│ ├── aws-java-sdk-1.6.4-sources.jar
│ ├── aws-java-sdk-flow-build-tools-1.6.4.jar
│ ├── <span style="color: blue;">commons-lang-2.6.jar</span>
│ ├── <span style="color: blue;">jsonic-1.3.0.jar</span>
│ └── <span style="color: blue;">KinesisClientLibrary.jar</span>
├── samples
│ └── <span style="color: red;">MemoKinesis</span>
│ ├── <span style="color: red;">AwsCredentials.properties</span>
│ ├── <span style="color: red;">build.xml</span>
│ ├── <span style="color: red;">ConfigKeys.java</span>
│ ├── <span style="color: red;">Hoge.java</span>
│ ├── <span style="color: red;">MemorycraftKinesisDistanceConsumer.java</span>
│ ├── <span style="color: red;">MemorycraftKinesisDistanceProcessorFactory.java</span>
│ └── <span style="color: red;">MemorycraftKinesisDistanceProcessor.java</span>
└── third-party
</pre>
<br />
Consumer Bのインスタンス群では、ユーザーIDをハッシュキーにしたDynamoDBのレコードにXとYから距離を出してインクリメントしていき総距離を加算更新します。<br />
<br />
クラスとしてはMemorycraftKinesisDistanceProcessorを中心に実装します。<br />
<br />
<b>MemorycraftKinesisDistanceConsumer.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783459.js"></script>
<br />
<b>MemorycraftKinesisDistanceProcessorFactory.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783464.js"></script>
<br />
<b>MemorycraftKinesisDistanceProcessor.java</b>
<br />
<script src="https://gist.github.com/memorycraft/7783481.js"></script>
<br />
実行してみます。<br />
<br />
<pre class="cmdprint">[root@ip-10-60-155-21 MemoKinesis]# ant
Buildfile: /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml
run:
[javac] /usr/local/src/aws-java-sdk-1.6.4/samples/MemoKinesis/build.xml:12: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[java] Dec 03, 2013 3:22:17 PM MemorycraftKinesisDistanceConsumer configure
[java] INFO: Using workerId: ip-10-60-155-21.ec2.internal:584216f1-8d4d-429c-ba99-8af365345e17
[java] Dec 03, 2013 3:22:17 PM MemorycraftKinesisDistanceConsumer configure
.......
[java] INFO: Successfully published 18 datums.
[java] Dec 03, 2013 3:23:18 PM com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker$WorkerLog info
[java] INFO: Current stream shard assignments: shardId-000000000001, shardId-000000000000
[java] Dec 03, 2013 3:23:18 PM com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker$WorkerLog info
[java] INFO: Sleeping ...
[java] Dec 03, 2013 3:23:18 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: process record [21269323576357670914947437401207537664]
[java] Dec 03, 2013 3:23:19 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: saved [user_id:testuser_G, distance:61.260764757221075]
[java] Dec 03, 2013 3:23:19 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: process record [21269323576357720993054772957520920576]
[java] Dec 03, 2013 3:23:19 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: saved [user_id:testuser_W, distance:64.18558473711015]
[java] Dec 03, 2013 3:23:19 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: process record [21269323576357794417499720660453949440]
[java] Dec 03, 2013 3:23:19 PM MemorycraftKinesisDistanceProcessor process
[java] INFO: saved [user_id:testuser_O, distance:76.62457919060493]
.....
</pre>
<br />
<br />
それではDynamoDBを見てみます。<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
ちゃんとユーザーごとに集計されているようです。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-sY878-DjoX0/Up37E0MY5AI/AAAAAAAAEqM/71bCsawGV9s/s1600/2013-12-04+at+0.33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="378" src="http://1.bp.blogspot.com/-sY878-DjoX0/Up37E0MY5AI/AAAAAAAAEqM/71bCsawGV9s/s640/2013-12-04+at+0.33.png" width="640" /></a></div>
<br />
<br />
続々加算されていきます。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-1YnB6IEU8C8/Up37E1ch9YI/AAAAAAAAEqQ/ZSBKEDtM5w0/s1600/2013-12-04+at+0.38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="378" src="http://1.bp.blogspot.com/-1YnB6IEU8C8/Up37E1ch9YI/AAAAAAAAEqQ/ZSBKEDtM5w0/s640/2013-12-04+at+0.38.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<h1>
チェックポイント</h1>
<br />
<br />
KinesisのコンシューマーでKCLを使うとコンシューマーごとにチェックポイントというマーカーを打つことができます。<br />
IRecordProcessor.checkpointメソッド内で、checkpointer.checkpoint()を呼び出すと、ストリームのシーケンスのなかでどこまで読み込んだという記録が保存され、読み取りを中断したり障害が起こった後に、プロセスを再稼働すると、そのチェックポイントから読み取りが再開されます。<br />
チェックポイントを呼び出すタイミングはユーザーに委ねられていて、今回のサンプルでは1分に設定しています。<br />
<br />
<pre class="prettyprint"> private static final long CHECKPOINT_INTERVAL_MILLIS = 60000L;</pre>
<pre class="prettyprint"> public void processRecords(List<record> records, IRecordProcessorCheckpointer checkpointer) {
process(records);
if (System.currentTimeMillis() > nextCheckpointTimeInMillis) {
checkpoint(checkpointer);
nextCheckpointTimeInMillis = System.currentTimeMillis() + CHECKPOINT_INTERVAL_MILLIS;
}
}
</record></pre>
<br />
<br />
<h1>
わかったこと</h1>
<br />
<ul>
<li>定期的ではなく常にデータ処理を処理し続けることができる仕組みと、そのためのスケーラビリティを持っている。</li>
<li>ユーザーが書くコードは、最低限であればそんなに多くない。</li>
<li>バッチではタイムラグがありすぎる!という場合にはうってつけのサービス。</li>
<li>Consumer同士の処理順を気にしないでいい。処理順をつけたい場合は、そのConsumer内で行うか、出力先に別のストリームを指定しそちらで次の処理をするとか</li>
<li>DynamoDBと同様、ストリームのキャパシティの見積もりは必要です。でもシャード数を指定するだけなので変更自体は簡単</li>
<li>周辺のインスタンス、特にConsumerはバッチと同様インスタンスの負荷をみてロールごとにAutoScalingGroupを作る必要あり</li>
<li>Consumerからデータの移動先となるDynamoDBやRedshiftその他のエンドポイントのキャパシティ管理も同様に注意が必要</li>
</ul>
<br />
<br />
以上です。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-13496097159135110202013-12-04T11:00:00.000+09:002013-12-04T11:00:04.275+09:00Kinesisってなんじゃ?(ストリーム作成編)AWSの新サービス<a href="http://aws.amazon.com/jp/kinesis/" target="_blank">Kinesis</a>が限定プレビュー公開されています。<br />
私のところでも見れるようになったので、触ってみました。<br />
<br />
<h1>
Kinesisとは</h1>
<br />
Kinesisは大量なデータのリアルタイムイベント処理をサポートするサービスです。<br />
ユーザーは「ストリーム」を作り、そこにデータを流し、受け取り、処理を行います。<br />
<br />
データを流す、受け取る、処理を行う、という部分はユーザーがプログラムで実装します。<br />
Kinesisに接続するプログラムには大きく分けてProducerとConsumerという2つの立場があります。<br />
<ul>
<li>Producerはストリームにデータを入力します。Producerは場合によってWEBまたはAPPサーバーのようなエンドポイントであったり、既存データのフェッチプログラムとして実装されます。</li>
<li>Consumerはストリームからデータを受け取り処理します。Consumerは処理内容ごとにAutoScalingグループなどによってクラスタ化されることが多くなります。</li>
</ul>
<br />
ストリームを流れるデータは順序付けされたシーケンスとして扱われ、「シャード」に分散されます。<br />
また、Kinesisではシャードの単位でスループットが決定され、ユーザーは入出力の量に合わせてシャード数を設定できます。<br />
<br />
<br />
<h1>
ストリームの作成</h1>
<br />
それでは、まずストリームを作ってみます。<br />
限定公開なので、コンソールのメニューには現れませんが、申請が通っている場合は、以下のURLでアクセスできます。<br />
<br />
<a href="https://console.aws.amazon.com/kinesis/">https://console.aws.amazon.com/kinesis/</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-0rBFvqTBLVI/Up2H8S2n2PI/AAAAAAAAEoE/6OLxugaTY1w/s1600/2013-11-28+at+16.40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="635" src="http://3.bp.blogspot.com/-0rBFvqTBLVI/Up2H8S2n2PI/AAAAAAAAEoE/6OLxugaTY1w/s640/2013-11-28+at+16.40.png" width="640" /></a></div>
<br />
<br />
「Create Stream」をクリックして、ストリームを作成します。<br />
ストリーム名とストリーム数を入力します。<br />
ストリーム数の目安がわからない場合は、DynamoDBと同じように、データサイズや書込回数、Consumer数を設定することで自動的に最適なシャード数を適用できます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ze2RqHq34LA/Up2J5MSqKoI/AAAAAAAAEoQ/DVL3nOBatcc/s1600/2013-11-28+at+16.45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="592" src="http://2.bp.blogspot.com/-ze2RqHq34LA/Up2J5MSqKoI/AAAAAAAAEoQ/DVL3nOBatcc/s640/2013-11-28+at+16.45.png" width="640" /></a></div>
<br />
<br />
<br />
「Create」をクリックすると、作成中(CREATING)のストリームが一覧に表示されます。<br />
Statusが「ACTIVE」になると利用可能です。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-T52tR-v51zE/Up2MYRAYE0I/AAAAAAAAEoo/s4t72c1-Qvc/s1600/2013-12-03+at+16.46.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="http://1.bp.blogspot.com/-T52tR-v51zE/Up2MYRAYE0I/AAAAAAAAEoo/s4t72c1-Qvc/s640/2013-12-03+at+16.46.png" width="640" /></a></div>
<br />
<br />
ストリーム名をクリックすると、ストリームのメトリクスが表示されます。<br />
これをもとに、SDKなどでシャード数の変更などを行うことができます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-gpQsh0xCuzE/Up2agOrf2eI/AAAAAAAAEpQ/xZX5wuVfgBg/s1600/2013-12-03+at+17.45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="http://4.bp.blogspot.com/-gpQsh0xCuzE/Up2agOrf2eI/AAAAAAAAEpQ/xZX5wuVfgBg/s640/2013-12-03+at+17.45.png" width="475" /></a></div>
<br />
<br />
<h1>
料金</h1>
<br />
<br />
<ul>
<li>シャード:1シャードあたり1時間0.015ドル</li>
<li>リクエスト:100万PUTで0.028ドル</li>
<li>データ転送(入力):無料 </li>
<li>データ転送(出力):EC2で処理する分には無料</li>
</ul>
<br />
これとは別に、実際の処理を行うEC2のインスタンス料金が掛かります。<br />
ストリームの料金ではなく、接続するEC2の料金で回収するモデルのようです。<br />
<br />
<br />
次回は、ストリームを使った実装をやってみます。<br />
以上です。<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-81036604543307537952013-11-16T17:26:00.001+09:002013-11-16T17:27:40.708+09:00re:Inventってなんじゃ?(CloudTrail)re:Invent2013に来ています。<br />
そこでCloudTrailの発表があったので触ってみました。<br />
<br />
CloudTrailは、AWSのAPIコールの記録をS3にログとして保存するサービスです。<br />
これによってセキュリティ分析や運用チェックなどを行うことが可能です。<br />
<br />
AWSコンソールをみるとCoudTrailが追加されているので、開いてみます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-zDptSNv5g8I/UobHbynCkxI/AAAAAAAAEkk/w5ChDcMsqjw/s1600/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99+(2).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="http://1.bp.blogspot.com/-zDptSNv5g8I/UobHbynCkxI/AAAAAAAAEkk/w5ChDcMsqjw/s400/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99+(2).png" width="400" /></a></div>
<br />
ログの保存先のS3バケットを指定して、必要であればその他のオプションも設定します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/--sTrXUVRdSE/UobHb76gSCI/AAAAAAAAEkY/6S3enoh6Eyo/s1600/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="224" src="http://1.bp.blogspot.com/--sTrXUVRdSE/UobHb76gSCI/AAAAAAAAEkY/6S3enoh6Eyo/s400/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99+(1).png" width="400" /></a></div>
<br />
Subscribeボタンを押すと、設定完了です。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-SeMowaoZrzo/UobHb12deZI/AAAAAAAAEkc/6n6p43wyzWU/s1600/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="http://2.bp.blogspot.com/-SeMowaoZrzo/UobHb12deZI/AAAAAAAAEkc/6n6p43wyzWU/s400/2013-11-15+17.13+%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B7%E3%82%99.png" width="400" /></a></div>
<br />
<br />
しばらく、AWSの操作をしたあと、出力先に設定したS3バケットを確認します。<br />
すると、以下のように、json形式のログファイルが圧縮された状態で日ごとに保存されるようになります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ajjfEKPZda4/UocqMoc258I/AAAAAAAAEk8/3pW8npXnrMo/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013:11:16+0:17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="http://1.bp.blogspot.com/-ajjfEKPZda4/UocqMoc258I/AAAAAAAAEk8/3pW8npXnrMo/s400/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013:11:16+0:17.png" width="400" /></a></div>
<br />
<br />
このうちの一つをダウンロードして中身を見てみます。<br />
<br />
<pre class="prettyprint">{
"Records": [
{
"awsRegion": "us-east-1",
"eventName": "DescribeRouteTables",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:00Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"routeTableIdSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeSubnets",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:07:59Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"subnetSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeVpcs",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:07:58Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"vpcSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeSecurityGroups",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:03Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"securityGroupIdSet": {},
"securityGroupSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeNetworkAcls",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:01Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"networkAclIdSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeDBInstances",
"eventSource": "rds.amazonaws.com",
"eventTime": "2013-11-15T18:08:06Z",
"eventVersion": "1.0",
"requestParameters": null,
"responseElements": null,
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeVolumes",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:04Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"volumeSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeAddresses",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:03Z",
"eventVersion": "1.0",
"requestParameters": {
"allocationIdsSet": {},
"filterSet": {},
"publicIpsSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
},
{
"awsRegion": "us-east-1",
"eventName": "DescribeInstances",
"eventSource": "ec2.amazonaws.com",
"eventTime": "2013-11-15T18:08:02Z",
"eventVersion": "1.0",
"requestParameters": {
"filterSet": {},
"instancesSet": {}
},
"responseElements": "<responseOmitted>",
"sourceIPAddress": "54.249.240.229",
"userAgent": "aws-sdk-php/1.6.2 PHP/5.4.20 curl/7.19.7 openssl/1.0.0-fips",
"userIdentity": {
"accessKeyId": "xxxxxxxxxxxxxxxxxx",
"accountId": "821635308497",
"arn": "arn:aws:iam::821635308497:root",
"principalId": "821635308497",
"type": "Root"
}
}
]
}
</pre>
<br />
<br />
このように呼び出したAPIの内容が表示されるため、jqやログ解析ツールなどと併用してAWSアカウントに対してどういった操作があったかを簡潔に知ることが可能になります。
<br />
<br />
以上です。Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-54913360472277654192013-09-26T11:00:00.000+09:002013-09-26T11:00:00.317+09:00EBSってなんじゃ?(cryptsetup + S3 + IAM Roleでディスク暗号化鍵をS3で管理)EBSの暗号化の方法のひとつとしてcryptsetupという技術があります。cryptsetupはパスフレーズで暗号化されたディスクにアクセス(マウント)しますが、今回は鍵ファイルを使用してアクセスする手順をまとめました。<br />
また、鍵ファイルを同じインスタンス内に置かないためにS3から鍵ファイルを取得し、マウントした後に削除するようにします。<br />
<br />
それでは手順を追ってみます。<br />
<br />
まずcryptsetupで/dev/xvdfにアタッチされたEBSボリュームの暗号化を行い、マウントします。<br />
<pre class="cmdprint"># yum install -y cryptsetup
# yum install xfsprogs -y
# cryptsetup luksFormat -c aes -h sha256 /dev/xvdf
# cryptsetup luksOpen /dev/xvdf encrypted
# ls -l /dev/mapper/
# mkfs.xfs /dev/mapper/luks
# mkdir /mnt/vol
# mount -t xfs /dev/mapper/luks /mnt/vol
# mkdir /mnt/vol/data
</pre>
<br />
<br />
次に鍵ファイルを作成し、cryptsetupに登録します
<br />
<pre class="cmdprint"># dd if=/dev/urandom of=/root/encrypted_key bs=1 count=1024
# cryptsetup luksAddKey /dev/xvdf /root/encrypted_key
</pre>
<br />
<br />
S3バケットを作成し、そこへ鍵を保管します
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-JfkICA2SIxU/UkL2Gxl2ISI/AAAAAAAAEcs/ajseqBgwmkg/s1600/S3+Management+Console-64.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://2.bp.blogspot.com/-JfkICA2SIxU/UkL2Gxl2ISI/AAAAAAAAEcs/ajseqBgwmkg/s400/S3+Management+Console-64.png" width="400" /></a></div>
<br />
<br />
<br />
自動で暗号化+マウントするために起動スクリプトをつくり、S3から鍵ファイルを取得しマウントするようにします。終わったらAMIを作成します。<br />
<pre class="cmdprint"># cat /etc/init.d/cryptmount
-----------
#!/bin/sh
#
#
# chkconfig: 345 60 16
aws s3 get-object --region ap-northeast-1 --bucket luks-key --key xvdf_luks_key /boot/xvdf_luks_key
cryptsetup luksOpen /dev/xvdf luks --key-file /boot/xvdf_luks_key
mount -t xfs /dev/mapper/luks /mnt/vol
rm -rf /boot/xvdf_luks_key
-----------
# rm -rf /root/xvdf_luks_key
</pre>
<br />
<br />
<br />
IAM Roleを作成し、S3へのアクセスを許可します
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-vVujcyHl2k0/UkLzeNXzGxI/AAAAAAAAEcc/3BQekvObVSc/s1600/IAM+Management+Console-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="http://2.bp.blogspot.com/-vVujcyHl2k0/UkLzeNXzGxI/AAAAAAAAEcc/3BQekvObVSc/s400/IAM+Management+Console-3.png" width="400" /></a></div>
<br />
<br />
作成したAMIの起動時にIAM Roleを指定します
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-qnTWOHAsE8s/UkLzedPDHkI/AAAAAAAAEck/OKkSxIXvOR0/s1600/EC2+Management+Console-104.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="http://2.bp.blogspot.com/-qnTWOHAsE8s/UkLzedPDHkI/AAAAAAAAEck/OKkSxIXvOR0/s400/EC2+Management+Console-104.png" width="400" /></a></div>
<br />
<br />
<br />
これで、鍵がない状態ではEBSをマウントすることができなくなりました。<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-11669953207704803762013-06-15T16:59:00.000+09:002013-06-15T17:14:18.002+09:00Spiderってなんじゃ?(SUBPARTITIONで負荷分散しながらストレージ容量を無限追加)<a href="http://memocra.blogspot.jp/search/label/spider" target="_blank">Spiderシリーズ</a>です。<a href="http://wild-growth-ja.blogspot.jp/search/label/Spider" target="_blank">Spider</a>ではパーティションを使ってシャーディングしますが、パーティションの定義によって分散の特性が変わります。<br />
<br />
<b>1. サロゲートキーなどのHASHパーティション</b><br />
<ul>
<li>データは均等に分散</li>
<li>更新負荷は均等に分散</li>
<li>増設はデータ全体の再ハッシュが必要</li>
</ul>
<br />
<b>2. 日付の年月などのHASHパーティション</b><br />
<ul>
<li>データは順次格納</li>
<li>更新負荷は常に1データノードにのみかかる</li>
<li>増設は新しい年月を追加</li>
</ul>
<br />
<b>3. サロゲートキーなどのRANGEパーティション</b><br />
<ul>
<li>データは順次格納</li>
<li>更新負荷は常に1データノードにのみかかる</li>
<li>増設は新しいキー範囲を追加</li>
</ul>
<br />
理想は均等に負荷分散しながら、データ容量を後から増やせるのがベストですが、1,2,3とも負荷分散と容量追加のどちらかにしか親和性がありません。<br />
そこで、作者の斯波さん(<a href="https://twitter.com/kentokushiba" target="_blank">@kentokushiba</a>)に伺ったところ、 SpiderでもSUBPARTITIONが使えるとのことでRANGEとHASHを組み合わせることで実現できると教えて頂きました。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-7jPpPSgMTvg/UbwiDr-22fI/AAAAAAAAENE/SzWivrPWJHI/s1600/2p.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="http://4.bp.blogspot.com/-7jPpPSgMTvg/UbwiDr-22fI/AAAAAAAAENE/SzWivrPWJHI/s320/2p.png" width="320" /></a></div>
<br />
<br />
早速やってみます。<br />
<pre class="prettyprint">CREATE TABLE `spdoc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created_at` datetime DEFAULT NULL,
`content` text,
`docname` varchar(255),
INDEX(created_at) ,
PRIMARY KEY (`id`)
) ENGINE=SPIDER DEFAULT CHARSET=utf8 CONNECTION=' table "spdoc", user "xxxxxxxx", password "yyyyyyyyy" auto_increment_mode "1" '
PARTITION BY RANGE (id)
SUBPARTITION BY HASH(id) (
PARTITION p1 VALUES LESS THAN (1000000) (
SUBPARTITION db1 COMMENT = 'host "10.0.1.141", port "3306"' ENGINE = SPIDER,
SUBPARTITION db2 COMMENT = 'host "10.0.1.142", port "3306"' ENGINE = SPIDER
),
PARTITION p2 VALUES LESS THAN (2000000) (
SUBPARTITION db3 COMMENT = 'host "10.0.1.143", port "3306"' ENGINE = SPIDER,
SUBPARTITION db4 COMMENT = 'host "10.0.1.144", port "3306"' ENGINE = SPIDER
)
);
</pre>
<br />
<br />
まずRANGEパーティションをidの値の範囲で定義します。試しに1000000,2000000に設定します。<br />
次に、SUBPARTITIONでidでHASHパーティションを定義し、ここにデーターノードを指定します。<br />
<br />
すると、idが1000000以下のデータについてdb1, db2のデータノードに均等に分散され、<br />
1000000〜2000000の範囲では、db3, db4に均等に分散されます。<br />
<br />
idが2000000を超えそうになった場合は、後から3つめのパーティションを追加することができます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-vtXYcwGwC0k/UbwiDu-GuCI/AAAAAAAAENA/UJw_lE5QnDo/s1600/3p.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="182" src="http://3.bp.blogspot.com/-vtXYcwGwC0k/UbwiDu-GuCI/AAAAAAAAENA/UJw_lE5QnDo/s320/3p.png" width="320" /></a></div>
<br />
<br />
<pre class="prettyprint">ALTER TABLE spdoc ADD PARTITION
(
PARTITION p3 VALUES LESS THAN (3000000) (
SUBPARTITION db5 COMMENT = 'host "10.0.1.145", port "3306"' ENGINE = SPIDER,
SUBPARTITION db6 COMMENT = 'host "10.0.1.146", port "3306"' ENGINE = SPIDER
)
);
</pre>
<br />
これでデータ容量はほぼ無限に増やすことができます。<br />
<br />
パーティションごとにSUBPARTITIONの数を変えることはできないので、負荷の分散数は同じデータノード数で賄わなければいけませんが、その場合はパーティションごとのデータノードのインスタンスタイプやPIOPSを増やすことで処理能力をアップさせることで対応できるかと思います。<br />
<br />
斯波さんありがとうございました!<br />
<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.comtag:blogger.com,1999:blog-6812554369115335550.post-20504580265082066762013-05-28T20:10:00.000+09:002013-05-28T20:10:27.115+09:00Fluentdってなんじゃ?(設定ファイルをリモートから読み込む)fluentdのドキュメントに以下のような記載がありました。<br />
<br />
<a href="http://docs.fluentd.org/articles/config-file#3-include-directive" target="_blank">Configuration File - (3) Include Directive</a><br />
<blockquote class="tr_bq">
<pre># absolute path
include /path/to/config.conf
# if using a relative path, the directive will use
# the dirname of this config file to expand the path
include extra.conf
# glob match pattern
include config.d/*.conf
# http
include http://example.com/fluent.conf
</pre>
</blockquote>
<br />
最後の行、、、HTTPから設定ファイルを取得してインクルードできるみたいです。<br />
<br />
ということで試してみました。<br />
<br />
<b>common.conf</b>
<br />
<pre class="prettyprint"><source>
type tail
format apache
pos_file /var/log/td-agent/httpd-access.log.pos
path /var/log/httpd/access_log
tag apache.access
</source>
<match apache.access>
type s3
aws_key_id xxxxxxxxxxxxxxxxxxx
aws_sec_key yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
s3_bucket hoge-bucket
path logs/
buffer_path /var/log/fluent/s3
flush_interval 10s
</match></pre>
<br />
これをS3にアップロードしてWEBホスティングしてみます。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1Id58Qp7VYI/UaSEzXP6dTI/AAAAAAAAEL0/WKIp9-wYA8k/s1600/S3+Management+Console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="http://2.bp.blogspot.com/-1Id58Qp7VYI/UaSEzXP6dTI/AAAAAAAAEL0/WKIp9-wYA8k/s640/S3+Management+Console.png" width="640" /></a></div>
<br />
<br />
そして、EC2では以下のように設定します。<br />
<br />
<b>/etc/td-agent/td-agent.conf</b><br />
<pre class="prettyprint">include http://s3-ap-northeast-1.amazonaws.com/hoge-bucket/conf/fluentd/common.conf
</pre>
<pre class="cmdprint"># /etc/init.d/td-agent start
</pre>
<br />
<br />
httpdのコンテンツにアクセスしてしばらくたつと、、、
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-aFjLBWQapmE/UaSO3Dc0YMI/AAAAAAAAEME/YuPOyBgTMfc/s1600/S3+Management+Console-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="http://2.bp.blogspot.com/-aFjLBWQapmE/UaSO3Dc0YMI/AAAAAAAAEME/YuPOyBgTMfc/s640/S3+Management+Console-1.png" width="640" /></a></div>
<br />
無事出力されていました!<br />
<br />
これの何がいいかというと、<br />
<br />
<ul>
<li>各サーバーに共通の設定ファイルなどを外部化しておき、一括変更をかけられる
(再起動は必要ですが、定期的に再起動をかけるようにしておくという手もあります)</li>
<li>いっそ全設定を外出しして完全に外部で管理する</li>
</ul>
<br />
などが可能になります。<br />
<br />
以上です。<br />
<br />Anonymoushttp://www.blogger.com/profile/17275248655542748871noreply@blogger.com