learn.lianglianglee.com/专栏/MySQL实战宝典/19 高可用套件:选择这么多,你该如何选?.md.html
2022-05-11 18:52:13 +08:00

779 lines
22 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>19 高可用套件:选择这么多,你该如何选?.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="/专栏/MySQL实战宝典/00 开篇词 从业务出发,开启海量 MySQL 架构设计.md">00 开篇词 从业务出发,开启海量 MySQL 架构设计.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/01 数字类型:避免自增踩坑.md">01 数字类型:避免自增踩坑.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/02 字符串类型:不能忽略的 COLLATION.md">02 字符串类型:不能忽略的 COLLATION.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/03 日期类型TIMESTAMP 可能是巨坑.md">03 日期类型TIMESTAMP 可能是巨坑.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/04 非结构存储:用好 JSON 这张牌.md">04 非结构存储:用好 JSON 这张牌.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/05 表结构设计:忘记范式准则.md">05 表结构设计:忘记范式准则.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/06 表压缩:不仅仅是空间压缩.md">06 表压缩:不仅仅是空间压缩.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/07 表的访问设计:你该选择 SQL 还是 NoSQL.md">07 表的访问设计:你该选择 SQL 还是 NoSQL.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/08 索引:排序的艺术.md">08 索引:排序的艺术.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/09 索引组织表:万物皆索引.md">09 索引组织表:万物皆索引.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/10 组合索引:用好,性能提升 10 倍!.md">10 组合索引:用好,性能提升 10 倍!.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/11 索引出错:请理解 CBO 的工作原理.md">11 索引出错:请理解 CBO 的工作原理.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/12 JOIN 连接:到底能不能写 JOIN.md">12 JOIN 连接:到底能不能写 JOIN.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/13 子查询:放心地使用子查询功能吧!.md">13 子查询:放心地使用子查询功能吧!.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/14 分区表:哪些场景我不建议用分区表?.md">14 分区表:哪些场景我不建议用分区表?.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/15 MySQL 复制:最简单也最容易配置出错.md">15 MySQL 复制:最简单也最容易配置出错.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/16 读写分离设计:复制延迟?其实是你用错了.md">16 读写分离设计:复制延迟?其实是你用错了.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/17 高可用设计:你怎么活用三大架构方案?.md">17 高可用设计:你怎么活用三大架构方案?.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/18 金融级高可用架构:必不可少的数据核对.md">18 金融级高可用架构:必不可少的数据核对.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/MySQL实战宝典/19 高可用套件:选择这么多,你该如何选?.md">19 高可用套件:选择这么多,你该如何选?.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/20 InnoDB Cluster改变历史的新产品.md">20 InnoDB Cluster改变历史的新产品.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/21 数据库备份:备份文件也要检查!.md">21 数据库备份:备份文件也要检查!.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/22 分布式数据库架构:彻底理解什么叫分布式数据库.md">22 分布式数据库架构:彻底理解什么叫分布式数据库.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/23 分布式数据库表结构设计:如何正确地将数据分片?.md">23 分布式数据库表结构设计:如何正确地将数据分片?.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/24 分布式数据库索引设计:二级索引、全局索引的最佳设计实践.md">24 分布式数据库索引设计:二级索引、全局索引的最佳设计实践.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/25 分布式数据库架构选型:分库分表 or 中间件 .md">25 分布式数据库架构选型:分库分表 or 中间件 .md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/26 分布式设计之禅:全链路的条带化设计.md">26 分布式设计之禅:全链路的条带化设计.md.html</a>
</li>
<li>
<a href="/专栏/MySQL实战宝典/27 分布式事务:我们到底要不要使用 2PC.md">27 分布式事务:我们到底要不要使用 2PC.md.html</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>19 高可用套件:选择这么多,你该如何选?</h1>
<p>在 17、18 讲中,我们已经学习了 MySQL 数据库的高可用解决方案,并且学习了怎么根据金融业务的要求,通过无损半同步复制的方式进行三园区的同城容灾设计,以及三地务中心的跨城容灾设计。</p>
<p>但是当数据库发生宕机时MySQL 的主从复制并不会自动地切换,这需要高可用套件对数据库主从进行管理。</p>
<p>这一讲,我们就来学习 MySQL 常用的高可用套件,希望你在学完今天的内容之后,能够理解高可用套件的实现原理,将高可用套件用于自己的生产环境。</p>
<h3>高可用套件</h3>
<p>MySQL 的高可用套件用于负责数据库的 Failover 操作也就是当数据库发生宕机时MySQL 可以剔除原有主机,选出新的主机,然后对外提供服务,保证业务的连续性。</p>
<p>可以看到MySQL 复制是高可用的技术基础用于将数据实时同步到从机。高可用套件是MySQL 高可用实现的解决方案,负责切换新主机。</p>
<p>为了不让业务感知到数据库的宕机切换,这里要用到 VIPVirtual IP技术。其中VIP 不是真实的物理 IP而是可以随意绑定在任何一台服务器上。</p>
<p>业务访问数据库,不是服务器上与网卡绑定的物理 IP而是这台服务器上的 VIP。当数据库服务器发生宕机时高可用套件会把 VIP 插拔到新的服务器上。数据库 Failover后业务依旧访问的还是 VIP所以使用 VIP 可以做到对业务透明。</p>
<p>下面这张图显示了业务通过 VIP 进行数据库的访问:</p>
<p><img src="assets/CioPOWDVmJeAKFW4AACnY-tPNl8837.png" alt="Drawing 0.png" /></p>
<p>从上图可以看到MySQL 的主服务器的 IP 地址是 192.168.1.10,两个从服务器的 IP 地址分别为 192.168.1.20、192.168.1.30。</p>
<p>上层服务访问数据库并没有直接通过物理 IP 192.168.1.10,而是访问 VIP地址为192.168.1.100。这时,如果 MySQL 数据库主服务器发生宕机,会进行如下的处理:</p>
<p><img src="assets/Cgp9HWDVmJ6ATYQPAAC1xJ9Zf2M275.png" alt="Drawing 1.png" /></p>
<p>我们可以看到,当发生 Failover 后,由于上层服务访问的是 VIP 192.168.1.100,所以切换对服务来说是透明的,只是在切换过程中,服务会收到连接数据库失败的提示。但是通过重试机制,当下层数据库完成切换后,服务就可以继续使用了。所以,上层服务一定要做好错误重试的逻辑,否则就算启用 VIP也无法实现透明的切换。</p>
<p>但是 VIP 也是有局限性的,仅限于同机房同网段的 IP 设定。如果是我们之前设计的三园区同城跨机房容灾架构VIP 就不可用了。这时就要用名字服务,常见的名字服务就是 DNSDomain Name Service如下所示</p>
<p><img src="assets/Cgp9HWDVmKSATzziAADNdCl83J0164.png" alt="Drawing 2.png" /></p>
<p>从上图可以看到,这里将域名 m1.insidemysql.com 对应的 IP 指向为了 192.168.1.10,上层业务通过域名进行访问。当发生宕机,进行机房级切换后,结果变为:</p>
<p><img src="assets/Cgp9HWDVmKqAfnSUAADHqckLKlU955.png" alt="Drawing 3.png" /></p>
<p>可以看到,当发生 Failover 后,高可用套件会把域名指向为新的 MySQL 主服务器IP 地址为202.177.54.20,这样也实现了对于上层服务的透明性。</p>
<p>虽然使用域名或其他名字服务可以解决跨机房的切换问题,但是引入了新的组件。新组件的高可用的问题也需要特别注意。在架构设计时,请咨询公司提供名字服务的小组,和他们一起设计高可用的容灾架构。</p>
<p>了解了上述的高可用透明切换机制,我们继续看一下业界 MySQL 常见的几款高可用套件。</p>
<h3>MHA</h3>
<p>MHA(Master High Availability)是一款开源的 MySQL 高可用程序,它为 MySQL 数据库主从复制架构提供了 automating master failover 的功能。</p>
<p>MHA 是由业界大名鼎鼎的 Facebook 工程师 Yoshinorim 开发,开源地址为:<a href="https://github.com/yoshinorim/mha4mysql-manager">https://github.com/yoshinorim/mha4mysql-manager</a>它由两大组件所组成MHA Manger 和 MHA Node。</p>
<p>MHA Manager 通常部署在一台服务器上,用来判断多个 MySQL 高可用组是否可用。当发现有主服务器发生宕机,就发起 failover 操作。MHA Manger 可以看作是 failover 的总控服务器。</p>
<p>而 MHA Node 部署在每台 MySQL 服务器上MHA Manager 通过执行 Node 节点的脚本完成failover 切换操作。</p>
<p>MHA Manager 和 MHA Node 的通信是采用 ssh 的方式,也就是需要在生产环境中打通 MHA Manager 到所有 MySQL 节点的 ssh 策略,那么这里就存在潜在的安全风险。</p>
<p>另外ssh 通信效率也不是特别高。所以MHA 比较适合用于规模不是特别大的公司所有MySQL 数据库的服务器数量不超过 20 台。</p>
<p><img src="assets/Cgp9HWDVmMOAevY4AAEiqr35GSw848.png" alt="Drawing 4.png" />!</p>
<h3>Orchestrator</h3>
<p>Orchestrator 是另一款开源的 MySQL 高可用套件,除了支持 failover 的切换还可通过Orchestrator 完成 MySQL 数据库的一些简单的复制管理操作。Orchestrator 的开源地址为:<a href="https://github.com/openark/orchestrator">https://github.com/openark/orchestrator</a></p>
<p>你可以把 Orchestrator 当成 MHA 的升级版,而且提供了 HTTP 接口来进行相关数据库的操作,比起 MHA 需要每次登录 MHA Manager 服务器来说,方便很多。</p>
<p>下图显示了 Orchestrator 的高可用设计架构:</p>
<p><img src="assets/CioPOWDVmLaAd1fTAAOTUVey1gw096.png" alt="Drawing 5.png" /></p>
<p>其基本实现原理与 MHA 是一样的只是把元数据信息存储在了元数据库中并且提供了HTTP 接口和命令的访问方式,使用上更为友好。</p>
<p>但是由于管控节点到下面的 MySQL 数据库的管理依然是 ssh 的方式,依然存在 MHA 一样的短板问题,总的来说,关于 Orchestrator 我想提醒你,依然只建议使用在较小规模的数据库集群。</p>
<h3>数据库管理平台</h3>
<p>当然了,虽然 MHA 和 Orchestrator 都可以完成 MySQL 高可用的 failover 操作,但是,在生产环境中如果需要管理成千乃至上万的数据库服务器,由于它们的通信仅采用 ssh 的方式,并不能满足生产上的安全性和性能的要求。</p>
<p>所以,几乎每家互联网公司都会自研一个数据库的管理平台,用于管理公司所有的数据库集群,以及数据库的容灾切换工作。</p>
<p>接下来,我想带你详细了解数据库管理平台的架构。下图显示了数据库管理平台大致的实现框架:</p>
<p><img src="assets/CioPOWDVmNeAdMXUAAD0Ll-5ibs948.png" alt="Drawing 6.png" /></p>
<p>上图中的数据库管理平台是用户操作数据库的入口。对数据库的大部分操作,比如数据库的初始化、数据查询、数据备份等操作、后续都能在这个平台完成,不用登录数据库服务器,这样的好处是能大大提升数据库操作的效率。</p>
<p>数据库管理平台提供了 HTTP API 的方式,可用前后端分离的方式支持 Web、手机等多种访问方式。</p>
<p>元数据库用于存储管理 MySQL 数据库所有的节点信息,比如 IP 地址、端口、域名等。</p>
<p>数据库管理平台 Manager 用来实际控制下面的所有 MySQL 节点Manager 和后端 MySQL 的通信通过 MySQL 服务器上部署的 agent 方式进行。两者通过 BP 协议以 grpc 的方式通信。这样解决了 ssh 的不安全性以及性能。</p>
<p>其中agent 用来上报数据库各节点的状态给 Manager管理节点 Manager 通过上报的信息判断数据库是否宕机,是否需要进行切换,切换到哪个节点。</p>
<p>上图的设计,能完成一个比较基本的数据库管理平台。另外,每个公司有自己的一些需求,也可以做到数据库管理平台中,比如安全要求、审计需求、工单系统等。</p>
<p>所以,有了数据库管理平台,数据库的高可用切换、数据库日常管理和访问,都可以由平台自动完成。有了数据库管理平台,才能真正实现数据库管理的无人驾驶。</p>
<h3>总结</h3>
<p>这一讲我们主要学习了 MySQL 数据库的高可用套件,我们知道 MySQL 复制是高可用实现的技术基础,但是需要高可用套件才能完成 Failover 的操作。MySQL 复制技术本身不能实现failover 的功能。</p>
<p>为了实现数据切换的透明性,可以采用 VIP 和名字服务机制。VIP 仅用于同机房同网段,名字服务器,比如域名可以跨机房进行切换。</p>
<p>MySQL 常用的高可用套件有 MHA 和 Orchestrator它们都能完成 failover 的工作。但是由于管理节点与 MySQL 通信采用 ssh 协议,所以安全性不高,性能也很一般,一般建议用在不超过 20 台数据库节点的环境中。</p>
<p>对于要管理 MySQL 数量比较多的场景,推荐自研数据库平台,这样能结合每家公司的不同特性,设计出 MySQL 数据库的自动管理平台,这样才能解放 DBA 的生产力,投入业务的优化工作中去。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/MySQL实战宝典/18 金融级高可用架构:必不可少的数据核对.md">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/MySQL实战宝典/20 InnoDB Cluster改变历史的新产品.md">下一页</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":"70997324daee3d60","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>