【问题标题】:How to make polling from database scalable?如何使数据库轮询具有可扩展性?
【发布时间】:2021-09-26 14:27:51
【问题描述】:

我正在尝试找到一种可扩展的方式,以允许我的桌面应用程序在数据库发生更改时运行命令。

该应用程序用于在您的 PC 上运行远程命令。用户登录网站并可以选择运行命令。目前,用户必须下载一个桌面应用程序,每隔几秒检查一次数据库以查看值是否已更改。只有当他们登录网站并按下按钮时才能更改该值。

目前它似乎运行良好,因为用户不多。但是当我击中 100 多个用户时,每隔几秒访问数据库 100 次以上并不好。有什么更好的方法?

【问题讨论】:

标签: mysql database scalability


【解决方案1】:

确实,轮询更改的成本太高,尤其是在您有很多客户的情况下。查询通常非常昂贵,并且经常运行查询以确保在更改后及时通知客户是很诱人的。最好避免轮询数据库。

上述 cmets 中的一个建议是使用从触发器调用的 UDF。但我不建议这样做,因为触发器在您执行 INSERT/UPDATE/DELETE 时运行,而不是在您提交更改时运行。因此,客户端可能会收到更改通知,然后当他们检查数据库时,更改似乎不存在,因为要么事务已回滚,要么事务还没有提交。

触发器解决方案不好的另一个原因是 MySQL 触发器对每一行更改执行一次,而不是对每个 INSERT/UPDATE/DELETE 语句执行一次。因此,如果您执行影响数千行的更新,可能会导致通知垃圾邮件。

另一种解决方案是使用message queue,例如 RabbitMQ、ActiveMQ 或 Amazon SQS(还有很多其他方法)。当客户端提交他们的 INSERT/UPDATE/DELETE 时,他们确认提交成功,然后在消息队列主题上发布一条消息。许多客户可以通过这种方式得到有效的通知。但它要求每个提交更改到数据库的客户端都编写代码发布到消息队列。

另一种解决方案是让客户端订阅 MySQL 的二进制日志并将其作为更改数据捕获日志读取。对数据库的每个提交更改都记录在二进制日志中。你可以让客户端读取这个,它对数据库服务器的影响不亚于复制客户端(MySQL 可以轻松支持数百个副本)。

混合解决方案是使用二进制日志,并将这些更改转换为消息队列中的事件。这就是像Debezium 这样的产品的工作原理。它读取二进制日志,并将事件发布到 Apache Kafka 消息队列。然后其他客户端可以等待 Kafka 队列上的事件并做出响应。

【讨论】:

  • 关于在提交写入之前调用触发器的好点,我没有想到这一点。也就是说,在实践中,并且考虑到 OP 所描述数据库的(看似)SOHO 性质,我认为 DML 故障根本不会发生... ymmv,ofc。
  • 哦,还有一个想法:自定义 MySQL 复制订阅者(根本不是数据库)怎么样,只是听 pub/sub 消息?我认为这样的事情是可能的,无需手动读取二进制日志。
  • 读取二进制日志正是复制客户端所做的。例如,这就是像 Debezium 这样的 CDC 解决方案订阅更改的方式。这是另一个关于它的博客:percona.com/blog/2016/09/13/…
  • 抱歉,我本可以更好地表达自己:当你说他们会阅读二进制日志文件时,我以为你的意思是他们都必须使用自己重新实现的库来读取和解析磁盘上的 MySQL 二进制日志文件 - 而不是使用记录良好且支持良好的 API 或 MySQL 服务。 (我想在 1990 年代中期糟糕的 4GL 数据库产品经验丰富之后,我就预料到了这一点,这些产品仍然存在于你确实必须对封闭的、未记录的专有二进制数据库磁盘/文件格式进行逆向工程和解析才能做任何事情的地方。 .!)
猜你喜欢
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 2017-04-06
  • 2011-03-22
  • 2010-09-18
  • 1970-01-01
相关资源
最近更新 更多