水平分库如何做到平滑扩展

这个对于我们常用的分库分表方案来说,有很大的优势,分库分表的扩容是一件头疼的问题,如果采用对db层做一致性hash,或是中间价的支持,它的成本过于高昂了,如果不如此,只能停机维护来处理,对高可用性会产生影响。

那是否有方案,既可以快速扩展,又不降低可用性?这一篇,我们聊聊分库分表的扩展方案,供大家一起探讨。

一、水平分库扩展问题
为了增加db的并发能力,常见的方案就是对数据进行sharding,也就是常说的分库分表,这个需要在初期对数据规划有一个预期,从而预先分配出足够的库来处理。

比如目前规划了3个数据库,基于uid进行取余分片,那么每个库上的划分规则如下:

如上我们可以看到,数据可以均衡的分配到3个数据库里面。

但是,如果后续业务发展的速度很快,用户量数据大量上升,当前容量不足以支撑,应该怎么办?

需要对数据库进行水平扩容,再增加新库来分解。新库加入之后,原先sharding到3个库的数据,就可以sharding到四个库里面了

不过此时由于分片规则进行了变化(uid%3 变为uid%4),大部分的数据,无法命中在原有的数据库上了,需要重新分配,大量数据需要迁移。

比如之前uid1通过uid1%3 分配在A库上,新加入库D之后,算法改为uid1%4 了,此时有可能就分配在B库上面了。如果你有看到之前《一致性哈希的原理与实践》,就会发现新增一个节点,大概会有90%的数据需要迁移,这个对DB同学的压力还是蛮大的,那么如何应对?

一般有以下几种方式。

二、停服迁移

停服迁移是最常见的一种方案了,一般如下流程:
1.预估停服时间,发布停服公告

2.停服,通过事先做好的数据迁移工具,按照新的分片规则,进行迁移

3.修改分片规则

4.启动服务

我们看到这种方式比较安全,停服之后没有数据写入,能够保证迁移工作的正常进行,没有一致性的问题。唯一的问题,就是停服了和时间压力了。

1.停服,伤害用户体验,同时也降低了服务器的可用性

2.必须在制定时间内完成迁移,如果失败,需要择日再次进行。同时增加了开发人员的压力,容易发生大的事故

3.数据量的巨大的时候,迁移需要大量时间

那有没有其他方式来改进一下,我们看下以下两种方案。

三、升级从库

线上数据库,我们为了保持其高可用,一般都会每台主库配一台从库,读写在主库,然后主从同步到从库。如下,A,B是主库,A0和B0是从库。

此时,当需要扩容的时候,我们把A0和B0升级为新的主库节点,如此由2个分库变为4个分库。同时在上层的分片配置,做好映射,规则如下:

uid%4=0和uid%4=2的分别指向A和A0,也就是之前指向uid%2=0的数据,分裂为uid%4=0和uid%4=2

uid%4=1和uid%4=3的指向B和B0,也就是之前指向uid%2=1的数据,分裂为uid%4=1和uid%4=3

因为A和A0库的数据相同,B和B0数据相同,所以此时无需做数据迁移即可。只需要变更一下分片配置即可,通过配置中心更新,无需重启。

由于之前uid%2的数据分配在2个库里面,此时分散到4个库中,由于老数据还存在(uid%4=0,还有一半uid%4=2的数据),所以需要对冗余数据做一次清理。

而这个清理,不会影响线上数据的一致性,可是随时随地进行。

处理完成以后,为保证高可用,以及下一步扩容需求。可以为现有的主库再次分配一个从库。

总结一下此方案步骤如下:

1.修改分片配置,做好新库和老库的映射。

2.同步配置,从库升级为主库

3.解除主从关系

4.冗余数据清理

5.为新的数据节点搭建新的从库

四、双写迁移

双写的方案,更多的是针对线上数据库迁移来用的,当然了,对于分库的扩展来说也是要迁移数据的,因此,也可以来协助分库扩容的问题。

原理和上述相同,做分裂扩容,只是数据的同步方式不同了。

1.增加新库写链接

双写的核心原理,就是对需要扩容的数据库上,增加新库,并对现有的分片上增加写链接,同时写两份数据。

因为新库的数据为空,所以数据的CRUD对其没有影响,在上层的逻辑层,还是以老库的数据为主。

2.新老库数据迁移

通过工具,把老库的数据迁移到新库里面,此时可以选择同步分裂后的数据(1/2)来同步,也可以全同步,一般建议全同步,最终做数据校检的时候好处理。

3.数据校检

按照理想环境情况下,数据迁移之后,因为是双写操作,所以两边的数据是一致的,特别是insert和update,一致性情况很高。但真实环境中会有网络延迟等情况,对于delete情况并不是很理想,比如:

A库删除数据a的时候,数据a正在迁移,还没有写入到C库中,此时C库的删除操作已经执行了,C库会多出一条数据。

此时就需要做好数据校检了,数据校检可以多做几遍,直到数据几乎一致,尽量以旧库的数据为准。

4.分片配置修改

数据同步完毕,就可以把新库的分片映射重新处理了,还是按照老库分裂的方式来进行,

u之前uid%2=0,变为uid%4=0和uid%4=2的

uid%2=1,变为uid%4=1和uid%4=3的。

引用:

https://mp.weixin.qq.com/s/BLOneOs-cPxP_9b5eH8oQA

来源:https://my.oschina.net/u/1859679/blog/1577049

时间: 2024-12-06 07:01:09

水平分库如何做到平滑扩展的相关文章

PostgreSQL 9.6 sharding + 单元化 (based on postgres_fdw) 最佳实践 - 通用水平分库场景设计与实践

PostgreSQL 9.6 sharding + 单元化 (based on postgres_fdw) 最佳实践 - 通用水平分库场景设计与实践 作者 digoal 日期 2016-10-05 标签 PostgreSQL , 9.6 , 水平分库 , sharding , 单元化 背景 20161004_01.md这篇文档讲解了PostgreSQL postgres_fdw的用法以及9.6的增强. 本文将以实践为主,定一个小目标,讲解一下如何使用postgres_fdw实现sharding.

水平分库分表的关键步骤和技术难点

在之前的文章中,我介绍了分库分表的几种表现形式和玩法,也重点介绍了垂直分库所带来的问题和解决方法.本篇中,我们将继续聊聊水平分库分表的一些技巧. 分片技术的由来 关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的"有状态性"导致了它并不像Web和应用服务器那么容易扩展.在互联网行业海量数据和高并发访问的考验下,聪明的技术人员提出了分库分表技术(有些地方也称为Sharding.分片).同时,流行的分布式系统中间件(例如MongoDB.Elas

ALICloudDB for PostgreSQL 试用报告 - 3 水平分库 vs 单机 性能

本文是针对单个RDS实例(同样的配置)承载6400万数据的测试.对比前面的水平分库. 创建测试表,生成测试数据. create table userinfo(userid int,info text); create table session (userid int,last_login timestamp); create table login_log (userid int,db_user name,client_addr inet,                        cli

ALICloudDB for PostgreSQL 试用报告 - 4 水平分库 之 节点扩展

RDS现在还欠缺一个功能,就是数据库克隆,你可以这么理解,给现有的数据库创建STANDBY,然后将这个STANDBY激活,就完成了对数据库的克隆. 为什么我们需要数据库克隆功能呢? 这会使得数据库的扩容变得非常简单,比如我们这里的应用场景,如果要将16个RDS,变成32个RDS,那么克隆无疑是最好的办法.因为不需要做逻辑数据迁移的事情,只需要删除不需要的数据库,以及调整plproxy的cluster配置即可. 我们先假设RDS有创建STANDBYD的功能(相信未来会增加),看看如何来实现RDS的

水平分库分表的关键问题及解决思路

分片技术的由来 关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的"有状态性"导致了它并不像Web和应用服务器那么容易扩展.在互联网行业海量数据和高并发访问的考验下,聪明的技术人员提出了分库分表技术(有些地方也称为Sharding.分片).同时,流行的分布式系统中间件(例如MongoDB.ElasticSearch等)均自身友好支持Sharding,其原理和思想都是大同小异的. 分布式全局唯一ID 在很多中小项目中,我们往往直接使用数据库自

PostgreSQL 最佳实践 - 水平分库(基于plproxy)

背景 我一直以来都比较推荐plproxy这个PostgreSQL代理软件, 因为它小巧灵活好用, 效率高. 最近朋友邀请我给他们做个分布式的方案, 所以又把plproxy翻出来了. 本文讲一讲在单节点中如何快速的部署plproxy环境. 环境 PostgreSQL 9.3.1 plproxy 2.x plrpoxy节点 hostaddr 172.16.3.150 port 1921 user proxy password proxy dbname proxy schema digoal // 这

PostgreSQL 9.6 水平分库,还差一点点啦

PostgreSQL 持续在基于fdw的sharding技术上深耕,9.6开始,在符合条件的前提下,支持JOIN和SORT下推到数据节点执行.下面是一个测试创建几个shard库 for subfix in 0 1 2 3 do psql -c "create database db$subfix" done 创建master库 psql -c "create database master;" psql master -c "create extensio

Mycat(5):聊天消息表数据库按月分表实践,平滑扩展

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/47003577 未经博主允许不得转载. 1,业务需求 比如一个社交软件,比如像腾讯的qq.可以进行群聊天(gid),也可以单人聊天. 数据量按月增加需要按月进行数据库拆分. 比如按照2015年进行12个月拆分,同时可以配合gid进行水平拆分,也可以利用mysql分区. mycat官方也推荐这样使用,这样可以增加单机单数据库的数据量,因为文件分开了. 关于mycat分区参考: [

ALICloudDB for PostgreSQL 试用报告 - 2 教你RDS PG的水平分库

使用pl/proxy 做分布式处理的性能. 大家可供参考,注意目前plproxy不支持跨库关联,仅仅是函数代理. 如果要做跨库事务需要结合PostgreSQL的prepared transaction(分布式事务/2PC)来实现, 如果要做跨库关联,可以用PostgreSQL的外部表,例如在每个节点上都建立其他节点需要关联的表的外部表,这样也可以做关联. plproxy支持run on all,any,NR,HASH四种方式. 接下来我会一一测试 .    部署ECS: 安装PostgreSQL