网络游戏架构的前世今生——数据库

2

主题

4

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2022-9-20 08:00:50 | 显示全部楼层
上文:
4. 数据库方案演进

4.1 通用数据库

在开发游戏的最早期阶段,例如游戏原型制作,我们将所有数据直接保存在应用的内存中,随时存、随时取出来用,开发起来高效,程序性能也很高。当我们想要正式开始做一个游戏工程项目,我们不得不考虑一个问题,游戏数据如何持久化
每次我们关闭一个应用,应用所申请的内存地址就被全部释放,也可以说内存中的数据全部丢失。我们必须在这之前保存下来其中的游戏数据——玩家相关的那部分数据,游戏进度等。这就是持久化的需求。
数据库是持久化的方式之一。数据库从来都不是开发者的必选项,而是存储数据的方式之一。我们可以将数据存在内存中,可以将数据存在文件中,可以将数据发送到其他应用中代为保存。如果我们需要这个“其他应用”具备一些好用的能力,例如按照特定的数据结构来组织存储,方便查询和修改,那就产生了数据库。数据库是一种存储方式,且这种存储方式是持久长期的。
在这里我花了一些篇幅,或者说是”废话“,讲述什么是数据库,为什么用数据库。不少开发者使用数据库很熟练,远比我熟练,在怎么用数据库这条路上走得很远,但会忘记为什么要用数据库,陷入思维定式而开发。MVC?框架要求?别人也用?这些都不是原因。
在开发时,我喜欢先用内存做存储,正如上文所说,这样开发起来最快最流畅。等所有接口功能开发完毕,写下不同角度的测试用例,进行完善的功能边界测试。然后再把需要持久化的数据套上数据库接口,选择合适的数据库存储,最后做整体的测试验证。
最简单的选择,也是最早期的数据库形态,就是关系型数据库。MySQL、PostgreSQL 和 SQLite 是通常的选择,我们将需要持久化的数据整理成一张张的数据表,规整的存储在数据库中。



关系型数据库的使用

这些关系型数据库,将数据按照特定的规则存储在文件中,按需读取。在本地测试时性能尚可,但当我们把应用部署好使用一段时间后,会发现关系型数据库的增删改查严重拖慢了我们接口的响应速度——在内存中是纳秒级的响应,而关系型数据库需要近百毫秒。我们需要加速接口调用速度!
仿照其他应用的做法,我们可以使用 memcached、redis 等缓存数据库来缓存这些热数据。数据库优先读写缓存中的数据,保证性能,然后异步保存到关系型数据库中,保证数据的一致性。



引入 redis 做缓存

更进一步,我们可以移除背后的关系型数据库,直接把部分数据存储在缓存数据库中。我们通常把相对临时的数据直接存在缓存数据库中,例如:匹配信息,排队信息。这样做,减少了保存两份数据的操作风险,使得数据操作更加快捷高效。



redis 直接做存储

我们发现,游戏业务中几乎不存在联表查询的需求,表与表之间相对独立。有些游戏会只用 redis 作为数据库,完全把所有游戏数据存储在缓存中。好处是简化了技术栈,坏处是,你需要额外考虑缓存数据库的备份、回滚问题,可能会带来额外的技术挑战和运维难度。

4.2 自定义缓存

全盘使用缓存数据库如 redis 作为持久化方案过于激进,备份与恢复会为游戏项目埋下雷,今后难以调整。更常见的做法是,使用自定义缓存 buffer 在关系型数据库前挡一层。当玩家的请求到来时,优先从本地内存中读取或修改数据,数据找不到再去查数据库获取数据。每隔五分钟,或十五分钟完成一次数据同步,从内存中将数据更新的内容写入数据库。



每个模块管理本地缓存

也有单独拆出来,成为一个独立应用的自定义缓存。不需要仿照 redis 这种公开的缓存数据库设计通用接口,只需要按照项目需要编写特定的数据操作接口,即可把所有数据库操作移入一个完全独立的应用中。



单独拆出一个独立应用做缓存

这两种方案是类似的,有一个明显的问题是,如果在数据库同步之前应用出现故障,则会丢失这期间内的数据更改,也就是数据回档的情况。
我们可以仿照 MySQL 的做法,打印 redo log 到本地文件中。只有当 redo log 打印成功,接口才允许返回结果给玩家。可以照搬 MySQL 的实现做出一整套防止崩溃机制,保证异常崩溃后数据不丢失不错乱。



实现 redo log,应对宕机

我们还能找到一些方案,但不管应用怎样的方案,使用自定义缓存的应用是有状态的。状态特性决定了,很难让这些应用模块自由的扩展收缩,想停就停想开就开(这里不考虑为此专门设计一套分布式内存数据库的场景)。自定义缓存虽然解决了通用数据库的性能问题,但也埋下了无法自由扩展的坑
我接触过的大部分游戏后端都有这样的问题。从传统的眼光来看,这不是大问题。我们可以停服维护,停服做垂直扩展或者水平扩展,大部分游戏都是这样设计的。

下期预告:
    4.3 文档型数据库
    4.4 列式数据库
回复

举报 使用道具

2

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-9-20 08:01:46 | 显示全部楼层
我还是个新手,有些还不太看得懂,先收藏起来[赞同]
回复

举报 使用道具

您需要登录后才可以回帖 登录 | 立即注册
快速回复 返回顶部 返回列表