我们正在使用 django 开发一个在线学校日记应用程序。原型已经准备好,该项目将于明年投入使用,约有 500 名学生。最初我们使用 sqlite,并希望对于初始实现,这将表现得足够好。数据表用于获取上学日的详细信息(期间、班级、教师、教室,使用了许多表,并且在相当快的 PC 上访问数据库需要 67 毫秒。一旦一年开始,大部分数据可能是静态的对教室的小改动。我想提取每个学生每个学期的时间表,这样就不需要表连接了。我把这些数据放到一个学生的文本文件中,文件大小为 100K。阅读时间这个数据和处理它一天的时间表大约是 8ms。如果我在登录时预加载数据并将其存储在会话中,则登录时需要 7 毫秒,每次查询需要 2 毫秒。对于 500 名学生,使用这种方法会对 Web 服务器产生什么影响以及还有哪些其他选项(例如,将学生文本文件放入某种内存缓存而不是会话中?)不会有大量的数据输入,学生添加笔记,老师也是如此,所以它主要是检查时间表状态并查看当天或那一周存在哪些事件。
4 回答
您的预期响应时间是多少,您每分钟的预期请求数是多少?请求的数据库访问时间的二十分之一秒(这可能是缓慢的部分)对我来说听起来不是问题。SQLite 应该在这种以读取为主的情况下表现良好。所以我不相信你甚至有性能问题。
如果您想要更快的响应,您可以考虑:
- 首先,通过检查索引和分析单个检索以查找性能瓶颈,确保您拥有最佳响应时间。
- 预先计算系统的静态部分并存储 HTML。您可以将 HTML 直接放回数据库或将其存储为磁盘文件。
- 仅将数据库用作后备存储(以在服务器关闭时保留系统状态)并在系统启动时将整个事物读入内存结构。这消除了对数据的磁盘访问,尽管它限制您使用一台物理服务器。
这听起来像是过早的优化。67 毫秒几乎不比我们人类可以观察到有延迟的约 50 毫秒长。
SQLite 对数据的表示将比文本格式更有效,并且与您必须解析的文本文件不同,操作系统可以有效地缓存您在 RAM 中实际使用的数据库部分。
您可以锁定约 50MB 的 RAM 来缓存所有学生的数据的解析表示,但使用该 RAM 可能会获得更好的性能,例如 OS 磁盘缓存。
我同意其他一些建议使用 MySQL 或 PostgreSQL 而不是 SQLite 的答案。它不是为用作生产数据库而设计的。它非常适合为单用户应用程序(例如移动应用程序甚至桌面应用程序)存储数据,但在服务器应用程序中很快就会出现不足。使用 Django,切换到任何其他完全质押数据库后端是微不足道的。
select_related
如果您切换到其中之一,您应该不会真正遇到任何性能问题,特别是如果您将使用and进行所有必要的连接prefetch_related
。
如果您仍然需要更高的性能,考虑到“大部分数据是静态的”,您实际上可能希望将 Django 站点转换为静态站点(html 文件的集合),然后使用 nginx 或类似的东西为这些站点提供服务。我能想到的最简单的方法是编写一个 cron-job,它将遍历所有需要的 url-configs,从 Django 请求页面,然后将其保存为 html 文件。如果您想朝那个方向发展,您可能还想看看 Python 的静态站点生成器:Hyde和Pelican。
这种方法肯定会比任何缓存系统运行得更快,但是您将丢失站点的任何动态组件。如果您需要它们,那么缓存似乎是最好和最快的解决方案。
您应该将 MySQL 或 PostgreSQL 用于生产数据库。sqlite3 不是一个好主意。
您还应该避免在登录时预加载数据。由于您的记录可以提前插入,因此请编写 django 管理命令并预先运行导入到您选择的数据库并设计您的模型,以便当用户登录时,用户已经能够访问和查看/编辑他或她相关数据(在应用程序上线之前预先插入)。从应用程序设计的角度来看,登录时的硬编码数据操作完全不合适。
https://docs.djangoproject.com/en/dev/howto/custom-management-commands/
设计您的 django 模型和使用自定义管理命令在应用程序上线之前正确插入记录的好处意味着您可以使用 django orm 在用户和他们的记录之间建立适当的关系。
我怀疑-根据您对上面所需内容的描述-您需要重新查看创建此应用程序的方法。
有 500 名学生,我们甚至不应该谈论缓存。如果您想要响应速度,您应该优先处理以下问题:-
- 使用生产质量数据库
- 正确设计您的应用程序用例并正确设计您的应用程序模型
- 将您需要的任何数据预加载到生产数据库中
- 前端优化优先(css/js压缩等)
- 使用 django 调试工具栏来确定您的任何 sql 是否很慢并专门优化那些
- 根据需要实现缓存(memcached 等)
作为一般准则。