Nick Sieger: Tag railsconf http://blog.nicksieger.com/articles/tag/railsconf?tag=railsconf en-us 40 Gig: Speaking at RailsConf Europe 2007 <p>Speaking of keeping busy, <a href="http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14961">I&#8217;ll be speaking</a> alongside my colleague <a href="http://blogs.sun.com/craigmcc/" title="Craig McClanahan's Weblog">Craig McClanahan</a> at <a href="http://www.railsconfeurope.com/" title="RailsConf Europe 2007 &#8226; September 17, 2007 - September 19, 2007 &#8226; Berlin, Germany">RailsConf Europe </a> in Berlin next week&#46;</p> <p>Sun is a Diamond Sponsor at RailsConf again, just like in Portland last May&#46; Part of that sponsorship money pays for a brief keynote spot (filled by Craig) as well as a session or two&#46; So no, I didn&#8217;t get my spot through an accepted proposal submission, but that doesn&#8217;t mean that the session is going to be a big <a href="http://headius.blogspot.com/2007/09/infoworld-bossies-close-to-my-heart.html">marketing shill</a>&#46;</p> <p>No, actually Craig and I are part of a small group at Sun that&#8217;s embracing Rails in a big way, and we&#8217;re going to be launching a site built mostly on Rails later this fall&#46; We&#8217;re taking what we think are some novel approaches to building a Rails&#45;based application and we thought we&#8217;d share some of those thoughts with you rather than drone on for the session about how great Sun is and what snazzy tools we make&#46; (Although expect to see a subtle plug or two for Sun hardware and tools&#46; Call it product placement rather than overt selling&#46;)</p> <p>I titled the session &#8220;Rails Hydra&#8221; because the central idea of the structure of our application is not one Rails app, but many&#46; The UI and views don&#8217;t even talk to a database; instead they make use of ActiveResource and RESTful web services, talking to the models living in other Rails applications in the backend&#46; One key point is we&#8217;re deploying &#46;war files to JRuby running on Glassfish, thus avoiding headaches of morbidly multiplying Mongrel math&#46; We&#8217;ll elaborate on this arrangement and talk about some of the other tools and tricks we&#8217;re using&#46;</p> <p>Also, Charlie, Tom and Ola will be there, so we&#8217;ll certainly have a JRuby summit at some point&#46; Stop by and say hello!</p> Fri, 14 Sep 2007 05:33:00 +0000 urn:uuid:be1363d9-dfe0-443e-8248-93aa31622820 Nick Sieger http://blog.nicksieger.com/articles/2007/09/14/gig-speaking-at-railsconf-europe-2007 java rails railsconf gig http://blog.nicksieger.com/articles/trackback/288 JRuby Q &amp; A at RailsConf <p>These are the notes I took during our &#8220;panelish&#8221; Q &amp; A session on Sunday afternoon at RailsConf&#46;</p> <ul> <li><p>Exceptions (behavior between ruby and java)</p> <ul> <li>Embedding: JSR&#45;223 preferred, BSF fallback</li> </ul></li> <li><p>Java integration, mocking, proxying, extension</p></li> <li><p>Multiple VM support</p> <ul> <li>multiple JRuby instances can be run in the same VM</li> <li>JavaSand (google it) &#45;&#45; Ola&#8217;s port of _why&#8217;s (freaky freaky) sandbox</li> </ul></li> <li><p>Startup time performance gain recently</p> <ul> <li>&#45;Xbootclasspath: VM does not verify classes in the &#8220;boot&#8221; classpath</li> <li>&#45;Xverify:none is not recommended because of runtime&#45;generated code</li> <li>Nailgun to keep VM running and &#8220;send commands&#8221; to it</li> </ul></li> <li><p>Compiling Ruby code to JVM bytecode</p> <ul> <li>Keep # of class files low</li> <li>Walk AST and dump out high&#45;level, abstracted operations (local variable access, dynamic invocation) and low&#45;level bytecode is built for each of those</li> <li>4096 &#45;&#45; maximum # of methods to be compiled</li> <li>Compiled methods are shared between runtimes</li> <li>Future:</li> <li>raise/eliminate overhead of compiled methods</li> <li>share AST, reduce memory load</li> </ul></li> <li><p>Community tasks/actions</p> <ul> <li>Projects needing help (e&#46;g&#46;, ActiveHibernate)</li> <li>Adoption, acceptance, blogging</li> <li>Documentation (http://wiki&#46;jruby&#46;org/ and others), screencasts</li> <li>Who&#8217;s using it?</li> </ul></li> <li><p>Sun&#8217;s commitment</p> <ul> <li>Ruby vs&#46; Groovy vs&#46; Python vs&#46; Scala vs&#46; other langs</li> <li>Rails vs&#46; Grails vs&#46; Lift vs&#46; JSF vs&#46; Struts 2 vs&#46; ???</li> <li>all of the above</li> <li>improve the JVM&#8217;s support for all dynamic languages</li> <li>JRuby is a full open source project, not owned or controlled by Sun, with history that extends years before main devs hired by Sun</li> </ul></li> <li><p>Ruby programming language, JRuby is an implementation</p> <ul> <li>community evangelism of Ruby the language vs&#46; implementations</li> <li>despite MVM, FFI and emerging areas that are not standard yet</li> </ul></li> <li><p>How do you pitch JRuby/Rails in a legacy environment?</p> <ul> <li>Consider demonstrating running application without discussing technology specifics</li> <li>IBM and JDK 1&#46;5 issues have been reported</li> <li>Free support as long as these issues are new and help improve JRuby and the community!</li> </ul></li> <li><p>Testing</p> <ul> <li>JRuby enables more agile testing</li> <li>Without production risks</li> <li>Ceremony vs&#46; Essence discussion</li> </ul></li> <li><p>Terracotta/DSO</p> <ul> <li><a href="http://jonasboner.com/2007/02/05/clustering-jruby-with-open-terracotta/" title="Jonas Bon&#233;r &raquo; Blog Archive &raquo; Clustering JRuby with Open Terracotta">Jonas Boner blogged about it over a year ago</a> </li> </ul></li> <li><p>Windows/Mongrel/ImageMagick issues</p> <ul> <li><a href="http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released" title="ImageVoodoo 0.1 Released">ImageVoodoo</a> is an imaging library using Java2D, comes with Java</li> <li>MiniMagick also reportedly works</li> </ul></li> <li><p>Rails benchmarks</p> <ul> <li>Micro&#45;benchmarks are problematic and usually don&#8217;t lead to measurable application speedups</li> <li>Community needs a real&#45;world, full application</li> <li>Antonio Cangiano working on new application&#45;level benchmarks?</li> <li>&#8220;Richards&#8221; &#45;&#45; Smalltalk&#45;originated application benchmark</li> </ul></li> <li><p>JSR&#45;292 (&#8220;invokedynamic&#8221;)</p> <ul> <li>Actually extension of &#8220;invokeinterface&#8221; bytecode</li> <li>Call site structure/method handles</li> <li>Expose the dynamic nature of the JVM (get the Java&#45;specific stuff out of the way)</li> <li>Language&#45;specific calling semantics, method invocation</li> <li>&#8220;Punching a hole&#8221; through the JVM</li> <li>Comments on <a href="http://blogs.sun.com/jrose/entry/dynamic_invocation_in_the_vm" title="dynamic invocation in the VM : John Rose @ Sun">JSR&#45;292 Early Draft Review</a> currently ongoing</li> </ul></li> </ul> Sun, 01 Jun 2008 22:07:33 +0000 urn:uuid:b09ae6ba-f3b3-4624-a962-227b9646560e Nick Sieger http://blog.nicksieger.com/articles/2008/06/01/jruby-q-a-at-railsconf jruby railsconf railsconf2008 http://blog.nicksieger.com/articles/trackback/420 RailsConf: Stefan Kaes - Rails Performance <p>Stefan starts by citing a factor of 4&#45;5 improvement in performance in Rails over the last year&#46;</p> <h2>Performance, broken down</h2> <ul> <li>Latency &#45;&#45; how fast</li> <li>Throughput &#45;&#45; how many</li> <li>Utilization &#45;&#45; how idle is the cpu</li> <li>Cost efficiency &#45;&#45; performance per unit cost</li> </ul> <p>For completeness calculate the min, max, mean and standard deviation of these metrics and use the deviation as your guide for how reliable the data is&#46;</p> <h2>Tools</h2> <ul> <li>Log files (level > <code>Logger::DEBUG</code>)</li> <li><a href="http://rails-analyzer.rubyforge.org/">Rails Analyzer Tools</a> (Eric Hodel)</li> <li>Benchmarker (<code>script/benchmarker</code>)</li> <li>DB vendor tools</li> <li>Apache bench (<code>ab</code> or <code>ab2</code>)</li> <li>httperf</li> <li><a href="http://rubyforge.org/projects/railsbench">railsbench</a> (Stefan Kaes)</li> </ul> <h2>Railsbench</h2> <p>Railsbench measuress raw performance of rails request processing&#46; It&#8217;s configured using <code>config/benchmarks.yml</code> and <code>config/benchmarks.rb</code>&#46; These files let you control which requests get benchmarked, whether to create a new session when benchmarking them, etc&#46;</p> <h2>Profiling Tools</h2> <ul> <li>Ruby Profiler</li> <li>Zen Profiler</li> <li>rubyprof</li> <li>Rails profiler script</li> <li><a href="http://www.softwareverify.com/rubyPerformanceValidator/index.html">Ruby Performance Validator</a></li> </ul> <p>At this point Stefan gave an overview of RPV, which appears to be a nifty tool that lets you get typical hotspot tree views of where time is spent in code&#46; It currently only runs on Windows&#46;</p> <h2>Top Rails Performance Problems</h2> <ul> <li>slow helper methods</li> <li>complicated routes</li> <li>associations &#45;&#45; navigating and eager loading vs&#46; proxy loading</li> <li>retrieving too much data from the DB</li> <li>slow session storage (e&#46;g&#46;, ActiveRecord store)</li> </ul> <p>Stefan says that in his experience, DB performance is generally not a big factor or bottleneck&#46; Instantiating ActiveRecord objects is expensive, though&#46;</p> <h2>Session containers</h2> <ul> <li>In memory &#45;&#45; if you server crashes&#46;&#46;&#46;oops&#46; Also doesn&#8217;t scale&#46;</li> <li>File system &#45;&#45; easy to set up, scales with NFS, but slower than&#46;&#46;&#46;</li> <li>ActiveRecordStore &#45;&#45; easy to set up since it comes with Rails, but much slower than&#46;&#46;&#46;</li> <li>SQLSessionStore &#45;&#45; which uses the same table structure as ActiveRecordStore, but was written by Stefan to overcome performance issues with ActiveRecordStore&#46; Setup is more involved&#46;</li> <li>memcached &#45;&#45; slightly faster than SQLSessionStore, scales best, but setup is also more involved&#46;</li> <li>DrbStore &#45;&#45; distributed ruby store</li> </ul> <h2>Caching</h2> <ul> <li>Full pages &#45;&#45; fastest, complete pages are served on the filesystem&#46; Web server bypasses appserver for rendering&#46; If you have private pages, you can&#8217;t use it&#46;</li> <li>Actions &#45;&#45; pages are cached after an action is rendered&#46; The user ID can be used as part of the storage key&#46;</li> <li>Fragments &#45;&#45; fragments can be cached in memory, on the file system, in a DrbStore, or in memcached&#46; Memcached scales the best but doesn&#8217;t support expiring fragments by regular expression&#46;</li> </ul> <h2>ActionController</h2> <ul> <li>Stefan recommends avoiding components, and replacing them with helpers or partials&#46; He has not found a use for them&#46;</li> </ul> <h2>ActionView</h2> <ul> <li>Don&#8217;t create unnecessary instance variables in the controller; creating them in the view with <code>instance_variable_set</code> and accessing with <code>instance_variable_get</code> is slow&#46;</li> </ul> <h2>Helpers</h2> <ul> <li>pluralize &#45;&#45; don&#8217;t use the inflector if you don&#8217;t need to, it&#8217;s expensive&#46;</li> <li>link<em>to and url</em>for are among the slowest helpers, since they need to use routes&#46; Instead, if you have page with lots of links, you might consider hard&#45;coding the links&#46; This reduces the amount of GC by up to 50% and the GC time down by a few percentage points (11&#46;3% to 8&#46;7% of total processing time)&#46;</li> </ul> <h2>ActiveRecord</h2> <ul> <li>use the <code>:include</code> option to prefetch associations, it avoids extra onesy&#45;twosy SQL statements&#46;</li> <li>use piggy&#45;backing plugin for <code>has_one</code> or <code>belongs_to</code> relationships &#45;&#45; allows you to retrieve extra attributes from additional tables in the same fetch query&#46;</li> <li>Field values are retrieved from the DB mostly as strings, so type conversion happens on each access, which can be slow&#46;</li> </ul> <h2>Language&#45;level and miscellaneous issues</h2> <ul> <li>Method calls are the slowest &#45;&#45; don&#8217;t needlessly create method abstractions</li> <li>Short&#45;circuit intermediate results to improve performance</li> <li>Cache results in instance variables or class variables</li> <li>Don&#8217;t call <code>ObjectSpace.each_object</code> on each request</li> </ul> <h2>Ruby Memory Management</h2> <ul> <li>designed for batch scripts, not long&#45;running servers&#46;</li> <li>no generational garbage collection&#46;</li> <li>this is suboptimal for Rails because ASTs are stored on the heap (biggest portion of non&#45;garbage for Rails apps), and get processed/traversed more often than they need to be</li> <li><a href="http://rubyforge.org/projects/railsbench">Railsbench</a> includes a patch to allow one to recompile Ruby and tweak the garbage collector&#46;</li> </ul> <h2>Rails Template Optimizer</h2> <ul> <li>Stefan has started a project to &#8220;compile&#8221; templates&#46;</li> <li>The idea is to cache results of some ERb scriptlets and essentially &#8220;compile&#8221; or replace the template with one that has more expressions expanded or inlined&#46;</li> <li>Code forthcoming; I assume you can stay tuned to <a href="http://railsexpress.de/blog/">Rails Express</a> for news&#46;</li> </ul> <h2>Questions</h2> <ul> <li>There was a question on JRuby &#45;&#45; Stefan replied that it would certainly solve GC issues, but he doesn&#8217;t know if it&#8217;s in a state to be able to benchmark Rails requests&#46;</li> <li>What are your recommendations for a web server&#46; <em>I don&#8217;t have any&#46;</em></li> <li>Is horizontal or vertical scaling better? <em>I don&#8217;t know, I&#8217;ve been focused on making single requests go fast, so I don&#8217;t have enough experience&#46;</em></li> </ul> Fri, 23 Jun 2006 20:40:00 +0000 urn:uuid:032b3183-e579-4896-a439-2f62ee8279e6 Nick Sieger http://blog.nicksieger.com/articles/2006/06/23/railsconf-stefan-kaes-performance ruby rails railsconf http://blog.nicksieger.com/articles/trackback/24 Spring and Summer Gigs <p>Just a quick note on some upcoming gigs&#46; I&#8217;ll be speaking next month at both <a href="https://www28.cplan.com/cc191/session_details.jsp?isid=296490&amp;ilocation_id=191-1&amp;ilanguage=english">JavaOne</a> and <a href="http://en.oreilly.com/rails2008/" title="RailsConf 2008 - O'Reilly Conferences, May 29 - June 01, 2008,Portland, Oregon">RailsConf</a>, giving an update on the JRuby deployment situation, which by the way is rapidly improving! Despite my proposal for a hands&#45;on tutorial on JRuby deployment not getting accepted for RailsConf, I&#8217;ve been asked to fill one of the Sun&#45;sponsored talk slots again&#46; So, much like <a href="/articles/2007/10/06/railsconf-europe-hydra">RailsConf EU last fall</a>, if you come listen I promise you will not get a heavy sales pitch from me! Do stop by, I may even have a couple goodies in store for you&#46;</p> <p>I also feel privileged to be speaking at <a href="http://rubyfringe.com/speakers#nick_sieger">RubyFringe</a> this summer, where I haven&#8217;t yet determined exactly what I&#8217;ll be talking about (although it will probably have some connection to JRuby)&#46;</p> <p>Hope to see you at one of these upcoming events!</p> <p><em>Update:</em> We just re&#45;jiggered the schedule of 3 JRuby&#45;related talks at JavaOne, including mine, so that they flow better from beginning to end of the week&#46; My talk is now on Thursday morning instead of Wednesday morning&#46; In addition, <a href="https://www28.cplan.com/cc191/session_details.jsp?isid=295416&amp;ilocation_id=191-1&amp;ilanguage=english">Charlie and Tom&#8217;s</a> is on Tuesday, and <a href="https://www28.cplan.com/cc191/session_details.jsp?isid=294806&amp;ilocation_id=191-1&amp;ilanguage=english">Ola&#8217;s</a> is on Wednesday&#46; If you&#8217;re attending JavaOne and are interested in JRuby&#45;related talks, please make sure you log into Schedule Builder and re&#45;check your schedule&#46;</p> Fri, 18 Apr 2008 17:25:16 +0000 urn:uuid:13f5e270-43ae-4f56-b7c4-27fb1c688419 Nick Sieger http://blog.nicksieger.com/articles/2008/04/18/spring-and-summer-gigs gig railsconf javaone rubyfringe http://blog.nicksieger.com/articles/trackback/395 RailsConf 2007 Opening Keynote: David Heinemeier Hansson <h1>Rails 2&#46;0</h1> <h2>Where we&#8217;ve been</h2> <p>David is surprised and proud of the community that we already have, and wants us to be comfortable with where we are, and not always looking toward the future&#46; We have:</p> <ul> <li>Million gem downloads</li> <li>Hundreds of plugins</li> <li>10k users on the rubyonrails&#45;talk mailing list</li> <li>Ruby job descriptions (asking for 3 years RoR experience, longer than David)</li> <li><a href="http://www.amazon.com/s/002-0555878-2213644?ie=UTF8&amp;tag=mozilla-20&amp;index=blended&amp;link%5Fcode=qs&amp;field-keywords=ruby%20on%20rails&amp;sourceid=Mozilla-search">Books, books, books</a> (and not just English books, but non&#45;English titles as well), surpassing VBA, Perl, and Python in book sales</li> <li>IDEs from NetBeans, Borland, Aptana, etc&#46;</li> </ul> <p>Rails 2&#46;0 is not going to be the &#8220;Unicorn&#8221;&#46; It&#8217;s not going to be a total rewrite, it actually has a release schedule, it will not break backwards&#45;compatibility&#46; Instead, it will build upon what we already have, and continue the philosophy of building on what is useful and needed&#46; In fact, 95% of what&#8217;s in 2&#46;0 already works today, in the edge&#46; Example, a simple controller that handles three formats of input/output, with a person resource for accessing the data from a remote server&#46;</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">PeopleController</span> <span class="punct">&lt;</span> <span class="constant">ApplicationController</span> <span class="punct">...</span> <span class="keyword">def </span><span class="method">create</span> <span class="attribute">@person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(...)</span> <span class="ident">respond_to</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">format</span><span class="punct">|</span> <span class="ident">format</span><span class="punct">.</span><span class="ident">html</span> <span class="punct">{</span> <span class="ident">redirect_to</span> <span class="ident">person_url</span><span class="punct">(</span><span class="attribute">@person</span><span class="punct">)</span> <span class="punct">}</span> <span class="ident">format</span><span class="punct">.</span><span class="ident">xml</span> <span class="punct">{</span> <span class="ident">render</span> <span class="symbol">:status</span> <span class="punct">=&gt;</span> <span class="symbol">:created</span><span class="punct">,</span> <span class="symbol">:location</span> <span class="punct">=&gt;</span> <span class="ident">person_url</span><span class="punct">(</span><span class="attribute">@person</span><span class="punct">),</span> <span class="punct">...</span> <span class="punct">}</span> <span class="ident">format</span><span class="punct">.</span><span class="ident">js</span> <span class="punct">{</span> <span class="ident">render</span> <span class="symbol">:update</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">js</span><span class="punct">|</span> <span class="punct">...</span> <span class="keyword">end</span> <span class="punct">}</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="keyword">class </span><span class="class">Person</span> <span class="punct">&lt;</span> <span class="constant">ActiveResource</span><span class="punct">::</span><span class="constant">Base</span> <span class="constant">self</span><span class="punct">.</span><span class="ident">site</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://example.com/</span><span class="punct">&quot;</span> <span class="keyword">end</span></code></pre></div> <p>David then goes into a live demo of the new scaffold resource, which by appearance is identical to the old scaffolding, except it comes pre&#45;baked with a REST&#45;ful XML interface&#46; He then adds support for a text format with a couple of lines of code, jumps into IRB, defines an active resource, and proceeds to change the data remotely&#46;</p> <p>If you want to add search to your controller, you can do it in a DRY way, and all the format/view work you&#8217;ve done will benefit:</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">PeopleController</span> <span class="punct">&lt;</span> <span class="constant">ApplicationController</span> <span class="keyword">def </span><span class="method">index</span> <span class="keyword">if</span> <span class="ident">params</span><span class="punct">[</span><span class="symbol">:name</span><span class="punct">]</span> <span class="attribute">@people</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">find</span> <span class="symbol">:all</span><span class="punct">,</span> <span class="symbol">:conditions</span> <span class="punct">=&gt;</span> <span class="punct">[&quot;</span><span class="string">name like ?</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string"><span class="expr">#{params[:name]}</span>%</span><span class="punct">&quot;]</span> <span class="keyword">else</span> <span class="attribute">@people</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">find</span> <span class="symbol">:all</span> <span class="keyword">end</span> <span class="punct">...</span> <span class="keyword">end</span> <span class="keyword">end</span></code></pre></div> <p>David points out that 37signals, Shopify, Fluxiom, et&#46; al&#46; are real sites, with non&#45;trivial domains that are still well executed in Rails, so it&#8217;s not just about simple scaffolding demos&#46;</p> <p>In Rails 2&#46;0, ActiveResource will be bundled with Rails, and ActionWebService will not&#46;</p> <h2>Friends of Rails</h2> <ul> <li>AJAX!</li> <li>REST!</li> <li>Atom? &#45;&#45; Atom should be more native to Rails</li> <li>Openid? &#45;&#45; Openid is not necessarily something that needs to be used by all, but still a strong ally&#46;</li> </ul> <h2>9 other things I like about Rails 2</h2> <ul> <li>Breakpoints are back &#45;&#45; no longer depends on <code>Binding.of_caller</code>; instead Rails depends and builds upon <a href="http://rubyforge.org/projects/ruby-debug/"><code>ruby-debug</code></a> by Kent Sibilev&#46;</li> <li>HTTP Performance &#45;&#45; streamlining &#46;js and &#46;css, even though it feels better to break up Javascript and CSS into many little pieces, and gzip them</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="punct">&lt;%=</span><span class="string"> javascript_include_tag :all, :cache </span><span class="punct">=&gt;</span> <span class="constant">true</span> <span class="punct">%&gt;</span><span class="string"> &lt;%= stylesheet_link_tag :all, :cache =</span><span class="punct">&gt;</span> <span class="constant">true</span> <span class="punct">%&gt;</span><span class="string"></span></code></pre></div> <p>We can also fake out the browser and configure multiple asset hosts (4) you can maximize browser connections</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">config</span><span class="punct">.</span><span class="ident">action_controller</span><span class="punct">.</span><span class="ident">asset_host</span> <span class="punct">=</span> <span class="punct">'</span><span class="string">assets%d.highrisehq.com</span><span class="punct">'</span></code></pre></div> <ul> <li>Query cache</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span><span class="punct">.</span><span class="ident">cache</span> <span class="keyword">do</span> <span class="comment"># actions here are cached</span> <span class="keyword">end</span></code></pre></div> <ul> <li>Rendering and MIME types &#45;&#45; bake the MIME convention into the template, and separate from the rendering mechanism people/index&#46;html&#46;erb people/index&#46;xml&#46;builder people/index&#46;rss&#46;erb people/index&#46;atom&#46;builder</li> <li>config/initializers replacing config/environment&#46; Initializers are &#46;rb files in the config/initializers directory of your app that are automatically loaded during initialization time&#46;</li> <li>Sexy migrations</li> </ul> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">create_table</span> <span class="symbol">:people</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span> <span class="ident">t</span><span class="punct">.</span><span class="ident">integer</span> <span class="symbol">:account_id</span> <span class="ident">t</span><span class="punct">.</span><span class="ident">string</span> <span class="symbol">:first_name</span><span class="punct">,</span> <span class="symbol">:last_name</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=&gt;</span> <span class="constant">false</span> <span class="ident">t</span><span class="punct">.</span><span class="ident">text</span> <span class="symbol">:description</span> <span class="ident">t</span><span class="punct">.</span><span class="ident">timestamps</span> <span class="keyword">end</span></code></pre></div> <ul> <li>HTTP authentication (<code>authenticate_or_request_with_http_basic</code>, <code>authenticate_with_http_basic</code>)</li> <li>The MIT assumption &#45;&#45; the licensing question &#45;&#45; make it easier to understand</li> <li>Spring cleaning &#45;&#45; getting rid of the cruft &#45;&#45; stay tuned!</li> </ul> Fri, 18 May 2007 17:10:39 +0000 urn:uuid:35f07fbf-9a1b-4848-9e0a-848ba7029697 Nick Sieger http://blog.nicksieger.com/articles/2007/05/18/railsconf-2007-opening-keynote-david-heinemeier-hansson railsconf railsconf2007 http://blog.nicksieger.com/articles/trackback/241 RailsConf Europe: Hydra <p><img src="/files/hydra.png" alt="Hydra" title="Hydra"/></p> <p>On September 19, Craig and I presented our <a href="http://blog.nicksieger.com/articles/2007/09/14/gig-speaking-at-railsconf-europe-2007">talk at RailsConf</a>, which appears to have been <a href="http://loudthinking.com/posts/11-sun-surprises-at-railsconf-europe-2007">well received</a>&#46; It went off mostly without a hitch, if it wasn&#8217;t for a couple of hiccups in the demos&#46; I apparently didn&#8217;t practice them enough, because a couple of critical steps were either missed or I did them out of order and confused myself&#46; But that&#8217;s ok, because I&#8217;m releasing the demo steps, source and slides here so you can try them out for yourself&#46;</p> <p>So, <a href="http://blog.nicksieger.com/files/RailsConfEurope-Hydra.zip">download the zip</a> and follow along&#46; The contents look like this:</p> <pre><code>1-active-resource-basics.txt 2-make-resourceful.txt 3-atom-roller.txt 4-service-chatter.txt RailsConfEurope-Hydra.pdf demo/ demo-baked/ </code></pre> <p>The demo steps are in the text files; I&#8217;d recommend going in the order specified&#46; It turns out the third isn&#8217;t really a demo but more of a code review, because it also requires you to have Roller set up and I&#8217;m not going into those details for now&#46; If you want to just run the demos, skip to <code>demo-baked</code>, the finished product&#46;</p> <p>For those of you who didn&#8217;t see the talk, here&#8217;s the basic message&#46;</p> <p>Look at your basic MVC Rails app&#46;</p> <p><img src="/files/single.png" alt="Single app" title="Single app"/></p> <p>Why not consider spliting it into two? ActiveResource allows you to access a RESTful resource in your Rails application like it was just another model&#46;</p> <p><img src="/files/double.png" alt="Double app" title="Double app"/></p> <p>This might seem like overkill for a simple application, but what if you had an e&#45;commerce application domain like this?</p> <p><img src="/files/ecomm.png" alt="E-Commerce app" title="E-Commerce app"/></p> <p>Splitting up your code into separate Rails applications encourages encapsulation, reduces potential coupling, and gives you more flexible deployment options&#46; Basing interactions upon REST and HTTP means that you can more easily mash up data or create caching strategies, given proper usage of ETags/Last&#45;Modified and/or cache&#45;control headers&#46; The great thing is that existing HTTP reverse proxies can be used without having to mix the caching code in with your application code&#46;</p> <p>In the application we&#8217;re building, we have a number components that are not Rails&#45;based&#46; To expose them to our environment, we&#8217;ve taken the strategy of exposing a simple REST web service for the component, and then it can be consumed by the other applications using ActiveResource&#46; The REST web service can either be implemented in the component&#8217;s native language/technology, or in some cases we&#8217;ve written a wrapper service in Rails since Rails makes it so easy to build REST interfaces&#46; In that case, Rails is pure integration &#45;&#45; RESTful glue&#46;</p> <p>The idiom that makes this all possible is the uniform interface&#46; In HTTP, this means addressability (each resource gets a unique URI) coupled with the HTTP method verbs HEAD, GET, POST, PUT, and DELETE&#46; Inside your Rails applications, it&#8217;s the ActiveRecord interface&#46; If you <a href="http://www.therailsway.com/2007/6/1/railsconf-recap-skinny-controllers">keep your controllers skinny</a>, you can boil the interface down to the following set of methods (in this case, for the prototypical blog post model):</p> <pre><code>Post.new/Post.create Post.find @post.save @post.update_attributes @post.errors @post.destroy </code></pre> <p>And in fact, this is precisely what ActiveResource provides, and it&#8217;s enabled by <a href="http://en.wikipedia.org/wiki/Duck_typing">duck&#45;typing</a>&#46; Walking through the demos illustrates this pretty well, as you&#8217;ll basically swap ActiveRecord for ActiveResource with no noticeable difference, all the way down to validation errors in the scaffolded forms (which I was unable to demo in the talk due to the hiccups)&#46;</p> <p>We&#8217;ve found that when you&#8217;re making RESTful web services, the controllers largely become boilerplate because of the uniform interface&#46; <a href="http://svn.hamptoncatlin.com/make_resourceful/trunk/"><code>make_resourceful</code></a> has been a boon in that regard, as the demos also show&#46; There are several plugins that help you DRY up your controllers (other approaches include <a href="http://plugins.ardes.com/doc/resources_controller/"><code>resources_controller</code></a>), so you have some choices there&#46;</p> <p>We mentioned some drawbacks in our experience with ActiveResource, which have largely been addressed for the upcoming Rails 2&#46;0 release&#46;</p> <p>Finally, we noted that deployment could be a pain with so many Rails applications to keep running&#46; To that end, we are leveraging JRuby and Glassfish to make this a non&#45;issue, as we simply WAR up our Rails applications with <a href="http://blog.nicksieger.com/articles/2007/09/04/warbler-a-little-birdie-to-introduce-your-rails-app-to-java">warbler</a> and let Glassfish take care of the rest&#46; Performance is still an open question, but we plan to roll up our sleeves and make sure this combination really hums&#46;</p> <p>Enjoy the demos! Feel free to drop me an email if you have any questions or troubles with them&#46;</p> Sat, 06 Oct 2007 12:04:00 +0000 urn:uuid:d9edbea6-8e0e-43b6-af40-7d8bb3d69f52 Nick Sieger http://blog.nicksieger.com/articles/2007/10/06/railsconf-europe-hydra railsconf railsconfeurope2007 http://blog.nicksieger.com/articles/trackback/301 RailsConf 2007: Chris Wanstrath: Kickin' Ass with Cache-fu <p>Chris is here to talk about games, since he used to work for Gamespot&#46; He coded PHP, which is like training wheels without the bike&#46; He had to sit in a glass cube and help keep the site running during E3 last year&#46; There were 100 gajillion teenage boys during their lunch break hitting refresh, and it all blew up&#46; Couldn&#8217;t even gzip the responses, because the servers heated up to much&#46; They served 50M pages in a day, without downtime&#46; They did it with Memcache&#46;</p> <p>Memcache is a distributed hash &#45;&#45; multiple daemons running on different servers&#46; Developed by Livejournal for their infrastructure, you just put up the servers, and they just work&#46;</p> <p>Should you use Memcache? No&#46; <a href="http://c2.com/xp/YouArentGonnaNeedIt.html">YAGNI</a>, UYRDNI (unless you really do need it)&#46;</p> <h2>Rails and Memcache</h2> <p>Fragments, Actions, Sessions, Objects, cache it all&#46; You can use:</p> <ul> <li><code>memcache-client</code> (by Robot&#45;coop guys/Eric Hodel)&#46; Marshal&#46;unload is 40 times faster than Object&#46;new/loading from the database&#46;</li> <li>CachedModel &#45;&#45; integration with ActiveRecord</li> <li>Fragment Cache Store</li> <li>Memcache session store</li> </ul> <p>&#46;&#46;&#46;or&#46;&#46;&#46;</p> <h2><code>cache_fu</code></h2> <p>Or, <code>acts_as_cached</code>&#46; It knows about all the aforementioned objects, with a single YAML config file (<code>config/memcached.yml</code>)&#46; Word to the wise: don&#8217;t use names in your server config file&#46; Use IPs, avoid BIND and connections to the servers with every connection&#46; Don&#8217;t let DNS outages bring down your servers&#46;</p> <ul> <li><code>get_cache</code></li> <li><code>expire_cache</code></li> </ul> <p>This is all you need &#45;&#45; if you&#8217;re using <code>set_cache</code>, you probably don&#8217;t understand how the plugin works&#46; Expire cache on the &#8220;after save&#8221; hook, which allows you to cache ID misses as well&#46;</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">acts_as_cached</span> <span class="ident">after_save</span> <span class="symbol">:expire_cache</span> <span class="keyword">end</span></code></pre></div> <p>Example: only cache published items</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">acts_as_cached</span> <span class="symbol">:conditions</span> <span class="punct">=&gt;</span> <span class="punct">'</span><span class="string">published = 1</span><span class="punct">'</span> <span class="keyword">end</span></code></pre></div> <p>Cached&#45;scoped&#45;finders (if somebody thinks of a good name, let Chris know)&#46; The idea is to move custom finder logic to a method on your model, and then wrap a cache&#45;scoping thingy around it&#46; <code>cache_fu</code> ties this up nicely by giving you a <code>cached</code> method on AR::Base&#46;</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Topic</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="keyword">def </span><span class="method">self.weekly_popular</span> <span class="constant">Topic</span><span class="punct">.</span><span class="ident">find</span> <span class="symbol">:all</span><span class="punct">,</span> <span class="punct">...</span> <span class="keyword">end</span> <span class="keyword">end</span> <span class="constant">Topic</span><span class="punct">.</span><span class="ident">cached</span><span class="punct">(</span><span class="symbol">:weekly_popular</span><span class="punct">)</span></code></pre></div> <p>Adding date to cache key with <code>alias_method_chain</code>:</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">def </span><span class="method">self.cache_key_with_date</span><span class="punct">(</span><span class="ident">id</span><span class="punct">)</span> <span class="punct">...</span> <span class="keyword">end</span> <span class="keyword">class </span><span class="punct">&lt;&lt;</span> <span class="constant">self</span> <span class="ident">alias_method_chain</span> <span class="symbol">:cache_key</span><span class="punct">,</span> <span class="symbol">:date</span> <span class="keyword">end</span></code></pre></div> <p>Cached loads by ID: <code>Topic.find(1, 2, 3)</code> moves to <code>Topic.get_cache(1, 2, 3)</code>, which can parallelize calls to memcached and bring them back as they&#8217;re ready&#46;</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="ident">user_ids</span> <span class="punct">=</span> <span class="attribute">@topic</span><span class="punct">.</span><span class="ident">posts</span><span class="punct">.</span><span class="ident">map</span><span class="punct">(&amp;</span><span class="symbol">:user_id</span><span class="punct">).</span><span class="ident">uniq</span> <span class="attribute">@users</span> <span class="punct">=</span> <span class="constant">User</span><span class="punct">.</span><span class="ident">get_cache</span><span class="punct">(</span><span class="ident">user_ids</span><span class="punct">)</span></code></pre></div> <p>You can also cache associations, so that you&#8217;re navigating associations via Memcache&#46;</p> <p>Cache overrides</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">ApplicationController</span> <span class="punct">&lt;</span> <span class="constant">ActionController</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">before_filter</span> <span class="symbol">:set_cache_override</span> <span class="keyword">def </span><span class="method">set_cache_override</span> <span class="constant">ActsAsCached</span><span class="punct">.</span><span class="ident">skip_cache_gets</span> <span class="punct">=</span> <span class="punct">!!</span><span class="ident">params</span><span class="punct">[</span><span class="symbol">:skip_cache</span><span class="punct">]</span> <span class="keyword">end</span> <span class="keyword">end</span></code></pre></div> <p><code>reset_cache</code>: Slow, uncached operations can sometimes queue up and wedge a site&#46; Instead, issue cache resets on completion of a request, rather than expiring beforehand&#46; That way, requests that continue to pile up will still use the cached copy until the rebuild is complete&#46;</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">after_save</span> <span class="symbol">:reset_cache</span> <span class="keyword">end</span></code></pre></div> <p>Versioning: a way to expire cache on new code releases</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">acts_as_cached</span> <span class="symbol">:version</span> <span class="punct">=&gt;</span> <span class="number">1</span> <span class="keyword">end</span></code></pre></div> <p>Deployment: Chris recommends using Monit to ensure your Memcache servers are up&#46;</p> <p><code>libketama</code>: consistent hashing that gives you the ability to redeploy Memcache servers without invalidating all the keys&#46;</p> <p>Q: Page caching? A: Nginx with native Memcache page caching, but outside of Rails domains&#46;</p> <p>Lots of other questions, but dude, Chris talks too fast!</p> Sat, 19 May 2007 20:34:00 +0000 urn:uuid:40171862-80d2-460f-9ad6-ead9fe29fd91 Nick Sieger http://blog.nicksieger.com/articles/2007/05/19/railsconf-2007-chris-wanstrath-kickin-ass-with-cache-fu railsconf railsconf2007 http://blog.nicksieger.com/articles/trackback/247 RailsConf 2007: Bradley Taylor: Virtual Clusters <p>How does Rails figure into virtualization? Bradley will cover this topic with examples and case studies&#46; Along the way, hardware items may be mentioned, but are not critical&#46; Really, it&#8217;s about the design of the clusters, not the bits of plumbing you use to connect them up&#46;</p> <p>Virtualization is partitioning of physical servers that allow you to run multiple servers on it&#46; Xen, Virtuozzo, VMWare, Solaris containers, KVM, etc&#46; Bradley uses Xen&#46; The virtual servers share the same processor (hopefully multi&#45;core), memory, storage, network cards (but with indepenent IP addresses), etc&#46;, but run independently of each other&#46; VPS, slice, container, accelerator, VM, it&#8217;s all the same&#46; Memory, storage, and CPU can be guaranteed with the virtualization layer&#46;</p> <p>Why would you do this? <em>Consolidate</em> servers for less hardware and cost; <em>Isolate</em> applications &#45;&#45; bad apps don&#8217;t drag the server down, contain intrusions, use different software stacks; <em>Replicate</em> &#45;&#45; easily create new servers and deploy in a standardized and automated way; <em>Utilize</em> &#45;&#45; take advantage of all CPU, memory, storage, resources; <em>Allocate</em> resources, give a server exactly what it requires, grow/shrink up and down, and balance them&#46; Bradley says, &#8220;Once you go to virtualization you won&#8217;t want to go back&#46; Do the simplest thing that could possibly work&#46;&#8221;</p> <p>Virtual clusters, then, are a bunch of servers cooperating toward a common goal &#45;&#45; if you have many versions or copies of one thing&#46; More than one customer, more than one version of software, etc&#46;</p> <p>For Rails, this means a lot of things: you can have many development environments and stages, take advantage of memory isolation, protect against PHP/Java, and make multiple&#45;server scaling accessible&#46;</p> <h2>Examples</h2> <ul> <li>Two servers for production and staging</li> <li>Three for web/db/staging</li> <li>Mixed languages &#45;&#45; instead of 1x1GB server use 3x300MB servers</li> <li>High availability applications with fewer servers</li> <li>Multiple applications &#45;&#45; one server per application</li> <li>Standardized roles/appliances &#45;&#45; mail, ftp, dns, web, db</li> </ul> <h2><a href="http://www.eastmedia.com/">EastMedia</a></h2> <ul> <li>They can incubate customers in separate images</li> <li>Dev/staging/production servers</li> <li>Shared SVN/trac</li> <li>2 physical servers => 8 virtual servers</li> </ul> <h2>Boom Design</h2> <ul> <li>Again, multiple stages</li> <li>Customer staging, with lower uptime requirements</li> <li>Low&#45;traffic apps on a single server, but everything else gets its own dedicated server</li> <li>2GB memory spread across 9 virtual servers</li> </ul> Sat, 19 May 2007 19:30:06 +0000 urn:uuid:f0f0e50c-df6a-47dc-81fe-0845c594512c Nick Sieger http://blog.nicksieger.com/articles/2007/05/19/railsconf-2007-bradley-taylor-virtual-clusters railsconf railsconf2007 http://blog.nicksieger.com/articles/trackback/246 RailsConf 2007: Saturday Morning Keynotes <p><strong>Cyndi Mitchell &#45;&#45; ThoughtWorks Studios</strong></p> <p>Enterprise (the &#8220;e&#8221; word)</p> <p>Before IT got involved, &#8220;enterprise&#8221; was a bold new venture&#46; Toyota manufacturing, Skype disruption of telephony&#46;</p> <p>Enterprise in terms of IT has come to mean bloatware, incompetence, corruption, waste of time, no value&#46;</p> <p>So this is the battle: The enterprise (to boldly go where no man has gone before) we need to reclaim vs&#46; the bloatware/competence/corruption/fear&#45;based selling etc&#46;</p> <p>RubyWorks &#45;&#45; package stack with haproxy, mongrel, monit through an RPM repository</p> <p>For JRuby support, call <a href="http://ola-bini.blogspot.com/">Ola</a>&#46;</p> <p><strong>Tim Bray &#45;&#45; Web Guy from Sun Microsystems</strong></p> <p>Change the world that are better than just using a cool web framework: http://pragmaticstudio&#46;com/donate/</p> <p>Sun loves Ruby&#46; Ruby <em>and</em> Rails, that is&#46; The impact of the Ruby language is going to be at least as big as Rails is for web development&#46;</p> <p>Sun provided servers for Ruby 2&#46;0 development, and can provide servers for your potentially cool, worthy, open source project, just drop Tim an email&#46;</p> <p>A few more obligatory plugs for NetBeans and Sun sponsoring the conference&#46; &#8220;Pre&#45;alpha,&#8221; he says&#46; Hmm, I wonder what <a href="http://blogs.sun.com/tor/">Tor</a> would say about that!</p> <p>JRuby: when would you use JRuby vs&#46; Ruby? If you have no pain, keep using C Ruby&#46; But if you have management concerns, deployment concerns, etc&#46; then by all means do try it!</p> <p>Obligatory handshake/sandal connection with ThoughtWorks and Cyndi &#45;&#45; running <a href="http://studios.thoughtworks.com/2007/5/7/mingle-to-run-on-jruby">Mingle</a> (and cruisecontrol&#46;rb) with JRuby&#46;</p> <p>Sun: &#8220;Hi, the answer is Java, what was the question?&#8221; So why would Sun want to support Ruby? Well, you guys are programmers&#46; Programmers who deliver quality software fast&#46; And those programmers need computers, and OSes, and web servers, and support and services, etc&#46; Plug, plug, plug&#46;</p> <p>How do you make money on free products? Sun has open&#45;sourcing Java, Solaris, even Sparc&#46; Joyent is open&#45;sourcing their stuff&#46; Where does the money come from? 1&#46; Adoption 2&#46; Deployment 3&#46; Monetization at the point of value</p> <p>What if we win? Are our problems over? No, we&#8217;ll have to deal with Java&#46; And &#46;NET&#46; And PHP&#46; <em>From the audience: And COBOL&#46;</em> The Network Is The Computer&#46; The Network Is Heterogeneous&#46; <strong>Deal with it&#46;</strong> So how do we interoperate?</p> <ul> <li>Just Run Java (and JRuby, of course!, and JavaScript, and PHP, etc&#46;)</li> <li>Use Atom/REST&#46; Everything should have a publish button&#46; <em>Don&#8217;t use WS&#45;DeathStar or WCF or WSIT&#46;</em></li> </ul> <p>Developer issues: Scaling, Static vs&#46; Dynamic, Maintainability, Concurrency, Tooling, Integration, Time to Market&#46; Which two of these matter the most?</p> <p>Tim&#8217;s final assertion: Maintainability and Time to Market, and that&#8217;s why we&#8217;re all at RailsConf&#46;</p> Sat, 19 May 2007 17:22:42 +0000 urn:uuid:c67fa477-41f0-4798-9fa2-2c27ae65e537 Nick Sieger http://blog.nicksieger.com/articles/2007/05/19/railsconf-2007-saturday-morning-keynotes railsconf railsconf2007 http://blog.nicksieger.com/articles/trackback/245 RailsConf 2007: Evan Weaver: Going Off Grid <p>Evan is talking about leaving Rails as a full&#45;stack framework and remixing bits and pieces for integration projects&#46; He&#8217;s doing it in the context of a case study on Bio: a project at the University of Delaware working with DNA data in large SQL databases&#46; Evan states that all of bioinformatics is an integration problem&#46; (Me: That&#8217;s probably true of any research project where data is coming from multiple, varied sources&#46; So where does Rails fit in this?)</p> <p>So how do you cope with this? Use the Rails console as an admin interface, mapping AR onto the legacy schema&#46;</p> <p>Shadow (<code>gem install shadow</code>) is a REST&#45;ful record server &#45;&#45; a small Mongrel handler that allows you to manipulate the database remotely&#46; It uses dynamic ActiveRecord classes that are created and trashed for each request&#46;</p> <p>Parallelization &#45;&#45; uses the Sun 1 grid engine that distributes shell scripts across 128 nodes&#46; Used for job and backend processing&#46;</p> <p>bioruby/bioperl/biopython &#45;&#45; bioinformatics libraries in other languages &#45;&#45; bioruby is not complete, but we still want to use Ruby, so he looked at ways of integrating Ruby with other languages&#46; No RubyInline for Perl or Python, no up&#45;to&#45;date direct/C bindings&#46; He ended up building a socket&#45;level interface into python&#46;</p> <p>Admin tools to consider &#45;&#45; streamlined, active_scaffold, autoadmin, Django (<code>manage.py inspectdb; manage.py syncdb; manage.py runserver</code>)&#46; (Wow, come to RailsConf, get a Django demo&#46; Unexpected surprise!)</p> <p>Extending Rails &#45;&#45; <code>has_many_polymorphs</code> for easy creation directed graphs</p> <p>Frustrating AR tidbits: <code>has_many_through</code> has a huge case statement, with sql strings everywhere, and tightly intertwined classes&#46; Ugh&#46;</p> <p>Scaling big webapps: AR/SQL is not the way&#46; Instead, go to a hyper&#45;denormalized model, where the DB is just a big hash&#46; This leads to things like berkeleydb, memcached, madeleine, etc&#46; and MySQL just becomes a persistence store for memcache&#46; One key is moving joins at write&#45;time, so that reads don&#8217;t need to re&#45;join associations&#46; You&#8217;re essentially duplicating/caching the data out to each association, but this makes sharding/splitting of data easier&#46; Example: Flickr user photos vs&#46; photos placed in a group&#46;</p> <p>Evan doesn&#8217;t believe that SQL is a viable data store for webapps &#45;&#45; I think he means large&#45;scale webapps&#46; Not everyone who&#8217;s trying to build a web application will run into these kinds of issues, so your mileage may vary&#46; Still, it&#8217;s refreshing to see more people rebel against the incumbent 30&#45;year gorilla of SQL&#46;</p> Fri, 18 May 2007 19:33:31 +0000 urn:uuid:f408e374-3a8c-4436-b31f-cf1d3fe7e4be Nick Sieger http://blog.nicksieger.com/articles/2007/05/18/railsconf-2007-evan-weaver-going-off-grid railsconf railsconf2007 http://blog.nicksieger.com/articles/trackback/243