聊天记录存储实践

公司的某款游戏在1月初接入微软小冰AI聊天功能。为了保存聊天记录并为后续的统计功能做好准备,决定将聊天记录存放在服务端。最初并不清楚聊天数据量的大小以及玩家对聊天功能的使用情况,所以采用了价格和性能相对宽容的MySQL作为存储介质。

经过大约一个月的运营后,聊天记录表中的数据量已经达到了两千万条。反馈给策划部门后,为控制数据量,决定对聊天记录数量进行限制。每个玩家的每个角色最多只保存200条记录,每个玩家最多可保存3个角色的记录,即每个玩家最多只保存900条聊天记录。服务端的处理逻辑随即修改为每存储300条记录后就清理一次,以确保数据量控制在一定范围内。

根据游戏的新增和玩家留存数据,假设每个玩家平均游戏时间为10天,新增的玩家数在2000至3000之间。因此,每10天会有20000至30000个新的玩家数据,按最高值计算,每10天可能会产生最高2700万条数据,每月最多可能达到5000万条数据。这样计算下来,在一个月后,MySQL可能会无法支持数据的频繁读写操作,需要对聊天记录的存储进行调整。

针对游戏的AVG属性,玩家的生命周期相对较短,因此可以根据玩家的注册时间对其进行划分,从而对玩家数据进行分表存储。具体来说,可以按照玩家注册时间的月份对数据进行划分,并使用相应的表进行数据的存储和查询。这样,每个月份可以相对均匀地承载玩家数据,原本可能达到千万级别的数据量,现在可以控制在百万级别,完全可以解决目前的问题(聊天数据量与新增数据正相关,新增相对稳定)

接下来需要考虑的是,当一个玩家的生命周期结束后,其数据仍然会一直存储在数据库中。而当新的一年开始,新注册的玩家会继续存储,这样对玩家数据的切片就只是一个临时的措施。解决这个问题的方法是分析玩家在主生命周期结束后的行为,发现这些玩家长时间不会再次登录并进行聊天。因此,可以将这些不活跃的玩家数据迁移到便宜的分布式文件存储中,并且记录迁移标志,删除掉原数据库表中的记录。采用定时任务的方式,这样可以减少对业务的影响。

以上的删除操作,都要注意一点,mysql delete删除操作不会释放表空间。这里需要对表空间进行手动释放。手动释放大表空间是一个比较耗费性能的操作,还会对表数据进行锁定。所以释放操作是需要对实际情况进行设计的。在上面的情况中,我们对数据进行按月操作,可以在一个月后,对上月的数据进行清理。比如 3月初清理1月份的表,因为3月份活跃的玩家大多可能是2月份注册的。可以定在凌晨进行定时删除,对业务影响降到最低。

在2月份,新增了对聊天记录进行标记的操作需求,以进行定期反馈和AI调教。这里我们将标记操作的聊天记录独立出来存储,这样可以方便后续的统计和分析。这样也可以避免将标记操作分散在不同的表中,增加数据处理的复杂性。同时,由于标记操作的数据量不会很大,也可以考虑采用NoSQL数据库或者其他内存型数据库来存储这些数据,以提高查询速度和减少存储成本。

猜你喜欢

转载自blog.csdn.net/w_monster/article/details/129239076