简介
你是否也有这样的困扰?
苦恼怎么样设计才能让数据库支持数亿,数十亿或者数百亿级别的数据业务。
苦恼设计怎样一种模式,才可以兼容高体量数据的动态分配,扩容,合并。
如果你还没有找到合适的方案,不如看看这篇文章,帮助你认识基于角色数据的寻址模型(Role Data Addressing Model)。
这个方案用能够解决哪些问题?
减轻数据负载,它的核心思想是以角色为中心,将角色的所有负载数据拆分成子表管理,从而减轻数据体量对数据库造成的压力。
动态分配,使用它你可以在运行时指定当前的角色数据,应该被分配在哪一个子表中,且无需业务层关心子表的数量和作用范围。
弹性容量,它可以做到根据实际情况,对已有数据进行缩容,对即将到来的更大体量的数据进行扩容
合并,它允许你根据应用场景,将多个子表中的已有数据合并到其他子表或者新建子表。
ROLE DATA ADDRESSING MODEL
概念图
组成部分
该方案由角色索引,版本索引,寻址索引,数据负载分表实例集四个部分组成
- 角色索引
- 声明:此处谈论对的角色表并不等同与游戏中对角色,它跟用户是一对一对关系
- 他负责提供唯一标识和角色负载数据的版本号,起承上启下的作用
- 其中角色版本号,是再创建角色时确定的,创建后运行时则不可更改
- 版本索引
- 声明: 这个版本索引和通常游戏设计中的分服是一个概念
- 他负责向业务层提供当前开放存储的版本号,可能是一个也可能是多个
- 寻址索引
- 他负责提供角色负载数据的所有分表地址,版本号则作为查找分表的依据
- 数据负载分表实例
- 他就是实际负责处理数据存储的实例了
- 单个角色负载数据表的分表数量应该与当前 版本索引 中最大的version相等
- 意思就是 版本索引 中最大的version是10,那么各个角色负载分表的个数也因该等于10
如何工作
- 离线构建数据库分表结构
- 在线下环境由运维人员创建分表索引和角色负载数据的分表项
- 由人工根据数据监控决定 版本索引 中哪些版本应该接受新建角色数据,哪些又因为达到了负载上限应该停止接收新建角色
- 业务人员根据 版本索引 决定新建角色的 version 是应该属于哪个版本
- 业务人员在新建角色负载数据时,根据 角色索引 的 version 字段,来辨别应该往哪个分表中存储
- 同样业务人员在查询数据时,应该持有【角色的编号(role.id)】和【版本号(role.version)】去对应的角色负载数据分表中查询
附录
弹性容量
弹性容量,并不是指向云服务容器那样,自动化扩充或缩减实例,它意味着在这种规则下,允许你在不破坏原有数据的情况和业务下,做到扩充或缩减表的容量(分表个数)
扩充是再简单不过的事情了,你仅仅需要往版本索引表中,增加一个新的版本,创建对应版本号的分表,开启新版本关闭旧版本即完成了扩容操作(就像游戏开新服一样)
缩容也非常的简单,前提是参与缩容的分表,要离线进行,且期间不允许任何数据写入。我们仅仅需要将原表的数据拷贝到目标表,然后将角色的version修改为对应版本,就完成了缩容。
提示:扩容和缩容可以为运维人员提供自动化脚本,从而降低犯错率
合并
合并数据的原理与缩容是一样的,这里就不在赘述了。
重点是同一个表的分表所使用的ID应该是在分表中唯一的
总结
主要解决的问题时降低大体量数据对数据库的负载压力
次要解决运维人员对数据库扩容和缩容的可控性
其实这个方案,在游戏行业应用颇为广泛,它和游戏分区,开服是一个道理
把这种模式应用在WEB APP开发中,角色表其实对应的就是用户表,角色数据负载表,对应的就是用户的业务表
但这种方案现在仍存在问题,从上面的设计图中可以看到,被负载的是用户之下的业务部分,这没什么问题,但设想一下,如果你有1000w+的用户,或者多到上亿或十亿
怎么样去负载用户之上的业务,像登录,注册,修改密码等...... 如果你有过千万的用户,当你的用户点击登录时,怎么去处理校验凭证的问题?