`
wx1569020408
  • 浏览: 26954 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

一次难得的分库分表实践

 
阅读更多

背景

前不久发过两篇关于分表的文章:

从标题可以看得出来,当时我们只做了分表;还是由于业务发展,截止到现在也做了分库,目前看来都还比较顺利,所以借着脑子还记得清楚来一次复盘。

<!--more-->

先来回顾下整个分库分表的流程如下:

整个过程也很好理解,基本符合大部分公司的一个发展方向。

很少会有业务一开始就会设计为分库分表,虽说这样会减少后续的坑,但部分公司刚开始都是以业务为主。

直到业务发展到单表无法支撑时,自然而然会考虑分表甚至分库的事情。

于是本篇会作一次总结,之前提过的内容可能会再重复一次。

分表

首先讨论下什么样的情况下适合分表?

根据我的经验来看,当某张表的数据量已经达到千万甚至上亿,同时日增数据量在 2% 以上。

当然这些数字并不是绝对的,最重要的还是对这张表的写入和查询都已经影响到正常业务执行,比如查询速度明显下降,数据库整体 IO 居高不下等。

而谈到分表时我们着重讨论的还是水平分表;

也就是将一张大表数据通过某种路由算法将数据尽可能的均匀分配到 N 张小表中。

Range

而分表策略也有好几种,分别适用不同的场景。

首先第一种是按照范围划分,比如我们可以将某张表的创建时间按照日期划分存为月表;也可以将某张表的主键按照范围划分,比如 【1~10000】在一张表,【10001~20000】在一张表,以此类推。

这样的分表适合需要对数据做归档处理,比如系统默认只提供近三个月历史数据的查询功能,这样也方便操作;只需要把三月之前的数据单独移走备份保存即可)。

这个方案有好处也有弊端:

  • 好处是自带水平扩展,不需要过多干预。
  • 缺点是可能会出现数据不均匀的情况(比如某个月请求暴增)。

Hash

按照日期这样的范围分表固然简单,但适用范围还是比较窄;毕竟我们大部分的数据查询都不想带上时间。

比如某个用户想查询他产生的所有订单信息,这是很常见的需求。

于是我们分表的维度就得改改,分表算法可以采用主流的 hash+mod 的组合。

这是一个经典的算法,大名鼎鼎的 HashMap 也是这样来存储数据。

假设我们这里将原有的一张大表订单信息分为 64 张分表:

这里的 hash 便是将我们需要分表的字段进行一次散列运算,使得经过散列的数据尽可能的均匀并且不重复。

当然如果本身这个字段就是一个整形并且不重复也可以省略这个步骤,直接进行 Mod 得到分表下标即可。

分表数量选择

至于这里的分表数量(64)也是有讲究的,具体设为多少这个没有标准值,需要根据自身业务发展,数据增量进行预估。

根据我个人的经验来看,至少需要保证分好之后的小表在业务发展的几年之内都不会出现单表数据量过大(比如达到千万级)。

我更倾向于在数据库可接受的范围内尽可能的增大这个分表数,毕竟如果后续小表也达到瓶颈需要再进行一次分表扩容,那是非常痛苦的。

目前笔者还没经历这一步,所以本文没有相关介绍。

但是这个数量又不是瞎选的,和 HashMap 一样,也建议得是 2^n,这样可以方便在扩容的时尽可能的少迁移数据。

Range + Hash

当然还有一种思路,RangeHash 是否可以混用。

比如我们一开始采用的是 Hash 分表,但是数据增长巨大,导致每张分表数据很快达到瓶颈,这样就不得不再做扩容,比如由 64 张表扩容到 256 张。

但扩容时想要做到不停机迁移数据非常困难,即便是停机,那停多久呢?也不好说。

所以我们是否可以在 Mod 分表的基础上再分为月表,借助于 Range 自身的扩展性就不用考虑后续数据迁移的事情了。

这种方式理论可行,但我没有实际用过,给大家的思路做个参考吧。

烦人的数据迁移

分表规则弄好后其实只是完成了分表的第一步,真正麻烦的是数据迁移,或者说是如何做到对业务影响最小的数据迁移。

除非是一开始就做了分表,所以数据迁移这一步骤肯定是跑不掉的。

下面整理下目前我们的做法供大家参考:

  1. 一旦分表上线后所有的数据写入、查询都是针对于分表的,所以原有大表内的数据必须得迁移到分表里,不然对业务的影响极大。
  2. 我们估算了对一张 2 亿左右的表进行迁移,自己写的迁移程序,大概需要花 4~5 天的时间才能完成迁移。
  3. 意味着这段时间内,以前的数据对用户是不可见的,显然这样业务不能接受。
  4. 于是我们做了一个兼容处理:分表改造上线后,所有新产生的数据写入分表,但对历史数据的操作还走老表,这样就少了数据迁移这一步骤。
  5. 只是需要在操作数据之前做一次路由判断,当新数据产生的足够多时(我们是两个月时间),几乎所有的操作都是针对于分表,再从库启动数据迁移,数据迁移完毕后将原有的路由判断去掉。
  6. 最后所有的数据都从分表产生和写入。

至此整个分表操作完成。

业务兼容

同时分表之后还需要兼容其他业务;比如原有的报表业务、分页查询等,现在来看看我们是如何处理的。

报表

首先是报表,没分表之前之间查询一张表就搞定了,现在不同,由一张表变为 N 张表。

所以原有的查询要改为遍历所有的分表,考虑到性能可以利用多线程并发查询分表数据然后汇总。

不过只依靠 Java 来对这么大量的数据做统计分析还是不现实,刚开始可以应付过去,后续还得用上大数据平台来处理。

查询

再一个是查询,原有的分页查询肯定是不能用了,毕竟对上亿的数据分页其实没什么意义。

只能提供通过分表字段的查询,比如是按照订单 ID 分表,那查询条件就得带上这个字段,不然就会涉及到遍历所有表。

这也是所有分表之后都会遇到的一个问题,除非不用 MySQL 这类关系型数据库。

分库

分表完成后可以解决单表的压力,但数据库本身的压力却没有下降。

我们在完成分表之后的一个月内又由于数据库里“其他表”的写入导致整个数据库 IO 增加,而且这些“其他表”还和业务关系不大。

也就是说一些可有可无的数据导致了整体业务受影响,这是非常不划算的事情。

于是我们便把这几张表单独移到一个新的数据库中,完全和现有的业务隔离开来。

这样就会涉及到几个改造:

  1. 应用自身对这些数据的查询、写入都要改为调用一个独立的 Dubbo 服务,由这个服务对迁移的表进行操作。
  2. 暂时不做数据迁移,所以查询时也得按照分表那样做一个兼容,如果查询老数据就要在当前库查询,新数据就要调用 Dubbo 接口进行查询。
  3. 对这些表的一些关联查询也得改造为查询 Dubbo 接口,在内存中进行拼接即可。
  4. 如果数据量确实很大,也可将同步的 Dubbo 接口换为写入消息队列来提高吞吐量。

目前我们将这类数据量巨大但对业务不太影响的表单独迁到一个库后,数据库的整体 IO 下降明显,业务也恢复正常。

总结

最后我们还需要做一步历史数据归档的操作,将 N 个月之前的数据要定期迁移到 HBASE 之类存储,保证 MySQL 中的数据一直保持在一个可接受的范围。

而归档数据的查询便依赖于大数据提供服务。

本次分库分表是一次非常难得的实践操作,网上大部分的资料都是在汽车出厂前就换好了轮胎。

而我们大部分碰到的场景都是要对高速路上跑着的车子换胎,一不小心就“车毁人亡”。

有更好的方式方法欢迎大家评论区留言讨论。

你的点赞与分享是对我最大的支持

转载于:https://my.oschina.net/crossoverjie/blog/3084960

分享到:
评论

相关推荐

    Mycat数据库分库分表

    三、数据库分库分表实践 1. 分片策略:常见的分片策略有哈希分片、范围分片、列表分片等。哈希分片适合均匀分布的数据,范围分片适合时间序列或数值范围的数据,列表分片则适用于已知分区的数据。 2. 表结构设计:...

    去年底写的mysql分库分表中间件heisenberg

    Heisenberg是一款开源的MySQL分库分表中间件,它能够帮助开发者实现数据库的水平扩展,提升系统的处理能力和可用性。 **一、Heisenberg简介** Heisenberg取名自量子力学中的海森堡不确定性原理,寓意其在数据库分...

    对分库分表的一些想法

    在数据库规模不断增大的情况下,通过分库分表,可以避免单个数据库成为性能瓶颈,同时也能降低单次操作的数据量,提升处理速度。 1. 分库:当单个数据库服务器无法承载过多的数据和事务处理时,我们可以将数据按照...

    分库分表第二次1

    【标题】:“分库分表第二次1”课程详解——Mycat中间件的实战应用 【描述】:本课程深入探讨了Mycat作为数据库中间件在分库分表中的应用,旨在帮助学习者理解Mycat的基本原理,并通过实际操作掌握其在数据库管理中...

    MySQL分库分表-springboot-sharding.zip

    通过这个项目,我们可以学习到如何在Spring Boot环境下利用ShardingSphere实现MySQL的分库分表,理解数据分片的原理和实践,以及如何处理分布式环境下的事务和数据一致性问题。同时,这也是一次了解和掌握数据库治理...

    以前自己写的一套mysql分库分表的查询代码,查询速度大概在1300-Mysql_Query_By_Aspect.zip

    这套代码是作者自编的用于MySQL数据库的分库分表查询工具,其查询速度达到了约1300次/秒,表明它在处理大量数据时具备一定的效率。 1. **分库分表原理**: - **分库**:将一个大的数据库拆分为多个小的数据库,以...

    阿里巴巴数据库分库分表的实践

    业务数据从原来的单库单表模式变成了数据被拆分到多个数据库,甚至多个表中,如果在数据访问层做一下功能的封装和管控,所有分库分表的逻辑和数据的跨库操作都交给应用的开发人员来实现,则对开发人员的要求变得相对...

    ds-share.zip

    本文将深入探讨如何使用ShardingSphere实现分库分表,并分享一个基于ShardingSphere的实践案例,以及针对性能优化的考量。 一、ShardingSphere简介 ShardingSphere是由Apache软件基金会管理的项目,它包括Sharding-...

    分布式数据库架构及企业实践.pdf

    Mycat是一款基于MySQL协议的数据库中间件,它实现了数据库的分库分表功能,有效地解决了单个数据库在大数据量下性能下降的问题,为企业的高并发、大数据场景提供了有力的支持。 首先,我们要理解分布式数据库的基本...

    搜狗商业平台Java技术实践.docx

    Compass系统架构包括基础数据源层(通常使用C3P0等连接池)和代理数据源层,后者负责具体的分库分表逻辑,确保高效的数据管理和访问。 在面试中,对于Java开发者来说,掌握这些实践经验至关重要。候选人应该熟悉...

    ShardingSphere教程(下).rar

    《ShardingSphere教程(下)》是一份深入学习ShardingSphere技术的重要资料,包含了视频教程、源代码以及学习笔记,旨在帮助用户全面掌握数据库分库分表这一关键技能。ShardingSphere作为开源的分布式数据库解决方案,...

    美团技术沙龙-第50期:4-李明《外卖单元化实践》.pdf

    1. 为了应对业务体量的快速增长和扩展瓶颈,美团外卖业务对整体服务部署架构进行了演进,包括集群部署、负载均衡、分库分表、增加从库、单机服务、单应用、单机房、单地域服务拆分、微服务化、多机房部署、机房间...

    阿里企业级互联网架构实践

    - **分布式数据库服务**:通过分库分表技术,将数据分散到多个物理节点上,提高数据处理能力和可用性。 - **分布式消息服务**:用于实现异步通信,提高系统的解耦合度和响应速度。 - **分布式实时分析服务**:...

    【精品】余额宝背后的中台架构及落地实践-9.pdf

    在早期,余额宝的系统基于IDC和IOE构建,后来逐步转型至云计算环境,实施了分库分表以提高处理能力。随着时间的推移,余额宝的架构经历了四个主要阶段: 1. **余额宝1.0**:初始系统构建,采用传统的IDC和IOE架构。...

    海量数据的实时读写和查询实践.pptx

    - 分库分表查询在架构层面需要提高灵活性和可扩展性。 - 计划扩大TiDB的使用,逐步迁移核心业务库。 - 整合MySQL、TiDB、Hive、Spark的使用场景,探索大型互联网系统的云原生微服务和云原生数据库的集成。 总结...

    my-sharding

    在现代大数据处理中,数据库的分库分表策略已经成为了一种重要的解决方案,它能够有效地缓解单一数据库的压力,提高系统的并行处理能力。Sharding-JDBC作为阿里巴巴开源的一款轻量级Java框架,为开发者提供了透明化...

    携程MySQL迁移OceanBase最佳实践.pdf

    携程数据库的变迁过程中,业务数据模型呈现多元化,OLTP和OLAP出现融合的趋势,业务数据量增长迅速,容量成本显著提升,传统分库分表方案对开发不友好,核心库改造成本高,MHA模式因网络原因切换容易脑裂。...

    电信运营商级安全高可用互联网帐号认证体系技术架构实践-高保庆

    数据库的分库分表技术是实现数据库水平拆分的关键方法,它帮助系统分散压力并提升并发处理能力。 5. 多活服务节点架构: 多活服务节点架构支撑了中国电信互联网产品的全网认证接入服务,每个节点根据业务归属进行...

Global site tag (gtag.js) - Google Analytics