{"id":1775,"date":"2014-12-16T18:33:01","date_gmt":"2014-12-16T18:33:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1775"},"modified":"2023-04-28T10:33:14","modified_gmt":"2023-04-28T17:33:14","slug":"scaling-memcached-vbuckets","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/","title":{"rendered":"Scaling memcached with vbuckets"},"content":{"rendered":"<div id=\"post\">\n<p>For years, people have used memcached to scale large sites. Originally, there was a simple modulo selection hash algorithm that was used. It still is used quite a bit actually and it\u2019s quite easy to understand (although, it\u2019s shown regularly that some people don\u2019t truly understand it when applied to their full system). The algorithm is basically this:<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\"><\/div>\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\">servers <span style=\"color: #66cc66\">=<\/span> <span style=\"color: black\">[<\/span><span style=\"color: #483d8b\">&#8216;server1:11211&#8217;<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #483d8b\">&#8216;server2:11211&#8217;<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #483d8b\">&#8216;server3:11211&#8217;<\/span><span style=\"color: black\">]<\/span><br \/>\nserver_for_key<span style=\"color: black\">(<\/span>key<span style=\"color: black\">)<\/span> <span style=\"color: #66cc66\">=<\/span> servers<span style=\"color: black\">[<\/span><span style=\"color: #008000\">hash<\/span><span style=\"color: black\">(<\/span>key<span style=\"color: black\">)<\/span> % servers.<span style=\"color: black\">length<\/span><span style=\"color: black\">]<\/span><\/div>\n<\/div>\n<p>That is, given a hash algorithm, you hash the key and map it to a position in the server list and contact that server for that key. This is <em>really<\/em> easy to understand, but <a style=\"color: #0066cc\" href=\"https:\/\/www.couchbase.com\/memcached-replacement\">leads to a few problems<\/a>.<\/p>\n<ol>\n<li>Having some servers have greater capacity than others.<\/li>\n<li>Having cache misses skyrocket when a server dies.<\/li>\n<li>Brittle\/confusing configuration (broken things can appear to work)<\/li>\n<\/ol>\n<p>Ignoring weighting (which can basically be \u201csolved\u201d by adding the same server multiple times to the list), the largest problem you\u2019ve got is what to do when a server dies, or you <a style=\"color: #0066cc\" href=\"https:\/\/developer.couchbase.com\/documentation\/server\/3.x\/admin\/Concepts\/concept-dataStorage.html\">want to add a new one<\/a>, or you even want to <em>replace<\/em> one.<\/p>\n<p>In 2007, <a href=\"https:\/\/www.metabrew.com\/\"><u><span style=\"color: #0066cc\">Richard Jones<\/span><\/u><\/a> and crew over at <a href=\"https:\/\/www.last.fm\/\"><u><span style=\"color: #0066cc\">last.fm<\/span><\/u><\/a> created a new way to solve some of these problems called <a href=\"https:\/\/www.audioscrobbler.net\/development\/ketama\/\"><u><span style=\"color: #0066cc\">ketama<\/span><\/u><\/a>. This was a library and method for \u201cconsistent hashing\u201d \u2013 that is, a way to greatly lower the probability of hashing to a server that does not have the data you seek when the server list changes.<\/p>\n<p>It\u2019s an awesome system, but I\u2019m not here to write about it, so I won\u2019t get into the details. It still has a flaw that makes it unsuitable for projects like <a href=\"https:\/\/www.couchbase.com\/blog\/what-exactly-membase\/\">membase<\/a>:\u00a0it\u2019s only probabilistically more likely to get you to the server with your data. Looking at it another way, it\u2019s almost guaranteed to get you to the wrong server sometimes, just less frequently than the modulus method described above.<\/p>\n<h3>A New Hope<\/h3>\n<p>In early 2006, Anatoly Vorobey introduced <a href=\"https:\/\/github.com\/memcached\/memcached\/commit\/7a308025661a49a5e19f98d2c5b8df04d96b4642\"><u><span style=\"color: #0066cc\">some code<\/span><\/u><\/a> to create something he referred to as \u201cmanaged buckets.\u201d This code lived there until late 2008. <a href=\"https:\/\/github.com\/memcached\/memcached\/commit\/04319dddabaa06d15407ab6f793b160d3b1c5edb\"><u><span style=\"color: #0066cc\">It was removed<\/span><\/u><\/a> because it was never quite complete, not understood at all, and we had created a newer protocol that made it easier build such things.<\/p>\n<p>We\u2019ve been bringing that back, and I\u2019m going to tell you why it exists and why you want it.<\/p>\n<p>First, a quick summary of what we wanted to accompish:<\/p>\n<ol>\n<li>Never service a request on the wrong server.<\/li>\n<li>Allow scaling up <em>and<\/em> down at will.<\/li>\n<li>Servers refuse commands that they should not service, <em>but<\/em><\/li>\n<li>Servers still do not know about each other.<\/li>\n<li>We can hand data sets from one server another atomically, <em>but<\/em><\/li>\n<li>There are no temporal constraints.<\/li>\n<li>Consistency is guaranteed.<\/li>\n<li>Absolutely no network overhead is introduced in the normal case.<\/li>\n<\/ol>\n<p>To expand a bit on the last point relative to other solutions we looked at, there are no proxies, location services, server-to-server knowledge, or any other magic things that require overhead. A vbucket aware request requires no more network operations to find the data than it does to perform the operation on the data (it\u2019s not even a single byte larger).<\/p>\n<p>There are other more minor goals such as \u201cyou should be able to add servers while under peak load,\u201d but those just sort of fall out for free.<\/p>\n<h3>Introducing: The VBucket<\/h3>\n<p>A vbucket is conceptually a computed subset of all possible keys.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8866 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/vbucket.png\" alt=\"vbucket visualized\" width=\"234\" height=\"286\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/vbucket.png 234w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/vbucket-16x20.png 16w\" sizes=\"auto, (max-width: 234px) 100vw, 234px\" \/><\/div>\n<p>If you\u2019ve ever implemented a hash table, you can think of it as a virtual hash table bucket that is the first level of hashing for all node lookups. Instead of mapping keys directly to servers, we map vbuckets to servers statically and have a consistent key \u2192 vbucket computation.<\/p>\n<p>The number of vbuckets in a cluster remains constant regardless of server topology. This means that key <code>x<\/code> always maps to the same vbucket given the same hash.<\/p>\n<p>Client configurations have to grow a bit for this concept. Instead of being a plain sequence of servers, the config now also has the explicit vbucket to server mapping.<\/p>\n<p>In practice, we model the configuration as a server sequence, hash function, and vbucket map. Given three servers and six vbuckets (a very small number for illustration), an example of how this works in relation to the modulus code above would be as follows:<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\">servers <span style=\"color: #66cc66\">=<\/span> <span style=\"color: black\">[<\/span><span style=\"color: #483d8b\">&#8216;server1:11211&#8217;<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #483d8b\">&#8216;server2:11211&#8217;<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #483d8b\">&#8216;server3:11211&#8217;<\/span><span style=\"color: black\">]<\/span><br \/>\nvbuckets <span style=\"color: #66cc66\">=<\/span> <span style=\"color: black\">[<\/span><span style=\"color: #ff4500\">0<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #ff4500\">0<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #ff4500\">1<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #ff4500\">1<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #ff4500\">2<\/span><span style=\"color: #66cc66\">,<\/span> <span style=\"color: #ff4500\">2<\/span><span style=\"color: black\">]<\/span><br \/>\nserver_for_key<span style=\"color: black\">(<\/span>key<span style=\"color: black\">)<\/span> <span style=\"color: #66cc66\">=<\/span> servers<span style=\"color: black\">[<\/span>vbuckets<span style=\"color: black\">[<\/span><span style=\"color: #008000\">hash<\/span><span style=\"color: black\">(<\/span>key<span style=\"color: black\">)<\/span> % vbuckets.<span style=\"color: black\">length<\/span><span style=\"color: black\">]<\/span><span style=\"color: black\">]<\/span><\/div>\n<\/div>\n<p>It should be obvious from reading that code how the introduction of vbuckets provides tremendous power and flexibility, but I\u2019ll go on in case it\u2019s not.<\/p>\n<h3>Terminology<\/h3>\n<p>Before we get into too many details, let\u2019s look at the terminology that\u2019s going to be used here.<\/p>\n<dl>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Cluster:<\/dt>\n<dd>\u00a0A collection of collaborating servers.<\/dd>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Server:<\/dt>\n<dd>\u00a0An individual machine within a cluster.<\/dd>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">vbucket:<\/dt>\n<dd>\u00a0A subset of all possible keys.<\/dd>\n<\/dl>\n<p>Also, any given vbucket will be in one of the following states on any given server:<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8867 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/states.png\" alt=\"VBucket States\" width=\"294\" height=\"184\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/states.png 294w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/states-20x13.png 20w\" sizes=\"auto, (max-width: 294px) 100vw, 294px\" \/><\/div>\n<dl>\n<dt><\/dt>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Active:<\/dt>\n<dd>\u00a0This server is servicing all requests for this vbucket.<\/dd>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Dead:<\/dt>\n<dd>\u00a0This server is not in any way responsible for this vbucket<\/dd>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Replica:<\/dt>\n<dd>No client requests are handled for this vbucket, but it can receive replication commands.<\/dd>\n<dt style=\"float: left;clear: left;width: 100px;text-align: right;font-weight: bold\">Pending:<\/dt>\n<dd>\u00a0This server will block all requests for this vbucket.<\/dd>\n<\/dl>\n<h3>Client Operations<\/h3>\n<p>Each request must include the vbucket id as computed by the hashing algorithm. We made use of the reserved fields in the binary protocol\u00a0allowing for up to 65,536 vbuckets to be created (which is really quite a lot).<\/p>\n<p>Since all that\u2019s needed to consistently choose the right vbucket is for clients to agree on the hashing algorithm and number of vbuckets, it\u2019s significantly harder to misconfigure a server such that you\u2019re communicating with the wrong server for a given vbucket.<\/p>\n<p>Additionally, with libvbucket we\u2019ve made distributing configurations and distributing configuration, agreeing on mapping algorithms, and reacting to misconfigurations a problem that doesn\u2019t have to be solved repeatedly. Work is under way to get ports of libvbucket to java and .net, and in the meantime moxi\u00a0will perform all of the translations for you if you have a non-persistent clients or can\u2019t wait for your favorite client to catch up.<\/p>\n<h3>One Active Server<\/h3>\n<h3><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8868 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/oneserver.png\" alt=\"One server, six vbuckets\" width=\"172\" height=\"144\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/oneserver.png 172w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/oneserver-20x17.png 20w\" sizes=\"auto, (max-width: 172px) 100vw, 172px\" \/><\/h3>\n<p>While deployments typically have 1,024 or 4,096 vbuckets, we\u2019re going to continue with this model with six because it\u2019s a lot easier to think about and draw pictures of.<\/p>\n<p>In the image to the right, there is one server running with six active buckets. All requests with all possible vbuckets go to this server, and it answers for all of them.<\/p>\n<h3>One Active Server, One New Server<\/h3>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8869 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/one-quiesc.png\" alt=\"One active server, one quiescent server\" width=\"172\" height=\"284\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/one-quiesc.png 172w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/one-quiesc-12x20.png 12w\" sizes=\"auto, (max-width: 172px) 100vw, 172px\" \/><\/div>\n<p>Now let us add a new server. Here\u2019s the first bit of magic: Adding a server does not destabilize the tree (as seen on the right).<\/p>\n<p>Adding a server to the cluster, and even pushing it out in the configuration to all of the clients, does not imply it will be used immediately. Mapping is a separate concept, and all vbuckets are still exclusively mapped to the old server.<\/p>\n<p>In order to make this server useful, we will transfer vbuckets from one server to another. To effect a transfer, you select a set of the vbuckets that you want the new server to own and set them all to the pending state on the receiving server. Then we begin pulling the data out and placing it in the new server.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"floatleft alignleft wp-image-8870 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/transfer.gif\" alt=\"Transfering vbuckets from one server to two\" width=\"340\" height=\"178\" \/>By performing the steps in this exact order, are able to guarantee no more than one server is active for any given vbucket at any given point in time <em>without<\/em> any regard to actual chronology. That is, you can have hours of clock skew and vbucket transfers taking several minutes and never fail to be consistent. It\u2019s also guaranteed that clients will never receive <em>incorrect<\/em> answers.<\/p>\n<p>&nbsp;<\/p>\n<div><a href=\"https:\/\/dustin.sallings.org\/images\/vbucket\/flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8871 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/flow.png\" alt=\"flow and what-not\" width=\"401\" height=\"486\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/flow.png 401w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/flow-248x300.png 248w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/flow-300x364.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/flow-17x20.png 17w\" sizes=\"auto, (max-width: 401px) 100vw, 401px\" \/><\/a><\/div>\n<ol>\n<li>The vbucket on the new server is placed in a pending state.<\/li>\n<li>A vbucket extract <a href=\"https:\/\/www.couchbase.com\/blog\/want-know-what-your-memcached-servers-are-doing-tap-them\/\"><u><span style=\"color: #0066cc\">tap<\/span><\/u><\/a> stream is started.<\/li>\n<li>The vbucket tap stream atomically sets the state to dead when the queue is in a sufficient drain state.<\/li>\n<li>The new server only transitions from pending to active after it\u2019s received confirmation that the old server is no longer servicing requests.Since subsections are being transferred indepenently, you no longer have to limit yourself to thinking of a server moving at a time, but a tiny fraction of a server moving at a time. This allows you to start slowly migrating traffic from busy servers <em>at peak<\/em> to less busy servers with minimal impact (with 4,096 vbuckets over 10 servers each with 10M keys, you\u2019d be moving about 20k keys at a time with a vbucket transfer as you bring up your eleventh server).<\/li>\n<\/ol>\n<p>You may notice that there is a time period where a vbucket has <em>no<\/em> active server at all. This occurs at the very end of the transfer mechanism and causes blocking to occur. In general, it should be rare to observe a client actually blocked in the wild. This only happens when a client gets an error from the old server indicating it\u2019s done prepping the transfer and can get to the new server before the new server receives the last item. Then the new server only blocks the client until that item is delivered and the vbucket can transition from <code>pending<\/code> to <code>active<\/code> state.<\/p>\n<p>Although the vbucket in the old server automatically goes into the <code>dead<\/code> state when it gets far enough along, it <em>does not<\/em> delete data automatically. That is explicitly done <em>after<\/em> confirmation that the new node has gone <code>active<\/code>. If the destination node fails at any point before we set it <code>active<\/code>, we can just abort the transfer and leave the old server <code>active<\/code> (or set it back to <code>active<\/code> if we were far enough along).<\/p>\n<h3>What\u2019s This About Replica State?<\/h3>\n<p>HA comes up a lot, so we made sure to cover it. A <code>replica<\/code> vbucket is similar to a <code>dead<\/code> vbucket in that from a normal client\u2019s perspective. That is, all requests are refused, but replication commands are allowed. This is also similar to the <code>pending<\/code> state in that records are stored, but contrasted in that clients do not block.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright alignright wp-image-8872 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/replica1.png\" alt=\"One replica with three servers\" width=\"272\" height=\"318\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica1.png 272w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica1-257x300.png 257w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica1-17x20.png 17w\" sizes=\"auto, (max-width: 272px) 100vw, 272px\" \/><\/div>\n<p>Consider the image to the right where we have three servers, six vbuckets, and a single replica per vbucket.<\/p>\n<p>Like the masters, each replica is also statically mapped, so they can be moved around at any time.<\/p>\n<p>In this example, we replicate the vbucket to the \u201cnext\u201d server in the list. i.e. an <code>active<\/code> vbucket on <code>S1<\/code> replicates to a <code>replica<\/code> bucket on <code>S2<\/code> \u2013 same for <code>S2<\/code>\u00a0\u2192\u00a0<code>S3<\/code> and <code>S3<\/code>\u00a0\u2192\u00a0<code>S1<\/code>.<\/p>\n<p><span style=\"color: #343e47;font-family: Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 40px\">Multiple Replicas<\/span><\/p>\n<p>We also enable strategies to have more than one copy of your data available on nodes.<\/p>\n<p>The diagram below shows two strategies for three servers to have one active and two replicas of each bucket.<\/p>\n<h3>1:n Replication<\/h3>\n<p>The first strategy (<code>1:n<\/code>) refers to a master servicing multiple slaves concurrently. The concept here is familiar to anyone who\u2019s dealt with data storage software that allows for multiple replicas.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8873 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/replica-many.png\" alt=\"Strategies for many-child replication\" width=\"558\" height=\"338\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica-many.png 558w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica-many-300x182.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2014\/12\/replica-many-20x12.png 20w\" sizes=\"auto, (max-width: 558px) 100vw, 558px\" \/><\/div>\n<h3>Chained Replication<\/h3>\n<p>The second strategy (<code>chained<\/code>) refers to a single master servicing only a single slave, but having that slave have a further downstream slave of its own. This offers the advantage of having a single stream of mutation events coming out of a server, while still maintaining two copies of all records. This has the disadvantage of compounding replication latency as you traverse the chain.<\/p>\n<p>Of course, with more than two additional copies, you could mix them such that you do a single stream out of the master and then have the second link of the chain V out a <code>1:n<\/code> stream to two further servers.<\/p>\n<p>It\u2019s all in how you map things.<\/p>\n<h3>Acknowledgments<\/h3>\n<p>Thanks to <a href=\"https:\/\/www.dormando.me\/\"><u><span style=\"color: #0066cc\">Dormando<\/span><\/u><\/a> for helping decipher the original \u201cmanaged bucket\u201d code, intent, and workflows, and <a href=\"https:\/\/github.com\/jayesh\"><u><span style=\"color: #0066cc\">Jayesh Jose<\/span><\/u><\/a> and the other Zynga folks for independently discovering it and working through a lot of use cases.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>For years, people have used memcached to scale large sites. Originally, there was a simple modulo selection hash algorithm that was used. It still is used quite a bit actually and it\u2019s quite easy to understand (although, it\u2019s shown regularly [&hellip;]<\/p>\n","protected":false},"author":34,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8992],"class_list":["post-1775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Scaling memcached with vbuckets - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scaling memcached with vbuckets\" \/>\n<meta property=\"og:description\" content=\"For years, people have used memcached to scale large sites. Originally, there was a simple modulo selection hash algorithm that was used. It still is used quite a bit actually and it\u2019s quite easy to understand (although, it\u2019s shown regularly [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T18:33:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-28T17:33:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/vbucket.png\" \/>\n<meta name=\"author\" content=\"Dustin Sallings, Chief Architect, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dustin Sallings, Chief Architect, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\"},\"author\":{\"name\":\"Dustin Sallings, Chief Architect, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0\"},\"headline\":\"Scaling memcached with vbuckets\",\"datePublished\":\"2014-12-16T18:33:00+00:00\",\"dateModified\":\"2023-04-28T17:33:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\"},\"wordCount\":1954,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\",\"name\":\"Scaling memcached with vbuckets - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T18:33:00+00:00\",\"dateModified\":\"2023-04-28T17:33:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scaling memcached with vbuckets\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0\",\"name\":\"Dustin Sallings, Chief Architect, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/c5bddc8d7dab8b5c9121282556b0dbff\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g\",\"caption\":\"Dustin Sallings, Chief Architect, Couchbase\"},\"description\":\"Dustin Sallings is a Chief Architect at Couchbase. Dustin is an Author of spymemcached and core contributor to Couchbase and Memcached projects.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/dustin-sallings\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Scaling memcached with vbuckets - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/","og_locale":"en_US","og_type":"article","og_title":"Scaling memcached with vbuckets","og_description":"For years, people have used memcached to scale large sites. Originally, there was a simple modulo selection hash algorithm that was used. It still is used quite a bit actually and it\u2019s quite easy to understand (although, it\u2019s shown regularly [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T18:33:00+00:00","article_modified_time":"2023-04-28T17:33:14+00:00","og_image":[{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2014\/12\/vbucket.png","type":"","width":"","height":""}],"author":"Dustin Sallings, Chief Architect, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dustin Sallings, Chief Architect, Couchbase","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/"},"author":{"name":"Dustin Sallings, Chief Architect, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0"},"headline":"Scaling memcached with vbuckets","datePublished":"2014-12-16T18:33:00+00:00","dateModified":"2023-04-28T17:33:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/"},"wordCount":1954,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/","url":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/","name":"Scaling memcached with vbuckets - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T18:33:00+00:00","dateModified":"2023-04-28T17:33:14+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/scaling-memcached-vbuckets\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Scaling memcached with vbuckets"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0","name":"Dustin Sallings, Chief Architect, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/c5bddc8d7dab8b5c9121282556b0dbff","url":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","caption":"Dustin Sallings, Chief Architect, Couchbase"},"description":"Dustin Sallings is a Chief Architect at Couchbase. Dustin is an Author of spymemcached and core contributor to Couchbase and Memcached projects.","url":"https:\/\/www.couchbase.com\/blog\/author\/dustin-sallings\/"}]}},"authors":[{"term_id":8992,"user_id":34,"is_guest":0,"slug":"dustin-sallings","display_name":"Dustin Sallings, Chief Architect, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","author_category":"","last_name":"Sallings","first_name":"Dustin","job_title":"","user_url":"","description":"Dustin Sallings is a Chief Architect at Couchbase. Dustin is an Author of spymemcached and core contributor to Couchbase and <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/3.x\/developer\/dev-guide-3.0\/memcached.html#projects\">Memcached projects.<\/a>"}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1775"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1775\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1775"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}