0
点赞
收藏
分享

微信扫一扫

MySQL-分库分表初探



文章目录

  • ​​生猛干货​​
  • ​​官方文档​​
  • ​​主从复制 解决不了 主节点DB写的的压力​​
  • ​​常见的分库分表的方式​​
  • ​​分库​​
  • ​​分表​​
  • ​​DB分片前的准备​​
  • ​​如何选择分区键 ,尽量避免跨分片查询​​
  • ​​如何存储无需分片的表​​
  • ​​如何在节点上部署分片​​
  • ​​如何分配分片中的数据​​
  • ​​如何生成全局唯一ID​​
  • ​​使用oneProxyp 分库分表演示​​
  • ​​目标效果​​
  • ​​oneProxyp​​
  • ​​简介​​
  • ​​下载安装使用​​
  • ​​搞定MySQL​​


MySQL-分库分表初探_数据库

生猛干货

​​带你搞定MySQL实战,轻松对应海量业务处理及高并发需求,从容应对大场面试​​

官方文档

​​https://dev.mysql.com/doc/​​

MySQL-分库分表初探_mysql_02

如果英文不好的话,可以参考 ​​searchdoc​​ 翻译的中文版本

​​​http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html​​

MySQL-分库分表初探_分库分表_03

主从复制 解决不了 主节点DB写的的压力

我们前面的 主从复制 构建的高可用的架构中,主要解决的是 主节点 读的压力。 (通常情况下,一个系统中的读请求占据绝大部分)

那主节点的 写请求呢? — 主从复制高可用架构解决不了了。。。。。

当然了,你可以增加硬件配置,这里我们不讨论。我们这里要讨论的是 通过分库分表 来解决 主节点 写的压力。

常见的分库分表的方式

有个MySQL的集群哈

分库

两种方式,如下

  • 方式一: 把一个实例中的多个数据库拆分到不同的实例

    假设我们是个电商系统, DB集群中有 订单、用户、促销 三个数据库。

    MySQL-分库分表初探_mysql_04

当然了,如果你的情况是: 订单节点的写入压力比较大,你这样拆也解决不了问题。

那就需要第二种方式了

  • 方式二: 把一个库中的表分离到不同的数据库中 。

MySQL-分库分表初探_数据_05

原来写的压力 都在 一个节点上,这样才到不同的数据库上,原来一个节点的写压力,就被分散到了3个节点上。

如果 随着业务的发展,订单的DB 写压力 又扛不住了呢? -----------> 那只有终极大招-----> 分表

分表

分表 : 就是对一个库中的相关表 进行水平拆分到不同实例的数据库中。

这一块很复杂,坑太多。。。。。 一句话,能不分就不分。

举个订单的表的分表后的例子。

MySQL-分库分表初探_数据库_06

DB分片前的准备

如何选择分区键 ,尽量避免跨分片查询

  • 分区键要能尽量避免跨分片查询的发生 ,

    举个例子,博客系统 ,如果我们按照博客id hash进行分片,那么这个blog_id 会分配到各个节点上,那么查询某个用户的博客, 不得不去所有的数据库上去查询。 但如果按照user_id分呢? 那只要查询一个数据库就可以了。 就避免了跨分区的查询

  • 分区键要尽可能的使各个分配片中数据平均

    分片的目的,是为了降低数据库的写负载,如果分片不均匀,大部分数据都写到一个节点上了,这个节点很累,其他节点闲的没事儿,那么这个分片还有啥意义???

比较好的方式,如果 分完以后,你的查询能包含这个分区键,那就非常好了。

如何存储无需分片的表

一个库中,大部分的表,是没有必要分片的,只有几个写入非常频繁的表,才需要分片。

那不用分片的如何存储呢?

  • 每个分片中存储一份相同的数据

    这种方法通常用于: 表本身数据量不大,而且不怎么变更的表,比如字典表。 查询也经常关联这种表,每个分片都有的话,这样的话 就不用跨分片查询了,提高查询效率。

    当然了,缺点要维护多个分片的一致性,避免不一致导致查询出错。

  • 使用额外的节点统一存储

    需要查询的话,由应用来分别查询,然后组合了。 效率不如第一种,但好在不用去维护数据一致性。

如何在节点上部署分片

  • 方式一: 每个分片使用单一的数据库,并且数据库名也相同

  • 方式二: 将多个分片表存储在一个数据库中,并在表名上加入分片号后缀
    这个是对表进行编号

  • 方式三: 在一个节点中部署多个数据库,每个数据库包含一个分片

    这个是对数据库进行编号

  • 其他方式。。。。

如何分配分片中的数据

数据如何分布,对查询的性能,影响很大。

这个平均包括 : 数据分部平均,第二 并发访问也要平均

  • 方式一: 按照分区键的hash值取模来分配分片数据

    先hash再取模, 并不是所有的分区键都是数字,所以最好hash一下

    如果是自增id为主键,也可以不用hash, 直接取模就行。

    举个例子 10个分片, 101 这个该存在哪个分片呢 ?

    101 % 10 = 1 ----> 第一个分分片 。

  • 方式二: 按照分区键的范围来分配数据

    举个例子 10个分片 ,第一个分片存 1 - 100 ,第二个 101 -199 依次类推

    那101 放哪里呢 ----> 第二个分片

    常用于 分区键为 日期类型或者数值类型的场景。

    优点: 很容易知道放哪里

    缺点: 容易造成数据的分配不平均 ,从而导致访问也不平均。

    比如一个 在线题库,以 课程id作为分区键来分区, 但是Java这个课,大家都爱选这个,导致运行一段时间后,java课程的那个分片,压力特别大,所以前期设计要充分考量。

  • 方式三:利用分区键和分片的映射表来分配分片数据

    使用第三种方式,方便控制

    需要建立一张 分区键和分片的映射表, 先通过查询映射表 来查询具体的分区。

    这个表的压力比较大, 记得做缓存。

如何生成全局唯一ID

这个可能是最关键的了

  • 方式一: 单节点的话,可以采用auto_increament_increament和 auto_increament_offset 参数

  • 方式二: 分片的话 ,也可以用 可以采用auto_increament_increament和 auto_increament_offset 参数

    auto_increament_increament 和 分片数目相同

    比如 6个节点, auto_increament_increament 就要设置为6 ,auto_increament_offset 分别设置为 1到 6 ,每个节点相同表的自增id ,不冲突。

    但这个只适用于 一个节点 只有一套分片表的情况。

  • 方式二:全局节点

    弄个全局表 ,但这个表有可能成为瓶颈,所以引入第三种

  • 方式三: 使用redis代替全局节点,Redis缓存服务器中创建全局ID

  • 其他方式。。。。

使用oneProxyp 分库分表演示

目标效果

MySQL-分库分表初探_分库分表_07

解释下

原来在一个节点中存储了 订单表 + 订单商品表 + 分类表

经过分库分表后

两个节点

节点1 : 存储 订单表 01 + 订单商品表 01 + 分类表 (每个节点数据一致,冗余)

节点1 : 存储 订单表 02 + 订单商品表 02 + 分类表 (每个节点数据一致,冗余)

oneProxyp

简介

OneProxy 中间件是具备透明读写分离、分库分表功能的数据库中间件,轻松构建分布式数据库集群,支持Oracle/MySQL等多种数据库

下载安装使用

带后续使用的话补充,这里有个思路即可。

链接:​​​https://pan.baidu.com/s/15kdQ-Q2u1sT063A-Qa2tdg​​

提取码:pbp9

搞定MySQL




举报

相关推荐

0 条评论