mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-24 12:16:39 +08:00
263 lines
19 KiB
HTML
263 lines
19 KiB
HTML
<!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>00 开篇词 从业务出发,开启海量 MySQL 架构设计.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 class="current-tab" href="/专栏/MySQL实战宝典/00 开篇词 从业务出发,开启海量 MySQL 架构设计.md.html">00 开篇词 从业务出发,开启海量 MySQL 架构设计</a>
|
||
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/01 数字类型:避免自增踩坑.md.html">01 数字类型:避免自增踩坑</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/02 字符串类型:不能忽略的 COLLATION.md.html">02 字符串类型:不能忽略的 COLLATION</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/03 日期类型:TIMESTAMP 可能是巨坑.md.html">03 日期类型:TIMESTAMP 可能是巨坑</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/04 非结构存储:用好 JSON 这张牌.md.html">04 非结构存储:用好 JSON 这张牌</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/05 表结构设计:忘记范式准则.md.html">05 表结构设计:忘记范式准则</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/06 表压缩:不仅仅是空间压缩.md.html">06 表压缩:不仅仅是空间压缩</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/07 表的访问设计:你该选择 SQL 还是 NoSQL?.md.html">07 表的访问设计:你该选择 SQL 还是 NoSQL?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/08 索引:排序的艺术.md.html">08 索引:排序的艺术</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/09 索引组织表:万物皆索引.md.html">09 索引组织表:万物皆索引</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/10 组合索引:用好,性能提升 10 倍!.md.html">10 组合索引:用好,性能提升 10 倍!</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/11 索引出错:请理解 CBO 的工作原理.md.html">11 索引出错:请理解 CBO 的工作原理</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/12 JOIN 连接:到底能不能写 JOIN?.md.html">12 JOIN 连接:到底能不能写 JOIN?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/13 子查询:放心地使用子查询功能吧!.md.html">13 子查询:放心地使用子查询功能吧!</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/14 分区表:哪些场景我不建议用分区表?.md.html">14 分区表:哪些场景我不建议用分区表?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/15 MySQL 复制:最简单也最容易配置出错.md.html">15 MySQL 复制:最简单也最容易配置出错</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/16 读写分离设计:复制延迟?其实是你用错了.md.html">16 读写分离设计:复制延迟?其实是你用错了</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/17 高可用设计:你怎么活用三大架构方案?.md.html">17 高可用设计:你怎么活用三大架构方案?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/18 金融级高可用架构:必不可少的数据核对.md.html">18 金融级高可用架构:必不可少的数据核对</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/19 高可用套件:选择这么多,你该如何选?.md.html">19 高可用套件:选择这么多,你该如何选?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/20 InnoDB Cluster:改变历史的新产品.md.html">20 InnoDB Cluster:改变历史的新产品</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/21 数据库备份:备份文件也要检查!.md.html">21 数据库备份:备份文件也要检查!</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/22 分布式数据库架构:彻底理解什么叫分布式数据库.md.html">22 分布式数据库架构:彻底理解什么叫分布式数据库</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/23 分布式数据库表结构设计:如何正确地将数据分片?.md.html">23 分布式数据库表结构设计:如何正确地将数据分片?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/24 分布式数据库索引设计:二级索引、全局索引的最佳设计实践.md.html">24 分布式数据库索引设计:二级索引、全局索引的最佳设计实践</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/25 分布式数据库架构选型:分库分表 or 中间件 ?.md.html">25 分布式数据库架构选型:分库分表 or 中间件 ?</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/26 分布式设计之禅:全链路的条带化设计.md.html">26 分布式设计之禅:全链路的条带化设计</a>
|
||
</li>
|
||
<li>
|
||
<a href="/专栏/MySQL实战宝典/27 分布式事务:我们到底要不要使用 2PC?.md.html">27 分布式事务:我们到底要不要使用 2PC?</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>00 开篇词 从业务出发,开启海量 MySQL 架构设计</h1>
|
||
<p>你好,我是姜承尧(常用ID:破产码农),目前是腾讯金融数据平台与研发中心总监。</p>
|
||
<p>我与 MySQL 结缘已有十余年,最开始在久游开启了数据库职业生涯,接着在网易负责数据库内核、云数据库开发,现在腾讯负责金融支付系统的数据库开发。</p>
|
||
<p>毕业至今,我一直从事 MySQL 相关的工作(比如运维、平台开发、内核开发、云计算开发),经历了无数个 DBA 必经的通宵之旅,也因此累积了无数架构实战经验。</p>
|
||
<h3>我与 MySQL 相伴相随</h3>
|
||
<p>在久游工作时,我负责全国最为热火的网游劲舞团,那时只要说你是负责劲舞团的 DBA,身上都闪着光芒,但谁又能想到,我曾遇到过连续 72 小时的加班回档全服游戏数据。为了避免再次发生类似情况,<strong>早在 2008 年我就在久游设计了多实例高可用架构</strong>,并结合 LVM 快照功能,防止下一次游戏升级可能导致的业务数据错乱等情况。</p>
|
||
<p>我可以说是<strong>国内最早从事 MySQL 内核工作的 DBA</strong>。那时随着海量数据的不断发展,业务对于 MySQL 数据库的要求变得更为“苛刻”,不但要能够使用 MySQL,还要能对内核进行额外的开发。为此,我深入 MySQL 内核设计领域,为迎合 SSD 技术的发展,独立开发了 SBP(Secondary Buffer Pool)架构,并在久游、网易等业务中大规模使用。</p>
|
||
<p>在网易期间,我发现 MySQL 数据半同步复制功能不断改进,当时就预见它将很快进入金融核心业务领域,于是<strong>主导网易开源 MySQL 分支版本 InnoSQL,设计并开发出金融级 MySQL 高可用架构 VSR,VSR 同时作为开源数据库组件,成功应用于某四大行核心系统</strong>。</p>
|
||
<p>2017 年来到腾讯后,我<strong>主导了新一代腾讯金融核心数据库架构的设计与研发</strong>工作,让各位小伙伴所使用的金融与支付功能得到了更为安全的保障。</p>
|
||
<p><strong>可以说,MySQL 数据库在互联网业务中的成功,让我获益良多:</strong></p>
|
||
<ul>
|
||
<li>收入不断攀升,比起其他种类数据库,MySQL 收入显然优势突出。目前,一线城市的数据库从业人员要达到 50 万是很轻松的一件事情,若去互联网公司,薪资可以说上不封顶。</li>
|
||
<li>作为一份职业的成就感,MySQL 带给我太多的“感动”。伴随着互联网的崛起,MySQL 已经成为互联网公司数据库的标准配置。看到自己运维开发的数据库能够支撑数以万计的用户,这种感觉真的是好极了。</li>
|
||
</ul>
|
||
<p>我时常思考,如何将自己这么多年在 MySQL 方面的知识沉淀形成方法论进行输出,<strong>希望能有更多的同学享受到 MySQL 发展的红利。</strong></p>
|
||
<h3>怎么用好 MySQL 呢</h3>
|
||
<p>虽然这些年先后出版过 <strong>《MySQL技术内幕》《MySQL内核》</strong> 系列三本书,但相对理论,每本书的方向都较为专一,未能有效地<strong>从整个业务的全链路角度去分享一个互联网海量 MySQL 架构的实现</strong>。</p>
|
||
<p>同样,纵观整个业界,各技术书籍也好,在线课程也罢,都只专注于怎么用好 MySQL 的某一个功能,并没有<strong>站在业务的角度去考虑,怎么设计一个海量并发业务的 MySQL 数据库架构</strong>。</p>
|
||
<blockquote>
|
||
<p>比如,站在理论角度看,自增的 INT 类型用于主键没有问题,但站在类似双 11、春节红包的业务角度看,INT 类型做核心业务主键非常不可取,甚至会带来无尽的麻烦。</p>
|
||
<p>再比如,你肯定知道用MySQL 复制技术可以搭建一个高可用架构,但结合不同业务类型,一定要数据库层去完成高可用的架构吗?不一定!因为数据库是有状态的,当发生问题时,切换速度可能比较慢,你其实可以通过与业务相结合的方法去设计一套高可用的架构。</p>
|
||
</blockquote>
|
||
<p>总之,数据库学到最后,要与业务紧密结合,站在业务的角度,全流程地进行思考,这样才能设计出真正好用的数据库架构。</p>
|
||
<p>非常有幸,收到拉勾教育平台的邀请,给了我再次进行 MySQL 创作的动力,拉勾网上有许多技术同学,他们有着一颗对知识渴望的心,希望学习对其工作真正有帮助的课程。</p>
|
||
<p>所以我将着力打造好这门课程,结合现阶段你学习 MySQL 时存在的痛点,<strong>如对于 MySQL 8.0 新特性与业务结合、金融级数据库高可用设计、分布式架构设计能力等,</strong> 用自己超过 15 年的一线 MySQL 工作经验,帮助你从业务全流程的角度看待数据库系统,设计出一个基于 MySQL 的海量并发系统。同时,也希望你能在学完这门课程后,形成自己的数据库架构方法论,并积极交流与探讨,不断成长。</p>
|
||
<h3>课程设计</h3>
|
||
<p>总的来说,我通过表结构设计、索引设计、高可用架构设计、分布式架构设计,由浅入深、循序渐进地与你一起<strong>打造出一个能支撑海量的并发访问的分布式 MySQL 架构。</strong></p>
|
||
<p><strong>模块一:表结构设计</strong>,该模块中我会以实际的业务为案例分析,先带你分析不同字段类型的选型,然后再学习 MySQL 中表的设计,比如表结构设计、访问设计、物理存储设计。通过模块一解决你表结构设计的痛点问题,让你打好架构设计最为基础的工作。</p>
|
||
<p>又因为单表的设计不足以支撑业务上线,所以在学完“表结构设计”后,<strong>模块二就是索引的设计</strong>。在该模块中,我会通过讲述索引的基本原理,层层推进到索引的创建和优化,最后触达复杂 SQL 索引的设计与调优,比如多表 JOIN、子查询、分区表的问题。希望学完这部分内容之后,你能解决线上所有的 SQL 问题,不论是 OLTP 业务,还是复杂的 OLAP 业务。</p>
|
||
<p>那么在讲完表结构与索引设计之后,业务上线必不可少的就是高可用的环节,而 MySQL 作为一个开源的数据库,虽然提供了大量的高可用解决方案,但或多或少存在不少问题。所以<strong>模块三高可用的架构设计</strong>中,我会层层递进,手把手教你搭建一个完整的、可靠的、符合各种业务类型的高可用解决方案。</p>
|
||
<p>除此之外,海量的业务还会涉及分布式架构的设计,这其实对当前业务与 DBA 同学来说,是非常具有挑战性的技术难点。而在<strong>模块四分布式架构</strong>中,我将会从分布式架构概述、分布式表结构设计、分布式索引设计、分布式事务等角度展开。相信我,学完这部分内容,你会觉得分布式并不是一个很难的架构,对于各种分布式架构中的难题,可以做到信手拈来。</p>
|
||
<p><strong>模块五偏向拓展</strong>,是对一些数据库设计中热门话题的分析,当你学完前四部分的内容后,进阶学习这些问题,能从更宏观、更上层的角度去设计出一个更好的架构,解决对应的问题,比如热点更新问题、数据迁移等问题。</p>
|
||
<p>总的来说,这门课值得你期待,也是我所认为最具有架构实战的 MySQL课程,所以我希望你能认真钻研、学透这门课程,早日成为一名真正合格的数据库架构师。</p>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
|
||
<div style="float: right">
|
||
<a href="/专栏/MySQL实战宝典/01 数字类型:避免自增踩坑.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":"709972f8ba013d60","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>
|