将堆栈的不同组件拆分到几台较小的机器上更好,还是使用 1 或 2 台较大的机器并将多个组件放在同一台机器上更好?
我的想法是,如果我从几台机器开始,那么在需要时通过增加每台机器的功能将更容易扩展。无论如何,我目前还没有准备好进行水平扩展。
我的起始预算是每月 20 美元。
我选择 DigitalOcean 是因为它的 512MB droplet 看起来很灵活,所以我的选择如下:
1, 2, 3 or 4 Machines of 512MB
2 Machines of 1GB
1 Machine of 2GB
1 or 2 Machines of 512MB + 1 Machine of 1GB
这是我的堆栈:
Nginx
+
Gunicorn with 3 workers (=4 processes, memory footprint: ~50MB/process)
+
3 or 4 RQ workers (memory footprint of each worker: ~50MB)
+
Redis as Cache (limit to 100MB to start)
+
Redis as DataStore (small size: it is not meant to store a lot of data, mainly used to store the queues for the workers)
+
PostgreSQL (not sure how much RAM I would need)
我认为使用多台小型机器的主要缺点是,由于操作系统安装在每台机器上,因此每台机器都有一组专用于操作系统的资源,而这些资源对于应用程序而言是“丢失”的。我认为主要的优点是垂直扩展似乎更容易,因为每台机器都可以单独升级。
怎样的权衡才是好的?
选项1
512MB: Nginx, Gunicorn, Redis Cache
512MB: RQ Workers, Redis DataStore
1GB or 512MB: PostgreSQL
我不确定是否值得只为 PostgreSQL 提供 1GB...也许我应该也使用 512MB 的 droplet?另外,我想知道装有 Nginx、Gunicorn 和 Redis 缓存的 512MB 机器是否不会太小。
所以我可以这样做:
选项 2
1GB: Nginx, Gunicorn, Redis Cache
512MB: RQ Workers, Redis DataStore
512MB: PostgreSQL
选项 3 使用 2 台更大的机器
1GB: Nginx, Gunicorn, (RQ Workers), Redis Cache, (Redis DataStore)
1GB or 512MB: PostgreSQL, (RQ Workers here?), (Redis DataStore here?)
答案1
将应用程序分布到多台机器上的一种方法是将每一层运行在单独的硬件上。例如,Web 服务器和数据库服务器可以在一台机器或不同的机器上运行。
执行其中一个或另一个并不需要对软件堆栈进行重大的设计更改。主要需要注意的是,将其拆分到不同的机器上会引入额外的通信延迟。例如,如果您的应用程序使用许多数据库查询来呈现网页,那么大量的往返将导致应用程序速度明显减慢。但这是您可以设计的问题。
通过在不同的机器上运行不同的层来实现的扩展量并不大。软件堆栈中的层数增长速度往往比用户数量增长速度慢。因此,仅靠这种方法根本无法实现扩展。
然而,在不同的硬件上分割层可能会为您向另一个方向的扩展做好准备。
如果您有一台 Web 服务器与一台数据库服务器通信,那么设置两台 Web 服务器与一台数据库服务器通信也没什么困难。换句话说,软件堆栈的每一层都可以独立扩展。
然而,任何维护状态的层都难以在更多机器上扩展。特别是数据库可能是最难扩展的部分。
就单个机器的尺寸而言,我会以性价比最高的尺寸为目标。从这个角度来看,会有一个最佳尺寸。较大的机器太贵,较小的机器又不够便宜。
但还有一个问题,即现在还是以后设计可扩展性。您可能会浪费时间设计可扩展性,而您永远都不需要它。另一方面,如果您没有为跨多台机器的可扩展性进行设计,您可能会发现自己不得不费力寻找一台足够大的机器来承载您系统中无法展开的那部分(数据库很可能是在某些时候需要一台巨型机器的部分)。
答案2
这是一个有趣的问题,@kasperd 提出的最后一点是最中肯的(所以仅凭这一点就 +1)。在我看来(以及许多其他人)——这种类型的问题很好,但绝对不是你应该做的事情,除非你真的期待增长——否则你就是在浪费时间和金钱。话虽如此,这里有一些考虑因素和选择。
实际上,这个问题包含几个问题,主要问题是是向上扩展还是向外扩展(需要考虑成本)。向上扩展通常比向外扩展更受限制(如果需要冗余,成本可能会更高),而且由于有各种可用的 PaaS 选项,向外扩展比过去简单得多,但话虽如此,您需要考虑所交付应用程序的目的,才能得出最佳选择的具体结论。
Digital Ocean 目前没有任何自动扩展功能,因此如果你预计需求会激增,你将不得不手动做这个。
从架构方面来看,系统内的许多瓶颈在于数据库,但这实际上取决于您的应用程序如何“数据驱动”,因此,如果不知道应用程序到底是什么或做什么,我真的不能建议为您的数据库使用更大的实例。
在某些方面,管理多个小实例(修补/维护等)增加了复杂性,但是,如果所有应用程序层都被分离出来,则在许多情况下可能会更容易找到瓶颈(注意:如果最终成为网络性能问题,它也会使其变得更加复杂)。
我的最终建议是尽可能从小处着手,将整个堆栈放在一个小实例上,并使用类似的工具锻造在需要时管理堆栈。没有什么可以阻止您在稍后阶段分离层级、扩展和关闭给定盒子上不需要的服务(一旦分离了层级)。
这使您可以灵活地选择垂直或水平扩展(如果需要),使您能够轻松地分离关注点,我想最重要的是,因为您没有可以参考的指标,所以您实际上是在处理未知事物。