learn.lianglianglee.com/专栏/24讲吃透分布式数据库-完/01 导论:什么是分布式数据库?聊聊它的前世今生.md.html
2022-09-06 22:30:37 +08:00

342 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>01 导论:什么是分布式数据库?聊聊它的前世今生.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/24讲吃透分布式数据库-完/00 开篇词 吃透分布式数据库,提升职场竞争力.md.html">00 开篇词 吃透分布式数据库,提升职场竞争力</a>
</li>
<li>
<a class="current-tab" href="/专栏/24讲吃透分布式数据库-完/01 导论:什么是分布式数据库?聊聊它的前世今生.md.html">01 导论:什么是分布式数据库?聊聊它的前世今生</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/02 SQL vs NoSQL一次搞清楚五花八门的“SQL”.md.html">02 SQL vs NoSQL一次搞清楚五花八门的“SQL”</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/03 数据分片:如何存储超大规模的数据?.md.html">03 数据分片:如何存储超大规模的数据?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/04 数据复制:如何保证数据在分布式场景下的高可用?.md.html">04 数据复制:如何保证数据在分布式场景下的高可用?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/05 一致性与 CAP 模型:为什么需要分布式一致性?.md.html">05 一致性与 CAP 模型:为什么需要分布式一致性?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/06 实践:设计一个最简单的分布式数据库.md.html">06 实践:设计一个最简单的分布式数据库</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/07 概要:什么是存储引擎,为什么需要了解它?.md.html">07 概要:什么是存储引擎,为什么需要了解它?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/08 分布式索引:如何在集群中快速定位数据?.md.html">08 分布式索引:如何在集群中快速定位数据?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/09 日志型存储:为什么选择它作为底层存储?.md.html">09 日志型存储:为什么选择它作为底层存储?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/10 事务处理与恢复(上):数据库崩溃后如何保证数据不丢失?.md.html">10 事务处理与恢复(上):数据库崩溃后如何保证数据不丢失?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/11 事务处理与恢复(下):如何控制并发事务?.md.html">11 事务处理与恢复(下):如何控制并发事务?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/12 引擎拓展:解读当前流行的分布式存储引擎.md.html">12 引擎拓展:解读当前流行的分布式存储引擎</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/13 概要:分布式系统都要解决哪些问题?.md.html">13 概要:分布式系统都要解决哪些问题?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/14 错误侦测:如何保证分布式系统稳定?.md.html">14 错误侦测:如何保证分布式系统稳定?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/15 领导选举:如何在分布式系统内安全地协调操作?.md.html">15 领导选举:如何在分布式系统内安全地协调操作?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/16 再谈一致性:除了 CAP 之外的一致性模型还有哪些?.md.html">16 再谈一致性:除了 CAP 之外的一致性模型还有哪些?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/17 数据可靠传播:反熵理论如何帮助数据库可靠工作?.md.html">17 数据可靠传播:反熵理论如何帮助数据库可靠工作?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/18 分布式事务(上):除了 XA还有哪些原子提交算法吗.md.html">18 分布式事务(上):除了 XA还有哪些原子提交算法吗</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/19 分布式事务Spanner 与 Calvin 的巅峰对决.md.html">19 分布式事务Spanner 与 Calvin 的巅峰对决</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/20 共识算法:一次性说清楚 Paxos、Raft 等算法的区别.md.html">20 共识算法:一次性说清楚 Paxos、Raft 等算法的区别</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/21 知识串讲:如何取得性能和可扩展性的平衡?.md.html">21 知识串讲:如何取得性能和可扩展性的平衡?</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/22 发展与局限:传统数据库在分布式领域的探索.md.html">22 发展与局限:传统数据库在分布式领域的探索</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/23 数据库中间件:传统数据库向分布式数据库的过渡.md.html">23 数据库中间件:传统数据库向分布式数据库的过渡</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/24 现状解读:分布式数据库的最新发展情况.md.html">24 现状解读:分布式数据库的最新发展情况</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/加餐1 概念解析云原生、HTAP、图与内存数据库.md.html">加餐1 概念解析云原生、HTAP、图与内存数据库</a>
</li>
<li>
<a href="/专栏/24讲吃透分布式数据库-完/加餐2 数据库选型:我们该用什么分布式数据库?.md.html">加餐2 数据库选型:我们该用什么分布式数据库?</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>01 导论:什么是分布式数据库?聊聊它的前世今生</h1>
<p>你好,欢迎学习分布式数据库,我们的课程就正式开始了。</p>
<p>在开设这门课程之前,我简短地与身边同僚、朋友交流了课程的大纲。当时,大家都表示出了浓厚的兴趣,并且不约而同地问了我这样一个问题:啥是分布式数据库?更有“爱好学习”的朋友希望借此展现出“勤学好问”的品德,进而补充道:“这是哪个大厂出的产品?”</p>
<p>好吧,我的朋友,你们真的戳中了我的笑点。但笑一笑后,我不禁陷入了思考:为什么分布式数据库在大众,甚至专业领域内认知如此之低呢?</p>
<p>原因我大概可以总结为两点:<strong>数据库产品特点与商业氛围</strong></p>
<p>首先,数据库产品的特点是抽象度高。用户一般仅仅从使用层面接触数据库,知道数据库能实现哪些功能,而不关心或者很难关心其内部原理。而一些类型的分布式数据库的卖点正是这种抽象能力,从而使用户觉得应用这种分布式化的数据库与传统单机数据库没有明显的差别,甚至更加简单。</p>
<p>其次,数据库的商业氛围一直很浓厚。数据库产品高度抽象且位置关键,这就天然成为资本追逐的领地。而商业化产品和服务的卖点就是其包含支撑服务,而且许多商业数据库最赚钱的部分就是提供该服务。因此这些产品有意无意地对终端用户掩盖了数据库的技术细节,而用户有了这层商业保障,也很难有动力去主动了解内部原理。</p>
<p>这就造成即使你工作中接触了分布式数据库,也没有意识到它与过去的数据库有什么不同。但“福报迟到,但不会缺席”——当由于对其原理缺乏必要认识,导致技术问题频发时,用户才会真正意识到它们好像类似,但本质却截然不同。</p>
<p>而随着分布式数据库逐步渗透到各个领域,用户再也不能“傻瓜式”地根据特性选择数据库产品了。新架构催生出来的新特性,促使使用者需要深入参与其中,并需要他们认真评估数据库技术特点,甚至要重新设计自己的产品来与之更好地结合。</p>
<p>因此,我将<strong>本专栏课程设计为一把钥匙,帮助你打开分布式数据库的大门</strong>。你也可以将本门课程当作一个网游的新手村任务,完成后会获取初始装备(原理与方法论),继而掌握深入该领域所必要的知识。</p>
<p>我是“历史决定论”的忠实簇拥者,在这一讲中,我会沿着分布式数据库的发展脉络来介绍它。相信你在读完后,会对一开始的那个问题有自己的答案。那么现在我们从基本概念开始说起。</p>
<h3>基本概念</h3>
<p>分布式数据库,从名字上可以拆解为:分布式+数据库。用一句话总结为:由多个独立实体组成,并且彼此通过网络进行互联的数据库。</p>
<p>理解新概念最好的方式就是通过已经掌握的知识来学习,下表对比了大家熟悉的分布式数据库与集中式数据库之间主要的 5 个差异点。</p>
<p><img src="assets/CgpVE2ABTo6AR5YmAAEPyUn_Xrc581.png" alt="png" /></p>
<p>从表中,我们可以总结出<strong>分布式数据库的核心——数据分片、数据同步</strong></p>
<h4>1. 数据分片</h4>
<p>该特性是分布式数据库的技术创新。它可以突破中心化数据库单机的容量限制,从而将数据分散到多节点,以更灵活、高效的方式来处理数据。这是分布式理论带给数据库的一份礼物。</p>
<p>分片方式包括两种。</p>
<ul>
<li>水平分片:按行进行数据分割,数据被切割为一个个数据组,分散到不同节点上。</li>
<li>垂直分片按列进行数据切割一个数据表的模式Schema被切割为多个小的模式。</li>
</ul>
<h4>2. 数据同步</h4>
<p>它是分布式数据库的底线。由于数据库理论传统上是建立在单机数据库基础上,而引入分布式理论后,一致性原则被打破。因此需要引入数据库同步技术来帮助数据库恢复一致性。</p>
<p>简而言之,就是使分布式数据库用起来像“正常的数据库”。所以数据同步背后的推动力,就是人们对数据“一致性”的追求。这两个概念相辅相成,互相作用。</p>
<p>当然分布式数据库还有其他特点,但把握住以上两点,已经足够我们理解它了。下面我将从这两个特性出发,探求技术史上分布式数据库的发展脉络。我会以互联网、云计算等较新的时间节点来进行断代划分,毕竟我们的核心还是着眼现在、面向未来。</p>
<h3>商业数据库</h3>
<p>互联网浪潮之前的数据库,特别是前大数据时代。谈到分布式数据库绕不开的就是 Oracle RAC。</p>
<p><img src="assets/CgqCHmABT3OAWKNmAADhjXR2H_U089.png" alt="png" /></p>
<p>Oracle RAC 是典型的大型商业解决方案,且为软硬件一体化解决方案。我在早年入职国内顶级电信行业解决方案公司的时候,就被其强大的性能所震撼,又为它高昂的价格所深深折服。它是那个时代数据库性能的标杆和极限,是完美方案与商业成就的体现。</p>
<p>我们试着用上面谈到的两个特性来简单分析一下 RAC它确实是做到了数据分片与同步。每一层都是离散化的特别在底层存储使用了 ASM 镜像存储技术,使其看起来像一块完整的大磁盘。</p>
<p>这样做的好处是实现了极致的使用体验,即使用单例数据库与 RAC 集群数据库,在使用上没有明显的区别。它的分布式存储层提供了完整的磁盘功能,使其对应用透明,从而达到扩展性与其他性能之间的平衡。甚至在应对特定规模的数据下,其经济性又有不错的表现。</p>
<p><strong>这种分布式数据库设计被称为“共享存储架构”share disk architecture</strong>。它既是 RAC 强大的关键又是其“阿喀琉斯之踵”DBA 坊间流传的 8 节点的最大集群限制可以被认为是 RAC 的极限规模。</p>
<p>该规模在当时的环境下是完全够用的,但是随着互联网的崛起,一场轰轰烈烈的“运动”将会打破 Oracle RAC 的不败金身。</p>
<h3>大数据</h3>
<p>我们知道 Oracle、DB2 等商业数据库均为 OLTP 与 OLAP 融合数据库。而首先在分布式道路上寻求突破的是 OLAP 领域。在 2000 年伊始,以 Hadoop 为代表的大数据库技术凭借其“无共享”share nothing的技术体系开始向以 Oracle 为代表的关系型数据库发起冲击。</p>
<p><img src="assets/CgpVE2ABT4iAci6AAAE2nfoHLwM617.png" alt="png" /></p>
<p>这是一次水平扩展与垂直扩展,通用经济设备与专用昂贵服务,开源与商业这几组概念的首次大规模碰撞。<strong>拉开了真正意义上分布式数据库的帷幕</strong></p>
<p>当然从一般的观点出发Hadoop 一类的大数据处理平台不应称为数据库。但是从前面我们归纳的两点特性看,它们又确实非常满足。因此我们可以将它们归纳为早期面向商业分析场景的分布式数据库。<strong>从此 OLAP 型数据库开始了自己独立演化的道路</strong></p>
<p>除了 Hadoop另一种被称为 MPP大规模并行处理类型的数据库在此段时间也经历了高速的发展。MPP 数据库的架构图如下:</p>
<p><img src="assets/CgpVE2ABT4-AdI5VAAE42YTeOoQ273.png" alt="png" /></p>
<p>我们可以看到这种数据库与大数据常用的 Hadoop 在架构层面上非常类似,但理念不同。简而言之,它是对 SMP对称多处理器结构、NUMA非一致性存储访问结构这类硬件体系的创新采用 shared-nothing 架构,通过网络将多个 SMP 节点互联,使它们协同工作。</p>
<p>MPP 数据库的特点是首先支持 PB 级的数据处理,同时支持比较丰富的 SQL 分析查询语句。同时,该领域是商业产品的战场,其中不仅仅包含独立厂商,如 Teradata还包含一些巨头玩家如 HP 的 Vertica、EMC 的 Greenplum 等。</p>
<p>大数据技术的发展使 OLAP 分析型数据库从原来的关系型数据库之中独立出来形成了完整的发展分支路径。而随着互联网浪潮的发展OLTP 领域迎来了发展的机遇。</p>
<h3>互联网化</h3>
<p>国内数据库领域进入互联网时代第一个重大事件就是“去 IOE”。</p>
<p><img src="assets/Cip5yGABT5qAM34oAAE2hs8yVAU932.png" alt="png" /></p>
<p>其中尤以“去 Oracle 数据库”产生的影响深远。十年前,阿里巴巴喊出的这个口号深深影响了国内数据库领域,这里我们不去探讨其中细节,也不去评价它正面或负面的影响。但从对于分布式数据库的影响来说,它至少带来两种观念的转变。</p>
<ol>
<li>应用成为核心:去 O 后开源数据库需要配合数据库中间件proxy去使用但这种组合无法实现传统商业库提供的一些关键功能如丰富的 SQL 支持和 ACID 级别的事务。因此应用软件需要进行精心设计,从而保障与新数据库平台的配合。应用架构设计变得非常关键,整个技术架构开始脱离那种具有调侃意味的“面向数据库” 编程,转而变为以应用系统为核心。</li>
<li>弱一致性理念普及:虽然强一致性仍然需求旺盛,但人们慢慢接受了特定场景下可以尝试弱一致性来解决系统的吞吐量问题。而这带来了另外一个益处,一线研发与设计人员开始认真考虑业务需要什么样的一致性,而不是简单依靠数据库提供的特性。</li>
</ol>
<p>以上两个观念都是在破除了对于 Oracle 的迷信后产生的,它们本身是正面的,但是如果没有这场运动,其想要在普通用户之中普及确实有很大困难。而这两种观念也为日后分布式数据库,特别是国产分布式数据的发展带来了积极的影响。</p>
<p>而与此同期,全球范围内又上演着 NoSQL 化浪潮,它与国内去 IOE 运动一起推动着数据库朝着横向分布的方向一路狂奔。关于 NoSQL 的内容,将会在下一讲详细介绍。</p>
<p>与上一部分中提到的大数据技术类似,随着互联网的发展,去 IOE 运动将 OLTP 型数据库从原来的关系型数据库之中分离出来,但这里需要注意的是,<strong>这种分离并不是从基础上构建一个完整的数据库,而是融合了旧有的开源型数据库,同时结合先进的分布式技术,共同构造了一种融合性的“准”数据库</strong>。它是面向具体的应用场景的,所以阉割掉了传统的 OLTP 数据库的一些特性,甚至是一些关键的特性,如子查询与 ACID 事务等。</p>
<p>而 NoSQL 数据库的重点是支持非结构化数据如互联网索引GIS 地理数据和时空数据等。这种数据在传统上会使用关系型数据库存储,但需要将此种数据强行转换为关系型结构,不仅设计烦琐,而且使用效率也比较低下。故<strong>NoSQL 数据库被认为是对整个数据库领域的补充</strong>,从而人们意识到数据库不应该仅仅支持一种数据模式。</p>
<p>随着分布式数据库的发展,一种从基础上全新设计的分布式 OLTP 数据库变得越来越重要,而云计算更是为这种数据库注入新的灵魂,两者的结合将会给分布式数据库带来美妙的化学反应。</p>
<h3>云原生是未来</h3>
<p>从上文可以看到人们真正具有广泛认知的分布式数据库,即 OLTP 型交易式分布式数据库,依然是分布式数据库领域一个缺失的片段,且是一个重要的片段。一个真正的 OLTP 数据库应该具备什么特点呢?</p>
<p>实际上人们需要的是<strong>它既具有一个单机的关系型数据库的特性,又有分布式的分片与同步特性</strong>。 DistributedSQL 和 NewSQL 正是为了这个目的而生的 。它们至少具有如下两点引人注目的特性:</p>
<ol>
<li>SQL 的完整支持</li>
<li>可靠的分布式事务。</li>
</ol>
<p>典型的代表有 Spanner、NuoDB、TiDB 和 Oceanbase 等。并且本课程会重点围绕 DistributedSQL 的关键特性展开研究,这些特性是现代分布式数据库的基石。这里我就不占用过多篇幅介绍了,在 02 | SQL vs NoSQL一次搞清楚五花八门的各种“SQL”中我们再一起详细学习。</p>
<p>与此同时,随着云计算的纵向深入发展,分布式数据库又迎来新的革命浪潮——云原生数据库。</p>
<p>首先,由于云服务天生的“超卖”特性,造成其采购成本较低,从而使终端用户尝试分布式数据库的门槛大大降低。</p>
<p>其次,来自云服务厂商的支撑人员可以与用户可以进行深度的合作,形成了高效的反馈机制。这种反馈机制促使云原生的分布式数据库有机会进行快速的迭代,从而可以积极响应客户的需求。</p>
<p>这就是云原生带给分布式数据库的变化,它是<strong>通过生态系统的优化完成了对传统商业数据库的超越</strong>。以下来自 DB-Engines 的分析数据说明了未来的数据库市场属于分布式数据库,属于云原生数据库。</p>
<p><img src="assets/CgqCHmABT_aAByOoAAH2ctjuqy4281.png" alt="png" /></p>
<p>随着分布式数据库的发展,我们又迎来了新的一次融合:那就是 OLTP 与 OLAP 将再一次合并为 HTAP融合交易分析处理数据库。</p>
<p>该趋势的产生主要来源于云原生 OLTP 型分布式数据库的日趋成熟。同时由于整个行业的发展,客户与厂商对于实时分析型数据库的需求越来越旺盛,但传统上大数据技术包括开源与 MPP 类数据库,强调的是离线分析。</p>
<p>如果要进行秒级的数据处理,那么必须将交易数据与分析数据尽可能地贴近,并减少非实时 ELT 的引入,这就促使了 OLTP 与 OLAP 融合为 HTAP。下图就是阿里云 PolarDB 的 HTAP 架构。</p>
<p><img src="assets/Ciqc1GABT_6AVFtwAAHdreedW2k751.png" alt="png" /></p>
<h3>总结</h3>
<p>用《三国演义》的第一句话来说:“天下大势,分久必合,合久必分。”而我们观察到的分布式数据库,乃至数据库本身的发展正暗合了这句话。</p>
<p><strong>分布式数据库发展就是一个由合到分,再到合的过程</strong></p>
<ol>
<li>早期的关系型商业数据库的分布式能力可以满足大部分用户的场景,因此产生了如 Oracle 等几种巨无霸数据库产品;</li>
<li>OLAP 领域首先寻求突破,演化出了大数据技术与 MPP 类型数据库,提供功能更强的数据分析能力;</li>
<li>去 IOE 引入数据库中间件并结合应用平台与开源单机数据库形成新一代解决方案让商业关系型数据库走下神坛NoSQL 数据库更进一步打破了关系型数据库唯我独尊的江湖地位;</li>
<li>新一代分布式 OLTP 数据库正式完成了分布式领域对数据库核心特性的完整支持,它代表了分布式数据库从此走向了成熟,也表明了 OLAP 与 OLTP 分布式场景下,分别在各自领域内取得了胜利;</li>
<li>HTAP 和多模式数据处理的引入,再一次将 OLAP 与 OLTP 融合,从而将分布式数据库推向如传统商业关系型数据库数十年前那般的盛况,而其产生的影响要比后者更为深远。</li>
</ol>
<p>我们回顾历史目的是更好地掌握未来。在本课程中我们将详细分析现代分布式数据库、OLTP 型数据库的关键技术、使用场景和应用案例。使你在未来可以更好地评估和使用分布式数据库。</p>
<p><strong>分布式数据库的历史同时体现了实用主义的特色</strong>,其演化是需求与技术博弈的结果,而不是精心设计出来的。我们的课程也会体现出实用主义的特点,让你学以致用,学有所获。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/24讲吃透分布式数据库-完/00 开篇词 吃透分布式数据库,提升职场竞争力.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/24讲吃透分布式数据库-完/02 SQL vs NoSQL一次搞清楚五花八门的“SQL”.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70996ddc0ea53d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>