当前位置: 首页 > 后端技术 > Java

面试官居然问我分库分表怎么办?幸运的是,我总结了一组八字文

时间:2023-04-01 23:13:19 Java

一个啤酒肚,穿着格子衬衫,发际线严重后退的中年男人,手里拿着保温瓶,腋下夹着MacBook,正向你走来.架构师级别。采访开始,开门见山。面试官:小伙子,我在你的简历上看到项目是有MySQL的分库分表的。为什么需要分库分表?我不知道!谁知道老板在想什么,反正我来的时候已经分好了。采访者:嗯……,今天的采访就到这里吧。如果有后续面试我会通知你,我会送你下去。不要啊,你老是说会通知我,然后我回去等通知。实话实说,要不要订阅一灯的文章,给你背八股文?好的!自古真爱留不住,套路总得人心。再次背诵一登总结的八股文。我:当MySQL单表数据量过大,比如超过5000万条时,读写性能会变得很差。而且,常规的优化手段已经行不通了,比如:SQL调优、加索引、主从复制、读写分离等。这时候就需要使用MySQL的终极优化方案——分库分表。面试官:对,我怎么判断这个项目需要分库还是分表呢?是先数据库还是先表?谁能现场总结一下?别着急,等我来看看一登的八股文。我可以。当数据库QPS过高,数据库连接数不足时,需要对数据库进行分库。当单表数据量过大,读写性能较差时,就需要分表。当两者都可用时,需要分库分表。至于先分库还是先分表?建议先分表。如果表能解决问题,就不用分库了。毕竟需要单独的服务器资源,成本较高。采访者:小伙子,总结的还是挺全的。分库分表有哪些拆分方案?我:分库分表有垂直拆分和水平拆分。垂直拆分也包括垂直分库和垂直分表。垂直分库,不同的业务拆分成不同的数据库。垂直拆分表,将长度大或访问频率低的字段拆分到扩展表中。水平拆分表格。当单表数据量过大时,根据订单ID拆分成多个表。采访者:小伙子,有件事。我们都知道分库分表好用,那么有什么缺点吗?我:当然,“命运赐予的礼物,都已经暗中定价了。”分库分表带来了低耦合和高性能的优点,但是缺点也很多。数据库垂直分库:不同数据库的多张表无法联合查询,只能通过接口聚合,复杂度呈线性上升。跨多个数据库导致无法使用本地事务。甚至不要考虑强数据一致性。只能引入更复杂的分布式事务,勉强做到数据的最终一致性,可用性直线下降。垂直分表:原来一张表就能查到的数据,现在需要多张表join相关查询,不会浪费时间。水平分表:多表关联查询时无法实现分页和排序功能。面试官:分库分表带来了这么多问题,你考虑过相应的解决方案吗?怎么会没有解决办法,问问题是在给自己挖坑吗?我:当然想过,“有问必有答”。跨库查询问题:如果采用字段冗余方案,比如订单表中存储的店铺ID和店铺名称,则不需要查询商户数据库。但是,这种方案要求冗余字段很少被改动,并且即使改动后,旧数据也能被容忍。多表分页查询问题:这个需要大量的技术含量来处理。例如:订单表按照订单ID(order_id%128)进行分片,分为128张表。领导看了看说:每个表的数据量差不多,数据分布均匀,以后不要再分了。同一个用户的订单分散在不同的表中。如果用户想查询自己的订单,是不可能通过页面查询的。是不是可以一次查询用户所有的订单,然后做内存分页,不管机器内存有多少,都会挂掉。如果要实现用户订单的分页查询,可以根据用户ID(user_id%128)分表,这样同一个用户的订单只会存储在一张表中,可以显示出来在页面中。没有完美的分片解决方案,如果商家想分页查看他店铺的订单怎么办?然后再冗余存储一份订单,按照店铺ID拆分,(shop_id%128)。但是由于商户数量较少,可以设置一个异步线程来同步商户订单分片表。订单按用户ID分片后出现数据倾斜怎么办?因为不同用户的订单量是不一样的,一个爱逛街的小姐姐的订单量抵得上几十个绅士。结果一张表有几百条数据,另一张表有几千万条数据。我应该怎么办?冷热数据分离,基础库只存储3个月以内的订单,其他全部移至历史订单库。这个需要跟产品商量。3个月前的订单需要单独的查询页面。跨库事务问题:这个问题比较复杂。下一个订单需要调用多个服务,只能使用分布式事务。分布式事务的实现非常复杂,常用的解决方案有以下几种:两阶段提交TCC本地消息表MQ事务消息分布式事务中间件面试官:准备的比较齐全。订单表分片后,绝对不可能使用数据库自??增主键作为订单ID,因为不能全局唯一。有什么好的解决办法吗?我:我在手心里又问了一遍。前两天刚刚看了一登写的《雪花算法》。我当场手写了订单ID的生成码。采访者:你可以的,年轻人。下一部分是HR面试。如果你有任何薪资要求,尽管问。你必须来我们公司工作。总结:虽然分库分表的知识点很多,但是都在这张图里做了总结。文章持续更新中,大家可以在微信搜索“一光架构”第一时间阅读更多技术干货。