我正在使用 docker 构建一个具有微服务结构的游戏。
我开始构建服务的方式是为每个服务提供一个 mongoDB 实例,因此为 mongoDB 实例提供 OneToOne 服务,
Resources ---> resourcesDB (mongoDB instance 1)
Chat ---> chatDB (mongoDB instance 2)
Buildings ---> buildingsDB (mongoDB instance 3)
Battle ---> battleDB (mongoDB instance 4)
...
这在开始时真的很有意义,因为例如这些服务没有任何共同点,也不需要与同一个 mongo 实例建立连接,当它们确实有一些共同点(构建 <-> 资源)时,它们只需发送一个调用到所需的服务并处理其余的(更新他的数据库)。
但我开始认为这不是正确的方法,因为有几件事:
1 - 例如,resourcesDB 只有 2 个集合,
Logs ---> logging every resources change (building built, war lost etc.)
Resources ---> 1 document per user holding how much he have.
这意味着这个数据库不会保存任何巨大的数据(日志将在一段时间后被删除),所以为这两个集合设置一个实例看起来像是一个巨大的过度杀戮,即使这个实例没有自己的服务器并且会共享服务器与服务。
2 - 维护和做备份将需要一些额外的工作,我不确定在我的情况下是否需要。
每个服务都会经常更新他的数据库,资源每秒都在计算以查看每个用户有多少,所以它会'users amount'
每秒更新数据库,除了其他请求,比如建造建筑物(减少资源)和其他更新,聊天服务将在每条私人消息或聊天消息中更新数据库,战斗服务将在每场战斗中每秒更新部队地点和统计数据以及更多内容。
我正在考虑将该结构用于下一个:
可能只有 1 个带有独立数据库的数据库实例,因此每个服务都将连接到一个独立的数据库,但我读到维护数据库的备份和扩展仍然很麻烦。
有 1 个数据库,其中包含所有集合,每个集合都将由不同的服务访问,并且永远不会被 2 访问,所以我不必担心 2 个服务更改同一个集合。
保持原样,并使用许多 mongoDB 实例
关于上述方法的几个问题:
我应该选择什么?拥有 1 个数据库听起来不错,因为它将为我节省大量资源并使我的生活更轻松,但是将服务与许多数据库分开对我来说是合理的逻辑,因为一项服务不需要查看集合或能够访问一个集合与他的工作无关。
我不确定 mongoDB 如何处理与同一个实例或同一个数据库的许多连接,正如您所见,即使我的用户数量很少,它也可能在一秒钟内收到很多调用。
我阅读了有关 mongo Sharding 的信息,据我了解它发生在每个数据库而不是实例级别,这就是为什么我正在考虑 1 数据库选项,因为它在我的情况下非常有用,对吗?
考虑将来如何扩展您的应用程序是明智的,但您可以从一个更简单的部署开始,该部署可以随着您的需求而增长。
我的建议是设置单个 MongoDB 部署(理想情况下从具有高可用性和数据冗余的副本集或托管服务开始):
MongoDB的单个部署可以有多个数据库;每个服务的 MongoDB 部署增加了不必要的管理复杂性。
对于您的用例,每个服务都有一个数据库并为每个服务设置一个用户听起来很合理,因此操作仅限于与预期数据库的直接交互。
每个服务的数据库还限制了可能创建数据库级争用的管理操作(例如前台索引构建)的潜在影响。
directoryPerDB
稍后,您可以从诸如(例如,某些数据库的更快存储)或使用分片对数据进行分区之类的选项开始扩展/调整部署。这是一个更微妙的问题,因为它取决于服务器资源以及这些连接在做什么以及您的驱动程序如何/是否实现连接池。理想情况下,我会对您的实际应用程序进行负载测试,并确定资源使用量如何随着用户活动的增加而扩展。如果您正在管理自己的 MongoDB 部署,则应查看生产说明,特别是确保适当增加ulimit 设置以确保不会用完文件描述符。
如果您担心易于扩展,您还可以考虑托管数据库即服务解决方案(例如,MongoDB Atlas)。
分片最初在数据库级别启用,但分区发生在基于shard key的集合级别。您可以在同一个 MongoDB 部署中混合使用分片/非分片数据库和分片/非分片集合。