检查 Azure 上不活动的策略
我在 Azure 表存储中有一个表,其中的行由各种进程定期更新。我希望有效地监视行在特定时间段内尚未更新的情况,并在发生这种情况时生成警报。
我见过的 Azure 功能的大多数任务计划程序实现都是确保一次只有一个工作线程执行给定的作业。但是,设置等待 n 分钟的计划任务,然后查询最新时间戳以确定是否应采取操作,似乎效率很低,因为工作不会分散到各个工作人员之间。必须轮询如此多的记录通常效率也很低。
使用此功能的一个示例是向过去 30 天内未登录网站的用户发送电子邮件。为了产生有效的算法,假设用户数量是一个“大量”。
有没有人对可用于检查最近活动而不强迫仅一名工人完成这项工作的策略有任何建议?
I have a table in Azure Table Storage, with rows that are regularly updated by various processes. I want to efficiently monitor when rows haven't been updated within a specific time period, and to cause alerts to be generated if that occurs.
Most task scheduler implementations I've seen for Azure function by making sure only one worker will perform a given job at a time. However, setting up a scheduled task that waits n minutes, and then queries the latest time-stamp to determine if action should be taken, seems inefficient since the work won't be spread across workers. It also seems generally inefficient to have to poll so many records.
An example use of this would be to send an email to a user that hasn't logged into a web site in the last 30 days. Assume that the number of users is a "large number" for the purposes of producing an efficient algorithm.
Does anyone have any recommendations for strategies that could be used to check for recent activity without forcing only one worker to do the job?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
保留一个带有时间戳的 LastActive 表作为行键 (
DateTime.UtcNow.Ticks.ToString("d19")
)。通过执行删除旧行并插入新行的批处理事务来更新它。现在,对非活动用户的查询就像
from user in LastActive where user.PartitionKey == string.Empty && user.RowKey < (DateTime.UtcNow - TimeSpan.FromDays(30)).Ticks.ToString("d19") 选择用户
。这对于任何大小的桌子都非常有效。根据您要对该信息执行的操作,您可能希望将一条消息放入队列中,然后删除该行(以便下次检查时不会再次注意到它)。现在,多个工作人员可以提取这些队列消息并采取行动。
我对您想要在多个工作实例上执行此操作的愿望感到困惑...您可能只想对非活动用户执行一次操作,因此您只需要一个实例来进行检查。 (发送电子邮件或您正在做的其他任何事情都可以通过使用队列来分散,但初始检查应该由一个实例完成。)
Keep a LastActive table with a timestamp as a rowkey (
DateTime.UtcNow.Ticks.ToString("d19")
). Update it by doing a batch transaction that deletes the old row and inserts the new row.Now the query for inactive users is just something like
from user in LastActive where user.PartitionKey == string.Empty && user.RowKey < (DateTime.UtcNow - TimeSpan.FromDays(30)).Ticks.ToString("d19") select user
. That will be quite efficient for any size table.Depending on what you're going to do with that information, you might want to then put a message on a queue and then delete the row (so it doesn't get noticed again the next time you check). Multiple workers can now pull those queue messages and take action.
I'm confused about your desire to do this on multiple worker instances... you presumably want to act on an inactive user only once, so you want only one instance to do the check. (The work of sending emails or whatever else you're doing can then be spread about by using a queue, but that initial check should be done by exactly one instance.)