文中聊的是数据路由,不是nginx之类的。
几乎每一个分布式系统,都会给用户提供自定义路由的功能。因为,仅通过range、mod、hash等方法,很大概率已经满足不了用户的需求。下面以一个实际场景为例,说一下数据路由的思路。
某个大型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字段修改为人工设值,延伸出另外一个配号系统,在此不多提。