【问题标题】:High traffic, 500M+ hits per day (analytics like) application architecture on AzureAzure 上的高流量、每天 5 亿次以上的点击(类似分析)应用程序架构
【发布时间】:2026-02-07 15:10:01
【问题描述】:

这个问题是针对有经验的建筑师的——大男孩是怎么做的? :)

概述

我正在构建这个基于 .NET 的高流量、类似分析的解决方案,它最终将托管在 Azure 上。假设这个 Web 应用程序每天将收到 5 亿+“事务”,这些对我们的服务器的访问速度非常快,几乎不需要对每个数据库进行查询,几乎所有繁重的工作都将在服务器端按设定的时间间隔完成.我很确定我必须实现某种队列来存储所有传入的命中,并在后端实现“聚合器”,每分钟左右运行一次以处理队列中的新项目。

建议的解决方案

如果我错了,请纠正我,但我认为将这些事务直接写入数据库(某种日志表)将是一个错误,因此我将使用 Azure 存储帐户(表)作为我的队列和旋转关闭几个 Azure 工作角色(根据需要)来处理数据和更新数据库。想法?

请务必记住,Azure 存储主要基于按事务处理模型,因此我必须为所有传入事务(写入)和聚合器(读取)事务付费。因此,每天 5 亿次写入和 5 亿次读取,这大约是 100 美元/天。那有意义吗?此外,使用 Azure 存储,我可以读取一组行(以说明单个事务)还是必须读取队列中的一条记录?

最后,为每一行执行数据库插入/更新对于我的聚合器来说是一种过度杀伤,所以我认为每个聚合器都应该聚合内存中的工作负载,然后将其清除到数据库中。

【问题讨论】:

  • 看起来更像程序员的问题而不是 SO,这里没有任何特定的编程问题
  • 不是一个详细的答案,而是从某个地方开始;看看 CQRS、DDD 和 RabbitMQ/Azure 服务总线。然后也许看看使用 bit.ly/1zRXQma 托管的像 nancyfx 这样的轻量级 API

标签: architecture azure analytics azure-table-storage


【解决方案1】:

我同意更新存储中的分析数据的请求应通过放入队列的消息来完成,以便辅助角色可以在后台处理这些消息而不会影响实时用户。您甚至可以使用 AzureWatch @ http://www.paraleap.com 之类的工具根据队列中的数据量自动扩展服务器

我建议您考虑一下每个队列每秒最多可支持 500 个事务的事实。如果您需要更多,请考虑托管多个队列并为您的队列设置一个模式(可能就像拥有可以随机连接的 X 个队列一样简单:“Queue001..Queue100”。工作角色将检查所有 100 个队列,而您的网络服务器将生成 1 到 100 之间的随机数并连接到该队列

交易量实际上可能要大得多: 每天 5 亿次点击您的服务可能意味着:

  • 500M 写入队列
  • 从队列中读取 500M
  • n * 500M 写入存储(其中 n 可能是倍数,如果您的存储结构 要求您在写出之前先阅读内容,允许 批量交易等)
  • x * 24*60*60/delay 检查队列是否存在新消息(x 是队列数,延迟是每次检查之间的延迟秒数)

现在,如果您希望通过队列最大限度地减少写入/读取量,请考虑将来自 Web 服务器的请求缓冲到队列中,这样就不会将每个数据点作为单独的消息发送,而是将一堆数据点一起发送。这将限制对也算作事务(读取和写入)的队列的命中。您可以在您的网站中使用带有静态变量的锁来捕获命中,以便所有内容都存储在内存中,然后不时刷新到队列中

如果您希望尽量减少针对表存储的存储事务量,请考虑在可能的情况下使用本地存储来预聚合数据,并且仅将预聚合的数据同步到表存储。这可能会有所帮助

每当我们缓冲数据写入时,假设如果带有缓冲数据的机器由于某种原因出现故障并且缓冲区尚未刷新,则可能会丢失一些数据。由于我们在这里不处理金钱交易,我假设您对数据丢失的容忍度略高于 0,并且写入缓冲所节省的成本抵消了潜在的罕见数据丢失

HTH

【讨论】:

  • 我还会考虑缓存,因为它是分布式的,每 1000 万笔交易花费 1 美元。 windowsazure.com/en-us/pricing/details/#header-8
  • 缓存不按事务收费。 CDN 不是一回事,在这里无济于事
  • 如果您在 Web 层进行缓冲,您可以通过在 OnStop() 方法中添加代码以等待未完成的 HTTP 请求完成并将待处理的事务刷新到存储中来减少数据丢失。它仍然不会 100% 安全,但会更接近。
  • @Igorek,我建议在将整个块写入表存储之前使用缓存进行缓冲。
  • 感谢@Igorek 的精彩想法和建议!很高兴您同意队列方法,我有几个澄清问题:1)我正在考虑使用 Azure 存储表而不是队列,因为我需要以结构化的方式(client_id、user_ip、date、等) - 你同意吗? 2) 我需要保留所有这些事务,将它们留在这些队列表中是否有害,或者您会推荐其他方法吗?