文中聊的是数据路由,不是nginx之类的。

几乎每一个分布式系统,都会给用户提供自定义路由的功能。因为,仅通过rangemodhash等方法,很大概率已经满足不了用户的需求。下面以一个实际场景为例,说一下数据路由的思路。

场景

某个大型toB的应用,使用MySQL存储,单表数据量已达数亿,在结构变更、数据查询方面,已表现出明显的瓶颈,需要进行分库分表。

实施步骤

找到切分键

第一步就是找到切分的纬度。比如业务是按照时间纬度进行查询的,那么就把创建时间作为切分键。

此业务的切分键,是商户id(类似于你在美团开店了,美团给你分配的唯一id)。由于历史原因,这个id是用的数据库主键id,而且是自增的。业务具有以下特点:

一、 业务操作是由某个商户发起的,每张表都有商户id字段 二、 商户的数据不均衡,有的商户有几千万,有的可能只有十几条 三、 存在部分vip商家,其数据量非常庞大 四、 存储大量统计需求,所以无法分表,只能分库 五、 存在遍历数据的可能,比如部分定时

切分需求一阶段

分库迫在眉睫。通过分析,部分vip商户,数据量巨大,把它单独转移到一个数据库中也不为过。

通过维护一个映射文件,来控制vip商户到数据存储流向。这时候,就需要自定义路由。

伪代码如下:

function viptable(id){
    10 => "mysql-002"
    101 => "mysql-003"
}
function router4vip(id){
    aimDb = viptable(id)
    if(aimDb) return aimDb
    return "mysql-001"
}

商户为10,数据将落向mysql-002;商户为101,将落向mysql-003;数据默认使用mysql-001存储。

另外,由于id是自动生成的自增字段,与路由存在一个先有鸡还是先有蛋的问题,所以将id字段修改为人工设值,延伸出另外一个配号系统,在此不多提。

切分需求二阶段