我知道这是一个相对广泛的问题,但Django是否足够健壮以构建社交网络?我主要关心的是性能/速度。例如,对于用户群较小(<10,000用户)的网站,是否可以创建一个Django支持的网站,其速度与Facebook类似?
它有哪些潜在的弱点,以及需要关注的事情,以尽可能快地实现它?
答案 0 :(得分:27)
“它有哪些潜在的弱点,以及需要关注的事情,以尽可能快地实现它?”
您可能会担心的另一件事是,根据您创建模型的方式并将它们彼此连接,您可能会遇到一个问题,即单个页面会产生许多,很多,许多查询。
如果您使用的是涉及generic relation的模型,则尤其如此。
假设您正在使用django-activity-stream创建最近事件列表(类似于Facebook的新闻Feed)。 django-activity-stream基本上创建了一个通用关系列表。对于这些通用关系中的每一个,您将不得不运行查询以获取有关该对象的信息。并且,因为它是通用的(即,您不是为每种对象编写自定义查询),如果该对象具有您想要输出的自己的关系,您可能会查看类似于活动订阅源的40-100个查询只有20-30项。
对单个请求运行40-100个查询不是最佳行为。
好消息是Django实际上只是一堆用python编写的类和函数。您在python中编写的几乎任何内容都可以添加到Django中,因此您始终可以编写自己的函数或代码来优化给定的请求。
选择另一个框架不会避免可伸缩性问题;它只会在不同的领域呈现出不同的困难。
此外,您可以查看caching之类的内容,以加快响应并防止服务器负载。
答案 1 :(得分:16)
2011年问了这个问题,Django从那时起已经走了很长一段路。我以前在Django上建立了一个拥有200万用户的社交网络,并发现这个过程非常顺利。 getstream.io基础设施的一部分也在Django上运行,我们对此非常满意。以下是一些有关如何充分利用Django安装的技巧。从问题中我不是很清楚,但我假设你从一个完全没有优化的Django安装开始。
静态文件&amp; CDN 强>
首先在S3上托管您的静态文件,然后将Cloudfront CDN粘贴在它前面。托管Django实例中的静态文件是个糟糕的主意,请不要这样做。
数据库&amp; ORM:选择相关的
第二个最常见的错误是没有优化您对ORM的使用。您将要查看有关选择相关的文档并根据需要应用它。您网站上的大多数网页只需要2-3次查询,而不是N次查询,因为您通常会看到您是否正确使用了选择相关的内容: https://docs.djangoproject.com/en/1.11/ref/models/querysets/
数据库:PGBouncer
创建与postgres数据库的新连接是一项相当繁重的操作。您希望在localhost上运行PGBouncer,以确保在创建数据库连接时不会有任何不必要的开销。对于旧版本的Django来说,这更为紧迫,但总的来说仍然是一个好主意。
基本监控&amp;调试强>
接下来,您将要进行一些基本的监控和调试并运行。 django调试工具栏是你的第一个朋友: https://github.com/jazzband/django-debug-toolbar
之后,您将要查看NewRelic,Datadog,Sentry和StatsD / Graphite等工具,以获得更多见解。
分开关注
另一个第一步是分离出问题。您希望在自己的服务器上运行数据库,在自己的服务器上运行搜索服务器,在自己的服务器上运行Web等。如果您在一台计算机上运行所有内容,则很难看到#39;导致您的应用中断。服务器很便宜,拆分起来。
负载均衡器
如果您之前从未使用过负载均衡器,请从此处开始: https://aws.amazon.com/elasticloadbalancing/
使用正确的工具
如果您正在执行标记云,则代码搜索或搜索会使用专用工具(例如Elastic)。
如果您有经常更改的计数器或快速更改的列表,请使用Redis而不是数据库来缓存最新版本
芹菜和RabbitMQ
使用任务队列执行当前不需要在后台执行的任何操作。最广泛使用的任务队列是Celery: http://www.celeryproject.org/
非常规化所有内容
您不想计算诸如对阅读的喜欢和评论之类的计数。每当有人添加新的喜欢或评论时,简单更新类似和评论计数。这使得写入操作更重,但读取更轻。由于你可能会有大量的阅读和很少的写作,这正是你想要的。
新闻Feed和活动流
如果您要构建Feed,请查看building news feeds & activity streams或open source Stream-Framework
的此服务2011年,你必须建立自己的饲料技术,现在已不再是这种情况了。 Build a social network with PHP
现在我们已经了解了基础知识,让我们回顾一些更高级的提示。
CDN和2阶段加载
您已经在使用Cloudfront作为静态文件。作为下一步,您也希望将Cloudfront坚持在您的网络流量之前。这允许您缓存CDN上的某些页面并减少服务器上的负载。
您甚至可以在CDN上缓存登录用户的页面。在从CDN提供页面后,只需使用Javascript加载所有页面自定义和用户特定的详细信息。
数据库:PGBadger
PGBadger等工具可让您深入了解数据库的实际用途。您希望对部分日志数据运行每日报告。
数据库:索引
您想要开始阅读数据库索引。大多数早期扩展问题可以通过应用正确的索引并稍微优化数据库来解决。如果你的索引正确,你将比大多数人做得更好。数据库优化还有很多空间,第二象限人员的这些书很棒。 https://www.2ndquadrant.com/en/books/
数据库:调整
如果您不使用RDS,则需要对数据库运行快速PGTune检查。默认情况下,postgres&#39;配置相当缓慢,PGTune告诉你正确的设置: https://github.com/gregs1104/pgtune
缓存所有内容
扩展数据库很痛苦。最终,您将拥有多个从属数据库,处理分片和分区等。缩放数据库非常耗时,避免花费大量时间的最佳方法是缓存。 Redis是你现在去的缓存,但是memcached也是一个不错的选择。基本上你会想要缓存一切。页面显示帖子列表:从Redis中读取,查找用户配置文件?阅读Redis。您希望尽可能少地使用数据库并将大部分负载放在缓存层上,因为扩展缓存层非常简单
<强>偏移强>
Postgres不喜欢大偏移。在对大型结果集进行分页时使用ID过滤。
<强>死锁强>
随着大量流量,您最终会陷入僵局。当postgress上的多个事务试图锁定一条信息而A等待B而B等待C和C等待A时,会发生这种情况。显而易见的解决方案是使用较小的事务。这减少了发生死锁的机会。接下来,您将要批量更新最常用的数据。 IE浏览器。您不希望每当有人喜欢帖子时更新计数,而是希望存储一个类似更改的列表,并每5分钟左右将其同步到计数中。
这些是一些基本技巧,与快速发展的社交网络一起玩得很开心:)。
答案 2 :(得分:6)
Pinterest&amp; Instagram使用django,我敢肯定它是可扩展的,对于大多数加载的部分,例如活动源,你可以使用像Redis这样的内存存储。
django上的高负荷网站
Disqus http://www.slideshare.net/zeeg/djangocon-2010-scaling-disqus
Pinterest的 http://www.slideshare.net/eonarts/mysql-meetup-july2012scalingpinterest
的Instagram http://instagram-engineering.tumblr.com/
答案 3 :(得分:5)
我的头......
Pinax有一个社交网站的个人资料。
Convore和Disqus将Django用于其网站的某些部分。
关于Django可伸缩性 - Does Django Scale ?
编辑:在谷歌搜索其他内容时找到了这个。
PyCon 2011: Django: Pitfalls I Encountered and How to Avoid Them
由Luke Sneeringer主持
你是从中等到大的开始吗? 大小的Django项目?你需要吗? 提前计划并构建一个应用程序 这会对意料之外的事情做出反应 需要吗?这个讲座涵盖了一些 我遇到的技术和陷阱 在写我的第一个相当大的 Django网站,以及我所做的 不同的是我第二次开始 一个项目。
答案 4 :(得分:2)
Django当然可以用于构建社交网络,它为caching等性能增强功能提供了很多功能。请参阅scaling上的这篇文章。
主要瓶颈将伴随您设计模型的方式。根据我的经验,当您运行复杂查询时,创建深层嵌套的外部链接和许多连接(许多关系)会变慢。对于此类情况,您应该尝试listfields。您还可以调查Google在appengine的大表中使用的键/值对,它比关系数据库扩展得更多。
您还应该方便地订阅项目,您可能希望使用ajax来保持用户体验并阻止用户加载页面以查看更多帖子。
答案 5 :(得分:0)
This question讨论了如何使用Django进行扩展。这可能会增加您尝试创建潜在大型网站的信心。
答案 6 :(得分:0)
这不仅仅是Django或python的问题,而是云和软件工程的问题。单独一台服务器可能适用于10,000个用户,因为它们不是并发的,也是位置,这些用户是否在同一个城市?国家?
我相信Django非常好,我会在类似的项目中使用它,我的问题不是Django,而是IaaS,我将运行它的基础设施。
如果您仍然担心Python是否是答案,那么您可以研究Ruby on Rails和asp .Net,甚至perl,php等等。对我来说,Python绝对是答案。