服务器集群(Django、Apache、Nginx、Postgres)

服务器集群(Django、Apache、Nginx、Postgres)

我有一个使用 django、Apache、Nginx 和 Postgres 部署的项目。该项目需要客户可以查看实时数据。该项目的要点是:1. 现场设备登录后将数据发送到服务器(设备也像网站用户)。2. 有一个后台导入过程,它将上传的数据导入到 postgres 中。3. 系统的网络用户使用此数据并可以向设备发送命令,设备登录后会读取这些命令。4. 数据上还有后台分析例程在运行。

所有上述设置和系统都部署在一台亚马逊 EC2 云机器上。该项目目前支持超过 600 台设备和 400 名用户。但随着设备数量的增加,服务器的性能正在下降。

我们想扩展这个项目,以便它能够支持越来越多的设备。我最初的想法是,我们将再创建一个像当前服务器一样的服务器,并将设备分配到这些服务器中。但我们再次需要一个通过 django admin 实现的中央用户和设备管理点。

有什么想法吗?创建可扩展架构的最佳方法是什么?如果可能的话,如何创建 Postgres 集群并将其与 Django 一起使用?

答案1

您的问题缺乏细节,而且只是在做手势,但听起来您的初步想法是一个不错的开始。您的应用程序听起来与 Zenoss 监控套件非常相似,后者使用基本相同的负载分配架构进行扩展:多个监控主机共享数据收集工作负载,使用单个管理界面,并在管理主机或单独的系统上使用数据库。

如果您的瓶颈在点 #1(设备将数据发送到您的服务器),那么将这些任务拆分到第二台机器上应该可以为负载增长留出一些空间。最大的实施障碍通常是如何管理跨多个 Django 服务器的任务。Celery 是一个分布式任务队列引擎,可能是目前最好的选择。它最初是围绕 Django 设计的,这对您来说很有利,并且它拥有非常活跃且乐于助人的开发人员和用户社区。

但是,如果第 2 点和第 4 点是您当前的限制,那么您可能正在谈论数据库可扩展性。一般来说,这只是一个难题:没有代码透明、负载中立且廉价的方法来扩展数据库容量。

如果您只需要获得更多数据库“读取”IO 容量,那么复制可能就足够了。Postgres 支持使用名为 Slony-I 的外部工具进行复制。这是单主复制,具有多个只读“从属”主机,这些主机接收在主服务器上执行的语句的副本。您的所有应用程序写入(UPDATE、INSERT、DELETE...)都通过单个主主机,但您将读取(SELECT...)分布在主主机和所有从属主机上。

分布式读取所需的代码修改通常非常简单。Django 最近添加了对复制数据库的支持,我还没有使用过,但它应该相当不错。

如果您需要更多的数据库写入 IO 容量,分片可能会起作用。每个主机保留每个数据库表的单独、唯一块。数据库客户端使用确定性函数决定任何给定记录应驻留在何处,因此负载分布实际上是无状态的,并且可以扩展到大量数据库服务器。Django 的新多数据库支持(与上述相同的链接)也支持分片。您需要进行一些代码更改,麻烦应该会很少。

另外,我想提一下 Memcached,它似乎是当今互联网上几乎所有高度可扩展的 Web 应用程序的一部分(Facebook、Google、Twitter……)。良好的缓存实现可以将数据库要求削减到其原始大小的一小部分,方法是将昂贵、缓慢的数据库查找转换为廉价、快速的缓存查找。Django 已经支持 Memcached 集成很长一段时间了。

我知道这些都不是太具体,但它应该能给你一个非常好的起点来制定细节。祝你的项目好运。

答案2

首先你必须意识到,你的瓶颈在哪里?应用层问题?数据层访问?你的访问模式是什么?主要是读取?还是主要是写入?

对于应用层:

  • 添加更多应用服务器
  • 某些操作可以放入作业队列,无需用户等待完成(例如,向设备发出的命令)

对于数据层,您可以遵循以下一些方法:

  • 想想你的工作量?你能减少一些查询吗?你能改变你的模式吗?也许可以添加一些非规范化(预先计算统计数据、聚合数据)。对于非常大的表,你可能可以添加垂直分区
  • 对于读取扩展,您可以使用复制,正如 Ryan B. Lynch 所说
  • 使用 memcached 或类似工具进行缓存。但请记住:“计算机科学中只有两件难事:缓存失效和命名事物。”
  • 我不推荐分片(水平分区),因为管理分片数据库很痛苦。这是一篇很好的文章关于分片。
  • 将数据分成不同的数据后端。这是一篇很好的文章描述这个想法。

相关内容