{"id":1720,"date":"2014-12-16T18:57:02","date_gmt":"2014-12-16T18:57:02","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1720"},"modified":"2017-05-03T11:23:45","modified_gmt":"2017-05-03T18:23:45","slug":"new-operations-membase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/ko\/new-operations-membase\/","title":{"rendered":"Membase\uc758 \uc0c8\ub85c\uc6b4 \uc791\uc5c5"},"content":{"rendered":"<p><span style=\"color: #999999;\"><em>[This post also appears on Dustin&#8217;s github blog.]<\/em><\/span><\/p>\n<p>We built a couple of new protocol operations for people building applications. The general goal of adding an operation is to keep it orthogonal to other commands while enhancing the functionality in a way that lets you do things that couldn\u2019t be done before, or at least were common and difficult to do efficiently.<\/p>\n<p>Here is a description of the new commands and an idea of how they might be used.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/sites\/default\/files\/uploads\/all\/videos\/synchronize.png\" alt=\"synchronize!\" width=\"175\" height=\"148\" align=\"right\" \/><\/div>\n<h3>Sync<\/h3>\n<p>The other new concept we introduced is a <code>sync<\/code> command for providing a barrier where you wait for an application\u2019s data to change state in specific ways such as having an item change from a known value or achieve a specified level of durability.<\/p>\n<p>Quick background on how this works in membase (for which we implemented <code>sync<\/code> to begin with): Membase\u2019s engine has what is effectively an air-gap between the network interface and the disk. Operations are almost all processed from and to RAM and then asynchronously replicated and persisted. Incoming items are available for request immediately upon return from your mutation command (i.e. the next request for a given key will return the item that was just set), but replication and persistence will be happening soon.<\/p>\n<p>The membase <code>sync<\/code> command is somewhat analagous to <a href=\"https:\/\/linux.die.net\/man\/2\/fsync\">fsync<\/a> or perhaps <a href=\"https:\/\/linux.die.net\/man\/2\/msync\">msync<\/a> in that you can first freely lob items at membase and verify that it\u2019s accepted them at the lowest level of availability. When you have stored a set of critical items, you can then issue a <code>sync<\/code> command with the set of your critical keys and required durability level and the server will block until this level is achieved (or something happens that prevents us from doing so).<\/p>\n<p>There were discussions about different semantics (such as a fully-sync\u2019d mode or a specific <code>set+sync<\/code> type command). While a single <code>set+sync<\/code> command would be one fewer round trip than doing a separate <code>set<\/code> and <code>sync<\/code>, it makes little difference in practice since the typical effect of a <code>sync<\/code> command is a delay. This, however, comes at the cost of making it very difficult to do any sort of practical batching or pipelining. One can sync after every command, after a large batch, or on select items from within a large batch.<\/p>\n<h4>What can you Sync On?<\/h4>\n<p>The specification permits a given set of keys to be monitored for one of the following state changes:<\/p>\n<ol>\n<li>Wait for Replication<\/li>\n<li>Wait for Persistence<\/li>\n<li>Wait for Replication <em>and<\/em> Persistence<\/li>\n<li>Wait for Replication <em>or<\/em> Persistence<\/li>\n<li>Wait for Mutation<\/li>\n<\/ol>\n<p>There\u2019s also space for a lightly discussed \u201cany vs. all\u201d flag for the keys where you can hand the server a set of keys and be informed as soon as any one of them changes to the desired state instead of waiting for all of them.<\/p>\n<h4>Example<\/h4>\n<p>Given a giant sack of items, with a mix of important items (want stored) and really important items (must guarantee are stored before returning), let\u2019s do the right thing.<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace;\"><span style=\"color: #ff7700; font-weight: bold;\">def<\/span> store_stuff<span style=\"color: black;\">(<\/span>items<span style=\"color: black;\">)<\/span>:<br \/>\n<span style=\"color: #483d8b;\">&#8220;&#8221;&#8221;Store a collection of items.<\/p>\n<p>Items will be stored asynchronously, then important items<br \/>\nwill be synchronized on before returning.&#8221;&#8221;&#8221;<\/span><br \/>\nimportant <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: black;\">[<\/span><span style=\"color: black;\">]<\/span><br \/>\n<span style=\"color: #ff7700; font-weight: bold;\">for<\/span> i <span style=\"color: #ff7700; font-weight: bold;\">in<\/span> items:<br \/>\nmc.<span style=\"color: #008000;\">set<\/span><span style=\"color: black;\">(<\/span>i.<span style=\"color: black;\">key<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">exp<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">flags<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">value<\/span><span style=\"color: black;\">)<\/span><br \/>\n<span style=\"color: #ff7700; font-weight: bold;\">if<\/span> i.<span style=\"color: black;\">important<\/span>:<br \/>\nimportant.<span style=\"color: black;\">append<\/span><span style=\"color: black;\">(<\/span>i<span style=\"color: black;\">)<\/span><\/p>\n<p>mc.<span style=\"color: black;\">sync_replication_or_persistence<\/span><span style=\"color: black;\">(<\/span>important<span style=\"color: black;\">)<\/span><\/div>\n<\/div>\n<p>(note that a python client supports these features, but not <em>exactly<\/em> with this API, but this should give you the basic idea)<\/p>\n<p>Similarly, one can rate limit inserts such that items don\u2019t go in faster than they can be written to disk.<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace;\"><span style=\"color: #ff7700; font-weight: bold;\">def<\/span> store_stuff_slowly<span style=\"color: black;\">(<\/span>items<span style=\"color: #66cc66;\">,<\/span> sync_every<span style=\"color: #66cc66;\">=<\/span><span style=\"color: #ff4500;\">1000<\/span><span style=\"color: black;\">)<\/span>:<br \/>\n<span style=\"color: #483d8b;\">&#8220;&#8221;&#8221;Store a collection of items without building a large<br \/>\nreplication backlog.&#8221;&#8221;&#8221;<\/span><\/p>\n<p><span style=\"color: #ff7700; font-weight: bold;\">for<\/span> n<span style=\"color: #66cc66;\">,<\/span> i <span style=\"color: #ff7700; font-weight: bold;\">in<\/span> <span style=\"color: #008000;\">enumerate<\/span><span style=\"color: black;\">(<\/span>items<span style=\"color: #66cc66;\">,<\/span> <span style=\"color: #ff4500;\">1<\/span><span style=\"color: black;\">)<\/span>:<br \/>\nmc.<span style=\"color: #008000;\">set<\/span><span style=\"color: black;\">(<\/span>i.<span style=\"color: black;\">key<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">exp<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">flags<\/span><span style=\"color: #66cc66;\">,<\/span> i.<span style=\"color: black;\">value<\/span><span style=\"color: black;\">)<\/span><br \/>\n<span style=\"color: #ff7700; font-weight: bold;\">if<\/span> <span style=\"color: black;\">(<\/span>n % sync_every<span style=\"color: black;\">)<\/span> <span style=\"color: #66cc66;\">==<\/span> <span style=\"color: #ff4500;\">0<\/span>:<br \/>\nmc.<span style=\"color: black;\">sync_replication<\/span><span style=\"color: black;\">(<\/span>i<span style=\"color: black;\">)<\/span><\/div>\n<\/div>\n<p>Every <code>sync_every<\/code> item (default 1000) waits for synchronization to catch up. Setting <code>sync_every<\/code> to one would cause us fully synchronize every item.<\/p>\n<h3>Touch<\/h3>\n<p>We have heard from quite a few projects owners that they\u2019d like the ability to have items with a sliding window of expiration. For example, instead of having an item expire after five minutes of mutating (which is how you specify an object\u2019s time-to-live today), we\u2019d like it to expire after five minutes of inactivity.<\/p>\n<p>If you\u2019re familiar with LRU caches (such as memcached), you should note that this is semantically quite different from LRU. With an LRU, we effectively don\u2019t care about old data. The use cases for <code>touch<\/code> require us to actively disable access to inactive data on a user-defined schedule.<\/p>\n<p>The <code>touch<\/code> command can be used to adjust expiration on an existing key without touching the value. It uses the same type of expiration definition all mutation commands use, but doesn\u2019t actually touch the data.<\/p>\n<p>Similar to <code>touch<\/code> we added a <code>gat<\/code> (<code>get-and-touch<\/code>) command that returns the data and adjusts the expiration at the same time. For most use cases, <code>gat<\/code> is probably more appropriate than <code>touch<\/code>, but it really depends on how you build your application.<\/p>\n<h4>Example Usage<\/h4>\n<p>Usage of <code>touch<\/code> and <code>gat<\/code> are pretty straightforward. A really common pattern might be storing session data where we want \u201cidle\u201d data to be removed quickly, but active data to stick around as long as it\u2019s active.<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace;\"><span style=\"color: #ff7700; font-weight: bold;\">def<\/span> get_session<span style=\"color: black;\">(<\/span>session_id<span style=\"color: #66cc66;\">,<\/span> max_session_age<span style=\"color: #66cc66;\">=<\/span><span style=\"color: #ff4500;\">300<\/span><span style=\"color: black;\">)<\/span>:<br \/>\n<span style=\"color: #483d8b;\">&#8220;&#8221;&#8221;Get a valid session object for the given session ID.<\/p>\n<p>Sessions will only live for five minutes.<br \/>\nUnauthenticated will be thrown if the session<br \/>\ncan not be loaded.&#8221;&#8221;&#8221;<\/span><br \/>\ns <span style=\"color: #66cc66;\">=<\/span> mc.<span style=\"color: black;\">gat<\/span><span style=\"color: black;\">(<\/span>session_id<span style=\"color: #66cc66;\">,<\/span> max_session_age<span style=\"color: black;\">)<\/span><br \/>\n<span style=\"color: #ff7700; font-weight: bold;\">if<\/span> <span style=\"color: #ff7700; font-weight: bold;\">not<\/span> s:<br \/>\nthrow Unauthenticated<span style=\"color: black;\">(<\/span><span style=\"color: black;\">)<\/span><br \/>\n<span style=\"color: #ff7700; font-weight: bold;\">return<\/span> s<\/div>\n<\/div>\n<p>This example showed a simple session loader that keeps the session alive and signals mission sessions to another part of the application stack that can deal with logins and stuff.<\/p>\n<h4>Availability<\/h4>\n<p>We\u2019ve been using this stuff, but we haven\u2019t yet achieved universal availability.<\/p>\n<h3>Servers<\/h3>\n<p><a href=\"https:\/\/www.couchbase.org\/products\/membase\/1-7-beta\">Membase 1.7<\/a> provides this full <code>touch<\/code> and <code>gat<\/code> functionality and partial <code>sync<\/code> functionality.<\/p>\n<p>For <code>sync<\/code>, only waiting for replication is supported, and only a single replica. The protocol allows for the tracking of up to 16 replicas, but membase as a cluster uses transitive replication so it\u2019s not possible to track when the second replica is complete from the primary host (much less the sixteenth!).<\/p>\n<p>Similarly, we\u2019ve written most of the code for syncing on persistence, but before our 2.0 storage strategies, we thing it could be more harmful than useful in most applications. Even with our 2.0 strategies, it\u2019s likely that it\u2019s not as appropriate as replication tracking for all but the absolutely most important data.<\/p>\n<p>Memcached 1.6(ish) has support for <code>touch<\/code> and <code>gat<\/code> in the default engine (which also ships in Membase).<\/p>\n<h3>Clients<\/h3>\n<p>In addition to <code>mc_bin_client.py<\/code> (which is a sort of reference\/playground client that ships with membase and we write many of the tools with), we\u2019ve got support in two clients yet, but we\u2019re considering the feature \u201cevolving\u201d as we\u2019re trying to find the best way to do it. Feedback is far more than welcome!<\/p>\n<h4>Java<\/h4>\n<p>spymemcached 2.7 has support for <code>touch<\/code>, <code>gat<\/code>, and <code>sync<\/code>.<\/p>\n<h4>C Sharp<\/h4>\n<p>The enyim C# client for memcached has support for <code>touch<\/code>, <code>gat<\/code>, and <code>sync<\/code> in a release that should hit the shelves quite soon.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[This post also appears on Dustin&#8217;s github blog.] We built a couple of new protocol operations for people building applications. The general goal of adding an operation is to keep it orthogonal to other commands while enhancing the functionality in [&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-1720","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>New Operations in Membase - 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\/ko\/new-operations-membase\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"New Operations in Membase\" \/>\n<meta property=\"og:description\" content=\"[This post also appears on Dustin&#8217;s github blog.] We built a couple of new protocol operations for people building applications. The general goal of adding an operation is to keep it orthogonal to other commands while enhancing the functionality in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/ko\/new-operations-membase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T18:57:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-05-03T18:23:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/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=\"6\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/\"},\"author\":{\"name\":\"Dustin Sallings, Chief Architect, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/e68b6f4489072ef4a84f60bc437c07d0\"},\"headline\":\"New Operations in Membase\",\"datePublished\":\"2014-12-16T18:57:02+00:00\",\"dateModified\":\"2017-05-03T18:23:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/\"},\"wordCount\":1182,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/\",\"name\":\"New Operations in Membase - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T18:57:02+00:00\",\"dateModified\":\"2017-05-03T18:23:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/new-operations-membase\\\/#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\\\/new-operations-membase\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"New Operations in Membase\"}]},{\"@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\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@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\":\"ko-KR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=gc5bddc8d7dab8b5c9121282556b0dbff\",\"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\\\/ko\\\/author\\\/dustin-sallings\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"New Operations in Membase - 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\/ko\/new-operations-membase\/","og_locale":"ko_KR","og_type":"article","og_title":"New Operations in Membase","og_description":"[This post also appears on Dustin&#8217;s github blog.] We built a couple of new protocol operations for people building applications. The general goal of adding an operation is to keep it orthogonal to other commands while enhancing the functionality in [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/ko\/new-operations-membase\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T18:57:02+00:00","article_modified_time":"2017-05-03T18:23:45+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Dustin Sallings, Chief Architect, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dustin Sallings, Chief Architect, Couchbase","Est. reading time":"6\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/"},"author":{"name":"Dustin Sallings, Chief Architect, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0"},"headline":"New Operations in Membase","datePublished":"2014-12-16T18:57:02+00:00","dateModified":"2017-05-03T18:23:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/"},"wordCount":1182,"commentCount":2,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Uncategorized"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/","url":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/","name":"New Operations in Membase - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T18:57:02+00:00","dateModified":"2017-05-03T18:23:45+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/new-operations-membase\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/new-operations-membase\/#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\/new-operations-membase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"New Operations in Membase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","description":"NoSQL \ub370\uc774\ud130\ubca0\uc774\uc2a4, Couchbase","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":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@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":"\ub354\uc2a4\ud2f4 \uc0b4\ub9c1\uc2a4, \uc218\uc11d \uc544\ud0a4\ud14d\ud2b8, \uce74\uc6b0\uce58\ubca0\uc774\uc2a4","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=gc5bddc8d7dab8b5c9121282556b0dbff","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\/ko\/author\/dustin-sallings\/"}]}},"acf":[],"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","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/1720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/comments?post=1720"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/1720\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media?parent=1720"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/categories?post=1720"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/tags?post=1720"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/ppma_author?post=1720"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}