我遇到了一个特定的问题并想到了解决方案。但是由于该解决方案涉及很多,我想知道其他人是否遇到过类似的事情并可以评论最佳实践或提出替代方案。
问题如下:我有一个用 Django 编写的 webapp,它有一些屏幕,其中以时间间隔收集、分组和聚合来自多个表的数据。它基本上是一个类似于矩阵的大型 excel,其中我们在一个轴上以时间间隔聚合数据,而另一个轴上每个时间间隔的聚合数据的资源。它涉及许多内连接和左连接来收集所有数据,并且由于呈现数据的“报告”性质,我使用原始 sql 一起查询所有内容。
问题是多个用户可以在这些时间间隔内同时查看和编辑数据。与使用相同数据的其他用户相比,他们还可以在更精细或更粗糙的粒度上编辑数据,但在子/重叠间隔中。目前,当用户编辑某些数据时,会触发 django 请求,更改数据,将受影响的间隔再次聚合和分组并返回。但由于这些数据的易变性,其他用户可能在他们之前更改了某些内容。此外,每次对表格进行分组/聚合和重新呈现是一项非常繁重的操作(取决于数据量和间隔范围)。并发用户编辑时,情况会变得更糟。
我提出的解决方案:很明显,http 请求/响应机制对于这种事情并不理想;分组/聚合是相当重量级的,不适合每个请求执行此操作,理想情况下,并发将在用户之间传递,并且反馈应该像 googledocs 一样实时,而不是整页刷新。
我正在考虑制作一个守护进程,它根据请求从 dbms 读取感兴趣的平面数据并将其缓存在内存中。然后,对数据的所有更改都将发生在内存中,并写入 dbms。该守护进程通过锁引导对数据的访问,因此该守护进程可以处理哪些用户可以覆盖其他更改。
使用python代码对平面数据进行聚合和分组,只返回用户需要的切片;用户/守护进程通信将通过 websockets 运行。守护进程将提供一个订阅者/发布者通道,当某些事情发生变化时,对特定数据片段感兴趣的用户会收到通知。这个守护进程可以使用像 twisted 这样的框架来实现。但是我不确定事件驱动的方法在这里是否有效,因为我们想“引导”所有传入的请求......也许这些应该放在一个队列中并在单独的线程中运行?在我的调度程序旁边的线程中进行扭曲运行会更好,还是应该扭曲的主循环分离在该队列上工作的线程?我的理解是线程最适合 IO,而 python 繁重的代码基本上会阻塞其他线程。
有没有人做过类似的事情?
提前致谢!
卡尔