Python 具有并发用户和大量数据处理的交互式webapp体系结构

Python 具有并发用户和大量数据处理的交互式webapp体系结构,python,django,multithreading,architecture,twisted,Python,Django,Multithreading,Architecture,Twisted,我遇到了一个具体的问题,并想出了解决办法。但由于解决方案涉及面很广,我想知道其他人是否也遇到过类似的情况,是否可以对最佳实践进行评论或提出替代方案 问题如下: 我有一个用Django编写的webapp,它有一个屏幕,在这个屏幕中,来自多个表的数据在时间间隔内被收集、分组和聚合。 它基本上是一个类似excel的大型矩阵,其中我们在一个轴上按时间间隔聚合数据,在另一个轴上按时间间隔聚合数据。 它涉及许多内部连接和左连接来收集所有数据,并且由于呈现数据的“报告”特性,我使用原始sql来一起查询所有数据

我遇到了一个具体的问题,并想出了解决办法。但由于解决方案涉及面很广,我想知道其他人是否也遇到过类似的情况,是否可以对最佳实践进行评论或提出替代方案

问题如下: 我有一个用Django编写的webapp,它有一个屏幕,在这个屏幕中,来自多个表的数据在时间间隔内被收集、分组和聚合。 它基本上是一个类似excel的大型矩阵,其中我们在一个轴上按时间间隔聚合数据,在另一个轴上按时间间隔聚合数据。 它涉及许多内部连接和左连接来收集所有数据,并且由于呈现数据的“报告”特性,我使用原始sql来一起查询所有数据

问题是多个用户可以在这些时间间隔内同时查看和编辑数据。他们还可以编辑粒度更细或更粗的数据,而不是使用相同数据的其他用户,但间隔较短/重叠。当前,当用户编辑某些数据时,会触发django请求,数据会被更改,受影响的间隔会被聚合并再次分组并显示出来。但由于这些数据的易变性,其他用户可能已经在他们之前改变了一些东西。此外,每次对表进行分组/聚合和重新排序也是一项非常繁重的操作(取决于数据量和间隔范围)。并发用户编辑时,情况会变得更糟

我提议的解决办法: 很明显,http请求/响应机制并不适合这种情况;分组/聚合非常重要,不适合每个请求都这样做,并发性最好在用户之间传递,反馈应该像googledocs一样实时,而不是整页刷新

我正在考虑创建一个守护进程,它根据请求从dbms中读取感兴趣的平面数据,并将其缓存在内存中。然后,对数据的所有更改都将在内存中发生,并写入dbms。此守护进程通过锁引导对数据的访问,因此守护进程可以处理哪些用户可以覆盖其他更改

平面数据使用python代码进行聚合和分组,只返回用户所需的切片;用户/守护进程通信将在WebSocket上运行。守护进程将提供订阅者/发布者通道,当某些内容发生更改时,将通知对特定数据片感兴趣的用户。这个守护进程可以使用twisted这样的框架来实现。但我不确定事件驱动的方法在这里是否有效,因为我们希望“引导”所有输入请求。。。也许这些应该放在一个队列中,并在一个单独的线程中运行?让twisted在我的调度程序旁边的线程中运行会更好,还是twisted主循环应该派生一个在此队列上工作的线程?我的理解是,线程最适合IO,而python繁重的代码基本上会阻塞其他线程。我两者都有(websockets/dbms和处理数据),这样行吗

以前有人做过类似的事情吗

提前谢谢


卡尔

我试过类似的方法,你可能对解决方案感兴趣。我的问题是:

答案如下:

他还写了一篇关于解决方案的博文:

软件堆栈包括:


这是我自己实现的,它工作起来很有魅力。

谷歌为现已废弃的Wave产品的并发编辑功能实施的方案已被记录在案。Wave的这一方面似乎是成功的,尽管Wave本身很快就被抛弃了

关于您提出的关于实施拟议计划的问题:

  • 事件驱动系统完全能够实现这一思想。事件驱动是组织代码的一种方式。它不会阻止您实现任何特定功能
  • 线程在很多情况下都不是最好的,尤其是在Python中。
  • 它对于CPU受限的工作有很大的缺点,因为CPython一次只运行一个Python线程(不管可用的硬件资源如何)。这意味着绑定CPU的多线程Python程序通常不会比单线程等效程序快,甚至更慢
  • 对于IO来说,这个缺点没有那么大的限制,因为IO不涉及在CPython上运行Python代码(IO API都是用C实现的)。这意味着您可以同时在多个线程中执行IO,因此线程化可能是一个优势。然而,在单个线程中并发执行IO正是Twisted的目的。与在单个线程中执行IO相比,线程化没有任何好处,只要您以非阻塞方式(或者可能是非同步方式)执行IO即可
  • 你好,世界

  • 谢谢你给OT的链接!除了有趣的阅读,我不确定它是否真的适用于我的情况。。。转换的工作原理类似于文本编辑器,但当协作数据稍微复杂时,冲突情况似乎变得非常特定于应用程序领域。至于NR2,在处理量大和异步IO(处理输入/输出连接)的情况下该怎么办?再次拆分为不同的进程?谢谢!我来看看这些库。龙卷风似乎比扭曲更适合这种情况。。这将涵盖我问题的通信部分。顺便说一句,另外,我还使用django应用程序作为反向代理来服务所有静态文件,并将请求重定向到uwsgi。最后一条评论已经过时。不需要uwsgi或gunicorn。Tornado能够为wsgi应用程序提供服务,因此您的软件堆栈中不需要其他工具。