rdbms 的自动保存性能

Auto save performance for rdbms

在我的应用程序中,用户输入了一些我希望在用户输入时自动保存的内容。保存调用并非针对每次击键,而是我仅在用户暂停超过 200 毫秒时才进行自动保存。所以在一个典型的段落中有 15-20 个服务器调用。内容不会经常被阅读,所以我需要优化写入。

由于遗留代码的原因,我必须将数据保存在 MSSQL Server 上。我在负载测试中得到 10 秒的平均响应时间。如何提高性能?

我正在考虑的一种方法是不直接将数据保存在 mssql 中,而是将其保存在 Cassandra 或 redis 中,然后最终(可能以固定的时间间隔)将其写入 mssql。

另一种方法不是频繁更新,而是为每次自动保存插入新记录。然后后台进程将每隔几分钟清理除最新记录之外的所有记录。

更新: 我用对 2 个表的简单更新调用替换了现有逻辑,现在我看到了改进。有一个很长的存储过程,在负载下最多需要 10 秒。所以现在我坚持这个问题。我还是想知道我可以在应用服务器层做些什么来减少频繁的数据库调用。

很难直接回答您的问题,但这里有一些基于我们在多个活跃用户情况下所做的工作的提示。

如果您在每次击键时都 writing/triggering,请将击键传递给后台线程,不要执行数据库写入或任何网络调用,同时阻止用户输入。快速打字员可以打 20 keystrokes/second,并且您不能承受引入延迟。

如果在网页上录制,您或许可以使用 localStorage。不要在每次击键时发出 AJAX 样式的调用,因为对未完成的请求有限制。您需要实现某种缓冲发送。请记住,现实世界中的网络调用可能需要 300 毫秒的规模才能遍历网络。

你真的需要保存每一次击键,还是每N秒acceptable?每个保存操作最终都会变成磁盘操作,因此您确实希望合并尽可能多的保存。做某事最快的方法就是根本不做。

如果您正在记录到数据库,那么更新现有行通常会更快,如果您可以先通过直接键获取它。不幸的是,有时插入新行并稍后清理多余部分会更快。如果 table 的索引很少,这往往是正确的。哪个更快取决于使用的数据库引擎及其使用方式。我们两种方法都用。

使用数据库时请记住,它们通常会保存某种日志,因此如果您经常更新,可能会对日志文件造成很大的负担。

如果你使用的技术(Using C terminology)如fopen、fwrite这些可以很好地执行,但如果你担心系统故障恢复,你可能需要调用fsync,这会限制你的最大性能率。如果您需要 fsync,数据库可能会更好。

您可能会考虑非常频繁地写入事务日志 table,然后每 N 秒发送一次到实际存储。例如,如果我输入客户姓名,我可能会将每次击键记录到键盘日志 table 中,然后让后台作业读取键盘日志 table 并将数据传输给客户 table。这有助于减少对客户的操作 table,同时还允许优化键盘日志 table 以记录击键。但是,以更多代码服务器端为代价。

总的来说,你想要这样的逻辑

在 keyup 处理程序上

  1. 将击键添加到后台队列
  2. 唤醒后台线程

后台线程

  1. Read/remove 来自后台队列的所有数据
  2. 如果没有数据,等待唤醒并重复
  3. 写入 database/network/file 等作为一个操作。 (这现在可以是同步调用)
  4. 可选一些速度控制,简单的是sleep(50mS)或sleep(2s)
  5. 重复

请记住上面的内容,用户可以键入并立即关闭,因此您的最终缓冲区写入可能尚未刷新。你需要处理这个。

如果你弄对了,用户将不会注意到任何延迟。在我们的使用中,我们记录了大约 1000 keystrokes/sec 个平均值,所有这些都通过专用网络路由到中心点。这个负载简直就是昙花一现,即使是网络监控也看不到这么小的流量。 祝你好运。