PageRenderTime 66ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/2013/04/28/more-rex/index.html

https://github.com/JEEN/jeen.github.com
HTML | 355 lines | 205 code | 146 blank | 4 comment | 0 complexity | 43beb1e30dfa9fbce3014be36e56d3b6 MD5 | raw file
  1. <!DOCTYPE html>
  2. <!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
  3. <!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
  4. <!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
  5. <head>
  6. <meta charset="utf-8">
  7. <title>Rex Common Practice - Jeen - Yet anothere techlog</title>
  8. <meta name="author" content="Jeen Lee">
  9. <meta name="description" content="Parallelism 설정 한 손에 셀 수 있을 정도의 서버규모라면 사실 특별하게 병렬처리를 하느니 하는 것은 별로 고려하지 않아도 되겠습니다만, 그 이상일 경우에는 한 작업을 수행함에 있어서 수십대의 서버에 순차적으로 접속하고 작업하고하는 것을 지켜보는 것은 상당히 &hellip;">
  10. <!-- http://t.co/dKP3o1e -->
  11. <meta name="HandheldFriendly" content="True">
  12. <meta name="MobileOptimized" content="320">
  13. <meta name="viewport" content="width=device-width, initial-scale=1">
  14. <link rel="canonical" href="http://jeen.github.io/2013/04/28/more-rex">
  15. <link href="/favicon.png" rel="icon">
  16. <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  17. <link href="/atom.xml" rel="alternate" title="Jeen - Yet anothere techlog" type="application/atom+xml">
  18. <script src="/javascripts/modernizr-2.0.js"></script>
  19. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  20. <script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/lib/jquery.min.js"%3E%3C/script%3E'))</script>
  21. <script src="/javascripts/octopress.js" type="text/javascript"></script>
  22. <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
  23. <link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
  24. <link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
  25. <script type="text/javascript">
  26. var _gaq = _gaq || [];
  27. _gaq.push(['_setAccount', 'UA-27958809-1']);
  28. _gaq.push(['_trackPageview']);
  29. (function() {
  30. var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  31. ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  32. var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  33. })();
  34. </script>
  35. </head>
  36. <body >
  37. <header role="banner"><hgroup>
  38. <h1><a href="/">Jeen - Yet anothere techlog</a></h1>
  39. <h2>STFUAWSC</h2>
  40. </hgroup>
  41. </header>
  42. <nav role="navigation"><ul class="subscription" data-subscription="rss">
  43. <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
  44. </ul>
  45. <form action="http://google.com/search" method="get">
  46. <fieldset role="search">
  47. <input type="hidden" name="q" value="site:jeen.github.io" />
  48. <input class="search" type="text" name="q" results="0" placeholder="Search"/>
  49. </fieldset>
  50. </form>
  51. <ul class="main-navigation">
  52. <li><a href="/">Blog</a></li>
  53. <li><a href="/blog/archives">Archives</a></li>
  54. </ul>
  55. </nav>
  56. <div id="main">
  57. <div id="content">
  58. <div>
  59. <article class="hentry" role="article">
  60. <header>
  61. <h1 class="entry-title">Rex Common Practice</h1>
  62. <p class="meta">
  63. <time datetime="2013-04-28T18:32:00+09:00" pubdate data-updated="true">Apr 28<span>th</span>, 2013</time>
  64. </p>
  65. </header>
  66. <div class="entry-content"><h3>Parallelism 설정</h3>
  67. <p> 손에 있을 정도의 서버규모라면 사실 특별하게 병렬처리를 하느니 하는 것은 별로 고려하지 않아도 되겠습니다만, 이상일 경우에는 작업을 수행함에 있어서 수십대의 서버에 순차적으로 접속하고 작업하고하는 것을 지켜보는 것은 상당히 고역이죠.
  68. 이럴 경우에는 <code>parallelism</code> 지정합니다.</p>
  69. <p> 방법은 <code>Rexfile</code> 다음과 같이 설정합니다.</p>
  70. <figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
  71. </pre></td><td class='code'><pre><code class=''><span class='line'>parallelism =&gt; 10;</span></code></pre></td></tr></table></div></figure>
  72. <p> 이렇게 하면 한번에 10대의 서버에 대해서 병렬로 작업을 수행하게 됩니다. 어차피 작업은 원격지서버에서 하는 것이고, 로컬에서는 SSH 커넥션이 1개로 붙던 것들이 10개로 늘어나며, 물론 시간 또한 parallelism 설정갯수에 비례하게 됩니다. 하지만 로그는 이쁘게 남지는 않을 겁니다.</p>
  73. <p> 애시당초 CLI 옵션에 <code>parallelism</code> 옵션이 있었으면 좋겠는데&hellip;</p>
  74. <h3>Logging</h3>
  75. <p> 일단 작업 기록은 꾸준히 남기는 것이 좋겠다라고 생각하는 , 작업분기마다 로그를 남기도록 합니다. 하지만 매뉴얼에는 마땅히 로그에 관한 설명은 보이지 않는 같았습니다.</p>
  76. <p> Rex 에서의 기본적인 로그를 쓰는 방법은 다음과 같습니다.</p>
  77. <figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
  78. </pre></td><td class='code'><pre><code class=''><span class='line'>Rex::Logger::info("MSG"[, "TYPE"]);</span></code></pre></td></tr></table></div></figure>
  79. <p> 로그 메시지는 당연히 필수이며, TYPE 사실 안써도 됩니다만, error/warn 두가지 인수를 넣을 있습니다. 에러 상황시 확실하게 눈에 띄게 해주는 정도(노랑색, 빨강색)입니다.</p>
  80. <p> Parallelism 사용시에 병렬로 작업을 수행함으로 인해서 로그가 뒤죽박죽이 되기 마련인데, 이때 로그에 명기해주었으면 하는 것은 역시 서버의 호스트/IP입니다.</p>
  81. <ul>
  82. <li><a href="https://metacpan.org/module/Rex::Logger">https://metacpan.org/module/Rex::Logger</a></li>
  83. </ul>
  84. <p> <code>Rex::Logger</code> 에서 다음과 같은 사용법을 통해서 해결할 있습니다.</p>
  85. <figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
  86. <span class='line-number'>2</span>
  87. </pre></td><td class='code'><pre><code class=''><span class='line'>$Rex::Logger::format = '%h - %D - %s';
  88. </span><span class='line'># srv001 - 2012-04-12 18:35:12 - Installing package vim</span></code></pre></td></tr></table></div></figure>
  89. <p> 포맷에 대한 자세한 설명은 위의 Metacpan 링크에서 확인할 있습니다.</p>
  90. <h3>CPAN 의존모듈 설치</h3>
  91. <p> 애시당초 처음에 Rex 사용하는 이유가 여러대의 서버에 CPAN 모듈을 설치해야할 필요가 있었기 때문이었습니다. 하지만 사용구조상 일일이 모든 서버에 대해서 <code>perlbrew</code> 설치한다거나, 하는 호화(?) 누릴 수는 없었습니다. <code>perlbrew</code> 꺼내는 자체가 애시당초 핀트에 어긋나버리는 얘기가 되어버리지만 &ndash;_&ndash;;</p>
  92. <p> , 방법은 간단합니다.</p>
  93. <figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
  94. </pre></td><td class='code'><pre><code class=''><span class='line'>run("curl -L http://cpanmin.us | perl - --notest --mirror ftp://cpan.mirror.cdnetworks.com/CPAN/ --mirror-only Test::More LWP::UserAgent JSON Nagios::Plugin");</span></code></pre></td></tr></table></div></figure>
  95. <p> 애시당초 Rex 접근은 <code>root</code> 이뤄지기 때문에 이와같은 설정으로 그냥 땜박질 있었지만, <code>sudo</code> 접근한다거나 하는 예외상황에서는 <code>--sudo</code> 옵션을 붙여주면 되겠습니다. 물론 <code>root</code> 접근했을 <code>--sudo</code> 옵션은 쓰면 오동작의 원인이 됩니다.</p>
  96. <p> <code>--notest</code> 물론 수많은 서버가 동일 구성이며, 처음 커맨드로 때려보고 한방에 된다고 했을 , 테스트가 불필요하다는 판단아래에서 집어넣었구요.</p>
  97. <p> 속도개선을 노려본다면 <code>--mirror</code> 옵션을 통해서 <code>CDNetworks</code> 같은 CPAN Mirror 이용해보는 것도 괜찮을 같습니다. 눈에 띄는 속도향상을 체감할 있을 겁니다.</p>
  98. <h3>결론</h3>
  99. <p> 어떤 일을 하기에 필요한 도구를 찾아서 사용하는 것이 일반적인 접근일텐데, 때로는 어떤 도구를 사용하기 위해서 일부러 일을 그쪽방향으로 맞추는 경우를 주변에서 많이 접하게 됩니다. 저는 어떻게해서 Rex 알고 사용하게 되었는지 이미 까먹었지만, 하는 일에 대한 최적의 선택이었다고 생각합니다.</p>
  100. </div>
  101. <footer>
  102. <p class="meta">
  103. <span class="byline author vcard">Posted by <span class="fn">Jeen Lee</span></span>
  104. <time datetime="2013-04-28T18:32:00+09:00" pubdate data-updated="true">Apr 28<span>th</span>, 2013</time>
  105. <span class="categories">
  106. <a class='category' href='/blog/categories/perl/'>perl</a>, <a class='category' href='/blog/categories/rex/'>rex</a>
  107. </span>
  108. </p>
  109. <div class="sharing">
  110. <a href="//twitter.com/share" class="twitter-share-button" data-url="http://jeen.github.io/2013/04/28/more-rex/" data-via="JEEN_LEE" data-counturl="http://jeen.github.io/2013/04/28/more-rex/" >Tweet</a>
  111. <div class="fb-like" data-send="true" data-width="450" data-show-faces="false"></div>
  112. </div>
  113. <p class="meta">
  114. <a class="basic-alignment left" href="/2013/04/08/data-printer-vs-data-dump-er/" title="Previous Post: Data::Printer vs Data::Dump(er)">&laquo; Data::Printer vs Data::Dump(er)</a>
  115. <a class="basic-alignment right" href="/2013/05/02/better-than-ack/" title="Next Post: Better Than Ack">Better Than Ack &raquo;</a>
  116. </p>
  117. </footer>
  118. </article>
  119. <section>
  120. <h1>Comments</h1>
  121. <div id="disqus_thread" aria-live="polite"><noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
  122. </div>
  123. </section>
  124. </div>
  125. <aside class="sidebar">
  126. <section>
  127. <h1>Recent Posts</h1>
  128. <ul id="recent_posts">
  129. <li class="post">
  130. <a href="/2013/07/18/patching-channel-length-of-unreal-irc/">Patching Channel Length of Unreal IRC</a>
  131. </li>
  132. <li class="post">
  133. <a href="/2013/07/17/solr-vs-elasticsearch-part-6-user-and-dev-communities-compared/">[번역] Solr vs. ElasticSearch: Part 6 User &amp; Dev Communities Compared</a>
  134. </li>
  135. <li class="post">
  136. <a href="/2013/07/17/solr-vs-elasticsearch-part-5-management-api-capabilities/">[번역] Solr vs ElasticSearch: Part 5 Management API Capabilities</a>
  137. </li>
  138. <li class="post">
  139. <a href="/2013/07/17/solr-vs-elasticsearch-part-4-faceting/">[번역] Solr vs ElasticSearch Part 4 - Faceting</a>
  140. </li>
  141. <li class="post">
  142. <a href="/2013/07/16/solr-vs-elasticsearch-part-3-searching/">[번역] Solr vs. ElasticSearch - Part 3 : Searching</a>
  143. </li>
  144. </ul>
  145. </section>
  146. <section>
  147. <h1>GitHub Repos</h1>
  148. <ul id="gh_repos">
  149. <li class="loading">Status updating...</li>
  150. </ul>
  151. <a href="https://github.com/jeen">@jeen</a> on GitHub
  152. <script type="text/javascript">
  153. $(document).ready(function(){
  154. if (!window.jXHR){
  155. var jxhr = document.createElement('script');
  156. jxhr.type = 'text/javascript';
  157. jxhr.src = '/javascripts/libs/jXHR.js';
  158. var s = document.getElementsByTagName('script')[0];
  159. s.parentNode.insertBefore(jxhr, s);
  160. }
  161. github.showRepos({
  162. user: 'jeen',
  163. count: 0,
  164. skip_forks: true,
  165. target: '#gh_repos'
  166. });
  167. });
  168. </script>
  169. <script src="/javascripts/github.js" type="text/javascript"> </script>
  170. </section>
  171. </aside>
  172. </div>
  173. </div>
  174. <footer role="contentinfo"><p>
  175. Copyright &copy; 2013 - Jeen Lee -
  176. <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
  177. </p>
  178. </footer>
  179. <script type="text/javascript">
  180. var disqus_shortname = 'jeen';
  181. // var disqus_developer = 1;
  182. var disqus_identifier = 'http://jeen.github.io/2013/04/28/more-rex/';
  183. var disqus_url = 'http://jeen.github.io/2013/04/28/more-rex/';
  184. var disqus_script = 'embed.js';
  185. (function () {
  186. var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
  187. dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
  188. (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  189. }());
  190. </script>
  191. <div id="fb-root"></div>
  192. <script>(function(d, s, id) {
  193. var js, fjs = d.getElementsByTagName(s)[0];
  194. if (d.getElementById(id)) {return;}
  195. js = d.createElement(s); js.id = id; js.async = true;
  196. js.src = "//connect.facebook.net/en_US/all.js#appId=212934732101925&xfbml=1";
  197. fjs.parentNode.insertBefore(js, fjs);
  198. }(document, 'script', 'facebook-jssdk'));</script>
  199. <script type="text/javascript">
  200. (function(){
  201. var twitterWidgets = document.createElement('script');
  202. twitterWidgets.type = 'text/javascript';
  203. twitterWidgets.async = true;
  204. twitterWidgets.src = '//platform.twitter.com/widgets.js';
  205. document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
  206. })();
  207. </script>
  208. </body>
  209. </html>