<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Wayfair Engineering</title>
	<atom:link href="http://engineering.wayfair.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://engineering.wayfair.com</link>
	<description>A team of engineers building a platform that serves a zillion products to the world.</description>
	<lastBuildDate>Mon, 01 Apr 2013 12:18:10 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>/dev/null vs. MongoDB benchmark bake-off</title>
		<link>http://engineering.wayfair.com/devnull-vs-mongodb-benchmark-bake-off/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=devnull-vs-mongodb-benchmark-bake-off</link>
		<comments>http://engineering.wayfair.com/devnull-vs-mongodb-benchmark-bake-off/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 12:18:10 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Web Performance]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sharding]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1662</guid>
		<description><![CDATA[We&#8217;ve used MongoDB at Wayfair for a subset of our customer data for a while.  But we&#8217;re always looking for opportunities to speed up our infrastructure and give our customers a more responsive user experience.  So when we heard about &#8230; <a href="http://engineering.wayfair.com/devnull-vs-mongodb-benchmark-bake-off/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve used MongoDB at Wayfair for a subset of our customer data for a while.  But we&#8217;re always looking for opportunities to speed up our infrastructure and give our customers a more responsive user experience.  So when we heard about a new database platform called &#8216;/dev/null&#8217;, we became pretty excited.  We can&#8217;t post a link, because it&#8217;s in a very private beta testing phase, but we can assure you that the stealth-mode startup that&#8217;s working on it is supported by a pair of high-class Silicon Valley VCs.  The technology is supposed to be too cutting-edge for stodgy Boston, so we felt pretty lucky to be included.  /dev/null is web scale, we heard, and it supports sharding!  The slashes in the name certainly give it an edgy feel.  IMHO it&#8217;s a bold move to name it that, because of the potential for gfail (weird names doing badly in Google search) and unexpected placement in alphabetical lists.  But hey, as an NYC cabbie character said in <em>Taxi Driver</em>, they&#8217;re way ahead of us out there in California.</p>
<p>Everything comes with trade-offs, and the word on the street is that /dev/null is so heavily optimized for write performance that &#8216;read&#8217; reliability can be less than ideal.  But who knows?  Maybe that&#8217;s the balance we want for our write-heaviest workloads.</p>
<p>So we got out our testing tools and went to work on a bake-off.  We wanted to simulate real-world conditions as much as possible, so we wrote some PHP scripts that connected to our sharded development Mongo cluster.  On the /dev/null side, configuration of a cluster was pretty easy, as long as you start from a standard posix-style system.</p>
<p>After function-testing the PHP, we wrote a quick Apache Bench script to bake off the two systems.  The results speak for themselves:<br />
<a href="http://engineering.wayfair.com/wp-content/uploads/2013/03/mongovsdevnull.png"><img class="alignnone size-full wp-image-1682" src="http://engineering.wayfair.com/wp-content/uploads/2013/03/mongovsdevnull.png" alt="" width="640" height="335" /></a><br />
Past the upper 90%, MongoDB is a classic hockey stick.  /dev/null starts fast and stays flat, out to the far horizon.  Love it.  I don&#8217;t know that we&#8217;re ready to switch right away: I&#8217;ll be a little uncomfortable while it&#8217;s still in beta, and I&#8217;ll have to get to the bottom of those unreliable read operations.  But this is looking *very* promising.</p>
<p>For now, I&#8217;m going to follow our internal process for new technologies like this, which is to email around a Wayfair Technical Finding (&#8216;WTF&#8217;) to all the senior software engineers and architects, so we can put our heads together, evaluate further, and eventually make a plan to roll this out across all our data centers.</p>
<p>Hat tip <a title="MongoDB is web scale" href="http://www.xtranormal.com/watch/6995033/mongo-db-is-web-scale">gar1t on xtranormal</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/devnull-vs-mongodb-benchmark-bake-off/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proposal to Control Wheelchairs with Google Glass</title>
		<link>http://engineering.wayfair.com/proposal-to-control-wheelchairs-with-google-glass/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=proposal-to-control-wheelchairs-with-google-glass</link>
		<comments>http://engineering.wayfair.com/proposal-to-control-wheelchairs-with-google-glass/#comments</comments>
		<pubDate>Wed, 27 Mar 2013 18:16:49 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1636</guid>
		<description><![CDATA[When our company&#8217;s co-founder encouraged all of our Engineering department to participate in the Google Glass Explorer contest, I thought about project ideas that could help people by using the unique features of this new augmented-reality technology. I remembered a &#8230; <a href="http://engineering.wayfair.com/proposal-to-control-wheelchairs-with-google-glass/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When our company&#8217;s co-founder encouraged all of our Engineering department to participate in the Google Glass Explorer contest, I thought about project ideas that could help people by using the unique features of this new augmented-reality technology. I remembered a project that some fellow students did during a robotics class that I took in graduate school. It used eye-tracking technology to remotely control the motors on a vehicle. After confirming that Google planned to embed eye-tracking technology in their new product, I realized this idea could work for applications such as wheelchairs.</p>
<p>My plan is to provide feedback about the wearer’s surroundings, including obstacles and suggested paths, and enable him or her to control the wheelchair with eye movements. The original student project used patterns of a user&#8217;s eyes being opened or closed to change between types of motion. For my project, I want to use subtle yet deliberate movements of the eye to let the user interact seamlessly with the surrounding environment. I think this technology could be life-changing for persons with disabilities. I hope that being able to work on this project with the support of the Google Glass Explorer program will help make it a reality.</p>
<p>I wrote up my idea, posted it on Google Plus with the #ifihadglass hashtag, and some fellow Wayfairians tweeted about it. Walter Frick of BostInno saw a tweet, did an interview with me, and then wrote an article about it. You can read the full story at these links:</p>
<p>BostInno: <a title="BostInno Article" href="http://bit.ly/X7nD6b">http://bit.ly/X7nD6b</a><br />
Popular Science write-up: <a title="Popular Science Write-up" href="http://bit.ly/16unjVS">http://bit.ly/16unjVS</a></p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/proposal-to-control-wheelchairs-with-google-glass/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tesla: Feel the Power</title>
		<link>http://engineering.wayfair.com/tesla-feel-the-power/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tesla-feel-the-power</link>
		<comments>http://engineering.wayfair.com/tesla-feel-the-power/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 14:09:17 +0000</pubDate>
		<dc:creator>Scott Sandler</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Data Warehousing]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1602</guid>
		<description><![CDATA[Data Warehousing at Wayfair In 2009 Wayfair&#8217;s database infrastructure was based almost entirely on Microsoft SQL Server. Our Business Intelligence team was using a SQL Server data warehouse to prepare a large amount of data for import into Analysis Services (SSAS) each &#8230; <a href="http://engineering.wayfair.com/tesla-feel-the-power/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Data Warehousing at Wayfair</strong></p>
<p>In 2009 Wayfair&#8217;s database infrastructure was based almost entirely on Microsoft SQL Server. Our Business Intelligence team was using a SQL Server data warehouse to prepare a large amount of data for import into <a href="http://en.wikipedia.org/wiki/Microsoft_Analysis_Services">Analysis Services</a> (SSAS) each day. We populated our data warehouse using <a href="http://en.wikipedia.org/wiki/Log_shipping">transaction log shipping</a> from production servers, which required about 3 hours of downtime on the data warehouse at midnight each night to restore the previous day&#8217;s logs. Once that was done, a series of stored procedures were kicked off by jobs that would crunch through data from several different servers to produce a <a href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CD8QFjAA&amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FStar_schema&amp;ei=RRYNUZudAYaQ9gSs2IDQCg&amp;usg=AFQjCNHepXf1GB4MhzwXYNGx-ZLiSKKOjQ&amp;sig2=oRWNyxu2st6Dk6wNUphFpw&amp;bvm=bv.41867550,d.eWU">star schema</a> that could be pulled into SSAS. Wayfair was scaling rapidly, and this approach started to become painfully slow, often taking 10-16 hours to crunch through the previous day&#8217;s data.</p>
<p>The BI team decided to look into other solutions for data warehousing, and ultimately purchased a <a href="http://en.wikipedia.org/wiki/Netezza">Netezza</a> appliance. Netezza is essentially a fork of PostgreSQL that takes a massively parallel cluster of nodes (24 in our case) and makes them look like one database server to the client. In our tests, Netezza could crunch through our data in roughly a quarter of the time, bringing 10-16 hours down to a much more reasonable 2-4 hours. The dream of updating our data warehouse multiple times each day was starting to look feasible. The feedback loop on business decisions would become dramatically shorter, enabling us to iterate more quickly and make well informed decisions at a much faster pace. There was just one glaring problem.</p>
<p><strong>Great, But How Are We Going to Get Data Into It?</strong></p>
<p>As soon as the DBA team heard that the Netezza purchase had been finalized, our first question was &#8220;great, but how are we going to get data into it?&#8221; The folks at Netezza didn&#8217;t have an answer for us, but they did send us an engineer to help devise a solution. As it turned out, the problem of how to incrementally replicate large amounts of data into a data warehouse was a common one, and there were surprisingly few open source solutions. Google it, and most people will tell you that they just reload all their data every day, or that they only have inserts so they can just load the new rows each day. &#8220;Great, but what if you want incremental replication throughout the day? What if you have updates or deletes? How do you deal with schema changes?&#8221; Crickets.</p>
<p><strong>The First Solution</strong></p>
<p>The solution we arrived upon was to use <a href="http://msdn.microsoft.com/en-us/library/bb933875.aspx">SQL Server Change Tracking</a> to keep track of which rows had changes on each table, and we built a replication system around that. We created stored procedures for each table that contained the commands required to use the <a href="http://msdn.microsoft.com/en-us/library/bb934145.aspx">CHANGETABLE</a>() function to generate change sets, dump those to flat files on a network share using <a href="http://msdn.microsoft.com/en-us/library/ms162802.aspx">bcp</a>, pipe them through dos2unix to fix the line endings, and load them into netezza using the proprietary <em>nzload</em> command. Over the course of a few months we came up with an elaborate series of REPLACE() functions for text fields to escape delimiters, eliminate line breaks and clean up other data anomalies that had the potential to break the nzload. The whole process was driven by <a href="http://en.wikipedia.org/wiki/SQL_Server_Integration_Services">SSIS</a> packages.</p>
<p>This solution worked, but it was a maintenance nightmare. We frequently had to edit stored procedures when adding new columns, and we had to edit the SSIS packages to add new tables. SSIS uses GUI based programming, and the editor for it (Business Intelligence Development Studio) is extremely slow and clunky, so even making simple changes was a painful process. Adding a new table into change tracking was a 14-step process that took over an hour of DBA time, and setting up a new database took roughly 28 steps and around two days of DBA time. We also had no solution for schema changes &#8211; we needed to manually apply them to the Netezza server, and if we forgot to do so the change tracking jobs would fail.</p>
<p><strong>Release Early, Then Iterate Like Hell</strong></p>
<p>Over the next few years, we iterated on this solution and added a number of useful features. We got rid of the stored procedures per table and switched to a single stored procedure that used <a href="http://msdn.microsoft.com/en-us/library/ms188001.aspx">dynamic SQL</a> instead. We created a solution for automated schema changes based off of <a href="http://technet.microsoft.com/en-us/library/ms190989(v=sql.105).aspx">DDL triggers</a>. We created a single stored procedure to handle adding new tables into change tracking, turning it into a one-step process. We added features to publish a subset of a table&#8217;s columns, because Netezza had a fixed row size limit that some of our tables exceeded. We added a feature to trim the length of text fields, because large blobs of text usually aren&#8217;t needed on the data warehouse and they slowed down the process. We added logging of performance and health metrics to <a href="https://github.com/etsy/statsd/">statsD</a> with alerts in <a href="https://github.com/wayfair/Graphite-Tattle">Tattle</a>. We added the ability to replicate changes from sharded master databases and consolidate them into one database on the slave. We added the ability to replicate to multiple SQL Server data warehouses in addition to Netezza. We had data on our masters that was moved into archive tables when certain criteria were met, so we added a feature to apply changes to a table and its archive in one transaction on the slave to eliminate the temporary appearance of duplicate data.</p>
<p><strong>Not Good Enough</strong></p>
<p>Ultimately, we were still unhappy with the solution. It was too heavily based on stored procedures, functions, configuration via database tables, <a href="http://msdn.microsoft.com/en-us/library/ms175046.aspx">xp_cmdshell</a>, and worst of all - <a href="http://msdn.microsoft.com/en-us/library/ms188279.aspx">linked servers</a>. It was still a nightmare to set up new databases, and when wanted to make changes we had to edit the same stored procedures in 20+ different places.  It was still single threaded. Worst of all, it was tightly coupled. If one slave server fell behind, the others suffered for it. It was also extremely specific to the use case of replicating data from SQL Server to either SQL Server or Netezza, and Wayfair was beginning to make much more use of open source databases like MySQL and MongoDB. In early 2012, we realized this solution wasn&#8217;t going to scale any further through iteration. We needed a redesign. We needed something fresh.</p>
<p><strong>Enter Tesla</strong></p>
<p>Redesigned from the ground up and inspired by the Tesla Replicator in <a href="http://www.imdb.com/title/tt0482571/">The Prestige</a>, Tesla was the solution to our data warehousing woes. We completely avoided stored procedures, functions, configuration tables, SSIS, dynamic SQL, xp_cmdshell and linked servers. Instead, we wrote Tesla in C# (primarily due to <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx">one incredibly useful .NET class</a> for copying data between SQL servers) and moved all the logic into the application. Tesla is a single console application that takes care of everything we were doing with stored procedures and SSIS before. Its configuration is based on files rather than tables, which we can version control and deploy using our <a href="http://engineering.wayfair.com/wayfair-code-deployment/">push tool</a>. It&#8217;s multi-threaded and uses a configurable number of threads, allowing us to replicate the most important databases as quickly as possible. It&#8217;s completely decoupled, meaning that if one slave falls behind it doesn&#8217;t impact the others. It was also designed to be extensible to other data technologies, both as sources and destinations.</p>
<p><strong>Tesla&#8217;s Design</strong></p>
<p>Tesla is built into a few agents such as Master and Slave. These agents are run as scheduled tasks in the scheduler of your choice, and they each have their own configuration files. They are completely decoupled and can be run on separate servers and at separate times.</p>
<p>The design for Tesla was inspired by LinkedIn&#8217;s article about <a href="http://highscalability.com/blog/2012/3/19/linkedin-creating-a-low-latency-change-data-capture-system-w.html">DataBus</a>. Specifically, the idea of a master server publishing its change sets to a relay server and the slaves polling the relay for those changes was appealing to us. It meant less load on the masters, and it also meant we could store the change sets in such a way that if a slave fell behind it would be able to get consolidated deltas to more efficiently catch up. The biggest difference between Tesla and DataBus is that we focus on batch-based change sets, rather than streaming. Batches are captured on the master as one semi-consistent view of a database at a given point in a time, reducing the chance of orphaned or incomplete data on the data warehouse. It also makes the most sense for a technology like Netezza, which is terrible at small transactions and great at large batches.</p>
<p><strong>Open Source</strong></p>
<p>Tesla is fully open source and available on <a href="http://github.com/wayfair/tesla">github</a>. It currently supports SQL Server as a master, slave and relay server, and Netezza as a slave. It was designed with extensibility in mind, so we expect to add more technologies on both sides over time. We already have a slave adapter for <a href="http://hive.apache.org/">Hive</a> in the works. Feel free to hack away, add features, and submit pull requests!</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/tesla-feel-the-power/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wayfair @ Beanpot Hackathon</title>
		<link>http://engineering.wayfair.com/wayfair-beanpot-hackathon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wayfair-beanpot-hackathon</link>
		<comments>http://engineering.wayfair.com/wayfair-beanpot-hackathon/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 14:05:54 +0000</pubDate>
		<dc:creator>bshaw</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[events boston hackathon]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1597</guid>
		<description><![CDATA[Wayfair was invited to be a sponsor at this year’s Beanpot Hackathon (link: http://www.hackbeanpot.com/), held last week at the Microsoft NERD center in  Cambridge.  The concept of a hackathon is so closely related to our core values, that we jumped &#8230; <a href="http://engineering.wayfair.com/wayfair-beanpot-hackathon/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wayfair was invited to be a sponsor at this year’s Beanpot Hackathon (link: <a href="http://www.hackbeanpot.com/">http://www.hackbeanpot.com/</a>), held last week at the Microsoft NERD center in  Cambridge.  The concept of a hackathon is so closely related to our core values, that we jumped at the opportunity to participate.  Wylie Conlon, along with others from the nuACM (link: <a href="http://acm.ccs.neu.edu/">http://acm.ccs.neu.edu/</a>), did a great job organizing this event.</p>
<p>For those unfamiliar, a hackathon is a fantastic display of creativity, technical skills, team work, problem solving, and time management, all compressed into a single marathon event. The beanpot hackathon produced 17 demos, impressive considering the event only lasted about 24-hours.</p>
<p>As the event got underway, the dinner area was buzzing with excitement.  Groups of people informally huddled together, some with a white board to their side, drawing sketches and getting feedback, others researching stuff on their laptops, everyone engaged in the discussion bouncing ideas back and forth.  As different teams solidified, they moved to the main conference room to start building their project.  The one theme that was consistent across all groups was passion for technology, and enthusiasm to get something ready for demo.</p>
<p>Most groups worked through the night, taking short naps between bursts of coding.  We had some of our engineers available as mentors, although most groups seemed to be heads down and not looking for outside assistance.  Near the entrance to the conference room, Wayfair setup a duck pond, available for those needing a fun distraction from their project.  There was a fishing pole, and you could pull a duck from the pond to win a prize.  The rubber duck also serves as a good sounding board for ideas, or debugging code when you are stuck. (link: <a href="http://en.wikipedia.org/wiki/Rubber_duck_debugging/">http://en.wikipedia.org/wiki/Rubber_duck_debugging/</a>)</p>
<p>By the time Saturday evening arrived, I was blown away by some of the projects that teams put together.  Not only were the demos some cool application, or something that solved a problem, but the presentations were well done.  In many cases, the presenters talked about their inspiration, thought process, and where they saw the idea going next.  Questions from the audience were often constructive and suggested improvements.</p>
<p>Looking back on the event, I think one of the reasons we aligned so well with this particular event is because of the similarities to our work environment &#8212; Smart people using technology to solve problems quickly and get things done.  I see that demonstrated every day in our engineering department, and it was refreshing to see so many talented students come together for an event like this.  On a related note, we are hiring for summer internships in our software development group.  If you were a participant at the beanpot hackathon, or this type of environment sounds good to you, please get in touch with us (link: <a href="mailto:eomeara@wayfair.com">eomeara@wayfair.com</a>)</p>
<p>Brad S.</p>
<p>(contributors: Elias Y., Nishan S.)</p>

<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/image1-2/' title='image1'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/image11-150x150.jpeg" class="attachment-thumbnail" alt="image1" title="image1" /></a>
<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/image2-2/' title='image2'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/image21-150x150.jpeg" class="attachment-thumbnail" alt="image2" title="image2" /></a>
<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/image3-2/' title='image3'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/image31-150x150.jpeg" class="attachment-thumbnail" alt="image3" title="image3" /></a>
<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/image4-2/' title='image4'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/image41-150x150.jpeg" class="attachment-thumbnail" alt="image4" title="image4" /></a>
<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/image5-2/' title='image5'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/image51-150x150.jpeg" class="attachment-thumbnail" alt="image5" title="image5" /></a>
<a href='http://engineering.wayfair.com/wayfair-beanpot-hackathon/photo2-2/' title='photo2'><img width="150" height="150" src="http://engineering.wayfair.com/wp-content/uploads/2013/02/photo21-150x150.jpg" class="attachment-thumbnail" alt="photo2" title="photo2" /></a>

]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/wayfair-beanpot-hackathon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why not give Code Deploy Clients access to the repository?</title>
		<link>http://engineering.wayfair.com/why-not-give-code-deploy-clients-access-to-the-repository/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-not-give-code-deploy-clients-access-to-the-repository</link>
		<comments>http://engineering.wayfair.com/why-not-give-code-deploy-clients-access-to-the-repository/#comments</comments>
		<pubDate>Mon, 17 Dec 2012 15:52:05 +0000</pubDate>
		<dc:creator>Dan R.</dc:creator>
				<category><![CDATA[Code Deployment]]></category>
		<category><![CDATA[Continuous Deployment]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1566</guid>
		<description><![CDATA[We&#8217;ve received a few online, and in person questions like this, so i figured it was probably worth explaining in a little more detail. On the Deployment server, we have a variety of applications that we deploy. From Windows .Net Services, &#8230; <a href="http://engineering.wayfair.com/why-not-give-code-deploy-clients-access-to-the-repository/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve received a few online, and in person questions like this, so i figured it was probably worth explaining in a little more detail.</p>
<p>On the Deployment server, we have a variety of applications that we deploy. From Windows .Net Services, Python, Classic ASP, CSS/JS and PHP to name a few.</p>
<p>We chose to standardize the interface to the Deployment server to make creating new code deployment clients simpler. Our Deployment server is essentially an on demand package creation and deployment system.<span id="more-1566"></span></p>
<p>For example when we push CSS/JS we minify the contents prior to packaging it up to be picked up by the static content servers. Same goes for things like the python deployments, where we actually build a virtualenv on the deploy server and package that up prior to deploying. This allows the code deploy clients to just download a ready to go package.</p>
<p>Other side benefits are that this allows us to cache the packages with varnish to offload the push server during deploys. It also allows us to have a cached version of the packages in each data center to increase the speed of deployments locally. We also get a little bit of increased security. Really more the Onion / Layers reasoning here, but every little bit helps.</p>
<p>A con that should be noted is that unlike an rsync or direct repo deployment, it&#8217;s a full package, not an incremental. At this point in time our largest application deployment is the CSS/JS application which is still only about ~70M when compressed. We may need to move to a different model when bandwidth/download time of packages become the bottleneck, but we have a lot of breathing room for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/why-not-give-code-deploy-clients-access-to-the-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons from a datacenter move</title>
		<link>http://engineering.wayfair.com/lessons-from-a-datacenter-move/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lessons-from-a-datacenter-move</link>
		<comments>http://engineering.wayfair.com/lessons-from-a-datacenter-move/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 22:16:43 +0000</pubDate>
		<dc:creator>Dan C.</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1350</guid>
		<description><![CDATA[Last winter we were discussing all of our upcoming projects, and what they would require for new hardware in the datacenter.  Then we took a look at the space we had in our cage space at our main datacenter.  Turns &#8230; <a href="http://engineering.wayfair.com/lessons-from-a-datacenter-move/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Last winter we were discussing all of our upcoming projects, and what they would require for new hardware in the datacenter.  Then we took a look at the space we had in our cage space at our main datacenter.  Turns out, we didn’t have enough space, and the facility wouldn’t give us any more power in the current footprint we had.  There was also no room to expand our cage.  We had two basic options, one would have been to add additional cage space either in the same building, or even another facility and rely on cross connects or WAN connections.  We weren’t wild about this approach because we knew it would come back to bite us later as we continuously fought with the concept, and had to decide which systems should be in which space.  The other option was to move entirely into a bigger footprint.  We opted to stay in the same facility, which made moving significantly easier, and moved to a space that is 70% larger then our old space, giving us lots of room as we grow.  Another major driver in the decision to move entirely was that it afforded us the opportunity to completely redo our network infrastructure from the ground up to have a much more modular setup and finally using 10Gb everywhere in our core and aggregation layers.</p>
<p>Some stats on the move:</p>
<ul>
<li>Data migrated for NAS and SAN block storage: 161 TB</li>
<li>Network cables plugged in: 798</li>
<li>Physical servers moved or newly installed: 99 rack mount and 50 blades</li>
<li>Physical servers decommissioned to save power and simplify our environment: 49</li>
<li>VMs newly stood up or migrated: 619</li>
</ul>
<p>It’s worth noting that the physical moves were done over the course of 2 months.  Why so long?  Unlike many companies that can have a weekend to bring things down, we aren’t afforded that luxury.  We have customer service working in our offices 7 days a week both in the US as well as Europe, and we have our website to think about, which never closes.  In fact, we were able to pull this off with only a single 4-hour outage to our storefront, and several very small outages to our internal and backend systems during weeknights throughout the project.</p>
<p>Lessons Learned:</p>
<p>No matter how good your documentation is, it’s probably not good enough.  Most folks documentation concentrates on break/fix and general architecture of a system, what’s installed, how it’s configured, etc.  Since we drastically changed our network infrastructure, we had to re-ip every server when it was moved.  We had to go through and come up with procedures for what else needed to happen when a machine suddenly had a new IP address.  We use DNS for some things, but not everything, so we had to ensure that inter-related systems were also updated when we moved things.</p>
<p>Get business leads involved in the timeline.  This sounds funny, but one of the biggest metrics in measuring the success of a project like this is the perception of the users.  Since a good percentage of the systems moved had certain business units as the main “customers”, we worked with leaders from these business units to ensure we understood  their use of the systems, what days or times of day were they using it the most, or if they had any concerns over off-hours operations during different times of the week.  Once we had this info from many different groups, we sat down in a big room with all the engineers responsible for these systems, and came up with a calendar for the move, then got final approval for dates from the business leads.  This was probably the smarted thing we did, and went a long way in helping our “customer satisfaction”.</p>
<p>Another thing we learned early on was to divide the work of the physical moving of equipment and the work done by the subject matter experts to make system changes and ensure things are working properly after the physical move.  This freed the subject matter expert to get right to work, and not have to worry about other, non-related systems that were also being moved in the same maintenance window.  How did we pull this off?  Again, include everyone.  We have a large Infrastructure Engineering team, 73 people as of this writing.  We got everyone involved, from our frontline and IT Support groups, all the way up to directors; even Steve Conine, one of our co-founders did an overnight stint at the datacenter helping with the physical move of servers.  It was an amazing team effort, and we would never have had such a smooth transition if everyone didn’t step up in a big way.</p>
<p>I hope these little tidbits are helpful to anyone taking on such a monumental task as moving an entire data center.  As always, thanks for reading.</p>
<p style="text-align: center;"><a href="http://engineering.wayfair.com/wp-content/uploads/2012/10/IMG_0974.jpg"><img class="alignnone size-full wp-image-1354" title="IMG_0974" src="http://engineering.wayfair.com/wp-content/uploads/2012/10/IMG_0974.jpg" alt="" width="300" height="225" /></a></p>
<p><a href="http://engineering.wayfair.com/wp-content/uploads/2012/10/DSC_0673.jpg"><img class="size-medium wp-image-1353 aligncenter" title="DSC_0673" src="http://engineering.wayfair.com/wp-content/uploads/2012/10/DSC_0673-300x199.jpg" alt="" width="300" height="199" /></a> <a href="http://engineering.wayfair.com/wp-content/uploads/2012/10/20120803_223420.jpg"><img class="wp-image-1352 aligncenter" title="20120803_223420" src="http://engineering.wayfair.com/wp-content/uploads/2012/10/20120803_223420.jpg" alt="" width="300" height="225" /></a></p>
<p style="text-align: center;">
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/lessons-from-a-datacenter-move/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rest@Wayfair.com</title>
		<link>http://engineering.wayfair.com/restwayfair-com/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=restwayfair-com</link>
		<comments>http://engineering.wayfair.com/restwayfair-com/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 17:36:03 +0000</pubDate>
		<dc:creator>Daniel B.</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1467</guid>
		<description><![CDATA[Some Background At Wayfair, we are working on a next generation of systems to power our business. The decade old  systems that currently keep us running in stride have allowed Wayfair.com to vault from nothing to where it is today. &#8230; <a href="http://engineering.wayfair.com/restwayfair-com/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="font-size: 75%;"></div>
<h2>Some Background</h2>
<p>At Wayfair, we are working on a next generation of systems to power our business. The decade old  systems that currently keep us running in stride have allowed Wayfair.com to vault from nothing to where it is today. But as with all systems, they have started to show their age.<span id="more-1467"></span></p>
<p>Up until just a few years ago our entire engineering team was less than 40 people.  At this team size, we could all easily work on a single shared code base that our entire business ran on. This monolithic architecture was a conscious decision given our bootstrapped startup beginnings.</p>
<p>The good news is that the ‘single code base’ approach successfully bootstrapped our way to millions of customers and products, 400 million dollars in revenue, and ‘a zillion things home’ (wink) over 9 years. We’re proud to say that we accomplished all of this with a small, sharp team of engineers.  We are a successful startup, and it is only a matter of time until any startup needs to evolve through technical step function changes. For Wayfair.com, that time is now.  You can call it technical debt, re-architecture, version 2.0, whatever you want.  The reality is we need to change our approach. If we want our large business to grow even more, we need to have teams who work in parallel, and in order for that to work, we need to decouple and distribute our organization.</p>
<p>One of our initial steps was to reorganize the Engineering department into ‘platform teams’ – small and efficient groups of domain-specific spec op developers. These platform teams are responsible for the maintainability, scalability, and evolution of discrete segments of the business.  We are excited about this change, and can already see the scaling advantages to this organization model.</p>
<p>This change has exposed an issue that gets to our core software architecture.  Prior to the Great Platforms Restructure of 2012, we could think of our code base as one big system that was either working or not working . The complexities of graceful degredation and multi modes of failure could be ignored. But no more! We need to ‘un-ignore’ these complexities and take them into account as we develop.</p>
<p>We can look around at all sorts of large internet success stories and see the obvious solution is to move to a distributed services architecture.  The high level plan turns out to be the easy part.  The hard part is the detail.</p>
<h2>Look at What Others Have Done</h2>
<p>There are two leading paradigms of web services in production today:  SOAP (Simple Object Access Protocol) and REST (REpresentational State Transfer).</p>
<p><strong>SOAP</strong></p>
<p>SOAP is tantamount to Remote Procedure Call (RPC), a concept in computer science that allows a machine to invoke a function or subroutine on a separate machine. With RPC, programmers create innumerable specific procedures that are accessible at any node in a distributed system – a truly attractive concept. Despite the physical gap between two machines, RPC hides the ‘distributed’ part of a ‘distributed system’ through a highly malleable, customized protocol. One downside to this customized protocol is the tight coupling of the client and service, which reduces <a href="http://steve.vinoski.net/pdf/IEEE-Serendipitous_Reuse.pdf">serendipitous reuse</a> and impedes total scalability of a system.</p>
<p>We all felt that SOAP was too heavy weight and came with too much overhead. Plus, what is this, the 20<sup>th</sup> century? Just kidding. Wayfair is a fast-paced business, so this client-service coupling could come at a very high price. Since these interfaces are specialized, they would constantly need to change! ‘RPC impedes total scalability of a system’ is a bold conclusion to make, but also is a conclusion partially provided to us by the largest distributed system known to man-kind: the World Wide Web.</p>
<p><strong>REST</strong></p>
<p>REST is an architectural style that characterizes what makes the WWW the world’s largest distributed system.  To our team, it felt lightweight and approachable. We did, though, struggle with the notion of a resource in the realm of our application, and keep in mind that resources are core to REST architectures.</p>
<p><em>Any information that can be named can be a resource: a document or image, a temporal service (e.g. &#8220;today&#8217;s weather in Los Angeles&#8221;), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author&#8217;s hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.</em></p>
<p><em>-Fielding</em></p>
<p>With this in mind our initial reaction to implement REST, given our database centric history, was to make every database table a resource.  Historically we’d been extremely thoughtful about our database structure.  We had very clean data, with very minimal duplication.  However, we’ve got 2 Million lines of code, and over 6,000 database tables.  ‘Resource’-ing our application with a relational database attitude quickly started to feel overwhelming and misdirected.  It quickly became apparent that we do a ton of complex joins in SQL. So a resource-to-table approach would mean we’d be trying to re-produce the highly tuned join capabilities of the best SQL databases in PHP.  Not a good idea.</p>
<h2>Go with your Gut</h2>
<p>Our thinking was something to the effect of:  Let’s start by putting our core functionality (mainly Classic ASP functions and Stored Procedures in SQL Server) behind URLs.</p>
<p>We’ll exemplify with one of the first services we created, the inventory service.</p>
<p><span style="text-decoration: underline;">Millions</span> of times a day we will lookup stock status of products in our catalog.  The basic use-case is given a SKU, return stock status.  Our service-less version of this was done as a SQL Procedure called like this:</p>
<p><code>EXECUTE spGetInventory @SKU=’TH1254’</code></p>
<p>This methodology that we grew comfortable with is super simple to use as in-line code.</p>
<p>Our first pass at moving this behind a service looked like this:</p>
<p><a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/get_inventory.php?sku=TH1254&amp;format=json</a></p>
<p>At this point we were pretty proud of ourselves.  We felt like we were moving in the services direction. We agreed, as a team, that any services would support some common query string parameters like: format, debug, verbosity, logging, help, etc…</p>
<p>Fast forward a few months and we start to adopt this approach in earnest.  As we move from talking directly to the database, to talking through a service we find ourselves basically wrapping what had previously been stored procedures.  This starts to look like this:</p>
<p><a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/create_customer.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/get_customer.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/update_customer.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/delete_customer.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/create_basket.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/get_basket.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/update_basket.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/delete_basket.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/create_order.php</a><br />
….</p>
<p>You get the gist of it.  We provide the standard CRUD operations through URLs. However, our business is complicated, so on top of the CRUD operations we start doing things like this:</p>
<p><a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/does_order_have_returns.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/is_order_cancellable.php</a><br />
<a href="http://www.wayfair.com/careers#dept=engineering">http://services.wayfair.com/apply_promotion_code.php</a></p>
<p>On one hand, we were happy because we were clearly separating our data storage from our application logic. We were creating a path where we could at some point change our database structure without affecting the application directly.  On the other hand, we weren’t actually making the code any simpler, improving the organization, or separating of functionality into more discrete areas.  We were just moving complexity to different areas.</p>
<p>So we decided to give our services a pinch of RESTful-ness.</p>
<p>One of the stages of adopting something new seems to always involve fighting to make it look like the old thing you were comfortable with. Refer to our first step towards a more RESTful approach in our past blog: “<a href="http://engineering.wayfair.com/rest-rest-rest-you-can-never-get-enough-rest-2/">REST, REST, REST, you can never get enough REST</a>”.</p>
<p>The path we were on was “REST like” because it sent HTTP messages, was stateless, and returned loosely structured data. We were still not happy that we were on the right long term path with our “REST variant”. We did not comply to the RFC that formally describes HTTP so we weren’t RESTful.  We then re-visited our approach and as we constantly do in software engineering, we evolved.</p>
<h2>We have evolved</h2>
<p>At some point ‘comfortable’ paradigms wear you out, and you have that ah-ha moment of clarity where you start to understand a different paradigm.</p>
<p>We’re happy to say we’re over the hump of fighting some of the “pure” concepts of REST and chose to imbibe them.  In particular, we’ve made a few very important changes from our home-grown REST approach.  We’ve embraced HTTP and are using a broader set of the functions it was intended to enable.  Namely we’ve standardized on:</p>
<ol>
<li>Identification of resources in our system (Resource Addressing): We have started to create resources that conform to our business domain. E.g. Orders, Order Products etc. That is, resources have started to represent our business domain objects and business logic.</li>
<li>Uniform Interface (GET, POST, PUT, DELETE): We are conforming to the boundaries provided to us by HTTP/1.1</li>
<li>HATEOAS (Linking it all together):  Resources are now defined across platform boundaries and links to these resources insures that we are not duplicating data when there isn’t any need (e.g. Order representation links to customer resource representation).</li>
<li>Self-descriptive messages (Headers, Response Codes): Utilizing properties of HTTP allows our messages to describe themselves.</li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/restwayfair-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Better Lucene/Solr searches with a boost from an external naive Bayes classifier</title>
		<link>http://engineering.wayfair.com/better-lucenesolr-searches-with-a-boost-from-an-external-naive-bayes-classifier/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-lucenesolr-searches-with-a-boost-from-an-external-naive-bayes-classifier</link>
		<comments>http://engineering.wayfair.com/better-lucenesolr-searches-with-a-boost-from-an-external-naive-bayes-classifier/#comments</comments>
		<pubDate>Tue, 23 Oct 2012 15:22:11 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Recommendations]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[bayes]]></category>
		<category><![CDATA[classifier]]></category>
		<category><![CDATA[naive]]></category>
		<category><![CDATA[solr]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1289</guid>
		<description><![CDATA[Me: Doug, what are you doing? Doug: Solving the problem of class struggle with one of Greg&#8216;s classifiers. Me:  Karl Marx should call his office.  What do you mean by that? Doug: Let me explain&#8230; Class struggle at Wayfair search used &#8230; <a href="http://engineering.wayfair.com/better-lucenesolr-searches-with-a-boost-from-an-external-naive-bayes-classifier/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Me</em>: <a title="Link to Doug's profile" href="http://engineering.wayfair.com/author/dhohensee">Doug</a>, what are you doing?</p>
<p><em>Doug</em>: Solving the problem of class struggle with one of <a title="Link to Greg's profile" href="http://engineering.wayfair.com/author/gpadowski">Greg</a>&#8216;s classifiers.</p>
<p><em>Me</em>:  Karl Marx should call his office.  What do you mean by that?</p>
<p><em>Doug</em>: Let me explain&#8230;<span id="more-1289"></span></p>
<p>Class struggle at Wayfair search used to manifest itself as searches for &#8216;red cups&#8217; that returned lists of beer pong tables, and other unlikely and embarrassing results.  In this particular example, our prospective customer was clearly looking for something in the &#8216;cups&#8217; class of things, but the pack of search monkeys behind the scenes were interpreting this request wrong.    Why, you may ask?  Easy answer.  There happens to be a<a title="Link to the Red Cup Pong tables on wayfair.com" href="http://www.wayfair.com/Red-Cup-Pong-C514226.html"> &#8216;Red Cup&#8217; brand of beer pong tables</a>, which forms a serendipitous linguistic pairing with these search terms, of a type that bedevils search engineers the world over.  But not at Wayfair, not any more.</p>
<p>When you type something into the search box on <a title="Link to Wayfair's home page" href="http://www.wayfair.com">Wayfair</a> or <a title="Link to AllModern home page" href="http://www.allmodern.com">AllModern</a>, your request will most likely be processed by the Solr search platform.  It&#8217;s a great platform, but in some cases vanilla Solr doesn&#8217;t do exactly what we want.   In some of these situations we <a title="Link to a blog post about our solution to SOLR-1093" href="http://engineering.wayfair.com/better-three-word-searches-with-solr/">hack Solr</a>, and in others we augment its functionality with a pre-processor.  This blog post is about a classifier that we use as a pre-processor, which has dramatically improved the quality of our Solr search results.</p>
<p>The way we did this is not the only way to do such things.  If you want to do everything in Java, there&#8217;s an emerging pattern (perhaps already common?) of Hadoop+Mahout+Solr, which Grant Ingersoll describes <a title="Grant Ingersoll's presentation on lucene, solr and mahout" href="http://www.lucidworks.com/about-us/events/enhancing-discovery-solr-and-mahout-user-group-meeting">here</a> (Powerpoint) and <a title="Link to Grant Ingersoll's article on integrating mahout with lucene" href="http://searchhub.org/dev/2010/03/16/integrating-apache-mahout-with-apache-lucene-and-solr-part-i-of-3/">here</a> (techie how-to), with particular attention to the index-time aspects of such setups.  We don&#8217;t currently have a lot of needs in that area, because our catalogue is pretty well classified before it makes its way to Solr. Trey Grainger of CareerBuilder gives a good overview of various plain-Solr and search-time machine-learning techniques <a title="Link to a good article about recommendations with Solr" href="http://www.slideshare.net/treygrainger/building-a-real-time-solrpowered-recommendation-engine">here</a>.  I think you could reasonably work along those lines by integrating some Mahout libraries into a custom search handler.   You might get the same results we did.  To us, that seemed like a lot of trouble.  We already have some machine-learning components, which we wrote for non-search purposes, in C, C++ and Python.  That stack is closer to the metal than Java anyway, and for most of the mathematical operations that we need in the machine-learning area we prefer to stick with it if possible.  When we&#8217;re writing our own compiled code, or when we need C or C++ libraries like BLAS, GSL, etc., for the hard or fast math in our processing stream, an expressive scripting language like Python feels to us like a better choice for wrapper programs than Java.  In a Cython/JNI bake-off, Cython wins hands down.</p>
<p>But enough about platform choice.  The flow of control for the pre-processors is this:</p>
<ol>
<li>User types search terms into box.</li>
<li>Php code pre-processes search terms, sometimes, as in this case, by calling out to a Python service.</li>
<li>Php code generates Solr request, executes it, displays results.</li>
</ol>
<p>Let&#8217;s return to our prospective customer who has typed &#8216;red cups&#8217; into the search box, because he wants to buy red cups.  Our unclassified search would reach for the &#8216;Red Cup&#8217; beer pong tables, but we can school it a bit. We use the pre-processing step to prioritize items in the &#8216;cups&#8217; class, or whatever we have that most closely resembles a &#8216;cups&#8217; class.  We send &#8216;red+cup&#8217; to a naive Bayesian classifier trained on our product catalogue, and we get this: &#8220;Confidence: 0.605732999499 4087, Plates, Bowls &amp; Mugs| 283, Cups &amp; Accessories|5027, Food Wrap &amp; Containers|&#8230;&#8221;.  That output represents a confidence score and the identifiers and names of some classes in our catalogue.  If we get a confidence score above a certain threshold, we will then generate a Solr query like this:<br />
<code><br />
/indexname/select/?qt=handlerName&amp;q=red+cup&amp;insertFilterQueriesHere&amp;version=2.2&amp;rows=40&amp;start=0&amp;<br />
facet.limit=250&amp;defType=edismax&amp;boost=map(classID,4087,4087,1.500,1.0)&amp;<br />
boost=map(classID,283,283,1.250,1.0)&amp;boost=map(classID,5027,5027,1.125,1.0)<br />
</code><br />
Boosting is a small opening into Solr, through which a big bucket of smarts from external systems can be poured.  Of course, this only works if you have an intelligently classified catalogue, or whatever you call your body of material.  Creating such a thing is a domain-specific black art if there ever was one.  That&#8217;s a barrier to entry, to be sure.  But if you can figure all that out (wink!), this technique can really help you.</p>
<p>Hat tip, by the way, to <a title="Aaron Beppu's Linkedin profile" href="http://www.linkedin.com/pub/aaron-beppu/13/778/a74">Aaron Beppu</a>, whose Hadoop World talk last year, available here (<a title="Aaron Beppu's Hadoop World 2011 slides" href="http://www.cloudera.com/resource/hadoop-world-2011-presentation-slides-data-mining-for-product-search-ranking/">Powerpoint</a>) and here (<a title="Aaron Beppu's Hadoop World 2011 talk video" href="http://www.cloudera.com/resource/hadoop-world-2011-presentation-video-data-mining-for-product-search-ranking/">video</a>), got me thinking about boosting Solr searches.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/better-lucenesolr-searches-with-a-boost-from-an-external-naive-bayes-classifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Better three-word searches with SOLR</title>
		<link>http://engineering.wayfair.com/better-three-word-searches-with-solr/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-three-word-searches-with-solr</link>
		<comments>http://engineering.wayfair.com/better-three-word-searches-with-solr/#comments</comments>
		<pubDate>Fri, 05 Oct 2012 17:40:31 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[solr]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1222</guid>
		<description><![CDATA[We use the Apache SOLR search platform behind the scenes at Wayfair.  Sometimes, when vanilla SOLR doesn&#8217;t quite do what we want, we improve it for our purposes. When we suspect that others might have the same purposes, and we &#8230; <a href="http://engineering.wayfair.com/better-three-word-searches-with-solr/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We use the <a title="Apache Solr home page" href="http://lucene.apache.org/solr/">Apache SOLR</a> search platform behind the scenes at Wayfair.  Sometimes, when vanilla SOLR doesn&#8217;t quite do what we want, we improve it for our purposes. When we suspect that others might have the same purposes, and we think that we have solved our problems in a generally useful way, we contribute our solutions back to the open source community, either on <a title="Wayfair code on github" href="https://github.com/wayfair">github</a>, or through a more project-specific distribution channel.  SOLR is an Apache project, so for SOLR, this means attaching a patch to a &#8216;Jira&#8217;.  This blog post is about <a title="Link to SOLR Jira 1093" href="https://issues.apache.org/jira/browse/SOLR-1093">SOLR Jira 1093</a>.<span id="more-1222"></span></p>
<p>We were having a problem with the quality of the searches that were executed when our customers typed three words into the search box on the site.  The best vanilla SOLR treatments we could find for these searches were either too narrow or too broad: they gave us either a small number of high-quality results (sometimes no results at all), or a very large number of medium-quality results that matched two out of three of the terms.  So we wanted to do the restrictive, high-quality search, and set a threshold for an acceptable minimum number of results.  Then, if the number of results from the first search did not cross the threshold, we would run the broader search for backfill. Why not just have the front-end client code issue queries in parallel?  A good question, with a simple answer: pagination.  It is always better to let SOLR or Elastic Search handle pagination for you if you can.  Otherwise your client code will have to work unnecessarily hard to interleave or sequence results.</p>
<p>We found that other people had been asking for this feature, and related features, in SOLR-1093, since 2009.  The comments indicated a good amount of interest in the community.  The original feature request was for a parallel executor of more than one query.  <a title="Grant Ingersoll's Apache profile" href="https://issues.apache.org/jira/secure/ViewProfile.jspa?name=gsingers">Grant Ingersoll</a> quickly commented that &#8216;fallback queries&#8217; should be handled as well, and <a title="Lance Noskog's Apache profile" href="https://issues.apache.org/jira/secure/ViewProfile.jspa?name=lancenorskog">Lance Norskog</a> added that serial execution would also be desirable. It turns out we only need the serial executor for fallback queries, so that&#8217;s what <a title="Karthick" href="http://engineering.wayfair.com/author/ksoundararaj/">Karthick</a> from our search team implemented.  It&#8217;s been in production for us for a couple of months now, and it works very well.  Karthick checked with the SOLR mailing list and then posted the patch.  It&#8217;s an extension to the SearchHandler class called MultiSesarchHandler.</p>
<p>Can others benefit from this patch?  I think so, but perhaps not indefinitely.   Will it be accepted into SOLR?  In the end, I think it will not, because the core SOLR people are working on a more general solution in trunk, similar in design to the <a title="ScriptUpdateProcessor link" href="http://wiki.apache.org/solr/ScriptUpdateProcessor">ScriptUpdateProcessor</a>.  This other thing is a completely different approach based on scripted queries.  When that&#8217;s in general use, we&#8217;ll probably switch to it.  But it&#8217;s not in SOLR 3.6, which is the most up-to-date general release as of this writing, and it&#8217;s not going to make it into SOLR 4.0.  For now we have all our patches applied to the very safe 3.6 branch, and we&#8217;re preparing to re-apply everything to 4.0 when it gets out of beta.  It might be a while before the other approach is easily available.  In the mean time, if you want to do this, get out your patch kits and enjoy!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/better-three-word-searches-with-solr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Information Week Interviews Wayfair on its use of Markov Clustering</title>
		<link>http://engineering.wayfair.com/information-week-interviews-wayfair-on-its-use-of-markov-clustering/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=information-week-interviews-wayfair-on-its-use-of-markov-clustering</link>
		<comments>http://engineering.wayfair.com/information-week-interviews-wayfair-on-its-use-of-markov-clustering/#comments</comments>
		<pubDate>Fri, 28 Sep 2012 21:09:03 +0000</pubDate>
		<dc:creator>Greg</dc:creator>
				<category><![CDATA[Recommendations]]></category>
		<category><![CDATA[bigdata]]></category>
		<category><![CDATA[recommendations]]></category>

		<guid isPermaLink="false">http://engineering.wayfair.com/?p=1235</guid>
		<description><![CDATA[These days, in the big data community, we often hear how biologists have adopted and are using distributed computing technologies that were first introduced to solve problems in software engineering. The fact that Wayfair has done the inverse and used &#8230; <a href="http://engineering.wayfair.com/information-week-interviews-wayfair-on-its-use-of-markov-clustering/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>These days, in the big data community, we often hear how biologists have adopted and are using distributed computing technologies that were first introduced to solve problems in software engineering. The fact that Wayfair has done the inverse and used a tool initially developed to help biologists cluster similar proteins together to solve a problem in e-commerce, piqued the curiosity of Information Week magazine, who asked us for an interview about our February blog post on using Markov clustering for generating recommendations <a title="Markov Clustering" href="http://engineering.wayfair.com/recommendations-with-markov-clustering/">http://engineering.wayfair.com/recommendations-with-markov-clustering/</a>. Read the interview here <a title="Information Week Article" href="http://www.informationweek.com/big-data/news/big-data-analytics/240007850/online-retailer-uses-dna-research-to-connect-with-customers">http://www.informationweek.com/big-data/news/big-data-analytics/240007850/online-retailer-uses-dna-research-to-connect-with-customers</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://engineering.wayfair.com/information-week-interviews-wayfair-on-its-use-of-markov-clustering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
