精华内容
下载资源
问答
  • mysql分库分表面试题
    2020-11-02 12:46:36

    975dd84da8c8a92ec2b91c2c88acc34e.png

    数据库数据过大的系统架构-mysql分库分表高可用面试题

    如果当你的数据量达到千万级,亿级的时候,我们用常规的方式去做优化那么效果可能就不是很好了。这已经不是说性能的问题了,而是数据量响应的处理问题了,所以我们需要针对根本的问题去使用对应的技术去进行彻底的解决

    如果对于这块技术内容不是很熟悉的话,或者没有去真正接触到这样的一个大项目实战,那么你在面试的时候你可能就只能答出一些技术名词来了,而有一些解决方案,细节问题你可能就答不上来了,可能你就嗝屁了。

    1.目前准备做数据库水平切分,需要注意什么关键问题?目前了解需要避免跨库事务。

    答:(1)需要注意分库patition key的选取,要保证两个均衡:数据量的均衡,请求量的均衡。

    (2)库后,需要注意分之前用SQL满足的需求是否还能满足,需要怎么改进满足,例如max, min, avg, sum都需要在服务层再做一次聚合。

    (3)夸库事务,分布式事务,在吞吐量是主要矛盾的互联网场景,目前没有能够很好解决的方案,尽量避免。

    2.如果分库分表的情况下碰到要对一个表或多个表关联并且按多个字段为条件进行检索的情况下怎么办呢?

    答:分库后join怎么办:

    (1)前端用户侧业务,流量大,并发大,join真的很少,58同城用户库几亿数据,帖子库300亿数据,没有join。

    (2)如果真要join,分库后冗余数据、索引表、分页,for循环低效查询 -> 总能解决的,只是看性能是不是主要矛盾、一致性是不是主要矛盾了。

    (3)拆成小sql是互联网的玩法,互联网很少用join、子查询、视图、外键、用户自定义函数、存储过程的。当然,我指面向用户侧的高并发业务。

    3.采用hash取模方式的表扩容策略及采用一致性hash分表的表扩容策略如何实现?

    答:数据库水平切分的方式,常用的有两种:

    (1)hash取模:user_id%2=0为0库,user_id%2=1为1库。

    (2)数据分段:user_id属于[0, 1亿]为0库,属于[1亿, 2亿]为2库。

    方案一

    优点:简单、数据均衡、负载均衡。

    缺点:扩容困难,要迁移数据,%2变%3麻烦。

    方案二

    优点:简单、数据均衡、扩容简单。

    缺点:负载不均衡,大号段的库往往压力更大。

    大部分互联网公司使用方案一。

    4.设定网站用户数量在千万级,但是活跃用户数量只有1%,如何通过优化数据库提高活跃用户访问速度?

    答:(1)可以使用MySQL的分区,把活跃用户分在一个区,不活跃用户分在另外一个区,本身活跃用户区数据量比较少,因此可以提高活跃用户访问速度。
    (2)还可以水平分表,把活跃用户分在一张表,不活跃用户分在另一张表,可以提高活跃用户访问速度。

    5.分库分表之后,id 主键如何处理

    (1)数据库自增 id

    这个就是说你的系统里每次得到一个 id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个 id。拿到这个 id 之后再往对应的分库分表里去写入。

    (2)设置数据库 sequence 或者表自增字段步长

    可以通过设置数据库 sequence 或者表的自增字段步长来进行水平伸缩。

    6.现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统从未分库分表动态切换到分库分表上?

    答:双写迁移方案。同时写俩库,老库和新库。然后系统部署之后,新库数据差太远,用之前说的导数工具,跑起来读老库数据写新库,写的时候要根据 gmt_modified 这类字段判断这条数据最后修改的时间,除非是读出来的数据在新库里没有,或者是比新库的数据新才会写。导完一轮之后,有可能数据还是存在不一致,那么就程序自动做一轮校验,比对新老库每个表的每条数据,接着如果有不一样的,就针对那些不一样的,从老库读数据再次写。反复循环,直到两个库每个表的数据都完全一致为止。

    7.你们具体是如何对数据库如何进行垂直拆分或水平拆分的?

    一般来说,垂直拆分,你可以在表层面来做,对一些字段特别多的表做一下拆分;水平拆分,你可以说是并发承载不了,或者是数据量太大,容量承载不了,拆了,按什么字段来拆。分表,你如果哪怕是拆到每个库里去,并发和容量都ok了,但是每个库的表还是太大了,那么你就分表,将这个表分开,保证每个表的数据量并不是很大。

    8.分库分表的拆分方式有?他们分别主要解决什么问题?

    (1)水平切分,主要解决单表过大造成的性能问题,单表过大造成的单服务器空间问题。

    (2)垂直切分,主要解决表与表之间资源争用问题,锁争用机率小,实现核心与非核心的分级存储,如UDB登陆库拆分成一级二级三级库,数据库同步压力问题。

    ·

    更多相关内容
  • 分库分表 基本分库分表: 1:分库分表 2:分库表冗余 3:分区表 分布式事务 1:XA分布式事务 2:TCC分布式事务 3:消息分布式事务 Mycat分片规则 Mycat读写分离 Mycat故障切换 Mycat+Percona+Haproxy+keepalived Zookeeper...
  • 5 MySQL分库分表动态扩容缩容 6 Mysql读写分离 7 MySQL分库分表id主键处理 8Mysql集群部署实现主从复制读写分离分表分库 1 问题分析: 1.1 背景 随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的...

    目录

    1 问题分析:

    1.1 背景

    1.2 业务分库

    1.3 数据库分表

    2 为什么要分库分表?

    3 用过哪些分库分表中间件?

    3.1 你们具体是如何对数据库如何进行垂直拆分或水平拆分的?

    4 Mysql将现有表进行分表分库

    5 MySQL分库分表动态扩容缩容

    6 Mysql读写分离

    7 MySQL分库分表id主键处理

    8 Mysql集群部署实现主从复制读写分离分表分库


    以下内容参考微信公众号石杉的架构笔记,欢迎大家关注,结合文章内容写一些自己的补充和心得感悟

    1 问题分析:

    1.1 背景

    随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量。

    数据库的扩展方式主要包括:业务分库、主从复制,数据库分表。

    1.2 业务分库

    业务分库指的是按照业务模块将数据分散到不同的数据库服务器。例如,一个简单的电商网站,包括用户、商品、订单三个业务模块,我们可以将用户数据、商品数据、订单数据分开放到三台不同的数据库服务器上,而不是将所有数据都放在一台数据库服务器上。这样的就变成了3个数据库同时承担压力,系统的吞吐量自然就提高了。

    虽然业务分库能够分散存储和访问压力,但同时也带来了新的问题,接下来我进行详细分析

    join 操作问题

    业务分库后,原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 join 查询。

    事务问题

    原本在同一个数据库中不同的表可以在同一个事务中修改,业务分库后,表分散到不同的数据库中,无法通过事务统一修改。

    成本问题

    业务分库同时也带来了成本的代价,本来 1 台服务器搞定的事情,现在要 3 台,如果考虑备份,那就是 2 台变成了 6 台。

    1.3 数据库分表

    将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。例如,淘宝的几亿用户数据,如果全部存放在一台数据库服务器的一张表中,肯定是无法满足性能要求的,此时就需要对单表数据进行拆分。

    单表数据拆分有两种方式:垂直分表和水平分表。示意图如下:

    垂直拆分:比如交友网,查询匹配信息基本就是年龄和性别,至于昵称和描述很少有人单独查询,所以拆出去提升性能,长字段很影响查询性能,也就是不常用的,只有匹配到才会展示,不用每次都去查询。

    单表进行切分后,是否要将切分后的多个表分散在不同的数据库服务器中,可以根据实际的切分效果来确定。如果性能能够满足业务要求,是可以不拆分到多台数据库服务器的,毕竟我们在上面业务分库的内容看到业务分库也会引入很多复杂性的问题。分表能够有效地分散存储压力和带来性能提升,但和分库一样,也会引入各种复杂性:

    • 垂直分表:
      • 垂直分表适合将表中某些不常用且占了大量空间的列拆分出去。
      • 例如,前面示意图中的 nickname 和 description 字段,假设我们是一个婚恋网站,用户在筛选其他用户的时候,主要是用 age 和 sex 两个字段进行查询,而 nickname 和 description 两个字段主要用于展示,一般不会在业务查询中用到。description 本身又比较长,因此我们可以将这两个字段独立到另外一张表中,这样在查询 age 和 sex 时,就能带来一定的性能提升。
    • 水平分表:
      • 水平分表适合表行数特别大的表,有的公司要求单表行数超过 5000 万就必须进行分表,这个数字可以作为参考,但并不是绝对标准,关键还是要看表的访问性能。对于一些比较复杂的表,可能超过 1000 万就要分表了;而对于一些简单的表,即使存储数据超过 1 亿行,也可以不分表。
      • 但不管怎样,当看到表的数据量达到千万级别时,作为架构师就要警觉起来,因为这很可能是架构的性能瓶颈或者隐患。

    水平分表相比垂直分表,会引入更多的复杂性,例如数据id:

    • 主键自增:
      • 以最常见的用户 ID 为例,可以按照 1000000 的范围大小进行分段,1 ~ 999999 放到表 1中,1000000 ~ 1999999 放到表2中,以此类推。
      • 复杂点:分段大小的选取。分段太小会导致切分后子表数量过多增加维护复杂度分段太大可能会导致单表依然存在性能问题,一般建议分段大小在 100 万至 2000 万之间,具体需要根据业务选取合适的分段大小。
      • 优点:可以随着数据的增加平滑地扩充新的表。例如,现在的用户是 100 万,如果增加到 1000 万,只需要增加新的表就可以了,原有的数据不需要动。
      • 缺点:分布不均匀,假如按照 1000 万来进行分表,有可能某个分段实际存储的数据量只有 1000 条,而另外一个分段实际存储的数据量有 900 万条。
    • Hash :
      • 同样以用户 ID 为例,假如我们一开始就规划了 10 个数据库表,路由算法可以简单地用 user_id % 10 的值来表示数据所属的数据库表编号,ID 为 985 的用户放到编号为 5 的子表中,ID 为 10086 的用户放到编号为 6 的字表中。
      • 复杂点:初始表数量的选取。表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题。
      • 优点:表分布比较均匀。
      • 缺点:扩充新的表很麻烦,所有数据都要重分布。

    主键自增的优点是hash的缺点,hash的优点是主键自增的缺点.

    • 雪花算法:分布式ID生成器
      • 雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。
      • 核心思想:
        • 长度共64bit(一个long型)。
        • 首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。
        • 41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。
        • 10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。
        • 12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。

    为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的?

    其实这块肯定是扯到高并发了,因为分库分表一定是为了支撑高并发、数据量大两个问题的。而且现在说实话,尤其是互联网类的公司面试,基本上都会来这么一下,分库分表如此普遍的技术问题,不问实在是不行,而如果你不知道那也实在是说不过去!

    2 为什么要分库分表?

    (设计高并发系统的时候,数据库层面该如何设计?)

    说白了,分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。

    我先给大家抛出来一个场景。

    假如我们现在是一个小创业公司(或者是一个 BAT 公司刚兴起的一个新部门),现在注册用户就 20 万,每天活跃用户就 1 万,每天单表数据量就 1000,然后高峰期每秒钟并发请求最多就 10。天,就这种系统,随便找一个有几年工作经验的,然后带几个刚培训出来的,随便干干都可以。

    结果没想到我们运气居然这么好,碰上个 CEO 带着我们走上了康庄大道,业务发展迅猛,过了几个月,注册用户数达到了 2000 万!每天活跃用户数 100 万!每天单表数据量 10 万条!高峰期每秒最大请求达到 1000!同时公司还顺带着融资了两轮,进账了几个亿人民币啊!公司估值达到了惊人的几亿美金!这是小独角兽的节奏!

    好吧,没事,现在大家感觉压力已经有点大了,为啥呢?因为每天多 10 万条数据,一个月就多 300 万条数据,现在咱们单表已经几百万数据了,马上就破千万了。但是勉强还能撑着。高峰期请求现在是 1000,咱们线上部署了几台机器,负载均衡搞了一下,数据库撑 1000QPS 也还凑合。但是大家现在开始感觉有点担心了,接下来咋整呢......

    再接下来几个月,我的天,CEO 太牛逼了,公司用户数已经达到 1 亿,公司继续融资几十亿人民币啊!公司估值达到了惊人的几十亿美金,成为了国内今年最牛逼的明星创业公司!天,我们太幸运了。

    但是我们同时也是不幸的,因为此时每天活跃用户数上千万,每天单表新增数据多达 50 万,目前一个表总数据量都已经达到了两三千万了!扛不住啊!数据库磁盘容量不断消耗掉!高峰期并发达到惊人的 5000~8000!别开玩笑了,哥。我跟你保证,你的系统支撑不到现在,已经挂掉了!

    好吧,所以你看到这里差不多就理解分库分表是怎么回事儿了,实际上这是跟着你的公司业务发展走的,你公司业务发展越好,用户就越多,数据量越大,请求量越大,那你单个数据库一定扛不住。

    分表

    比如你单表都几千万数据了,你确定你能扛住么?绝对不行,单表数据量太大,会极大影响你的 sql 执行的性能,到了后面你的 sql 可能就跑的很慢了。一般来说,就以我的经验来看,单表到几百万的时候,性能就会相对差一些了,你就得分表了。

    分表是啥意思?就是把一个表的数据放到多个表中,然后查询的时候你就查一个表。比如按照用户 id 来分表,将一个用户的数据就放在一个表中。然后操作的时候你对一个用户就操作那个表就好了。这样可以控制每个表的数据量在可控的范围内,比如每个表就固定在 200 万以内。

    分库

    分库是啥意思?就是你一个库一般我们经验而言,最多支撑到并发 2000,一定要扩容了,而且一个健康的单库并发值你最好保持在每秒 1000 左右,不要太大。那么你可以将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。

    这就是所谓的分库分表,为啥要分库分表?你明白了吧。

    分库分表前分库分表后
    并发支撑情况MySQL 单机部署,扛不住高并发MySQL从单机到多机,能承受的并发增加了多倍
    磁盘使用情况MySQL 单机磁盘容量几乎撑满拆分为多个库,数据库服务器磁盘使用率大大降低
    SQL 执行性能单表数据量太大,SQL 越跑越慢单表数据量减少,SQL 执行效率明显提升

    3 用过哪些分库分表中间件?

    不同的分库分表中间件都有什么优点和缺点?

    这个其实就是看看你了解哪些分库分表的中间件,各个中间件的优缺点是啥?然后你用过哪些分库分表的中间件。

    比较常见的包括:

    • Cobar
    • TDDL
    • Atlas
    • Sharding-jdbc
    • Mycat

    Cobar

    阿里 b2b 团队开发和开源的,属于 proxy 层方案,就是介于应用服务器和数据库服务器之间。应用程序通过 JDBC 驱动访问 Cobar 集群,Cobar 根据 SQL 和分库规则对 SQL 做分解,然后分发到 MySQL 集群不同的数据库实例上执行。早些年还可以用,但是最近几年都没更新了,基本没啥人用,差不多算是被抛弃的状态吧。而且不支持读写分离、存储过程、跨库 join 和分页等操作。

    TDDL

    淘宝团队开发的,属于 client 层方案。支持基本的 crud 语法和读写分离,但不支持 join、多表查询等语法。目前使用的也不多,因为还依赖淘宝的 diamond 配置管理系统。

    Atlas

    360 开源的,属于 proxy 层方案,以前是有一些公司在用的,但是确实有一个很大的问题就是社区最新的维护都在 5 年前了。所以,现在用的公司基本也很少了。

    Sharding-jdbc

    当当开源的,属于 client 层方案,目前已经更名为 ShardingSphere(后文所提到的 Sharding-jdbc,等同于 ShardingSphere)。确实之前用的还比较多一些,因为 SQL 语法支持也比较多,没有太多限制,而且截至 2019.4,已经推出到了 4.0.0-RC1 版本,支持分库分表、读写分离、分布式 id 生成、柔性事务(最大努力送达型事务、TCC 事务)。而且确实之前使用的公司会比较多一些(这个在官网有登记使用的公司,可以看到从 2017 年一直到现在,是有不少公司在用的),目前社区也还一直在开发和维护,还算是比较活跃,个人认为算是一个现在也可以选择的方案

    Mycat

    基于 Cobar 改造的,属于 proxy 层方案,支持的功能非常完善,而且目前应该是非常火的而且不断流行的数据库中间件,社区很活跃,也有一些公司开始在用了。但是确实相比于 Sharding jdbc 来说,年轻一些,经历的锤炼少一些。

    总结

    综上,现在其实建议考量的,就是 Sharding-jdbc 和 Mycat,这两个都可以去考虑使用。

    Sharding-jdbc 这种 client 层方案的优点在于不用部署,运维成本低,不需要代理层的二次转发请求,性能很高,但是如果遇到升级啥的需要各个系统都重新升级版本再发布,各个系统都需要耦合 Sharding-jdbc 的依赖;

    Mycat 这种 proxy 层方案的缺点在于需要部署,自己运维一套中间件,运维成本高,但是好处在于对于各个项目是透明的,如果遇到升级之类的都是自己中间件那里搞就行了。

    通常来说,这两个方案其实都可以选用,但是我个人建议中小型公司选用 Sharding-jdbc,client 层方案轻便,而且维护成本低,不需要额外增派人手,而且中小型公司系统复杂度会低一些,项目也没那么多;但是中大型公司最好还是选用 Mycat 这类 proxy 层方案,因为可能大公司系统和项目非常多,团队很大,人员充足,那么最好是专门弄个人来研究和维护 Mycat,然后大量项目直接透明使用即可。

    3.1 你们具体是如何对数据库如何进行垂直拆分或水平拆分的?

    水平拆分的意思,就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。水平拆分的意义,就是将数据均匀放更多的库里,然后用多个库来扛更高的并发,还有就是用多个库的存储容量来进行扩容。

    database-split-horizon

    垂直拆分的意思,就是把一个有很多字段的表给拆分成多个表或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会将较少的访问频率很高的字段放到一个表里去,然后将较多的访问频率很低的字段放到另外一个表里去。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。

    database-split-vertically

    这个其实挺常见的,不一定我说,大家很多同学可能自己都做过,把一个大表拆开,订单表、订单支付表、订单商品表。

    还有表层面的拆分,就是分表,将一个表变成 N 个表,就是让每个表的数据量控制在一定范围内,保证 SQL 的性能。否则单表数据量越大,SQL 性能就越差。一般是 200 万行左右,不要太多,但是也得看具体你怎么操作,也可能是 500 万,或者是 100 万。你的SQL越复杂,就最好让单表行数越少。

    好了,无论分库还是分表,上面说的那些数据库中间件都是可以支持的。就是基本上那些中间件可以做到你分库分表之后,中间件可以根据你指定的某个字段值,比如说 userid,自动路由到对应的库上去,然后再自动路由到对应的表里去

    你就得考虑一下,你的项目里该如何分库分表?一般来说,垂直拆分,你可以在表层面来做,对一些字段特别多的表做一下拆分;水平拆分,你可以说是并发承载不了,或者是数据量太大,容量承载不了,你给拆了,按什么字段来拆,你自己想好;分表,你考虑一下,你如果哪怕是拆到每个库里去,并发和容量都 ok 了,但是每个库的表还是太大了,那么你就分表,将这个表分开,保证每个表的数据量并不是很大。

    而且这儿还有两种分库分表的方式

    • 一种是按照 range 来分,就是每个库一段连续的数据,这个一般是按比如时间范围来的,但是这种一般较少用,因为很容易产生热点问题,大量的流量都打在最新的数据上了。
    • 或者是按照某个字段 hash 一下均匀分散,这个较为常用。

    range 来分,好处在于说,扩容的时候很简单,因为你只要预备好,给每个月都准备一个库就可以了,到了一个新的月份的时候,自然而然,就会写新的库了;缺点,但是大部分的请求,都是访问最新的数据。实际生产用 range,要看场景。

    hash 分发,好处在于说,可以平均分配每个库的数据量和请求压力;坏处在于说扩容起来比较麻烦,会有一个数据迁移的过程,之前的数据需要重新计算 hash 值重新分配到不同的库或表。

    4 Mysql将现有表进行分表分库

    Mysql将现有表进行分表分库https://blog.csdn.net/ZGL_cyy/article/details/112383748

    5 MySQL分库分表动态扩容缩容

    MySQL分库分表动态扩容缩容https://blog.csdn.net/ZGL_cyy/article/details/112383767

    6 Mysql读写分离

    Mysql读写分离https://blog.csdn.net/ZGL_cyy/article/details/112383791

    7 MySQL分库分表id主键处理

    MySQL分库分表id主键处理https://blog.csdn.net/ZGL_cyy/article/details/112383821

    8 Mysql集群部署实现主从复制读写分离分表分库

    Mysql集群部署实现主从复制读写分离分表分库_赵广陆的博客-CSDN博客目录1 集群1.1 集群的概念1.2 集群的原理2 Mycat环境搭建2.1 Mycat下载和安装2.2 环境准备3 主从复制4 读写分离5 分库分表1 集群1.1 集群的概念如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系型数据库已经无法满足快速查询与插入数据的需求。一台数据库服务器已经无法满足海量数据的存储需求,所以由多台数据库构成的数据库集群成了必然的方式。不过,为了保证数据的一致性,查询效率等,同时又要解决多台服务器间的通信https://blog.csdn.net/ZGL_cyy/article/details/122299663

    展开全文
  • 这期树懒君决定分享一下分库分表方面的面试题目,这是一个很经典的面试问题哦~ 首先,要知道分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。下面直接上问题! 1.分区...

     

    上期我们讲了索引,MyISAM和InnoDB的选择等相关的数据库面试题目,小伙伴们掌握得怎么样了?这期树懒君决定分享一下分库分表方面的面试题目,这是一个很经典的面试问题哦~

    首先,要知道分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。下面直接上问题!

    1.分区方案有哪些?

    分区表是由多个相关的底表实现的。这些基础表也由句柄对象表示,因此我们也可以直接访问各个区域,存储引擎管理区域的各个基础表与管理普通表相同(所有基础表都必须使用相同的存储引擎),区域表的索引只是在各个基础表相同的索引。该方案屏蔽了用户的细节,即使查询条件没有sharding column,也能正常工作。

    2.MySQL分区能做什么?

    • 分割逻辑数据
    • 提高单一的写作和阅读应用速度。
    • 提高分区范围阅读查询速度。
    • 分割数据能够有多个不同的物理文件路径
    • 高效保存历史数据。

    3.分区的类型

    • RANGE区域:根据给定连续区间的列值,将多行分配给区域。mysql根据指定的分割战略,将数据放入不同的表格文件中。相当于文件,被拆成小块。但是,对外给顾客的感觉是表,是透明的。
    • 根据range,每个库的连续数据,这一般在时间范围内,如交易表、销售表等,可以根据年月保管数据。可能会出现热点问题,大量的流量都在最新数据上。
    • 分range的好处是,扩张时很简单。
    • 类似于RANGE分区,每个分区都必须明确定义。其主要区别在于,LIST分区中每个分区的定义和选择是基于某个列的值从属于一个列的值集中在一个列的值中,而RANGE分区从属于一个连续区间值集中在一起。
    • 根据用户定义的表现式回归值进行选择的区域,将该表现式插入表中的列值进行计算。该功能包括MySQL中有效、产生非负整数值的表现。
    • hash分发的优点是,可以平均分配各仓库的数据量和请求压力的缺点是扩麻烦,有数据转移的过程,以前的数据需要重新计算hash值,重新分配到不同的库和表。
    • KEY分区:类似于HASH区域,KEY区域只支持计算一列或多列,MySQL服务器提供自己的哈希函数。必须有一列或多列包含整数值。

    4.为什么大部分互联网不使用分区,而是自己分库分表?

    许多资源受单体限制,如连接数量、网络吞吐等。如何进行隔断,在实际应用中是十分关键的要素之一。

    5.为什么要分库分表?

    从性能上看

    随着单库数据量越来越大,数据库查询QPS越来越高,数据库读写所需的时间也越来越多。数据库的读写性能可能成为业务发展的瓶颈。相应地,需要优化数据库的性能。本文只讨论数据库水平的优化,不讨论缓存等应用水平的优化手段。

    如果数据库查询QPS过高,就需要考虑拆库,通过分库分担单个数据库的连接压力。例如,如果查询QPS为3500,假设单个库可以支持1000个连接数,则可以考虑将其分成4个库来分散查询连接压力。

    单表数据量过大时,数据量超过一定量级后,无论是数据查询还是数据更新,在索引优化等纯数据库水平的传统优化手段后,都可能存在性能问题。这是量的变化产生了质的变化。此时,有必要改变解决问题的想法。例如,从数据生产的源头、数据处理的源头解决问题。既然数据量很大,我们就分别治疗,成零。这产生了分钟,将数据按照一定的规则分成多个钟表,解决了在钟表环境下无法解决的访问性能问题。

    从可用性上看

    如果单个数据库发生事故,很可能会丢失所有数据。特别是在云时代,许多数据库都在虚拟机上行驶。如果虚拟机/宿主机发生事故,可能会造成无法挽回的损失。因此,除了传统的Master-Slave、Master-Master等部署水平,还可以考虑从数据分割水平解决这个问题。

    此处我们以数据库宕机为例:

    • 单库部署情况下,如果数据库宕机,那么故障影响就是100%,而且恢复可能耗时很长。
    • 如果我们拆分成2个库,分别部署在不同的机器上,此时其中1个库宕机,那么故障影响就是50%,还有50%的数据可以继续服务。
    • 如果我们拆分成4个库,分别部署在不同的机器上,此时其中1个库宕机,那么故障影响就是25%,还有75%的数据可以继续服务,恢复耗时也会很短。

    当然,我们也不能无限制的拆库,这也是牺牲存储资源来提升性能、可用性的方式,毕竟资源总是有限的。

    6. 如何分库分表(分库?分表?还是既分库又分表?)

    分库分表方案可以分为下面3种

    数据库常见面试题,MySQL分库分表,MySQL分区,为什么要分库分表,数据切分

    7. 如何对数据进行切分?

    通常根据垂直拆分、水平拆分两种方式进行划分,当然,一些复杂的业务场景也可能选择两者结合的方式。

    垂直拆分

    垂直分表通常根据业务功能的使用频率,将主要受欢迎的字段放在一起作为主要表。然后,将不常用的东西根据各自的业务属性聚集起来,分成不同的次要表的主要表和次要表的关系一般是一对一的。

    水平拆分(数据分片)

    单表容量不超过500W,否则建议分级。将一块手表复制成同一块手表结构的不同手表,按照一定的规则将数据分别保存在这些手表中,保证手表的容量不太大,提高性能的当然,这些结构相同的手表可以放在一个或多个数据库中。

    水平分割的几种方法:

    • 使用MD5哈希,加密UIDmd5,取前几名(在这里取前两名),然后将不同的UID哈希放入不同的用户表中。
    • 根据时间可以放入不同的表。例如,article_201601、article_201602。
    • 按热度拆分,点击率高的词条生成各自的表,低热的词条放在大表中,低热的词条达到一定的贴数后,将低热的表单独分割成表。
    • 根据ID的值加入对应的表格,第一个表格user_0000,第二个100万用户数据加入第二个表格user_0001,随着用户的增加,直接加入用户表格即可。

     数据库常见面试题,MySQL分库分表,MySQL分区,为什么要分库分表,数据切分

    了解更多数据库知识,点击全文链接: 

    https://www.shulanxt.com/doc/mysqldoc/sjkcjm
    展开全文
  • mysql面试-分库分表

    千次阅读 2022-03-02 17:03:19
    一、mysql分库分表查询,不带分表键,且不是看第三页 1、全量查在通过内存分页 因为不清楚按照时间排序之后的第三页数据到底是如何分布在数据库上的,所以必须每个库都返回3页数据,所得到的6页数据在服务层进行内存...

    一、mysql分库分表查询,不带分表键,且只是看第三页

    1、全量查在通过内存分页
    因为不清楚按照时间排序之后的第三页数据到底是如何分布在数据库上的,所以必须每个库都返回3页数据,所得到的6页数据在服务层进行内存排序,得到全局视野,再取第3页数据。

    缺点:有性能瓶颈,如果查询偏移量过大的分页会导致数据库获取数据性能低下

    2、业务折中
    禁止跳页查询,不提供“直接跳到指定页面”的功能,只提供下一页的功能。极大的降低技术方案的复杂度。第一页的选取方法和全局视野法一样,但是点击下一页时记住上一页最后一条数据的作为第二次查询条件。

    3、数据汇总
    添加一张汇总表,属性中必有id属性,注意这张表存放的数据是所有分表的数据,但是胜在属性列少,只有提供索引的几个属性列,然后我们获取了id之后就可以去对应的表中查询了

    4、union all
    分表的数据通过sql中的union all查询出来在进行分页

    5、使用merge存储引擎
    其实这个和第三点很相似。只不过这个汇总的操作,不需要认为的去做,存储引擎会帮我们做

    缺点:这里范围比较窄,只能使用merge和Myisam引擎

    6、MYSQL的分区表

    二、水平分表后的路由问题

    1、范围路由
    即以分片键的某一段落到对应的数据库,不同分段分散到不同的数据库表中,比如:1到100万落到DB_0,100万到200万落到DB_1…以此类推划分id对应数据库。
    优点:可以随着数据的增加平滑的扩充新的表。 缺点:可能存在数据分布不均匀,而且有热点访问问题。

    2、hash取模
    选择某个列(或几个列的组合)的值进行hash运算,然后根据运算结果分散到不同的数据库中。
    优点:表数据分布比较均匀。 缺点:初始表数据量不好选取,扩充新的表数据需要重新分布

    3、配置路由
    使用独立的表(或者配置文件等)记录路由配置信息。
    优点:使用起来简单灵活,扩充表时只需要迁移指定的数据,然后修改路由表。缺点:必须多查询一次,影响整体性能,路由表本身太多影响系统整体性能,还有如果扩展表数据分布不平衡。

    三、join操作问题

    数据分散在不同的数据库中,无法join查询

    1.通过业务代码进行join查询,然后结果合并
    2.使用Databus

    四、分库分表-访问数据源的中间件

    1、TDDL:整个淘宝数据库体系里面具有非常重要的一个中间件产品,在公司内部具有广泛的使用
    2、sharding-sphere:他们均提供标准化的数据分片、读写分离、柔性事务和数据治理功能

    五、分库分表的设计思路:

    5.1、表的数量设计

    首先根据自身的业务量和增量来考虑分表的大小
    举个例子,现在我们日单量是10万单,预估一年后可以达到日100万单,根据业务属性,一般我们就支持查询半年内的订单,超过半年的订单需要做归档处理。
    那么以日订单100万半年的数量级来看,不分表的话我们订单量将达到100万X180=1.8亿,以这个数据量级部分表的话肯定单表是扛不住的。单边最大500w来算,半年归档一次,5000w除以180天等于2.8w,也就是单表一天的量最多2.8w,如果要每日100w那就是100w除以2.8w 大概需要36张表,也就是6*6=6库6表差不多。

    5.2、问题

    1、C端查询问题
    速度一定要快,性能一定要好,一定要带分库分表键进线查询。也就是shardingkey

    2、其他端查询问题
    方案1:双写,双写就是下单的数据落两份,C端和B端的各自保存一份,C端用你可以用单号、用户ID做shardingkey都行,B端就用商家卖家的ID作为shardingkey就好了。有些同学会说了,你双写不影响性能吗?因为对于B端来说轻微的延迟是可以接受的,所以可以采取异步的方式去落B端订单

    方案2:另外一个方案就是走离线数仓或者ES查询,比如订单数据落库之后,可以通过binlog还是MQ消息的形式,把数据同步到数仓或者ES,

    五、ShardingJDBC分库分表扩容

    1、扩容按什么倍数扩容
    2、扩容怎么让原来的key达到先前落的表,使用hashCode取模的方式肯定是不可以的。
    3、自定义分片key生成策略,如何自定义
    在这里插入图片描述

    4、当数据库买了或者达到一定的阈值,扩容的时候,怎么解决数据分配不均衡。有个定时任务跑所有表的数量,根据统计的结果计算好每个表的权重

    5、每个库的每个表的权重调整策略,其实这个有点类似于ABtest分流一样。

    6、分库分表键的分片策略是什么,有什么问题
    方案1、范围分片,最开始我打算分段分片,即以分片键的某一段落到对应的数据库,比如:1到100万落到DB_0,100万到200万落到DB_1…以此类推划分id对应数据库,会有一个问题,数据库热点写入问题。
    方案2、自定义分片key生成策略

    请看:https://juejin.cn/post/6844904142578647053

    5.1 按权重取随机数

    1 权重40 0到40
    2 权重30 40到70
    3 权重10 70到80
    4 权重20 80到100
    再从100里面取随机数

    5.2 abtest分流

    1、首先支持配置,允许修改A和B的权重。
    2、原来的数据已经AB分流之后,返回的就是历史分好的,新的数据使用最新的AB权重进行分流
    3、且如果开关关闭,所以流量都指到单测上面去。

    六、分布式事务

    1、2pc(缺点是什么)
    2、3pc(缺点是什么)
    3、事务补充

    七、mysql存储引擎区别

    Innodb和Myisam的区别和实现
    1、myisam是默认表类型不是事物安全的;innodb支持事物。
    2、myisam不支持外键;Innodb支持外键。
    3、myisam支持表级锁(不支持高并发,以读为主);innodb支持行锁(共享锁,排它锁,意向锁),粒度更小,但是在执行不能确定扫描范围的sql语句时,innodb同样会锁全表。
    4、执行大量select,myisam是最好的选择;执行大量的update和insert最好用innodb。
    5、myisam在磁盘上存储上有三个文件.frm(存储表定义) .myd(存储表数据) .myi(存储表索引);innodb磁盘上存储的是表空间数据文件和日志文件,innodb表大小只受限于操作系统大小。
    6、myisam使用非聚集索引,索引和数据分开,只缓存索引;innodb使用聚集索引,索引和数据存在一个文件。
    7、myisam保存表具体行数;innodb不保存。
    8、delete from table时,innodb不会重新简历表,而会一行一行的删除。
    9、Innodb用的是聚餐索引,myisam用的是辅助索引
    聚集索引表示叶子节点存储了整张表的数据,非聚集索引为存储了主键id,需要再次回表查询一次

    八、其他知识补充

    1、单表最大存储量

    MySQL本身并没有对单表最大记录数进行限制,业界流传是500万行。超过500万行就要考虑分表分库了。阿里巴巴《Java 开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。

    单个数据库最大并发量
    推荐:32个库,每个库32个表,那么总共是1024张表。这个分法,第一,基本上国内的互联网肯定都是够用了,第二,无论是并发支撑还是数据量支撑都没问题。
    每个库正常承载的写入并发量是1000,那么32个库就可以承载32 * 1000 = 32000的写并发,如果每个库承载1500的写并发,32 * 1500 = 48000 的写并发,接近 5 万每秒的写入并发,前面再加一个MQ,削峰,每秒写入MQ 8万条数据,每秒消费 5 万条数据。

    2、mysql分区

    一、分区的作用
    分区是将一个表的数据按照某种方式,比如按照时间上的月份,分成多个较小的,更容易管理的部分,但是逻辑上仍是一个表。
    个人理解起来,分区跟性能没有必然关系,分区更多的是从管理的角度出发的。

    二、MySQL分区表对分区字段的限制
    分区的字段,必须是表上所有的唯一索引(或者主键索引)包含的字段的子集,也就是说分区可以用多个字段,但是这些字段必须是在唯一索引或者主建索引中的某几个。

    3、索引类型

    2、normal:表示普通索引
    1、unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时可设置为unique

    3、full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
    总结,索引的类别由建立索引的字段内容特性来决定,通常normal最常见。

    4、union all和union的区别

    1、union 操作符用于合并两个或多个SELECT语句的结果集。默认地,UNION操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

    2、union all只是简单的将两个结果合并后就返回

    注意:union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。

    展开全文
  • 在互联网项目中比较常用到的关系型数据库是MySQL,随着用户和业务的增长,传统的单库单表模式难以满足大量的业务数据存储以及查询,单库单表中大量的数据会使写入、查询效率非常之慢,此时应该采取分库分表策略来...
  • 使用方法不变,是Tomcat封装的类将session存储到了redis,依赖web容器 spring session +redis:spring 将session存储到redis 分库分表 为什么要分库分表?表数据量达到上千万级别,数据库磁盘消耗高,QPS响应慢,...
  • 数据库数据过大的系统架构-mysql分库分表高可用 如果当你的数据量达到千万级,亿级的时候,我们用常规的方式去做优化那么效果可能就不是很好了。这已经不是说性能的问题了,而是数据量响应的处理问题了,所以我们...
  • MySQL分库分表面试知识总结

    万次阅读 2018-04-09 00:04:51
    Web开发工作,亦或是海量数据开发工作,学习分库分表、分区等知识都是很有必要的 。 面试的时候,也有可能也会被问到。不过作为一个有经验的Coder,不熟悉分库分表技术确实有些 low。 基础概念 分表,...
  • MYSQL分库分表总结

    千次阅读 2017-03-09 17:48:39
    单表  单单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db中的user表中查...如果使用mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有
  • 分库分表面试题及答案

    千次阅读 2021-03-28 22:32:14
    5.现在有一个未分库分表的系统,未来要分库分表, 如何设计才可以让系统从未分库分表动态切换到分 库分表上?6.如何设计可以动态扩容缩容的分库分表方案?7.你们有没有做 MySQL 读写分离?如何实现 mysql 的 读写...
  • 线程池,nginx的limit_conn模块 2、业务层限流 比如在秒杀系统中,一个商品库存只有100件商品,现在有两万人抢购,没必要放两万人进来,只需要放前500个人进来,后面的人直接返回已售完即可 二、分库分表 1、为什么...
  • 1. 为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的? 面试题剖析 为...
  • 在MyCat的逻辑结构主要负责逻辑、逻辑表、片规则、片节点等逻辑结构的处理,而具体的数据存储还是在物理结构,也就是数据库服务器中存储的。
  • 分库分表面试题

    2021-06-29 10:18:09
    什么是分库分表?/为什么分库分表? 随着业务的发展,数据量越来越大,数据库并发越来越高,单库单表降低了查询速度,影响了客户体验,所以要进行分库分表。首先要清楚,分库和分表是两回事,是两个独立的概念。分...
  • 动态扩容分库分表 1 面试题# 如何设计可以动态扩容缩容的分库分表方案? 2 面试官心理分析# 对于分库分表来说,主要是面对以下问题: 选择一个数据库中间件,调研、学习、测试; 设计你的分库分表的一个方案,...
  • 高频数据库分库分表面试题解析

    千次阅读 2019-05-23 17:29:38
    为啥要分库分表? 假如我们现在是一个小创业公司(或者是一个 BAT 公司刚兴起的一个新部门),现在注册用户就 20 万,每天活跃用户就 1 万,每天单表数据量就 1000,然后高峰期每秒钟并发请求最多就 10。天,就这种...
  • 关于分库分表面试题

    2021-06-01 06:55:58
    为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)? 用过哪些分库分表中间件? 不同的分库分表中间件都有什么优点和缺点? 你们具体是如何对数据库如何进行垂直拆分或水平拆分的? 高并发系统单库单...
  • PHP面试分库分表

    2021-01-19 11:18:05
    [TOC]真题简述MySQL分表操作和分区操作的工作原理,分别说说分区和分表的使用场景和各自的优缺点。分区表的原理工作原理对用户而言,分区表是一个独立的逻辑表,但是底层 MYSQL将其分成了多个物理子表,这对用户来说...
  • 大家好,今天跟大家聊聊分库分表。 什么是分库分表 为什么需要分库分表 如何分库分表? 什么时候开始考虑分库分表 分库分表会导致哪些问题 分库分表中间件简介 1. 什么是分库分表 ...
  • 依然存在单表数据量过大的问题(需要水平切分) 面试题: 一、谈谈什么是分库分表(为什么要分库分表)。 答:你都看到这里了,如果脑海里还没有一些逻辑的话,那么请再看一遍。 二、他们都有什么优缺点。 答:同第...
  • 【MySQL】MySQL分库分表详解

    千次阅读 多人点赞 2020-02-25 16:47:21
    目录 一、前言 1.1 数据量 1.2 磁盘 1.3 数据库连接 二、垂直拆分 or 水平拆分? 三、垂直拆分 3.1 垂直分库 3.2 垂直分表 ...4.2 水平分库分表 ...五、几种常用的分库分表的策略 ...六、分库分表...
  • mysql3库3表分库分表解决方案之 Apache ShardingSphere
  • 一、数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加... 分库和垂直分表。 第二种:网络IO瓶颈,请求的数据太多,网络带宽不够 -> 分库。2、CPU瓶颈 第一种:SQL问题,如SQL中包含j..
  • MYSQL分库分表方案

    2021-01-12 10:58:18
    导读:本文详细介绍了中间件,主要从数据库拆分过程及挑战、主流数据库中间件设计方案、读写分离核心要点、分库分表核心要点展开说明。 1. 数据库拆分过程及挑战 垂直拆分、读写分离、分库分表(水平拆分)。每个...
  • 文章目录分库分表一.分表1.1 为什么要分表1.2分表的方法1.2.1 纵向分表1.2.2 横向分表二. 分库三. 分库分表相关问题3.1 分库分表如何保证唯一ID3.1.1 UUID(不推荐)3.2 Snowflake算法 分库分表 分库分表即将表中的...
  • MySQL分库分表id主键处理

    千次阅读 2021-01-08 20:58:27
    其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定不对啊,需要一个全局唯一的 id 来支持。所以这都是你实际生产环境中必须考虑的问题。 2 ...
  • Sharding-JDBC—分库分表实例【面试+工作】学习之前先详细介绍Sharding-JDBCSharding-JDBC是一个开源的适用于微服务的分布式数据访问基础类库,它始终以云原生的基础开发套件为目标。Sharding-JDBC定位为轻量级java...
  • 关于Mysql分库分表面试的时候怎么回答比较好呢?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,253
精华内容 5,701
关键字:

mysql分库分表面试题

mysql 订阅