首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我们是否正确地排队和序列化?

我们是否正确地排队和序列化?
EN

Software Engineering用户
提问于 2013-10-15 19:21:19
回答 3查看 2.1K关注 0票数 13

我们通过各种服务来处理消息(一条消息在完成之前可能会接触到9条服务,每条消息都执行特定的IO相关功能)。现在,我们将最坏情况(XML数据契约序列化)和最佳情况(内存中的MSMQ)结合起来,以提高性能。

消息的性质意味着我们的序列化数据最终会达到12-15千字节,我们每周处理大约400万条消息。MSMQ中的持久消息对我们来说太慢了,而且随着数据的增长,我们感到来自MSMQ内存映射文件的压力。服务器的内存使用量为16 at,并且在不断增长,只是为了排队。当内存使用率很高时,性能也会受到影响,因为机器开始交换。我们已经在执行MSMQ自清理行为。

我觉得我们在做错事。我试着使用RavenDB来持久化消息,只是排队等待一个标识符,但是性能非常慢(最好是每分钟1000条消息)。我不确定这是否是使用开发版本的结果,但我们肯定需要更高的吞吐量1。这一概念在理论上运作得很好,但性能不能胜任这项任务。

使用模式有一个服务充当路由器,负责所有的读取。其他服务将根据其第三方挂钩附加信息,并转发回路由器。大多数对象被触摸了9-12次,尽管大约10%的对象被迫在这个系统中循环一段时间,直到第三方做出适当的反应。服务现在说明了这一点,并且有适当的睡眠行为,因为我们为此而使用消息的优先级字段。

那么,我的问题是,在C#/Windows环境中,什么是在离散但局域网的机器之间传递消息的理想堆栈?我通常会从BinaryFormatter开始,而不是XML序列化,但如果更好的方法是将序列化卸载到文档存储区,那将是个空子。因此,我的问题。

1:我们的业务性质意味着我们越早处理信息,我们赚的钱就越多。我们经验性地证明,在本周晚些时候处理信息意味着我们不太可能赚到钱。虽然"1000每分钟“的表现听起来相当快,但我们确实需要超过10k/分钟的数字。仅仅因为我每周给出信息中的数字,并不意味着我们有整整一周的时间来处理这些信息。

===============编辑:

附加信息

根据这些评论,我将补充一些澄清:

  • 我不确定序列化是我们的瓶颈。我已经对应用程序进行了基准测试,虽然序列化确实显示在热图中,但它只负责服务CPU利用率的2.5%-3%。
  • 我最关心的是我们的消息的持久性和MSMQ的潜在误用。我们正在使用非事务性的、非持久性的消息,这样我们就可以保持排队的性能,而且我非常希望至少有持久的消息,这样它们才能在重新启动时存活下来。
  • 增加更多的RAM是权宜之计。这台机器已经从4GB的-> 16 4GB内存中消失了,越来越难继续添加更多内存。
  • 由于应用程序的星型路由模式,有一半时间对象被弹出,然后被推送到队列中--它根本不改变。这再次(IMO)将其存储在其他地方的某种键值存储中,并简单地传递消息标识符。
  • 星型路由模式是应用程序的组成部分,不会改变。我们不能应用蜈蚣,因为沿途的每一块都是异步运行的(以轮询的方式),我们希望将重试行为集中在一个地方。
  • 应用程序逻辑是用C#编写的,对象是不可变的POCOs,目标部署环境是Windows 2012,如果特定的软件仅在Linux中支持,则允许我们站起来使用其他机器。
  • 我的目标是保持当前的吞吐量,同时减少内存占用,并以最少的资金增加容错能力。
EN

回答 3

Software Engineering用户

回答已采纳

发布于 2013-10-25 17:39:18

下面是一些您可能感兴趣的队列基准。 MSMQ应该能够每秒处理10K消息。这可能是配置问题,还是客户端跟不上队列的读取?另外,请注意ZeroMQ在这些基准测试中的速度有多快(大约每秒100 K消息),它没有提供持久性选项,但它应该可以帮助您达到性能方面的目标。

票数 1
EN

Software Engineering用户

发布于 2013-10-24 23:07:19

几年前,我们遇到了类似的情况,我们使用排队的消息系统(在我们的例子中是音频指纹)。我们非常重视已排队的数据包的持久性,但我们发现,将所有内容排队到磁盘并从磁盘中消耗队列是非常昂贵的。

如果我们切换到基于内存的队列,性能是异常的,但我们有一个大问题。每隔一段时间,队列的使用者就会变得不可用很长一段时间(在我们的示例中,使用者和生产者元素通过WAN连接),因此生产者的队列会增长到无法管理的程度,就像您的情况一样,一旦内存消耗非常高,在交换期间过度的内存破坏会使系统完全爬行。

我们设计了一个我们命名为VMQueue的队列(用于虚拟内存队列,回顾中的一个非常糟糕的名称)。这个队列的思想是,如果使用者进程运行到par,换句话说,处理速度足够快,能够将排队元素的数量保持在一定的水平以下,那么它的性能基本上与基于内存的队列相同。但是,当使用者放慢速度或变得不可用,并且生产者队列增长到一定大小时,队列将自动开始从磁盘分页元素(顺便说一下,使用BinaryFormatter序列化)。该进程保持内存使用完全受控,分页进程速度快,或者至少比重内存负载期间发生的虚拟内存交换快得多。一旦使用者设法排出低于阈值的队列,它就会恢复作为一个纯基于内存的队列工作。

如果系统崩溃或重新启动,则队列能够恢复存储到磁盘中的所有分页元素,只会丢失崩溃前仍保存在内存中的元素。如果在崩溃或重新启动期间丢失有限数量的数据包,则此队列可能会有所帮助。

如果您感兴趣,我可以共享VMQueue类源代码,这样您就可以使用它了。队列将接受标记为Serializable的任何类。在创建队列时,可以以元素数确定页面的大小。类接口实际上与标准队列类相同。但是,代码非常陈旧(.net 1.1),因此不幸地不存在通用接口。

我知道,从经过验证的MSMQ技术中转移是一个巨大的赌注,但是这个队列已经可靠地工作了近6年,并且使我们能够生存下来,并从生产者机器已经离线几个星期的场景中恢复过来!如果你有兴趣,请告诉我。:)

票数 4
EN

Software Engineering用户

发布于 2013-10-25 13:34:10

HP ProLiant ML350G5系统每分钟获得82 k事务--也就是说,它的吞吐量是您提到的“10k/分钟”吞吐量的8倍以上。

性能: 82,774 tpmC

而且,老实说,我只需要64甚至128 GB的RAM -- RAM很便宜。绿纺指出了“向它扔内存”和“让一个受过麻省理工学院教育的聪明人来优化它”之间的区别,然后RAM就赢了。

最后,他得到了一台Server机器,它配备了64 GB内存和少数运行ASP.NET页面的前端机器.该网站,swaptree.com,处理其现有成员超过40万用户(迅速增长),没有困难.

注意,“这台机器已经达到了16 GB的RAM”还远远不够,一篇文章指出,一台服务器在64 GB RAM上处理400 k用户。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/214517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档