背景
平台目前的一大核心业务,游戏在线存取档支持。(… 此处略去 …) 基于这样的一个数量级我们随着项目的迭代,数据存储分别采用过以下的几个方案。
方案1
散列机制
- 将游戏按优先级分别配置到两台的服务器上(假设分别了服务器A,服务器B)
- 每台服务器上按intval(Uid / 50W)将玩家存档散列到对应的数据表中
此方案在前期运行过程中表现相对稳定,但随着游戏和玩家的增多逐渐暴露出几个问题
- 两台服务器的压力表现不均衡(服务器A压力过大)
- 存档数增量过大,导致服务器空间不足
方案2
在和运维同事沟通后考虑添加新服务器以解决服务器压力和空间不足问题,在不变更数据结构的前提下进行服务器扩容
- 为服务器A和B各增加一台服务器,并取某个maxUid做为分服点
- 采用同样散列方式进行数据分表
这方案乍一看好像挺妥当的,一心想着新用户应该都会被分离到新的服务器上了; 但上线后的表现说明这个想法是错的,A2和B2服务器虽然有大于 maxUid的玩家数据进行存取,但A和B服务器的增量却还没有下降的趋势。 其实简单分析下就可以找到问题所在:这里的散列是按Uid分段来进行的,小于 maxUid的玩家(老玩家)进行新游戏的存取档时数据却还在存储在A和B服务器上。
方案3
总结方案1和2不难发现其扩展性的问题出现在
- 新服务器没有做到真正的分流
- 数据散列不均匀
为了从根本上解决问题,经过多方讨论后考虑重新设计了新的存储方案
- 为了使玩家数据散列更加均匀,采用取模方式进行Uid % N(N定为640张表)
- 为了使服务器更具有扩展性,采用80张表一个库的方案分为8个库(先采用两台服务器)
- 为了使热点数据采用更的服务器,定义冷热数据将3个月外的活跃存档归档到冷库中
- 热库硬盘成本比较高,是slc ssd硬盘;冷库就使用的是普通的sas硬盘
从以上方案中提取几个比较有意义的点
- 从目前的数据来看(存档数增量及空间占用量),数据散列相对均匀
- 服务器在不拆库的情况下可以最大扩展成8台,在拆库的话则相当大了
- 冷热数据分离让热点数据得到更好的服务
无缝数据同步方案
- 将数据同时写入新旧两套存储结构
- 运行迁移脚本将数据从旧结构迁移至新结构并区分冷热数据
- 待迁移完成则新旧结构数据达到一至状态,可考虑将读写切换至新结构
- 验证玩家数据没问题后下架旧结构
- 定时冷热迁移脚本