[开发者心得] 【数据存储原理】🎡数据原来是这样被存储起来的!

    [复制链接]
1546 |0
空伊伊 发表于 2023-2-21 13:51:07 | 显示全部楼层 |阅读模式

本帖最后由 空伊伊 于 2024-1-15 18:18 编辑

本帖最后由 空伊伊 于 2023-11-8 17:40 编辑

本帖最后由 空伊伊 于 2023-11-8 17:39 编辑

一、Dedicated Server(DS服务器)

Dedicated Server就是指DS服务器,也就是我们常说的服务端。下面我引用了一篇对DS概念做解释的文档作为参考

🔸要讲述Dedicated Server,可以先了解DS在UE的使用。UE提供了两种服务器Dedicated Server和Listen Server,Dedicated Server是专用服务器,服务器和客户端是剥离开来的,而Listen Server则是类似局域网联机一般的,使用其中某一个客户端作为服务器的模式。

🔹游戏网络同步的方式一般分为两种方式,P2P和C/S,P2P即每一台客户端之间互相直连,这种方式的同步极为复杂,对联机游戏来说基本已经淘汰了。C/S即经典的客户端/服务器模式,C/S又可细分为两种,一种是由一个客户端做主机,其他的客户端连接这个主机来进行网络同步,主机即拥有服务器功能也拥有客户端功能,这种模式多用于局域网联机,这种模式中每一个客户端都可以成为主机;一种是单独剥离服务器的功能,服务端只处理服务器相关的业务,所有的客户端都通过连接服务器来进行网络同步,同时客户端只留下客户端相关的业务,这就是网游中最常用的模式了。

🔸UE的客户端代码和服务器代码是一体的,即两端的代码实际上是混杂在一起的。我们经常听到一种说法叫“前后端分离”,就是服务器干服务器的,客户端干客户端的,二者各为两个工程互不干扰,互相之间通过TCP或者UDP进行通信。而UE的模式则是客户端和服务器不分离,同在一个工程之中,互相之间的代码使用宏来区分。两种方式各有各的好处。这点就和MetaWord的运行方式类似了

🔹DS服务器就是从这个一体的工程中单独剥离出来的一个服务器,为什么要剥离呢?如果不剥离,网络同步就变成了C/S模式的第一种情况了,但是大多数情况下服务器是不需要场景渲染,人物控制这些客户端业务的,剥离出来可以减轻服务器的运行压力。

🔸Dedicated Server服务器简称ds服务器,是UE用于解决FPS同步问题的一种专用服务器,UE在UDP上自己做了一层根据游戏特点专门优化的网络协议(epic不愧是fps起家的😂),专门用于ds通信,ds服务器的一大特点就是客户端和服务器共享一份代码,因为高性能的同步需要各种客户端预测和回溯的方法,可以很好的解决同步延迟问题。但是UEds服务器承载量不高,不适合用于需要连接大量客户端的场景。

————内容来源:https://goulandis.github.io/

二、KV服务器

游戏数据最终会存储在咱们的KV服务器里,并且每一个游戏(GameID),有且只有一个KV服务器来管理它的数据

简单点来说,KV服务器就是一个可以存储键值对的数据库

三、DS服务器与KV服务器的交互

DS服务器主要通过DataStorage命名空间下的API进行数据存取操作 (API文档: https://api-docs.ark.online/modules/DataStorage.DataStorage.html

1.服务器的分配

img

可以看出,KV服务器只对DS负责,所以当我们存储数据的时候,都得在服务端执行对应的API

2.数据传输限制

【单条数据的大小限制】 单条数据的大小不能超过64kb,超过大小DS服务器将会拒绝发送数据给KV服务器 【总频率限制】 接口调用时至一分钟前的时间区间内,某个Key的对应值在KV服务器上被获取Get、改写Set、删除Remove的总次数不能超过 (60+游戏设定的最大人数×10)次,不管它是在哪个ds服务器被操作的;如果时间区间内超限,请求会失败,然后Set、Remove会返回 FREQUENCY_OVERRUN(操作失败:请求频率超限) 而Get会catch到error timeout。 【改写间隔限制】 对于某个Key的对应值,在KV数据服务器上进行了1次改写Set 或 删除Remove操作后,该Key的对应值将会被锁定6秒,在这6秒内将无法再被Set、remove,尝试将会返回 FREQUENCY_OVERRUN(操作失败:请求频率超限),直到6秒过去解锁后才可修改。

四、数据丢失处理

数据丢失原因

原因一: 在设置数据时,传入了null,导致原数据被覆盖(这一点其实是直接原因)

原因二: 一般进入游戏后,会从KV服务器上拉取数据,然后游戏再根据这份数据进行运作。但是如果获取数据时没有进行异步等待,导致取到的是promise对象,然而对promise直接进行序列化会得到{}(空对象),所以也就导致游戏后面运行都是对这份空数据进行操作。

原因三: 获取数据时,没有捕获错误,导致即使没有获取到数据,也继续用空数据进行操作,导致数据丢失

原因四: 存取频率过高,导致存数据失败 或者 取数据失败

原因五: 单条数据过大,导致存储失败

imgimgimgimg

点个赞再走吧~

回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表