Answers:
在Stendhal中,我们通过将游戏事件添加到队列中,然后在后台异步处理它们来解决性能问题。
在我们的例子中,事件不仅是记录,而且还有一些逻辑的对象,因为在某些情况下,我们需要进行两次插入,并在它们之间建立链接。例如,第一次在游戏中处理物品时,需要先将其插入到物品表中,然后才能记录物品事件。
但是编写日志只是问题的一方面:
您想用日志回答什么问题?
仅按时间顺序读取完整的日志很容易;或为一位玩家过滤。
但是可能会有类似的问题:
在Stendhal中,我们将关系数据库用于游戏日志,因为这是允许执行即席查询的最简单方法。如果使用自定义日志格式,则基本上必须在需要时对所有这些查询进行编码。而要获得足够的性能则变得相当困难。
我们的gameEvents表有51,429,139行(去年),而我们有一个专用的itemlog表,其中有60,360,657行(所有时间)有15,893,831个项目。
您所说的效率是什么?无论是磁盘大小还是查询速度,关系数据库几乎肯定会击败或等于您专有的二进制格式,并且使用起来更加轻松,更加灵活。
关系数据库中使用的每个表几乎都允许您将确切的字节指定为要允许的每行多少空间。如果您不是在记录纯文本-并且“游戏事件日志(与错误/调试日志相对)”表示您不是,或者至少不需要-那么使用固定宽度字段方法关系数据库在空间方面非常接近最优,这使得它们首先非常快。最重要的是,关系数据库非常容易建立索引以进行快速访问,并优化查询以充分利用它们。
因此,我建议您坚持使用现有的东西。
如今,关系数据库因效率低下而被淘汰,但是在存储您正在谈论的日志类型时,您实际上并不需要效率,因为游戏或其用户不会经常访问它们-仅您的团队需要读取数据。
因此,“效率”并不重要。更重要的是,以一种易于讲述用户在游戏中所做的事情的方式对数据进行排序。开发人员通常需要使用此数据并将其显示在分析人员易于阅读的界面中,分析人员有时需要查询数据以深入了解用户行为。例如,如果玩家在更新之前购买了某个物品,但在更新之后停止购买,那么分析师将可以通过编写某些查询来公开某些有关购买行为的信息,从而确定用户为什么不再购买它,从而从中受益。最好是如果他们有标准的查询语言配合使用,并且有据可查。如果他们必须将这些查询转换为自定义二进制格式,那么他们的工作就会变得更加困难,
通常,游戏事件看起来像这样(特别是DeltaDNA的格式)
{
"eventName":"specific event code – eg. gameStarted",
"userID":"ABCD1-4321a879b185fcb9c6ca27abc5387e914",
"sessionID":"4879bf37-8566-46ce-9f3b-bd18d6ac614e",
"eventTimestamp":"yyyy-mm-dd hh:mm:ss.SSS",
"eventParams":
{
"platform":"WEB",
"param1":"stringParam",
"param2":true,
"param3":1234,
"param4":["a","b","c"]
},
}
事件通常包括事件名称,用户ID,会话ID,时间戳和参数,这些参数使您可以记录对记录该事件有用的任何数据。以我的经验,关系数据库格式最适合记录这种结构。