从传入流中计算一段时间内值的最佳方法是什么

时间:2016-06-01 02:19:22

标签: c# performance collections

运行一个C#.net应用程序,该应用程序每30秒从100个客户端接收数据,然后将数据存储在数据库中。数据用于每个客户端的两个参数。我需要为每个客户每小时确定每个参数的总数,并根据结果做出决策。决策算法将以滑动窗口方式决定最后一小时的数据。我最初的想法是保留这100个客户端的字典,其中密钥是客户端IP,值是运行总计。但是1)如果我的应用程序在一小时的中途或59分钟重新启动,我将失去所有那些热情的运行总计。 2)如果更多客户端开始发送数据,字典将消耗更多内存,3)如果将来2个参数变为100,字典变得更大4)使得运行总值始终反映一小时的近期数据值直截了当。

我应该考虑采用哪种不同的方法?最佳实践?设计模式?

1 个答案:

答案 0 :(得分:0)

非常广泛,但我会尝试定义结构:

  1. 使用连续的8字节整数UID标识每个客户端。不是GUID,甚至不是顺序GUID。 4字节整数是一个选项,但我坚持使用8字节。种子从100,000。

  2. 使用顺序8字节整数CID标识来自用户的每个调用。不是GUID,甚至不是顺序GUID。 4字节整数是一个选项,但我坚持使用8字节。我会把1970-01-01T00:00:00的微秒数作为CID。

  3. 将所有数据存储在存档数据库表REPORT_ARCHIVE中,UID + CID是复杂的PK。 CID哈希表上的群集表,使其变得粗糙(每年1个文件/ 14个记录)。

  4. 在操作数据库表REPORT_OPER中存储最后N条记录(N取决于您的时间窗口,应该是您的配置值),UID + CID是复杂的PK。 UID哈希上的群集(8-16个文件)。

  5. 将内存结构中的所有传入调用管道化,如队列。异步处理代理应该从队列中获取记录。抓取数据块,使用数据库分块(SQL服务器和Oracle支持)保存到数据库中。保存到REPORT_OPER表,在INSERT上设置触发器以将数据从REPORT_OPER推送到REPORT_ARCHIVE。

  6. 针对REPORT_OPER(总结等)运行所有工作查询,您的分析可能会在REPORT_ARCHIVE上运行。

  7. 对于像上次X报告的SUM这样的东西,我会使用UID作为密钥在ConcurrentDictionary中将SUM缓存在内存中。重要信息:缓存请求呼叫(管理员要求总计),而不是插入呼叫(用户呼叫以30秒为间隔)。为此,您需要就SLA达成一致 - 报告总数的可接受延迟是多少。如果客户希望接近实时 - 协商调用频率以计算缓存命中/未命中。

  8. 祝你好运。

相关问题