我对 mongodb 还很陌生,正在解决一些 devops 问题。
我们在 AWS 上部署了一个 B2B SAAS 产品,客户之间没有网络效应,有些客户的数据库比其他客户大得多。它们目前由一个中央 MongoDB 服务器运行,我们遇到了严重的嘈杂邻居问题,我们需要隔离拥有大量联系人的客户。
我的问题是:当我们在 aws 中为单个大客户提供他们自己的独立 vpc 时,最低合理的 mongodb 服务器是什么?这是否需要像 mongo 文档中指出的那样是一个 3 服务器副本集,或者是否可以合理地使用一个 ec2 实例作为小型数据库的生产 mongo 服务器?
答案1
你能有一个在单个 MongoDB 实例上运行的生产环境。非常特殊情况。让我们在弄清楚有关副本集的一些事情之后看看这些情况是什么。
在副本集上
与普遍看法相反,副本集只有一个主要目的:确保数据库的可用性。假设您只有一个实例。每次维护工作、每次服务器崩溃、每次管理失误都会导致停机。停机不仅会影响您的 SLA(已经够糟糕了),还可能导致 DBA 在参加完派对后早上 6:00 起床,现在他试图让自己的咖啡因水平足够高,以便在半醉的情况下恢复数据库。
此外:不可避免地,您将在备份和恢复服务之间丢失所有数据。首先,很明显,您将丢失上次备份和服务器不可用时之间的所有数据。然后,您将丢失停机期间生成的所有数据。
现在让我们假设您有一个副本集,其中包含两个数据承载节点和一个仲裁器。情况稍微好一点。您的主节点发生故障,另一个数据承载节点被选举出来,并且由于自动故障转移(大多数驱动程序都提供此功能),您的服务将继续运行,不会停机和丢失数据。但:您已经失去了冗余。因此,为了降低风险,一名 DBA 再次被打倒在地,他现在必须将仲裁器提升为数据承载节点,等待数据同步,同时希望同步速度快于数据的变化速度(更准确地说:您希望复制 oplog 窗口大于同步数据所需的时间)。如果不是,数据同步将失败,您必须关闭应用程序才能使同步成功。使用这种设置的好处是,您可以选择何时关闭应用程序以恢复冗余。
附注:如果您的数据变化率超出了复制 oplog 窗口,则应该进行分片。总是确保您的复制 oplog 窗口足够大。
现在让我们假设您有三个数据承载节点,正如建议的那样。即使一台服务器发生故障(或更新等),您仍然具有冗余。一个节点在夜间发生故障?睡个好觉!
那么什么时候我才能拥有一个仅含一台服务器的生产环境呢?
考虑到上述情况,您可以拥有单实例生产环境,前提是
- 没有 SLA 和/或您的客户可以忍受长时间的停机
- 您的 DBA 必须随时待命以恢复服务
- 您和/或您的客户可以忍受上次备份和恢复服务之间丢失数据。
据我所知,在大多数严肃的商业应用中,这些条件中的一个或多个的答案是“否”。
我可以拥有一个具有两个数据承载节点和一个仲裁器的生产环境吗?
是的,前提是您可以接受丢失一个数据承载节点会导致冗余度降低的事实。在这种情况下,您很可能必须重新同步数据,这需要您密切监控你的复制 oplog 窗口和确保;确定重新同步所需的时间适合它。
考虑到仲裁器实例和数据承载节点之间的价格差异,是选择两个数据承载节点和一个仲裁器的设置还是选择三个数据承载节点的建议设置是一个风险管理问题。
结论
是否可以合理地使用一个 ec2 实例作为小型数据库的生产 mongo 服务器?
坦白地说:在我看来不是。这几乎是疏忽,增加了可以用相对较少的钱来缓解的风险,而且很可能比拥有至少一个带有两个数据承载节点和一个仲裁器的副本集要昂贵得多。如果你把所有因素都考虑进去的话。
这是否需要像 mongo 文档中指出的那样设置 3 个服务器副本?
除非你真的,真的,真的知道自己在做什么:是的。
答案2
如果你愿意让所有客户的数据毫无预警地消失,那么你可以使用单个 EC2 实例作为生产 mongoDB 服务器。当然,一开始就选择 MongoDB(大概是因为它的知名的 WebScale 属性),你可能对耐用性不太感兴趣,但在单个 EC2 实例上运行所有这些只是乞讨数据库小精灵会给你带来糟糕的一天。