1824 lines
102 KiB
HTML
1824 lines
102 KiB
HTML
<!DOCTYPE html>
|
|
<html class='v2' dir='ltr' lang='en'>
|
|
<head>
|
|
<link href='https://www.blogger.com/static/v1/widgets/2872013778-css_bundle_v2.css' rel='stylesheet' type='text/css'/>
|
|
<meta content='width=1100' name='viewport'/>
|
|
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
|
|
<meta content='blogger' name='generator'/>
|
|
<link href='http://dbmsmusings.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/>
|
|
<link href='http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html' rel='canonical'/>
|
|
<link rel="alternate" type="application/atom+xml" title="DBMS Musings - Atom" href="http://dbmsmusings.blogspot.com/feeds/posts/default" />
|
|
<link rel="alternate" type="application/rss+xml" title="DBMS Musings - RSS" href="http://dbmsmusings.blogspot.com/feeds/posts/default?alt=rss" />
|
|
<link rel="service.post" type="application/atom+xml" title="DBMS Musings - Atom" href="https://www.blogger.com/feeds/8899645800948009496/posts/default" />
|
|
|
|
<link rel="alternate" type="application/atom+xml" title="DBMS Musings - Atom" href="http://dbmsmusings.blogspot.com/feeds/190191398605973736/comments/default" />
|
|
<!--Can't find substitution for tag [blog.ieCssRetrofitLinks]-->
|
|
<meta content='http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html' property='og:url'/>
|
|
<meta content='Replication and the latency-consistency tradeoff' property='og:title'/>
|
|
<meta content='As 24/7 availability becomes increasingly important for modern applications, database systems are frequently replicated in order to stay up ...' property='og:description'/>
|
|
<title>DBMS Musings: Replication and the latency-consistency tradeoff</title>
|
|
<style id='page-skin-1' type='text/css'><!--
|
|
/*
|
|
-----------------------------------------------
|
|
Blogger Template Style
|
|
Name: Ethereal
|
|
Designer: Jason Morrow
|
|
URL: jasonmorrow.etsy.com
|
|
----------------------------------------------- */
|
|
/* Content
|
|
----------------------------------------------- */
|
|
body {
|
|
font: normal normal 13px Arial, Tahoma, Helvetica, FreeSans, sans-serif;
|
|
color: #666666;
|
|
background: #fb5e53 url(https://resources.blogblog.com/blogblog/data/1kt/ethereal/birds-2toned-bg.png) repeat-x scroll top center;
|
|
}
|
|
html body .content-outer {
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
width: 100%;
|
|
}
|
|
a:link {
|
|
text-decoration: none;
|
|
color: #2198a6;
|
|
}
|
|
a:visited {
|
|
text-decoration: none;
|
|
color: #4d469c;
|
|
}
|
|
a:hover {
|
|
text-decoration: underline;
|
|
color: #2198a6;
|
|
}
|
|
.main-inner {
|
|
padding-top: 15px;
|
|
}
|
|
.body-fauxcolumn-outer {
|
|
background: transparent none repeat-x scroll top center;
|
|
}
|
|
.content-fauxcolumns .fauxcolumn-inner {
|
|
background: #ffffff url(https://resources.blogblog.com/blogblog/data/1kt/ethereal/bird-2toned-blue-fade.png) repeat-x scroll top left;
|
|
border-left: 1px solid #fb5e53;
|
|
border-right: 1px solid #fb5e53;
|
|
}
|
|
/* Flexible Background
|
|
----------------------------------------------- */
|
|
.content-fauxcolumn-outer .fauxborder-left {
|
|
width: 100%;
|
|
padding-left: 300px;
|
|
margin-left: -300px;
|
|
background-color: transparent;
|
|
background-image: url(//themes.googleusercontent.com/image?id=0BwVBOzw_-hbMNjViMzQ0ZDEtMWU1NS00ZTBkLWFjY2EtZjM5YmU4OTA2MjBm);
|
|
background-repeat: no-repeat;
|
|
background-position: left top;
|
|
}
|
|
.content-fauxcolumn-outer .fauxborder-right {
|
|
margin-right: -299px;
|
|
width: 299px;
|
|
background-color: transparent;
|
|
background-image: url(//themes.googleusercontent.com/image?id=0BwVBOzw_-hbMNjViMzQ0ZDEtMWU1NS00ZTBkLWFjY2EtZjM5YmU4OTA2MjBm);
|
|
background-repeat: no-repeat;
|
|
background-position: right top;
|
|
}
|
|
/* Columns
|
|
----------------------------------------------- */
|
|
.content-inner {
|
|
padding: 0;
|
|
}
|
|
/* Header
|
|
----------------------------------------------- */
|
|
.header-inner {
|
|
padding: 27px 0 3px;
|
|
}
|
|
.header-inner .section {
|
|
margin: 0 35px;
|
|
}
|
|
.Header h1 {
|
|
font: normal normal 60px Times, 'Times New Roman', FreeSerif, serif;
|
|
color: #ff8b8b;
|
|
}
|
|
.Header h1 a {
|
|
color: #ff8b8b;
|
|
}
|
|
.Header .description {
|
|
font-size: 115%;
|
|
color: #666666;
|
|
}
|
|
.header-inner .Header .titlewrapper,
|
|
.header-inner .Header .descriptionwrapper {
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
margin-bottom: 0;
|
|
}
|
|
/* Tabs
|
|
----------------------------------------------- */
|
|
.tabs-outer {
|
|
position: relative;
|
|
background: transparent;
|
|
}
|
|
.tabs-cap-top, .tabs-cap-bottom {
|
|
position: absolute;
|
|
width: 100%;
|
|
}
|
|
.tabs-cap-bottom {
|
|
bottom: 0;
|
|
}
|
|
.tabs-inner {
|
|
padding: 0;
|
|
}
|
|
.tabs-inner .section {
|
|
margin: 0 35px;
|
|
}
|
|
*+html body .tabs-inner .widget li {
|
|
padding: 1px;
|
|
}
|
|
.PageList {
|
|
border-bottom: 1px solid #fb5e53;
|
|
}
|
|
.tabs-inner .widget li.selected a,
|
|
.tabs-inner .widget li a:hover {
|
|
position: relative;
|
|
-moz-border-radius-topleft: 5px;
|
|
-moz-border-radius-topright: 5px;
|
|
-webkit-border-top-left-radius: 5px;
|
|
-webkit-border-top-right-radius: 5px;
|
|
-goog-ms-border-top-left-radius: 5px;
|
|
-goog-ms-border-top-right-radius: 5px;
|
|
border-top-left-radius: 5px;
|
|
border-top-right-radius: 5px;
|
|
background: #ffa183 none ;
|
|
color: #ffffff;
|
|
}
|
|
.tabs-inner .widget li a {
|
|
display: inline-block;
|
|
margin: 0;
|
|
margin-right: 1px;
|
|
padding: .65em 1.5em;
|
|
font: normal normal 12px Arial, Tahoma, Helvetica, FreeSans, sans-serif;
|
|
color: #666666;
|
|
background-color: #ffdfc7;
|
|
-moz-border-radius-topleft: 5px;
|
|
-moz-border-radius-topright: 5px;
|
|
-webkit-border-top-left-radius: 5px;
|
|
-webkit-border-top-right-radius: 5px;
|
|
-goog-ms-border-top-left-radius: 5px;
|
|
-goog-ms-border-top-right-radius: 5px;
|
|
border-top-left-radius: 5px;
|
|
border-top-right-radius: 5px;
|
|
}
|
|
/* Headings
|
|
----------------------------------------------- */
|
|
h2 {
|
|
font: normal bold 12px Arial, Tahoma, Helvetica, FreeSans, sans-serif;
|
|
color: #666666;
|
|
}
|
|
/* Widgets
|
|
----------------------------------------------- */
|
|
.main-inner .column-left-inner {
|
|
padding: 0 0 0 20px;
|
|
}
|
|
.main-inner .column-left-inner .section {
|
|
margin-right: 0;
|
|
}
|
|
.main-inner .column-right-inner {
|
|
padding: 0 20px 0 0;
|
|
}
|
|
.main-inner .column-right-inner .section {
|
|
margin-left: 0;
|
|
}
|
|
.main-inner .section {
|
|
padding: 0;
|
|
}
|
|
.main-inner .widget {
|
|
padding: 0 0 15px;
|
|
margin: 20px 0;
|
|
border-bottom: 1px solid #dbdbdb;
|
|
}
|
|
.main-inner .widget h2 {
|
|
margin: 0;
|
|
padding: .6em 0 .5em;
|
|
}
|
|
.footer-inner .widget h2 {
|
|
padding: 0 0 .4em;
|
|
}
|
|
.main-inner .widget h2 + div, .footer-inner .widget h2 + div {
|
|
padding-top: 15px;
|
|
}
|
|
.main-inner .widget .widget-content {
|
|
margin: 0;
|
|
padding: 15px 0 0;
|
|
}
|
|
.main-inner .widget ul, .main-inner .widget #ArchiveList ul.flat {
|
|
margin: -15px -15px -15px;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
.main-inner .sidebar .widget h2 {
|
|
border-bottom: 1px solid #dbdbdb;
|
|
}
|
|
.main-inner .widget #ArchiveList {
|
|
margin: -15px 0 0;
|
|
}
|
|
.main-inner .widget ul li, .main-inner .widget #ArchiveList ul.flat li {
|
|
padding: .5em 15px;
|
|
text-indent: 0;
|
|
}
|
|
.main-inner .widget #ArchiveList ul li {
|
|
padding-top: .25em;
|
|
padding-bottom: .25em;
|
|
}
|
|
.main-inner .widget ul li:first-child, .main-inner .widget #ArchiveList ul.flat li:first-child {
|
|
border-top: none;
|
|
}
|
|
.main-inner .widget ul li:last-child, .main-inner .widget #ArchiveList ul.flat li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.main-inner .widget .post-body ul {
|
|
padding: 0 2.5em;
|
|
margin: .5em 0;
|
|
list-style: disc;
|
|
}
|
|
.main-inner .widget .post-body ul li {
|
|
padding: 0.25em 0;
|
|
margin-bottom: .25em;
|
|
color: #666666;
|
|
border: none;
|
|
}
|
|
.footer-inner .widget ul {
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
.widget .zippy {
|
|
color: #cccccc;
|
|
}
|
|
/* Posts
|
|
----------------------------------------------- */
|
|
.main.section {
|
|
margin: 0 20px;
|
|
}
|
|
body .main-inner .Blog {
|
|
padding: 0;
|
|
background-color: transparent;
|
|
border: none;
|
|
}
|
|
.main-inner .widget h2.date-header {
|
|
border-bottom: 1px solid #dbdbdb;
|
|
}
|
|
.date-outer {
|
|
position: relative;
|
|
margin: 15px 0 20px;
|
|
}
|
|
.date-outer:first-child {
|
|
margin-top: 0;
|
|
}
|
|
.date-posts {
|
|
clear: both;
|
|
}
|
|
.post-outer, .inline-ad {
|
|
border-bottom: 1px solid #dbdbdb;
|
|
padding: 30px 0;
|
|
}
|
|
.post-outer {
|
|
padding-bottom: 10px;
|
|
}
|
|
.post-outer:first-child {
|
|
padding-top: 0;
|
|
border-top: none;
|
|
}
|
|
.post-outer:last-child, .inline-ad:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.post-body img {
|
|
padding: 8px;
|
|
}
|
|
h3.post-title, h4 {
|
|
font: normal normal 24px Times, Times New Roman, serif;
|
|
color: #2198a6;
|
|
}
|
|
h3.post-title a {
|
|
font: normal normal 24px Times, Times New Roman, serif;
|
|
color: #2198a6;
|
|
text-decoration: none;
|
|
}
|
|
h3.post-title a:hover {
|
|
color: #2198a6;
|
|
text-decoration: underline;
|
|
}
|
|
.post-header {
|
|
margin: 0 0 1.5em;
|
|
}
|
|
.post-body {
|
|
line-height: 1.4;
|
|
}
|
|
.post-footer {
|
|
margin: 1.5em 0 0;
|
|
}
|
|
#blog-pager {
|
|
padding: 15px;
|
|
}
|
|
.blog-feeds, .post-feeds {
|
|
margin: 1em 0;
|
|
text-align: center;
|
|
}
|
|
.post-outer .comments {
|
|
margin-top: 2em;
|
|
}
|
|
/* Comments
|
|
----------------------------------------------- */
|
|
.comments .comments-content .icon.blog-author {
|
|
background-repeat: no-repeat;
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==);
|
|
}
|
|
.comments .comments-content .loadmore a {
|
|
background: #ffffff url(https://resources.blogblog.com/blogblog/data/1kt/ethereal/bird-2toned-blue-fade.png) repeat-x scroll top left;
|
|
}
|
|
.comments .comments-content .loadmore a {
|
|
border-top: 1px solid #dbdbdb;
|
|
border-bottom: 1px solid #dbdbdb;
|
|
}
|
|
.comments .comment-thread.inline-thread {
|
|
background: #ffffff url(https://resources.blogblog.com/blogblog/data/1kt/ethereal/bird-2toned-blue-fade.png) repeat-x scroll top left;
|
|
}
|
|
.comments .continue {
|
|
border-top: 2px solid #dbdbdb;
|
|
}
|
|
/* Footer
|
|
----------------------------------------------- */
|
|
.footer-inner {
|
|
padding: 30px 0;
|
|
overflow: hidden;
|
|
}
|
|
/* Mobile
|
|
----------------------------------------------- */
|
|
body.mobile {
|
|
background-size: auto
|
|
}
|
|
.mobile .body-fauxcolumn-outer {
|
|
background: ;
|
|
}
|
|
.mobile .content-fauxcolumns .fauxcolumn-inner {
|
|
opacity: 0.75;
|
|
}
|
|
.mobile .content-fauxcolumn-outer .fauxborder-right {
|
|
margin-right: 0;
|
|
}
|
|
.mobile-link-button {
|
|
background-color: #ffa183;
|
|
}
|
|
.mobile-link-button a:link, .mobile-link-button a:visited {
|
|
color: #ffffff;
|
|
}
|
|
.mobile-index-contents {
|
|
color: #444444;
|
|
}
|
|
.mobile .body-fauxcolumn-outer {
|
|
background-size: 100% auto;
|
|
}
|
|
.mobile .mobile-date-outer {
|
|
border-bottom: transparent;
|
|
}
|
|
.mobile .PageList {
|
|
border-bottom: none;
|
|
}
|
|
.mobile .tabs-inner .section {
|
|
margin: 0;
|
|
}
|
|
.mobile .tabs-inner .PageList .widget-content {
|
|
background: #ffa183 none;
|
|
color: #ffffff;
|
|
}
|
|
.mobile .tabs-inner .PageList .widget-content .pagelist-arrow {
|
|
border-left: 1px solid #ffffff;
|
|
}
|
|
.mobile .footer-inner {
|
|
overflow: visible;
|
|
}
|
|
body.mobile .AdSense {
|
|
margin: 0 -10px;
|
|
}
|
|
|
|
--></style>
|
|
<style id='template-skin-1' type='text/css'><!--
|
|
body {
|
|
min-width: 1310px;
|
|
}
|
|
.content-outer, .content-fauxcolumn-outer, .region-inner {
|
|
min-width: 1310px;
|
|
max-width: 1310px;
|
|
_width: 1310px;
|
|
}
|
|
.main-inner .columns {
|
|
padding-left: 0;
|
|
padding-right: 350px;
|
|
}
|
|
.main-inner .fauxcolumn-center-outer {
|
|
left: 0;
|
|
right: 350px;
|
|
/* IE6 does not respect left and right together */
|
|
_width: expression(this.parentNode.offsetWidth -
|
|
parseInt("0") -
|
|
parseInt("350px") + 'px');
|
|
}
|
|
.main-inner .fauxcolumn-left-outer {
|
|
width: 0;
|
|
}
|
|
.main-inner .fauxcolumn-right-outer {
|
|
width: 350px;
|
|
}
|
|
.main-inner .column-left-outer {
|
|
width: 0;
|
|
right: 100%;
|
|
margin-left: -0;
|
|
}
|
|
.main-inner .column-right-outer {
|
|
width: 350px;
|
|
margin-right: -350px;
|
|
}
|
|
#layout {
|
|
min-width: 0;
|
|
}
|
|
#layout .content-outer {
|
|
min-width: 0;
|
|
width: 800px;
|
|
}
|
|
#layout .region-inner {
|
|
min-width: 0;
|
|
width: auto;
|
|
}
|
|
body#layout div.add_widget {
|
|
padding: 8px;
|
|
}
|
|
body#layout div.add_widget a {
|
|
margin-left: 32px;
|
|
}
|
|
--></style>
|
|
<!-- Google tag (gtag.js) -->
|
|
<script async='true' src='https://www.googletagmanager.com/gtag/js?id=G-WPSPKTZ8VQ'></script>
|
|
<script>
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
gtag('config', 'G-WPSPKTZ8VQ');
|
|
</script>
|
|
<link href='https://www.blogger.com/dyncss/8899645800948009496/authorization.css?zx=64628a2a-8581-41e2-b103-b6627e610902' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyncss/8899645800948009496/authorization.css?zx=64628a2a-8581-41e2-b103-b6627e610902' rel='stylesheet'/></noscript>
|
|
<meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/>
|
|
<meta name='google-adsense-platform-domain' content='blogspot.com'/>
|
|
|
|
</head>
|
|
<body class='loading variant-hummingBirds2'>
|
|
<div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript">
|
|
function setAttributeOnload(object, attribute, val) {
|
|
if(window.addEventListener) {
|
|
window.addEventListener('load',
|
|
function(){ object[attribute] = val; }, false);
|
|
} else {
|
|
window.attachEvent('onload', function(){ object[attribute] = val; });
|
|
}
|
|
}
|
|
</script>
|
|
<div id="navbar-iframe-container"></div>
|
|
<script type="text/javascript" src="https://apis.google.com/js/platform.js"></script>
|
|
<script type="text/javascript">
|
|
gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() {
|
|
if (gapi.iframes && gapi.iframes.getContext) {
|
|
gapi.iframes.getContext().openChild({
|
|
url: 'https://www.blogger.com/navbar/8899645800948009496?po\x3d190191398605973736\x26origin\x3dhttp://dbmsmusings.blogspot.com',
|
|
where: document.getElementById("navbar-iframe-container"),
|
|
id: "navbar-iframe"
|
|
});
|
|
}
|
|
});
|
|
</script><script type="text/javascript">
|
|
(function() {
|
|
var script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js';
|
|
var head = document.getElementsByTagName('head')[0];
|
|
if (head) {
|
|
head.appendChild(script);
|
|
}})();
|
|
</script>
|
|
</div></div>
|
|
<div class='body-fauxcolumns'>
|
|
<div class='fauxcolumn-outer body-fauxcolumn-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='content'>
|
|
<div class='content-fauxcolumns'>
|
|
<div class='fauxcolumn-outer content-fauxcolumn-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='content-outer'>
|
|
<div class='content-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left content-fauxborder-left'>
|
|
<div class='fauxborder-right content-fauxborder-right'></div>
|
|
<div class='content-inner'>
|
|
<header>
|
|
<div class='header-outer'>
|
|
<div class='header-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left header-fauxborder-left'>
|
|
<div class='fauxborder-right header-fauxborder-right'></div>
|
|
<div class='region-inner header-inner'>
|
|
<div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'>
|
|
<div id='header-inner'>
|
|
<div class='titlewrapper'>
|
|
<h1 class='title'>
|
|
<a href='http://dbmsmusings.blogspot.com/'>
|
|
DBMS Musings
|
|
</a>
|
|
</h1>
|
|
</div>
|
|
<div class='descriptionwrapper'>
|
|
<p class='description'><span>
|
|
</span></p>
|
|
</div>
|
|
</div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='header-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div class='tabs-outer'>
|
|
<div class='tabs-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left tabs-fauxborder-left'>
|
|
<div class='fauxborder-right tabs-fauxborder-right'></div>
|
|
<div class='region-inner tabs-inner'>
|
|
<div class='tabs no-items section' id='crosscol' name='Cross-Column'></div>
|
|
<div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div>
|
|
</div>
|
|
</div>
|
|
<div class='tabs-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='main-outer'>
|
|
<div class='main-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left main-fauxborder-left'>
|
|
<div class='fauxborder-right main-fauxborder-right'></div>
|
|
<div class='region-inner main-inner'>
|
|
<div class='columns fauxcolumns'>
|
|
<div class='fauxcolumn-outer fauxcolumn-center-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='fauxcolumn-outer fauxcolumn-left-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='fauxcolumn-outer fauxcolumn-right-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<!-- corrects IE6 width calculation -->
|
|
<div class='columns-inner'>
|
|
<div class='column-center-outer'>
|
|
<div class='column-center-inner'>
|
|
<div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'>
|
|
<div class='blog-posts hfeed'>
|
|
|
|
<div class="date-outer">
|
|
|
|
<h2 class='date-header'><span>Wednesday, December 7, 2011</span></h2>
|
|
|
|
<div class="date-posts">
|
|
|
|
<div class='post-outer'>
|
|
<div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'>
|
|
<meta content='8899645800948009496' itemprop='blogId'/>
|
|
<meta content='190191398605973736' itemprop='postId'/>
|
|
<a name='190191398605973736'></a>
|
|
<h3 class='post-title entry-title' itemprop='name'>
|
|
Replication and the latency-consistency tradeoff
|
|
</h3>
|
|
<div class='post-header'>
|
|
<div class='post-header-line-1'></div>
|
|
</div>
|
|
<div class='post-body entry-content' id='post-body-190191398605973736' itemprop='description articleBody'>
|
|
<div>As 24/7 availability becomes increasingly important for modern applications, database systems are frequently replicated in order to stay up and running in the face of database server failure. It is no longer acceptable for an application to wait for a database to recover from a log on disk --- most mission-critical applications need immediate failover to a replica.</div><div><br /></div><div>There are several important tradeoffs to consider when it comes to system design for replicated database systems. The most famous one is CAP --- you have to trade off consistency vs. availability in the event of a network partition. In this post, I will go into detail about a lesser-known but equally important tradeoff --- between latency and consistency. Unlike CAP, where consistency and availability are only traded off in the event of a network partition, the latency vs. consistency tradeoff is present even during normal operations of the system. (Note: the latency-consistency tradeoff discussed in this post is the same as the "ELC" case in my <a href="http://dbmsmusings.blogspot.com/2010/04/problems-with-cap-and-yahoos-little.html">PACELC post</a>).</div><div><br /></div><div>The intuition behind the tradeoff is the following: there's no way to perform consistent replication across database replicas without some level of synchronous network communication. This communication takes time and introduces latency. For replicas that are physically close to each other (e.g., on the same switch), this latency is not necessarily onerous. But replication over a WAN will introduce significant latency.</div><div><br /></div><div>The rest of this post adds more meat to the above intuition. I will discuss several general techniques for performing replication, and show how each technique trades off latency or consistency. I will then discuss several modern implementations of distributed database systems and show how they fit into the general replication techniques that are outlined in this post.</div><div><br /></div>There are only three alternatives for implementing replication (each with several variations): (1) data updates are sent to all replicas at the same time, (2) data updates are sent to an agreed upon master node first, or (3) data updates are sent to a single (arbitrary) node first. Each of these three cases can be implemented in various ways; however each implementation comes with a consistency-latency tradeoff. This is described in detail below.<div><br /><ol><li><b>Data updates are sent to all replicas at the same time</b>. If updates are not first passed through a preprocessing layer or some other agreement protocol, replica divergence (a clear lack of consistency) could ensue (assuming there are multiple updates to the system that are submitted concurrently, e.g., from different clients), since each replica might choose a different order with which to apply the updates . On the other hand, if updates are first passed through a preprocessing layer, or all nodes involved in the write use an agreement protocol to decide on the order of operations, then it is possible to ensure that all replicas will agree on the order in which to process the updates, but this leads to several sources of increased latency. For the case of the agreement protocol, the protocol itself is the additional source of latency. For the case of the preprocessor, the additional sources of latency are:<br /><ol type="a"><br /><li>Routing updates through an additional system component (the preprocessor) increases latency</li><br /><li>The preprocessor either consists of multiple machines or a single machine. If it consists of multiple machines, an agreement protocol to decide on operation ordering is still needed across machines. Alternatively, if it runs on a single machine, all updates, no matter where they are initiated (potentially anywhere in the world) are forced to route all the way to the single preprocessor first, even if there is a data replica that is nearer to the update initiation location.</li><br /></ol></li><br /><li><b>Data updates are sent to an agreed upon location first</b> (this location can be dependent on the actual data being updated) --- we will call this the “master node” for a particular data item. This master node resolves all requests to update the same data item, and the order that it picks to perform these updates will determine the order that all replicas perform the updates. After it resolves updates, it replicates them to all replica locations. There are three options for this replication:<br /><ol type="a"><br /><li>The replication is done synchronously, meaning that the master node waits until all updates have made it to the replica(s) before "committing" the update. This ensures that the replicas remain consistent, but synchronous actions across independent entities (especially if this occurs over a WAN) increases latency due to the requirement to pass messages between these entities, and the fact that latency is limited by the speed of the slowest entity.</li><br /><li>The replication is done asynchronously, meaning that the update is treated as if it were completed before it has been replicated. Typically the update has at least made it to stable storage somewhere before the initiator of the update is told that it has completed (in case the master node fails), but there are no guarantees that the update has been propagated to replicas. The consistency-latency tradeoff in this case is dependent on how reads are dealt with:<br /><ol type="i"><li>If all reads are routed to the master node and served from there, then there is no reduction in consistency. However, there are several latency problems with this approach:<br /><ol><li>Even if there is a replica close to the initiator of the read request, the request must still be routed to the master node which could potentially be physically much farther away.</li><br /><li>If the master node is overloaded with other requests or has failed, there is no option to serve the read from a different node. Rather, the request must wait for the master node to become free or recover. In other words, there is a potential for increased latency due to lack of load balancing options.</li></ol></li><br /><li>If reads can be served from any node, read latency is much better, but this can result in inconsistent reads of the same data item, since different locations have different versions of a data item while its updates are still being propagated, and a read can potentially be sent to any of these locations. Although the level of reduced consistency can be bounded by keeping track of update sequence numbers and using them to implement “sequential/timeline consistency” or “read-your-writes consistency”, these options are nonetheless reduced consistency options. Furthermore, write latency can be high if the master for a write operation is geographically far away from the requester of the write.</li></ol></li><br /><li>A combination of (a) and (b) are possible. Updates are sent to some subset of replicas synchronously, and the rest asynchronously. The consistency-latency tradeoff in this case again is determined by how reads are dealt with. If reads are routed to at least one node that had been synchronously updated (e.g. when R + W > N in a quorum protocol, where R is the number of nodes involved in a synchronous read, W is the number of nodes involved in a synchronous write, and N is the number of replicas), then consistency can be preserved, but the latency problems of (a), (b)(i)(1), and (b)(i)(2) are all present (though to somewhat lower degrees, since the number of nodes involved in the synchronization is smaller, and there is potentially more than one node that can serve read requests). If it is possible for reads to be served from nodes that have not been synchronously updated (e.g. when R + W <= N), then inconsistent reads are possible, as in (b)(ii) above .</li></ol><br /></li><li><b>Data updates are sent to an arbitrary location first</b>, the updates are performed there, and are then propagated to the other replicas. The difference between this case and case (2) above is that the location that updates are sent to for a particular data item is not always the same. For example, two different updates for a particular data item can be initiated at two different locations simultaneously. The consistency-latency tradeoff again depends on two options:<br /><ol type="a"><li>If replication is done synchronously, then the latency problems of case (2)(a) above are present. Additionally, extra latency can be incurred in order to detect and resolve cases of simultaneous updates to the same data item initiated at two different locations.</li><br /><li>If replication is done asynchronously, then similar consistency problems as described in case (1) and (2b) above present themselves.</li></ol></ol></div><div><br />Therefore, no matter how the replication is performed, there is a tradeoff between consistency and latency. For carefully controlled replication across short distances, there exists reasonable options (e.g. choice 2(a) above, since network communication latency is small in local data centers); however, for replication over a WAN, there exists no way around the significant consistency-latency tradeoff.</div><div><br />To more fully understand the tradeoff, it is helpful to consider how several well-known distributed systems are placed into the categories outlined above. Dynamo, Riak, and Cassandra choose a combination of (2)(c) and (3) from the replication alternatives described above. In particular, updates generally go to the same node, and are then propagated synchronously to W other nodes (case (2)(c)). Reads are synchronously sent to R nodes with R + W typically being set to a number less than or equal to N, leading to a possibility of inconsistent reads. However, the system does not always send updates to the same node for a particular data item (e.g., this can happen in various failure cases, or due to rerouting by a load balancer), which leads to the situation described in alternative (3) above, and the potentially more substantial types of consistency shortfalls. PNUTS chooses option (2)(b)(ii) above, for excellent latency at reduced consistency. HBase chooses (2) (a) within a cluster, but gives up consistency for lower latency for replication across different clusters (using option (2)(b)).</div><div><br />In conclusion, there are two major reasons to reduce consistency in modern distributed database systems, and only one of them is CAP. Ignoring the consistency-latency tradeoff of replicated systems is a great oversight, since it is present at all times during system operation, whereas CAP is only relevant in the (arguably) rare case of a network partition. In fact, the consistency-latency tradeoff is potentially more significant than CAP, since it has a more direct effect of the baseline operations of modern distributed database systems.<br /></div>
|
|
<div style='clear: both;'></div>
|
|
</div>
|
|
<div class='post-footer'>
|
|
<div class='post-footer-line post-footer-line-1'>
|
|
<span class='post-author vcard'>
|
|
Posted by
|
|
<span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
|
|
<meta content='https://www.blogger.com/profile/16753133043157018521' itemprop='url'/>
|
|
<a class='g-profile' href='https://www.blogger.com/profile/16753133043157018521' rel='author' title='author profile'>
|
|
<span itemprop='name'>Daniel Abadi</span>
|
|
</a>
|
|
</span>
|
|
</span>
|
|
<span class='post-timestamp'>
|
|
at
|
|
<meta content='http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html' itemprop='url'/>
|
|
<a class='timestamp-link' href='http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2011-12-07T20:38:00-08:00'>8:38 PM</abbr></a>
|
|
</span>
|
|
<span class='post-comment-link'>
|
|
</span>
|
|
<span class='post-icons'>
|
|
<span class='item-control blog-admin pid-2045359914'>
|
|
<a href='https://www.blogger.com/post-edit.g?blogID=8899645800948009496&postID=190191398605973736&from=pencil' title='Edit Post'>
|
|
<img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/>
|
|
</a>
|
|
</span>
|
|
</span>
|
|
<div class='post-share-buttons goog-inline-block'>
|
|
<a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=8899645800948009496&postID=190191398605973736&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=8899645800948009496&postID=190191398605973736&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=8899645800948009496&postID=190191398605973736&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=8899645800948009496&postID=190191398605973736&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=8899645800948009496&postID=190191398605973736&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a>
|
|
</div>
|
|
</div>
|
|
<div class='post-footer-line post-footer-line-2'>
|
|
<span class='post-labels'>
|
|
Labels:
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/CAP' rel='tag'>CAP</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/Cassandra' rel='tag'>Cassandra</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/database%20replication' rel='tag'>database replication</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/Dynamo' rel='tag'>Dynamo</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/HBase' rel='tag'>HBase</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/PACELC' rel='tag'>PACELC</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/PNUTS' rel='tag'>PNUTS</a>,
|
|
<a href='http://dbmsmusings.blogspot.com/search/label/Riak' rel='tag'>Riak</a>
|
|
</span>
|
|
</div>
|
|
<div class='post-footer-line post-footer-line-3'>
|
|
<span class='post-location'>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='comments' id='comments'>
|
|
<a name='comments'></a>
|
|
<h4>15 comments:</h4>
|
|
<div class='comments-content'>
|
|
<script async='async' src='' type='text/javascript'></script>
|
|
<script type='text/javascript'>
|
|
(function() {
|
|
var items = null;
|
|
var msgs = null;
|
|
var config = {};
|
|
|
|
// <![CDATA[
|
|
var cursor = null;
|
|
if (items && items.length > 0) {
|
|
cursor = parseInt(items[items.length - 1].timestamp) + 1;
|
|
}
|
|
|
|
var bodyFromEntry = function(entry) {
|
|
var text = (entry &&
|
|
((entry.content && entry.content.$t) ||
|
|
(entry.summary && entry.summary.$t))) ||
|
|
'';
|
|
if (entry && entry.gd$extendedProperty) {
|
|
for (var k in entry.gd$extendedProperty) {
|
|
if (entry.gd$extendedProperty[k].name == 'blogger.contentRemoved') {
|
|
return '<span class="deleted-comment">' + text + '</span>';
|
|
}
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
var parse = function(data) {
|
|
cursor = null;
|
|
var comments = [];
|
|
if (data && data.feed && data.feed.entry) {
|
|
for (var i = 0, entry; entry = data.feed.entry[i]; i++) {
|
|
var comment = {};
|
|
// comment ID, parsed out of the original id format
|
|
var id = /blog-(\d+).post-(\d+)/.exec(entry.id.$t);
|
|
comment.id = id ? id[2] : null;
|
|
comment.body = bodyFromEntry(entry);
|
|
comment.timestamp = Date.parse(entry.published.$t) + '';
|
|
if (entry.author && entry.author.constructor === Array) {
|
|
var auth = entry.author[0];
|
|
if (auth) {
|
|
comment.author = {
|
|
name: (auth.name ? auth.name.$t : undefined),
|
|
profileUrl: (auth.uri ? auth.uri.$t : undefined),
|
|
avatarUrl: (auth.gd$image ? auth.gd$image.src : undefined)
|
|
};
|
|
}
|
|
}
|
|
if (entry.link) {
|
|
if (entry.link[2]) {
|
|
comment.link = comment.permalink = entry.link[2].href;
|
|
}
|
|
if (entry.link[3]) {
|
|
var pid = /.*comments\/default\/(\d+)\?.*/.exec(entry.link[3].href);
|
|
if (pid && pid[1]) {
|
|
comment.parentId = pid[1];
|
|
}
|
|
}
|
|
}
|
|
comment.deleteclass = 'item-control blog-admin';
|
|
if (entry.gd$extendedProperty) {
|
|
for (var k in entry.gd$extendedProperty) {
|
|
if (entry.gd$extendedProperty[k].name == 'blogger.itemClass') {
|
|
comment.deleteclass += ' ' + entry.gd$extendedProperty[k].value;
|
|
} else if (entry.gd$extendedProperty[k].name == 'blogger.displayTime') {
|
|
comment.displayTime = entry.gd$extendedProperty[k].value;
|
|
}
|
|
}
|
|
}
|
|
comments.push(comment);
|
|
}
|
|
}
|
|
return comments;
|
|
};
|
|
|
|
var paginator = function(callback) {
|
|
if (hasMore()) {
|
|
var url = config.feed + '?alt=json&v=2&orderby=published&reverse=false&max-results=50';
|
|
if (cursor) {
|
|
url += '&published-min=' + new Date(cursor).toISOString();
|
|
}
|
|
window.bloggercomments = function(data) {
|
|
var parsed = parse(data);
|
|
cursor = parsed.length < 50 ? null
|
|
: parseInt(parsed[parsed.length - 1].timestamp) + 1
|
|
callback(parsed);
|
|
window.bloggercomments = null;
|
|
}
|
|
url += '&callback=bloggercomments';
|
|
var script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = url;
|
|
document.getElementsByTagName('head')[0].appendChild(script);
|
|
}
|
|
};
|
|
var hasMore = function() {
|
|
return !!cursor;
|
|
};
|
|
var getMeta = function(key, comment) {
|
|
if ('iswriter' == key) {
|
|
var matches = !!comment.author
|
|
&& comment.author.name == config.authorName
|
|
&& comment.author.profileUrl == config.authorUrl;
|
|
return matches ? 'true' : '';
|
|
} else if ('deletelink' == key) {
|
|
return config.baseUri + '/comment/delete/'
|
|
+ config.blogId + '/' + comment.id;
|
|
} else if ('deleteclass' == key) {
|
|
return comment.deleteclass;
|
|
}
|
|
return '';
|
|
};
|
|
|
|
var replybox = null;
|
|
var replyUrlParts = null;
|
|
var replyParent = undefined;
|
|
|
|
var onReply = function(commentId, domId) {
|
|
if (replybox == null) {
|
|
// lazily cache replybox, and adjust to suit this style:
|
|
replybox = document.getElementById('comment-editor');
|
|
if (replybox != null) {
|
|
replybox.height = '250px';
|
|
replybox.style.display = 'block';
|
|
replyUrlParts = replybox.src.split('#');
|
|
}
|
|
}
|
|
if (replybox && (commentId !== replyParent)) {
|
|
replybox.src = '';
|
|
document.getElementById(domId).insertBefore(replybox, null);
|
|
replybox.src = replyUrlParts[0]
|
|
+ (commentId ? '&parentID=' + commentId : '')
|
|
+ '#' + replyUrlParts[1];
|
|
replyParent = commentId;
|
|
}
|
|
};
|
|
|
|
var hash = (window.location.hash || '#').substring(1);
|
|
var startThread, targetComment;
|
|
if (/^comment-form_/.test(hash)) {
|
|
startThread = hash.substring('comment-form_'.length);
|
|
} else if (/^c[0-9]+$/.test(hash)) {
|
|
targetComment = hash.substring(1);
|
|
}
|
|
|
|
// Configure commenting API:
|
|
var configJso = {
|
|
'maxDepth': config.maxThreadDepth
|
|
};
|
|
var provider = {
|
|
'id': config.postId,
|
|
'data': items,
|
|
'loadNext': paginator,
|
|
'hasMore': hasMore,
|
|
'getMeta': getMeta,
|
|
'onReply': onReply,
|
|
'rendered': true,
|
|
'initComment': targetComment,
|
|
'initReplyThread': startThread,
|
|
'config': configJso,
|
|
'messages': msgs
|
|
};
|
|
|
|
var render = function() {
|
|
if (window.goog && window.goog.comments) {
|
|
var holder = document.getElementById('comment-holder');
|
|
window.goog.comments.render(holder, provider);
|
|
}
|
|
};
|
|
|
|
// render now, or queue to render when library loads:
|
|
if (window.goog && window.goog.comments) {
|
|
render();
|
|
} else {
|
|
window.goog = window.goog || {};
|
|
window.goog.comments = window.goog.comments || {};
|
|
window.goog.comments.loadQueue = window.goog.comments.loadQueue || [];
|
|
window.goog.comments.loadQueue.push(render);
|
|
}
|
|
})();
|
|
// ]]>
|
|
</script>
|
|
<div id='comment-holder'>
|
|
<div class="comment-thread toplevel-thread"><ol id="top-ra"><li class="comment" id="c4734889953096754294"><div class="avatar-image-container"><img src="//resources.blogblog.com/img/blank.gif" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user">Anonymous</cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323361403585#c4734889953096754294">December 8, 2011 at 8:23 AM</a></span></div><p class="comment-content">Daniel, I am not convinced that the (obvious?) relationship between latency and consistency has been ignored. <br><br>After all, the very same issues had already been extensively researched and addressed in context of multicore and the various shared memory consistency approaches by the chip manufacturers. <br><br>CAP was 'significant' as it addressed a shortcoming entirely absent from h/w based shared memory systems: unreliable connectivity. Had h/w systems shared the same characteristics, there is no question that CAP would have emerged from those efforts.<br><br>That said, thank you for the excellent survey of the approaches in context of distributed databases.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="4734889953096754294">Reply</a><span class="item-control blog-admin blog-admin pid-290883198"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/4734889953096754294">Delete</a></span></span></div><div class="comment-replies"><div id="c4734889953096754294-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c4734889953096754294-ra" class="thread-chrome thread-expanded"><div></div><div id="c4734889953096754294-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="4734889953096754294">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c4734889953096754294-ce"></div></li><li class="comment" id="c5849147120326916236"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/18328634816636495300" rel="nofollow">bhudgeons</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323362120541#c5849147120326916236">December 8, 2011 at 8:35 AM</a></span></div><p class="comment-content">Great article. I especially liked the explanations of the decisions that the different distributed DB systems made. <br><br>I'm not sure that I agree that it is useful to consider latency outside of the CAP theorem. CAP states that you can't have consistency, availability and partition tolerance and have an acceptable latency. The concept of latency is baked into the Availability term -- if the latency is higher than your requirements dictate, you've lost Availability. You can configure Cassandra to give you strong consistency. The tradeoff isn't that you'll lose "availability" in some pure sense, as if your system will suddenly become unavailable. The tradeoff is increased latency. If that latency is so high that your users close the browser, or client timeouts occur, or your servers get overloaded with backlogged requests, that is the reduced availability predicted by the CAP theorem.<br><br>Your article also discusses another (related, but separate) flavor of latency: the latency between different internal parts of the DB system, such as latency introduced by agreement protocols. Again, this latency is part of the CAP theorem itself. In fact, that latency is why the CAP theorem exists. If there were zero latency between internal components and protocols in a DB system, you could abstract the partition tolerance of the system and provide strong consistency without giving up availability. The fact that there is a delay between writes among servers is the reason we have to worry about CAP in the first place.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="5849147120326916236">Reply</a><span class="item-control blog-admin blog-admin pid-433718692"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/5849147120326916236">Delete</a></span></span></div><div class="comment-replies"><div id="c5849147120326916236-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c5849147120326916236-ra" class="thread-chrome thread-expanded"><div></div><div id="c5849147120326916236-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="5849147120326916236">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c5849147120326916236-ce"></div></li><li class="comment" id="c2091511577808999762"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/16753133043157018521" rel="nofollow">Daniel Abadi</a></cite><span class="icon user blog-author"></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323362804582#c2091511577808999762">December 8, 2011 at 8:46 AM</a></span></div><p class="comment-content">@alphazero, @bhudgeons, thanks for your kind words.<br><br>@bhudgeons, a lot of people like to put latency and availability together in the same category, and I don't have any particular problem with that (though I prefer to keep them separate since they generally describe different orders of magnitude levels of latency). However, even if you want to mix them, I maintain that there is still a fundamental difference between the A/L of CAP which is only traded off with C upon a network partition, and the A/L of this post, which is traded off with C at all times, even when there is no network partition.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="2091511577808999762">Reply</a><span class="item-control blog-admin blog-admin pid-2045359914"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/2091511577808999762">Delete</a></span></span></div><div class="comment-replies"><div id="c2091511577808999762-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c2091511577808999762-ra" class="thread-chrome thread-expanded"><div></div><div id="c2091511577808999762-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="2091511577808999762">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c2091511577808999762-ce"></div></li><li class="comment" id="c3496974031555289027"><div class="avatar-image-container"><img src="//resources.blogblog.com/img/blank.gif" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user">Anonymous</cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323367567334#c3496974031555289027">December 8, 2011 at 10:06 AM</a></span></div><p class="comment-content">Dan,<br><br>Great to see this post and also great to see that we're thinking about the issues in similar or parallel tracks.<br><br>I do believe however that the "latency" as perceived by an database client application is a result either of "availability latency", or "consistency latency". In that sense, I don't believe that latency is really a new factor or dimension, rather just a consolidation of two factors already part of the CAP; namely C and A.<br><br>An application developer is really concerned about the numerical bounds (time limits) on "latency", and these are, I believe best visualized as the variables that I refer to as Tc and Ta in my posts on the subject. (Please see: http://bit.ly/rX4SWW).<br><br>You write, "Ignoring the consistency-latency tradeoff of replicated systems is a great oversight, since it is present at all times during system operation, whereas CAP is only relevant in the (arguably) rare case of a network partition."<br><br>I agree entirely with you that IF one were to consider CAP to be relevant only in the rare case of a network partition, that would be foolish.<br><br>And that is also why I characterize CAP as something to be considered at all time where:<br><br>Ta + Tc >= Tp.<br><br>More details, proof, applications are available at http://bit.ly/tOwrz3 (part 1 of 6)</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="3496974031555289027">Reply</a><span class="item-control blog-admin blog-admin pid-290883198"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/3496974031555289027">Delete</a></span></span></div><div class="comment-replies"><div id="c3496974031555289027-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c3496974031555289027-ra" class="thread-chrome thread-expanded"><div></div><div id="c3496974031555289027-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="3496974031555289027">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c3496974031555289027-ce"></div></li><li class="comment" id="c5455129692457156897"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/10044910123796357914" rel="nofollow">Jamie</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323368026766#c5455129692457156897">December 8, 2011 at 10:13 AM</a></span></div><p class="comment-content">Another dimension in the consistency discussion is the type of transaction being performed and how it can influence consistency/latency trade-offs. Obviously many of the Dynamo derived systems allow for a per connection (xact?) consistency setting (not all that conceptually dissimilar from traditional single db xact isolation levels). But I think consistency semantics of Google's Megastore is very relevant to this discussion and looks at consistency from a slightly different perspective. In particular I'm referring to the differing degrees of consistency guarantees the system provides depending on whether your transaction is within a particular "entity group" or spans entity groups.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="5455129692457156897">Reply</a><span class="item-control blog-admin blog-admin pid-646925202"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/5455129692457156897">Delete</a></span></span></div><div class="comment-replies"><div id="c5455129692457156897-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c5455129692457156897-ra" class="thread-chrome thread-expanded"><div></div><div id="c5455129692457156897-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="5455129692457156897">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c5455129692457156897-ce"></div></li><li class="comment" id="c9078044461529935735"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/18328634816636495300" rel="nofollow">bhudgeons</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323369112765#c9078044461529935735">December 8, 2011 at 10:31 AM</a></span></div><p class="comment-content">Daniel -- Thank you for the response -- I hope I'm not seeming argumentative. I have a feeling that I may have some fundamental misunderstanding of CAP, and I suspect others may share it.<br><br>In the systems you described, each is using replication as a way to give away some C and A for some P. The architectural decisions they made (which you described) mean that some of them get more C, and some get more A. <br><br>Are you just saying that it's useful to look at that decision (the C/A tradeoff) in isolation of the P (where you've already decided to use replication)? I still can't get my head around what the "fundamental difference" is between the A/L of CAP and the A/L of the CA tradeoff. If there is no network partition tolerance, why are you doing replication?</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="9078044461529935735">Reply</a><span class="item-control blog-admin blog-admin pid-433718692"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/9078044461529935735">Delete</a></span></span></div><div class="comment-replies"><div id="c9078044461529935735-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c9078044461529935735-ra" class="thread-chrome thread-expanded"><div></div><div id="c9078044461529935735-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="9078044461529935735">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c9078044461529935735-ce"></div></li><li class="comment" id="c7782434261253041798"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/04235452983694120262" rel="nofollow">Unknown</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323373115336#c7782434261253041798">December 8, 2011 at 11:38 AM</a></span></div><p class="comment-content">Hiding Synchronous Replication stalls I suspect is very similar to OoO consistency and cache miss stall hiding tricks.<br>Lets assume every write takes 1ms to receive all acks from replicating agents.<br><br>[a] This latency only matters for *dependent* reads from the same source. So if I have a transaction with 20 writes and 1 read<br> this 1 read will take the stall not the 20 other writes. Of course you can't allow the transaction to commit until all<br> writes have been ack'ed but I suspect you can use ack aggregation and batching.<br><br>[b] Lets assume that the transaction contains multiple reads for data that is written in the same transaction. You can speculatively<br> allow these reads to continue with uncommitted writes (again batch your write-acks). These reads will of course have to be<br> rolled back if any of the above writes acks fail. <br><br>Bottomline, it appears to me write-stalls really only matter for Transaction commit time. As you can tell I m not a Database<br>Internals person but I enjoy reading your blogs. I do however intimately understand OoO processors that solve a similar problem.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="7782434261253041798">Reply</a><span class="item-control blog-admin blog-admin pid-1179309198"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/7782434261253041798">Delete</a></span></span></div><div class="comment-replies"><div id="c7782434261253041798-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c7782434261253041798-ra" class="thread-chrome thread-expanded"><div></div><div id="c7782434261253041798-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="7782434261253041798">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c7782434261253041798-ce"></div></li><li class="comment" id="c8247015823738713741"><div class="avatar-image-container"><img src="//resources.blogblog.com/img/blank.gif" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user">Anonymous</cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323376080885#c8247015823738713741">December 8, 2011 at 12:28 PM</a></span></div><p class="comment-content">@bhudgeons Per the 'proof' of CAP, "network" partition is not merely limited to (literally) network issues. Even without any network specific issues, node(s) may crash, and unless the system can transparently failover to a replica, then you have a 'network partition' in your distributed system, per the "proof" of CAP:<br><br>http://people.csail.mit.edu/sethg/pubs/BrewersConjecture-SigAct.pdf [§ 2.3 //+emph//]: <br><br>"In order to model partition tolerance, the network will be allowed to lose arbitrarily many messages sent from one node to another. When a network is partitioned, all messages sent from nodes in one component of the partition to nodes in another component are lost. (And //any pattern of message loss// can be modeled as a temporary partition separating the communicating nodes at the exact instant the message is lost.)"</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="8247015823738713741">Reply</a><span class="item-control blog-admin blog-admin pid-290883198"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/8247015823738713741">Delete</a></span></span></div><div class="comment-replies"><div id="c8247015823738713741-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c8247015823738713741-ra" class="thread-chrome thread-expanded"><div></div><div id="c8247015823738713741-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="8247015823738713741">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c8247015823738713741-ce"></div></li><li class="comment" id="c9179434905112689782"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/16753133043157018521" rel="nofollow">Daniel Abadi</a></cite><span class="icon user blog-author"></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323577267485#c9179434905112689782">December 10, 2011 at 8:21 PM</a></span></div><p class="comment-content">@Jamie Thanks for your comment.<br><br>@bhudgeons I will try to answer your question in an upcoming longer publication on this topic.<br><br>@Unknown Thanks for your comment. The latency I am talking about for this post includes the full latency all the way through transaction commit.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="9179434905112689782">Reply</a><span class="item-control blog-admin blog-admin pid-2045359914"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/9179434905112689782">Delete</a></span></span></div><div class="comment-replies"><div id="c9179434905112689782-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c9179434905112689782-ra" class="thread-chrome thread-expanded"><div></div><div id="c9179434905112689782-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="9179434905112689782">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c9179434905112689782-ce"></div></li><li class="comment" id="c8145274661602000871"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/17179073470437306420" rel="nofollow">PabloM</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323665325374#c8145274661602000871">December 11, 2011 at 8:48 PM</a></span></div><p class="comment-content">Hi Daniel,<br><br>Excellent post! I like the way you clarify this things.<br><br>Did you have the chance to read the CAP theorem analysis by parelastic.com mentioned by @amrith http://www.parelastic.com/database-architectures/an-analysis-of-the-cap-theorem/ ? <br><br>I would like to read a review about it from you.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="8145274661602000871">Reply</a><span class="item-control blog-admin blog-admin pid-1619189452"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/8145274661602000871">Delete</a></span></span></div><div class="comment-replies"><div id="c8145274661602000871-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c8145274661602000871-ra" class="thread-chrome thread-expanded"><div></div><div id="c8145274661602000871-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="8145274661602000871">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c8145274661602000871-ce"></div></li><li class="comment" id="c7111552531901564723"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/16753133043157018521" rel="nofollow">Daniel Abadi</a></cite><span class="icon user blog-author"></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1323667808083#c7111552531901564723">December 11, 2011 at 9:30 PM</a></span></div><p class="comment-content">Hi Pablo,<br><br>I read it a few months ago and sent my comments to Amrith. I do not feel comfortable making these comments public.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="7111552531901564723">Reply</a><span class="item-control blog-admin blog-admin pid-2045359914"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/7111552531901564723">Delete</a></span></span></div><div class="comment-replies"><div id="c7111552531901564723-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c7111552531901564723-ra" class="thread-chrome thread-expanded"><div></div><div id="c7111552531901564723-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="7111552531901564723">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c7111552531901564723-ce"></div></li><li class="comment" id="c6277462097129661620"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/04621807475180917035" rel="nofollow">Martao</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1324980480127#c6277462097129661620">December 27, 2011 at 2:08 AM</a></span></div><p class="comment-content">Hello Daniel,<br>Thanks for another insightful post.<br><br>I have a question. It is not really about your main point, but still, I have wondered about it before. It is about your option 1. I agree some pre-processing is needed to prevent replica divergence. But I have always wondered if this isnt introducing a new SPoF? <br>(And thereby introducing a new CAP-problem?)</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6277462097129661620">Reply</a><span class="item-control blog-admin blog-admin pid-1989209817"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/6277462097129661620">Delete</a></span></span></div><div class="comment-replies"><div id="c6277462097129661620-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6277462097129661620-ra" class="thread-chrome thread-expanded"><div></div><div id="c6277462097129661620-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6277462097129661620">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6277462097129661620-ce"></div></li><li class="comment" id="c307358897668058915"><div class="avatar-image-container"><img src="//resources.blogblog.com/img/blank.gif" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user">Anonymous</cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1325454055745#c307358897668058915">January 1, 2012 at 1:40 PM</a></span></div><p class="comment-content">There is potentially another source of read latency when using a Consistency Level higher than One. In the Cassandra world, when a read detects inconsistent data from nodes it is performed a second time and the inconsistencies are resolved. This happens synchronously to the read operations, the writes required to repair the inconsistency are then handled async to the read.<br><br>The general question would be how are inconsistencies handled during read operations.?<br><br>Cheers.<br>Aaron Morton</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="307358897668058915">Reply</a><span class="item-control blog-admin blog-admin pid-290883198"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/307358897668058915">Delete</a></span></span></div><div class="comment-replies"><div id="c307358897668058915-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c307358897668058915-ra" class="thread-chrome thread-expanded"><div></div><div id="c307358897668058915-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="307358897668058915">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c307358897668058915-ce"></div></li><li class="comment" id="c5716874424830130947"><div class="avatar-image-container"><img src="//1.bp.blogspot.com/-qP60iWzwwEY/Trz9MXQhqHI/AAAAAAAAAD8/akYV7lWIBFY/s35/Untitled_3.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/01534043514130919389" rel="nofollow">Peter Bailis</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1325705578506#c5716874424830130947">January 4, 2012 at 11:32 AM</a></span></div><p class="comment-content">Daniel,<br><br>I recently released a tech report with some other folks at Berkeley that helps quantify the latency-consistency trade-off you describe here for quorum-replicated eventually consistent data stores. Eventual consistency makes no guarantees regarding data recency, but we can predict the expected consistency a data store provides, which we call Probabilistically Bounded Staleness, or PBS.<br><br>Your post provided great motivation for our tech report (under submission):<br>http://www.eecs.berkeley.edu/Pubs/TechRpts/2012/EECS-2012-4.pdf<br><br>We also wrote a simple browser-based demo showing latency-consistency wins at: cs.berkeley.edu/~pbailis/projects/pbs/#demo<br><br>We'd welcome any feedback you have!<br>Peter</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="5716874424830130947">Reply</a><span class="item-control blog-admin blog-admin pid-1059195799"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/5716874424830130947">Delete</a></span></span></div><div class="comment-replies"><div id="c5716874424830130947-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c5716874424830130947-ra" class="thread-chrome thread-expanded"><div></div><div id="c5716874424830130947-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="5716874424830130947">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c5716874424830130947-ce"></div></li><li class="comment" id="c6408943743997735705"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/09831342731638036787" rel="nofollow">Greg Kemnitz</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html?showComment=1328209314042#c6408943743997735705">February 2, 2012 at 11:01 AM</a></span></div><p class="comment-content">I'll admit that we're lazy (and cheap). We just maintain parallel app stacks and failover completely to the other stack if one stack dies (and do load-balancing otherwise for read-only actions). Our data is such that we don't require absolute data-level consistency between stacks (eventual is ok), so we don't bother with db-level replication, which is expensive, hard, and typically the buggiest part of db engines.<br><br>Our approach is actually far cheaper than trying to replicate at the db level, since we can "get away" with nearly-free open-source DBMSs, where replication is even buggier than it is with old-line (and hugely expensive) commercial DBMSs, and the infrastructure needed is more vertical and less horizontal than it would need to be if we tried to use db-level replication.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6408943743997735705">Reply</a><span class="item-control blog-admin blog-admin pid-771395826"><a target="_self" href="https://www.blogger.com/comment/delete/8899645800948009496/6408943743997735705">Delete</a></span></span></div><div class="comment-replies"><div id="c6408943743997735705-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6408943743997735705-ra" class="thread-chrome thread-expanded"><div></div><div id="c6408943743997735705-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6408943743997735705">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6408943743997735705-ce"></div></li></ol><div id="top-continue" class="continue"><a class="comment-reply" target="_self">Add comment</a></div><div class="comment-replybox-thread" id="top-ce"></div><div class="loadmore hidden" data-post-id="190191398605973736"><a target="_self">Load more...</a></div></div>
|
|
</div>
|
|
</div>
|
|
<p class='comment-footer'>
|
|
<div class='comment-form'>
|
|
<a name='comment-form'></a>
|
|
<p>
|
|
</p>
|
|
<a href='https://www.blogger.com/comment/frame/8899645800948009496?po=190191398605973736&hl=en&saa=85391&origin=http://dbmsmusings.blogspot.com' id='comment-editor-src'></a>
|
|
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' frameborder='0' height='410px' id='comment-editor' name='comment-editor' src='' width='100%'></iframe>
|
|
<script src='https://www.blogger.com/static/v1/jsbin/3790099508-comment_from_post_iframe.js' type='text/javascript'></script>
|
|
<script type='text/javascript'>
|
|
BLOG_CMT_createIframe('https://www.blogger.com/rpc_relay.html');
|
|
</script>
|
|
</div>
|
|
</p>
|
|
<div id='backlinks-container'>
|
|
<div id='Blog1_backlinks-container'>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div></div>
|
|
|
|
</div>
|
|
<div class='blog-pager' id='blog-pager'>
|
|
<span id='blog-pager-newer-link'>
|
|
<a class='blog-pager-newer-link' href='http://dbmsmusings.blogspot.com/2012/05/if-all-these-new-dbms-technologies-are.html' id='Blog1_blog-pager-newer-link' title='Newer Post'>Newer Post</a>
|
|
</span>
|
|
<span id='blog-pager-older-link'>
|
|
<a class='blog-pager-older-link' href='http://dbmsmusings.blogspot.com/2011/10/overview-of-oracle-nosql-database.html' id='Blog1_blog-pager-older-link' title='Older Post'>Older Post</a>
|
|
</span>
|
|
<a class='home-link' href='http://dbmsmusings.blogspot.com/'>Home</a>
|
|
</div>
|
|
<div class='clear'></div>
|
|
<div class='post-feeds'>
|
|
<div class='feed-links'>
|
|
Subscribe to:
|
|
<a class='feed-link' href='http://dbmsmusings.blogspot.com/feeds/190191398605973736/comments/default' target='_blank' type='application/atom+xml'>Post Comments (Atom)</a>
|
|
</div>
|
|
</div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='column-left-outer'>
|
|
<div class='column-left-inner'>
|
|
<aside>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
<div class='column-right-outer'>
|
|
<div class='column-right-inner'>
|
|
<aside>
|
|
<div class='sidebar section' id='sidebar-right-1'><div class='widget Image' data-version='1' id='Image1'>
|
|
<h2>Daniel Abadi</h2>
|
|
<div class='widget-content'>
|
|
<img alt='Daniel Abadi' height='449' id='Image1_img' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjq7IZ-b9X74S5hxbSo0XZg6tWgFnU-Tkkg2SrZbH0sRSvLi37d5oAaTx5gj3DQG6jxEcvzmQIyduk9EiMPxzlvHVgl33-67YLUpDn-ns_DrXBNbQxKRAx1EDfjo5kmrW1qGIhnxdJgZw/s1600/dan_2019.jpg' width='315'/>
|
|
<br/>
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div><div class='widget Profile' data-version='1' id='Profile1'>
|
|
<h2>About Me</h2>
|
|
<div class='widget-content'>
|
|
<dl class='profile-datablock'>
|
|
<dt class='profile-data'>
|
|
<a class='profile-name-link g-profile' href='https://www.blogger.com/profile/16753133043157018521' rel='author' style='background-image: url(//www.blogger.com/img/logo-16.png);'>
|
|
Daniel Abadi
|
|
</a>
|
|
</dt>
|
|
<dd class='profile-textblock'>Daniel Abadi is the Darnell-Kanal Professor of Computer Science at University of Maryland, College Park. He is best-known for the development of the storage and query execution engines of the C-Store (column-oriented database) prototype, which was commercialized by Vertica and eventually acquired by Hewlett-Packard in 2011, for his HadoopDB research on fault tolerant scalable analytical database systems which was commercialized by Hadapt and acquired by Teradata in 2014, and deterministic, scalable, transactional, distributed systems such as Calvin which is currently being commercialized by <a href="https://fauna.com/">Fauna</a>. Abadi has been a recipient of a
|
|
Churchill Scholarship, a NSF CAREER Award, a Sloan Research Fellowship, a VLDB Best Paper Award, two VLDB <b>10 year</b> Best Paper Awards, the 2008 SIGMOD Jim Gray Doctoral Dissertation Award, the 2013-2014 Yale Provost's Teaching Prize, and the 2013 VLDB Early Career Researcher Award. He received his PhD in 2008 from MIT.
|
|
He blogs at <a href="http://dbmsmusings.blogspot.com">DBMS Musings</a> and tweets at <a href="http://www.twitter.com/daniel_abadi">@daniel_abadi</a>.</dd>
|
|
</dl>
|
|
<a class='profile-link' href='https://www.blogger.com/profile/16753133043157018521' rel='author'>View my complete profile</a>
|
|
<div class='clear'></div>
|
|
</div>
|
|
</div></div>
|
|
<table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>
|
|
<tbody>
|
|
<tr>
|
|
<td class='first columns-cell'>
|
|
<div class='sidebar section' id='sidebar-right-2-1'><div class='widget BlogArchive' data-version='1' id='BlogArchive1'>
|
|
<h2>Blog Archive</h2>
|
|
<div class='widget-content'>
|
|
<div id='ArchiveList'>
|
|
<div id='BlogArchive1_ArchiveList'>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2021/'>
|
|
2021
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2021/03/'>
|
|
March
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/'>
|
|
2019
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(8)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/12/'>
|
|
December
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/08/'>
|
|
August
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/07/'>
|
|
July
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/06/'>
|
|
June
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/05/'>
|
|
May
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2019/01/'>
|
|
January
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2018/'>
|
|
2018
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(3)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2018/12/'>
|
|
December
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2018/09/'>
|
|
September
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2018/03/'>
|
|
March
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2017/'>
|
|
2017
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(3)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2017/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2017/04/'>
|
|
April
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2015/'>
|
|
2015
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2015/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2012/'>
|
|
2012
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(4)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2012/11/'>
|
|
November
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2012/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2012/06/'>
|
|
June
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2012/05/'>
|
|
May
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate expanded'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy toggle-open'>
|
|
|
|
▼ 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/'>
|
|
2011
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(6)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate expanded'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy toggle-open'>
|
|
|
|
▼ 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/12/'>
|
|
December
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
<ul class='posts'>
|
|
<li><a href='http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html'>Replication and the latency-consistency tradeoff</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/07/'>
|
|
July
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/05/'>
|
|
May
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/03/'>
|
|
March
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2011/02/'>
|
|
February
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/'>
|
|
2010
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(8)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/12/'>
|
|
December
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/08/'>
|
|
August
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/07/'>
|
|
July
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/04/'>
|
|
April
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/03/'>
|
|
March
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2010/01/'>
|
|
January
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/'>
|
|
2009
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(21)</span>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/12/'>
|
|
December
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/11/'>
|
|
November
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(1)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/10/'>
|
|
October
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/09/'>
|
|
September
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/08/'>
|
|
August
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(2)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/07/'>
|
|
July
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(5)</span>
|
|
</li>
|
|
</ul>
|
|
<ul class='hierarchy'>
|
|
<li class='archivedate collapsed'>
|
|
<a class='toggle' href='javascript:void(0)'>
|
|
<span class='zippy'>
|
|
|
|
► 
|
|
|
|
</span>
|
|
</a>
|
|
<a class='post-count-link' href='http://dbmsmusings.blogspot.com/2009/06/'>
|
|
June
|
|
</a>
|
|
<span class='post-count' dir='ltr'>(8)</span>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div>
|
|
</div></div>
|
|
</td>
|
|
<td class='columns-cell'>
|
|
<div class='sidebar section' id='sidebar-right-2-2'><div class='widget Followers' data-version='1' id='Followers1'>
|
|
<h2 class='title'>Followers</h2>
|
|
<div class='widget-content'>
|
|
<div id='Followers1-wrapper'>
|
|
<div style='margin-right:2px;'>
|
|
<div><script type="text/javascript" src="https://apis.google.com/js/platform.js"></script>
|
|
<div id="followers-iframe-container"></div>
|
|
<script type="text/javascript">
|
|
window.followersIframe = null;
|
|
function followersIframeOpen(url) {
|
|
gapi.load("gapi.iframes", function() {
|
|
if (gapi.iframes && gapi.iframes.getContext) {
|
|
window.followersIframe = gapi.iframes.getContext().openChild({
|
|
url: url,
|
|
where: document.getElementById("followers-iframe-container"),
|
|
messageHandlersFilter: gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER,
|
|
messageHandlers: {
|
|
'_ready': function(obj) {
|
|
window.followersIframe.getIframeEl().height = obj.height;
|
|
},
|
|
'reset': function() {
|
|
window.followersIframe.close();
|
|
followersIframeOpen("https://www.blogger.com/followers/frame/8899645800948009496?colors\x3dCgt0cmFuc3BhcmVudBILdHJhbnNwYXJlbnQaByM2NjY2NjYiByMyMTk4YTYqByNmZmZmZmYyByM2NjY2NjY6ByM2NjY2NjZCByMyMTk4YTZKByNjY2NjY2NSByMyMTk4YTZaC3RyYW5zcGFyZW50\x26pageSize\x3d21\x26hl\x3den\x26origin\x3dhttp://dbmsmusings.blogspot.com");
|
|
},
|
|
'open': function(url) {
|
|
window.followersIframe.close();
|
|
followersIframeOpen(url);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
followersIframeOpen("https://www.blogger.com/followers/frame/8899645800948009496?colors\x3dCgt0cmFuc3BhcmVudBILdHJhbnNwYXJlbnQaByM2NjY2NjYiByMyMTk4YTYqByNmZmZmZmYyByM2NjY2NjY6ByM2NjY2NjZCByMyMTk4YTZKByNjY2NjY2NSByMyMTk4YTZaC3RyYW5zcGFyZW50\x26pageSize\x3d21\x26hl\x3den\x26origin\x3dhttp://dbmsmusings.blogspot.com");
|
|
</script></div>
|
|
</div>
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div>
|
|
</div></div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class='sidebar no-items section' id='sidebar-right-3'></div>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style='clear: both'></div>
|
|
<!-- columns -->
|
|
</div>
|
|
<!-- main -->
|
|
</div>
|
|
</div>
|
|
<div class='main-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<footer>
|
|
<div class='footer-outer'>
|
|
<div class='footer-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left footer-fauxborder-left'>
|
|
<div class='fauxborder-right footer-fauxborder-right'></div>
|
|
<div class='region-inner footer-inner'>
|
|
<div class='foot no-items section' id='footer-1'></div>
|
|
<table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>
|
|
<tbody>
|
|
<tr>
|
|
<td class='first columns-cell'>
|
|
<div class='foot no-items section' id='footer-2-1'></div>
|
|
</td>
|
|
<td class='columns-cell'>
|
|
<div class='foot no-items section' id='footer-2-2'></div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<!-- outside of the include in order to lock Attribution widget -->
|
|
<div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'>
|
|
<div class='widget-content' style='text-align: center;'>
|
|
Ethereal theme. Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>.
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='footer-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
<!-- content -->
|
|
</div>
|
|
</div>
|
|
<div class='content-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type='text/javascript'>
|
|
window.setTimeout(function() {
|
|
document.body.className = document.body.className.replace('loading', '');
|
|
}, 10);
|
|
</script>
|
|
|
|
<script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/1363620594-widgets.js"></script>
|
|
<script type='text/javascript'>
|
|
window['__wavt'] = 'AAPvtVk8qbhx6k5zGphDuu_OfOFE:1789170666303';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d8899645800948009496','//dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html','8899645800948009496');
|
|
_WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '8899645800948009496', 'title': 'DBMS Musings', 'url': 'http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html', 'canonicalUrl': 'http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html', 'homepageUrl': 'http://dbmsmusings.blogspot.com/', 'searchUrl': 'http://dbmsmusings.blogspot.com/search', 'canonicalHomepageUrl': 'http://dbmsmusings.blogspot.com/', 'blogspotFaviconUrl': 'http://dbmsmusings.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'G-WPSPKTZ8VQ', 'analytics4': true, 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22DBMS Musings - Atom\x22 href\x3d\x22http://dbmsmusings.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22DBMS Musings - RSS\x22 href\x3d\x22http://dbmsmusings.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22DBMS Musings - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/8899645800948009496/posts/default\x22 /\x3e\n\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22DBMS Musings - Atom\x22 href\x3d\x22http://dbmsmusings.blogspot.com/feeds/190191398605973736/comments/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/1890a9484e710b1c', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'item', 'postId': '190191398605973736', 'pageName': 'Replication and the latency-consistency tradeoff', 'pageTitle': 'DBMS Musings: Replication and the latency-consistency tradeoff'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'Ethereal', 'localizedName': 'Ethereal', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': false, 'variant': 'hummingBirds2', 'variantId': 'hummingBirds2'}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Replication and the latency-consistency tradeoff', 'description': 'As 24/7 availability becomes increasingly important for modern applications, database systems are frequently replicated in order to stay up ...', 'url': 'http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html', 'type': 'item', 'isSingleItem': true, 'isMultipleItems': false, 'isError': false, 'isPage': false, 'isPost': true, 'isHomepage': false, 'isArchive': false, 'isLabelSearch': false, 'postId': 190191398605973736}}]);
|
|
_WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/700075392-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/828616780-lightbox_bundle.css'}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_ImageView', new _WidgetInfo('Image1', 'sidebar-right-1', document.getElementById('Image1'), {'resize': true}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_ProfileView', new _WidgetInfo('Profile1', 'sidebar-right-1', document.getElementById('Profile1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-2-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_FollowersView', new _WidgetInfo('Followers1', 'sidebar-right-2-2', document.getElementById('Followers1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull'));
|
|
</script>
|
|
</body>
|
|
</html> |