1、知识框架图

2、MySQL可扩展的理解

2.1 可扩展的定义?与高可用的区别?

2.2 扩展与投入的关系?

2.3 扩展和拆分的概念区别?

3、垂直拆分

4、水平拆分

关注下面几个核心问题:

4.1 什么是水平拆分?

4.2 拆分原则有哪些?

4.3 如何进行水平拆分,有哪些切片方式,优劣比较?

4.4 如何选择分区键?

4.5 如何生成全局唯一ID?

5、实践

6、参考资料

一、知识框架图

二、可扩展的理解

可扩展性,是指随着系统负载的扩充,系统的可持续扩充能力,是一种软件系统处理能力相关的设计指标。系统扩充中,在尽量不影响现有系统的前提下,能够通过较少的变更或新增硬件资源,就能获取系统处理能力的提升,保持高性能。理解了这层定义,就不难理解可扩展和高可用的区别。“可扩展”代表了系统的伸缩能力,当系统负载迅速变高时,能以较小代价的调整来扩充系统的处理能力,持续提供有效支撑。而”高可用“则关注了有效服务处理能力的持续可用性,比如系统单点故障、某些节点的性能瓶颈导致服务无法响应或处理能力严重降低、宕机等都属于高可用相关。

       关于扩展与收益的关系。现实中大部分系统都不能获得线性扩展,而是以更低的扩展系数进行扩展。这部分可以参考USL可扩展性定律(《高性能mysql》)。 注意,存在扩展系数高于线性扩展的情况,比如某些条件下扩充一倍的缓存资源后,应用程序的查询命中率获得了超出一倍的提升,这个要结合场景具体分析。

关于”扩展“和“拆分”的概念理解。当数据量大到一定程度后,读写效率会降低,如果想保持mysql服务器高效运转的话,就需要想办法进行扩展,比如各种分库分表方案。在《高性能Mysql》一书中,作者划分了”垂直扩展“,”水平扩展“,”向内扩展“,”多实例“,”集群“等多种方式。在《Mysql运维内参》中则主要关注了“水平拆分”和“垂直拆分”。起先并没意识到“扩展”和“拆分”的区别,其实两者切入点还是不同的,个人理解如下:“扩展”侧重于mysql服务器方面,“拆分”则更多是数据库(设计)层面。垂直扩展是想办法提升单机硬件性能,提升单实例的狐狸能力;而水平扩展的思路则是将数据库分布到多台机器上,分化负载。整体的关系可以参考第一部分的知识结构图,本篇文章主要是谈谈对“拆分”的理解和总结。

三、垂直拆分

垂直拆分,所谓的”垂直"可以理解为被分隔后的数据库相互独立且各不相同,一般在考虑拆分时应优先考虑垂直拆分。

比如一个论坛将用户数据和内容数据统一存储到单个数据库,随着业务量的增长,单个库已不能满足读写TPS量。这时研发人员对业务架构进行重构升级,拆分出3个业务库帖子、评论、用户,部署到同一个实例,暂时满足需求;

业务量进一步增长,单个数据库实例已经接近性能瓶颈,无法满足快速增长的存储需求和高并发需求,研发人员将3个业务库分别拆分到单独的mysql实例上;

业务量进一步增长,又面临DB瓶颈,研发人员这次将三个库的多张表分别拆分到多个实例上,比如将用户数据的多张表遍布于多个实例中,缓存了服务器压力。

业务量进一步增长,用户数达到数亿级,不同运营部门对数据的处理和使用需求日益增多和多样化,热帖的并发访问量巨大,这时垂直拆分已经无法满足,需要考虑使用水平拆分了。


上面只是个简单的例子。另外,在业务发展中因为原先数据库设计不合理或单表容量过大等原因而对表结构进行改造,将单表拆分为多张不同结构的表也属于垂直拆分,如下图, “垂直拆分”的优点是各部分数据仍然是相对完整的对象,并没有显著降低业务的理解复杂度和处理复杂度。但如果数据量持续膨胀,垂直拆分并非终极解决方案,当单表容量超过数百G时,很难满足公司的多查询维度和高并发场景。个人觉得这部分关键是 理解什么是垂直拆分,何时可进行拆分,如何从某切入点(业务,实例,库,表等)进行拆分,垂直拆分的扩展局限性等。

四、水平拆分

什么是水平拆分?

拆分原则有哪些?

如何进行水平拆分,有哪些切片方式,优劣比较?

如何选择分区键?

如何生成全局唯一ID?

(1)什么是水平拆分?

水平拆分是对某个库或表按照指定算法或规则拆分为多个相同结构的库或表,以减少单库/表体积,将读写请求分配到各分库或分表上从而成倍的提高整体处理能力。下面是一个案例,

最初是一张订单表,承载用户中心、支付中心、商户中心等多个部门的写请求和多维度查询请求。单表容量迅速达到了上千万条记录,研发同学先将订单表按用户id拆分为10个表,降低每张表的容量。为了满足商户中心查询需求同时减少对订单应用的影响,又通过复制和处理组件得到一份按商户id分表的备份,如下。 ==>>>

单库吞吐能力成为瓶颈,研发同学按照特定分库分表算法将订单库拆分为多库多表,这是能满足今后几年业务发展了。==》

(2)拆分原则有哪些?

原则1:能不拆就不拆。

一般建议能不拆就不拆,而是优先考虑使用常用方法,如提升服务器性能,使用读写分离,优化数据库设计,使用和优化索引。现实中,存储模型与业务模型有一定关系,一定程度上反映了业务逻辑,任何拆分行为都或多或少的提升业务处理复杂度。分库分表可能会造成查询、合并和更新条件的分离,以及事务的分离(分库时可能要使用分布式事务保证数据强一致),使得业务处理时必须考虑这些因素,成倍提高了复杂度。

下面是需要拆分的场景,

原则2:数据量太大,日常的运维影响了正常的业务访问

数据量太大,单库或单表数据很大(比如超过5千万条记录),此时日常备份、迁移数据、更新等运维需求会影响服务器处理能力,造成业务响应变慢,部分业务处理失败。此时,需考虑拆分。

> 备份、迁移数据:资源瓶颈是磁盘IO和网络IO;

> 更新:DDL时会长时间锁表,影响业务访问;热点数据频繁更新,会造成锁等待,表压力大,经常出问题。

原则3:某些数据出现了无穷增长

这个场景的典型案例是微博和社交评论系统的数据存储。比如大V的每条微博都会扩散给上千万粉丝,可能一些索引或路由有存储需求,此时最佳解决方案是水平切分,使用按用户、日期、用途、类别等各种方式。(延伸下... 实际中,这个场景在设计层面有个“推拉模式”来做优化,参考“微博fed系统推拉模式和时间分区模式架构谈谈”http://www.cnblogs.com/sunli/archive/2010/08/24/twitter_feeds_push_pull.html 和 新浪微博架构和FEED架构分析 http://blog.sina.com.cn/s/blog_53b95aec0100ujim.html )

原则4:业务耦合性考虑,拆分不同业务或对单业务重构模型

从业务高度,需要对业务架构和技术架构进行重构升级,比如将一个论坛数据库拆分为用户、文章、评论三个库,或者将用户中心、商户中心的数据库拆分到不同的实例中以避免相互干扰。

原则5:表设计不合理,需要对某些表字段做拆分

见“垂直拆分”部分的例子。

原则6:安全性和可用性的考虑

分库分表客观上提升了安全性和高可用,单个实例的问题不至于影响整体业务。

(3)如何进行水平拆分,有哪些切片方式,优劣比较?     

《高性能mysql》中作者将切分方式划分为几大类:固定分配、动态分配、混合分配、显示分配。分类方式有很多,这里暂时遵循着书中的这个框架来。

3.1 固定分配

指借助于固定规则的分区函数,只使用分区键就能计算出分库分表的结果,常用的hash和取模、移位、按顺序运算都属于这类,见上图x。

优点是简单、高效、未引入外部依赖等;

缺点是

a. 分片较少时,难以平衡负载;

b. 无法自定义将数据放到哪个分片,可能出现热点数据分布不合理的情况。比如按商户id进行hash运算时,几个大商户的数据被放置到同一张表,造成该表压力很大。

c. 修改分配策略比较麻烦。比如原先的分表规则是%32, 后来数据据量增大需增加分表数量,遂将策略调整为%64,需要提前做数据迁移工作。

3.2 动态分配

将分区键和分库分表的映射关系提前配置和存储,该存储节点所存的内容相当于分配函数。

优点是能够细粒度的控制“分配规则”,比如将热点数据均匀分布在多个库或表中,将不同用途的数据做隔离等;

缺点是引入外部依赖,可用性和效率方面不如固定分配等。

3.3 混合分配

综合使用固定规则和动态配置两种策略,取两者优点,适用于一些特殊场景。比如根据url字段做分片,可以先对url做hash运算得出一个数值,然后根据动态分配方式映射到具体分表。

3.4 显式分配

将数据分片编码到ID中,感觉和静态分配本质上是一样的。见https://tech.meituan.com/dianping_order_db_sharding.html的分表键格式方案。

【这部分这样分类不是特别好理解,就实际中接触的项目中,使用最多的hash、取模、按顺序(如时间)等,需要根据业务数据的存储和处理特性来确定最佳方式。】 

(4)如何选择分区键 ?     

首先要明白分区键的功能和影响,然后思考下随便选个分区键会产生什么问题?实际中应该根据业务需求来选择适用的分区键,避免跨分片查询,方便存取且尽量不降低存取性能。

查询维度是多样的,有时可能需要多个分区键,比如在做一个评论应用中,有需要根据用户ID来查询用户所有的评论,也需要根据文章ID查询所有的评论,我们按用户ID或文章ID分片都不是好方法,因为总有一种要跨分片查询,我们的做法是存两份,分别以用户ID和文章ID进行分表,以满足上述两种查询场景。

有些数据遍布在个分片,又需要频繁跨片查询,可以分析是否有其他等同策略。还是上面提到的评论应用,能够将一些信息抽象为整体数据,比如数量统计,可以抽取出单张公共表。

这部分的重点是“选择分区键的方法”、“多分区键”、“跨分片查询问题”、“跨分片数据一致性”。

(5)全局唯一ID的生成     

全局唯一ID推荐几个优秀的资源,

1. 美团的分布式ID生成系统     https://tech.meituan.com/MT_Leaf.html

2. 阅文集团分布式ID (类snowflake方法)              https://mp.weixin.qq.com/s?__biz=MzIxMzgxMjQ1Mw==&mid=2247483661&idx=1&sn=4e459c618a2169f994f62f28f2159eba&chksm=97b05487a0c7dd91e45cd2c9d0dcc837586ee2652abc9efb3252e69b1bd2d6b2bb450c8c2e58&mpshare=1&scene=2&srcid=0525IV9AydzO0CEN4CXkEFuk&key=cf192bba2f919fcb70ed66331b7f4f5d4c61927abd688c4674e6088b2743fb2e495a694189f8dab322e8030e8a9143b9932ed7851e58024d51807a665ab48b9c0bd8f176efa0b7383fe7e857d55eddb6&ascene=0&uin=MjM3ODQzNjgwMA%3D%3D&devicetype=iMac+Macmini7%2C1+OSX+OSX+10.11.5+build(15F34)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=iZnDMUQlGa2cTsRI6ffMQ%2B585Qs0ZJK0s9FedcMFAmailXPsFNG2IPQ3oF3mBt5o

3. 贝聊亿级数据库分库分表实践 https://zhuanlan.zhihu.com/p/27363448

4. 唯品会订单分库分表实践  http://www.infoq.com/cn/articles/summary-and-key-steps-of-vip-orders-depots-table

5. 大众点评订单分库分表实践  https://tech.meituan.com/dianping_order_db_sharding.html

五、实践

我们这边目前使用的是类似“数据库生成-步长方案”,数据库和代码片段如下。
数据库表:
+-------------+--------------+------+-----+-------------------+-----------------------------+
| Field       | Type         | Null | Key | Default           | Extra                       |
+-------------+--------------+------+-----+-------------------+-----------------------------+
| biz_tag     | varchar(128) | NO   | PRI |                   |                             |
| max_id      | bigint(20)   | NO   |     | 1                 |                             |
| step        | int(11)      | NO   |     | NULL              |                             |
| desc        | varchar(256) | YES  |     | NULL              |                             |
| update_time | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+--------------+------+-----+-------------------+-----------------------------+

代码摘要:IdTypeEnum即接入业务的枚举,

六、参考资料

1、《高性能mysql》第三版

2、《mysql运维内参》

mysql可扩展(读书笔记)相关推荐

  1. mysql数据库teach_读书笔记 - 《MYSQL必知必会》

    术语: 数据库 , 表 , 模式 , 列 , 数据类型 , 行 , 主键 命令行: mysql -u ben -p -h myserver -P 9999 检索 SELECT 列名 FROM 表名; ...

  2. MySQL高级特性 读书笔记

    MySQL高级特性 1. 分区表 对于用户来说,分区表是一个独立的逻辑表,但是底层由多个物理子表组成.实现分区的代码实际上是对一组底层表的句柄对象的封装 以下场景分区表可以起到非常大的作用: 1. 表 ...

  3. MYSQL常用函数 读书笔记

    此书的学习笔记 字符串函数 函数 功能 用例 查询字符串信息 length(string) string的字节个数 LENGTH('adc哈') -> 6 char_length(string) ...

  4. MySQL技术内幕读书笔记(一)——Mysql体系结构和存储引擎

    目录 MySQL体系结构和存储引擎 定义数据库和实例 MYSQL体系结构 MYSQL存储引擎 MySQL体系结构和存储引擎 定义数据库和实例 数据库:物理操作系统文件或者其他形式文件类型的结合.在MY ...

  5. php和mysql web开发 笔记_PHP和MySQL Web开发读书笔记---创建Web数据库

    先写个题外话,老是要忘记,byte和bit的区别,1byte=8bit,即一个字节有8位 1.创建权限 GRANT命令 GRANT privileges [columns]          //pr ...

  6. 深入浅出mysql基础篇读书笔记

    版本8.0.25 1.p19 int(2)已经不推荐了 2.p28 无序排列改为按原表顺序排列会更好,无序也没错,但是容易被误解为随机排列(类似HashMap),但其实是按照原表顺序排列 3.p29 ...

  7. mysql数据库权威指南_MySQL_MySQL权威指南读书笔记(三),第二章:MYSQL数据库里面的数 - phpStudy...

    MySQL权威指南读书笔记(三) 第二章:MYSQL数据库里面的数据 用想用好MYSQL,就必须透彻理解MYSQL是如何看待和处理数据的.本章主要讨论了两个问题:一是SQL所能处理的数据值的类型:二是 ...

  8. 【SQL】【读书笔记】《MySQL必知必会》

    本文为<MySQL必知必会>[1]读书笔记,用于总结知识点和框架,仅供参考和交流,如有不妥请联系.由于软件版本更新,书中的一些代码已经不再适用,本文主要从SQL基本语句进行增删减.窗口函数 ...

  9. 读书笔记系列1——MySQL必知必会

    读书笔记系列1--MySQL必知必会 文章目录 读书笔记系列1--MySQL必知必会 MySQL官方文档:https://dev.mysql.com/doc/ 第一章 数据库基础 *2021.11.2 ...

最新文章

  1. EntityFramework之原始查询及性能优化(六)
  2. 无厘头的mysql故障排除
  3. pandas Series 的索引对象(一)
  4. (21)页目录表,页表基址(XP系统 10-10-12分页模式)
  5. 使用OpenSSL进行RSA加密和解密(非对称)
  6. 从 Flink 应用场景出发,了解它的设计思路
  7. 使用SQL Agent和SignalR的每日提醒
  8. 主板有电无法启动_电脑无法开机?这篇文章让你省下几百修理费
  9. php中取整的函数,php中四舍五入取整函数详细介绍
  10. java list数据的更新_新增页面提交数据 list页面没有更新数据
  11. MapServer使用笔记(二)
  12. php使用p12证书调用第三方接口
  13. 瑞星:愚人节Conficker蠕虫未在我国爆发
  14. CSS 框架 Bulma 教程
  15. 【论文阅读】The Generals’ Scuttlebutt: Byzantine-Resilient Gossip Protocols
  16. phpinfo()是什么
  17. 计算机网络:P4.1-网络层(上)
  18. 小程序中消息订阅与发布
  19. 中国十大可行性研究报告公司
  20. confirm点确认跳转,点取消关闭

热门文章

  1. Python机器学习12——神经网络
  2. 小米手机搭载鸿蒙,弃安卓支持华为,小米新机要率先搭载鸿蒙,这话到底是谁说的...
  3. oracle11g 联机重做日志、归档日志、日志文件组以及日志文件操作
  4. QT 编写Rtf(富文本格式) 文件实例
  5. 楼市低迷 看地方政府如何挽救财政
  6. 电子元器件篇---电阻
  7. 08 - vulhub - Aria2 任意文件写入漏洞
  8. HTML+CSS系列教程
  9. Android UI SVGA使用
  10. 在WSL中启动Ubuntu 20.04时出现错误[出现错误 2147942402 (0x80070002) (启动“ubuntu2004.exe”时)]