这个问题是为有经验的建筑师提出的-大男孩是如何做到的?:)
概述
我正在构建这个基于.NET的高流量、类似分析的解决方案,它最终将托管在Azure上。让我们假设这个网络应用程序每天将收到5亿笔以上的"交易",这些交易对我们的服务器来说是非常快速的,只需要很少的数据库查询,几乎所有的繁重工作都将在服务器端以设定的间隔完成。我非常确信,我必须实现某种队列,它将存储所有传入的点击,并在后端实现"聚合器",它将每隔一分钟左右运行一次,以处理队列中的新项目。
建议的解决方案
如果我错了,请纠正我,但我认为将这些事务直接写入数据库(某种日志表)将是一个错误,所以我将利用Azure存储帐户(表)来处理我的队列和衍生的几个Azure Worker角色(根据需要)来处理数据并更新数据库。想法?
重要的是要记住,Azure存储主要基于每笔交易模型,因此我必须为所有传入的交易(写入)和聚合器的交易(读取)付费。因此,每天有5亿次写作和5亿次阅读,这大约是每天100美元。这有道理吗?此外,使用Azure存储,我是否可以读取一块行(用于单个事务),或者我必须一次读取一条队列记录?
最后,对我的聚合器来说,为每一行执行DB插入/更新是一种过度操作,所以我认为每个聚合器可能都应该聚合内存中的工作负载,然后将其清除到数据库中。
我同意更新存储中分析数据的请求应该通过放入队列的消息来完成,这样工作人员角色就可以在后台处理这些消息,而不会影响实时用户。您甚至可以使用类似AzureWatch@的软件,根据队列中的数据量自动扩展服务器http://www.paraleap.com
我敦促您考虑这样一个事实,即每个队列每秒最多可以支持500个事务。如果你需要更多,可以考虑托管多个队列,并为你的队列设置一个模式(可以简单到有X个可以随机连接的队列:"Queue001..Queue100"。Worker角色将检查所有100个队列,而你的web服务器将生成1到100之间的随机数,并连接到该队列
交易金额实际上可能要大得多:每天5亿次点击您的服务按比例意味着:
- 5亿次写入队列
- 从队列读取5亿次
- n*500M写入存储器(其中n可能是多路复用器,如果您的存储结构要求你在把东西写出来之前先读一遍,允许批处理事务等)
- x*24*60*60/延迟检查队列以查看是否存在新消息(x是队列数,延迟是每次检查之间的延迟,以秒为单位)
现在,如果您希望最大限度地减少队列的写入/读取量,请考虑将来自web服务器的请求缓冲到队列中,这样就不会将每个数据点都作为单独的消息发送,而是将一堆数据一起批处理。这将限制对同时算作事务(读和写)的队列的命中。你可以在你的网站中使用带有静态变量的锁来捕获点击量,这样所有的东西都会存储在内存中,然后偶尔刷新一次,使排队
如果希望最大限度地减少表存储的存储事务量,请考虑在可能的情况下使用本地存储预聚合数据,并且仅将预聚合数据同步到表存储。这可能有助于
每当我们缓冲数据写入时,我们的假设是,如果具有缓冲数据的机器由于某种原因出现故障,并且缓冲区尚未刷新,则可能会丢失一些数据。由于我们在这里不处理金钱交易,我假设您对数据丢失的容忍度略高于0,并且写入缓冲所节省的成本抵消了潜在的罕见数据丢失
HTH