我正在为我即将推出的 Project Mangement 应用程序(例如)开发架构,并且我正在寻求明确如何最好地设计 MongoDB 数据层,特别是多租户。该应用程序将有多个“子应用程序”(例如日历、任务列表、媒体、团队等),每个子应用程序将映射到数据库中的一个集合(集中式数据库或它自己的项目数据库)。
数据库服务器 == 副本集。
问题
- 我应该使用一个巨大的集中式数据库来存储所有应用程序数据,还是为系统上创建的每个项目创建一个单独的数据库?
- 如果我选择单独的数据库策略,考虑到数据库“自然地”分散在多台服务器上,从而“自然地”将负载分散到多台服务器上,这是否消除了对数据层进行分片的需要?该应用程序将包含告诉它哪个服务器访问任何给定项目的数据的逻辑。
- 为每个项目使用单独的数据库是否会给我带来更好的性能(假设要查找任何给定的文档,Mongo 最多只需要在单独的项目数据库中搜索几千个文档,而在一个巨大的集中式数据库中可能会搜索数百万个文档)?
- 是否有可能减少 MongoDB 数据库的 32M 最小占用空间?我已经阅读了
--smallfiles
手册中的文档,但这并没有真正回答我的问题。这是一个硬性的最低要求吗? - 如果任何给定项目收到大量流量并成为“吵闹的邻居”,解决方案是否只是启动新的数据库服务器并将该项目移至新服务器?还是对容纳嘈杂邻居的数据库服务器进行分片以提高该服务器的性能是否是一种更好的方法?
- 对于为任何给定的已删除项目清理空间和/或“收缩包装”每个数据库以尽量减少它的足迹,以接近存储在任何给定项目数据库中的实际数据量,我会有什么“维护”问题?
- 对于必须在所有项目数据库中“推出”的数据“模式”的未来变化,我应该注意哪些问题?鉴于 Mongo 是“少模式”,假设如果我想向任何给定的 Collection 添加一个新的“字段”,我会在应用程序逻辑中这样做,而不必对数据库进行任何更新,这是否正确?他们自己?
- 我将使用哪些 MongoDB“工具”来获取有关任何给定数据库服务器的当前“状态”的信息?
- 我应该注意的任何给定数据库服务器上可以容纳的数据库数量是否有任何限制?
- 单个数据库策略如何影响备份?在跨许多数据库服务器备份(到 S3 以进行灾难恢复)许多数据库时,我应该注意哪些问题?
应用程序堆栈
Ubuntu 12.04 LTS
Nginx
node.js
express.js
MongoDB
目前的工作策略
我目前的工作策略是使用一个数据库来存储更高级别的“全局”数据,例如用户、通知、消息、使用情况和首选项。然后为系统上创建的每个项目创建一个新数据库。
出于多种原因,这似乎是一种理想的方法:安全性(每个数据库都有自己的凭据)、灾难性恢复(因为如果一个数据库服务器出现故障,整个应用程序不会出现故障)和性能(我认为,因为 Mongo 会搜索更少的文档来找到它正在寻找的文档)。
该应用程序将包含自动检测任何给定数据库服务器上的可用空间并在下一个可用数据库服务器上创建新项目数据库的逻辑。
根据MongoHQ 提供的这篇文章,这是“最佳”策略,尽管它会消耗大量存储空间。特别是因为每个数据库即使是空的也要占用 32M。如果您提供获得 Techcrunch 的“免费增值”应用程序,使用 MongoHQ 之类的服务会变得非常昂贵。
因此,在 ProjectManager 在系统上有三个项目的情况下,我的数据层将如下所示:
ProjectManager
Users
Notifications
Messages
Usage
Preferences
Project01
Calendar
Tasks
Media
Team
Project02
Calendar
Tasks
Media
Team
Project03
Calendar
Tasks
Media
Team
上面的每个 ProjectXX DB 都会很小。每个最多存储大约 2000-3000 个文档。
提前感谢您的任何见解。
要记住几件事:
鉴于此,在您现在构建系统时需要遵循一些设计模式。这些项目将使以后的扩展更容易,具体取决于您在此过程中学到的东西。
现在
分片 这迫使您开始考虑好的分片键,因为分片键是您的非模式的一部分,以后很难改变。在这一点上,您不是为了性能而分片,而是现在分片以确保您的代码可以处理它,并在几个里程碑之后引导性能问题。
立即设计多数据库支持
如果您预计您需要多个数据库,甚至多个 Mongo 数据库集群,那么在早期阶段构建数据本地性将有助于稍后将其放入。现在它可能都在一个集群中,所有项目/任务/日历/用户都在同一个三个 MongoD 实例中,但是当您了解到 Calendars 数据库正在减慢一切并需要移动到 SSD 支持的实例时,您可以那改变就容易多了。
数据库压缩只在某些情况下很重要
因为数据库文件本身是映射的,只要您的存储子系统很好地处理随机 I/O,2GB 数据库文件包含 200MB 数据库实际上不会影响性能。此外,压缩会使节点离线一段时间,这可能会对正常操作产生重大影响。此外,如果您从不删除文档,则不必担心压缩。
了解使用分离的集合和分离的数据库会得到什么
同一个数据库中的集合共享相同的数据库锁,它们在每个版本的 MongoDB 中都在稳步减少。
同一实例中的数据库彼此共享 I/O,并且仍然存在极少数 Global Lock 事件。
索引很重要
如果您没有足够的 RAM 来至少将索引保存在内存中,那么性能将会非常糟糕。根据您获得的大小,您最终可能会分片或拆分集合,以便获得能够再次适合 RAM 的索引。这是多租户可能成为问题的一个领域;如果您在单个集合中有一些大型未使用的租户,则所有这些索引都必须保存在 RAM 中以使整个系统运行。如果您根据租户拆分集合,则可以将未使用的索引分页而不会受到任何惩罚。