C# 可靠、持久的堆栈技术
在这里尝试心理重置:我试图用MSMQ创建一个可靠、持久的堆栈,但没有成功 因此,更笼统地说: 我有producer(一个webservice,虽然“只有一个”)/consumer(多个进程,视需要而定)设置,但它是多线程的。关键问题是 -数据需要按后进先出顺序消费/处理(~>堆栈) -数据需要以可靠的方式存储/处理(即由磁盘、消息队列等支持)。交易支持奖励积分。 -涉及进程间通信 鉴于以上几点,我很难找到一个简洁的解决方案。我看到的是:C# 可靠、持久的堆栈技术,c#,.net,data-structures,C#,.net,Data Structures,在这里尝试心理重置:我试图用MSMQ创建一个可靠、持久的堆栈,但没有成功 因此,更笼统地说: 我有producer(一个webservice,虽然“只有一个”)/consumer(多个进程,视需要而定)设置,但它是多线程的。关键问题是 -数据需要按后进先出顺序消费/处理(~>堆栈) -数据需要以可靠的方式存储/处理(即由磁盘、消息队列等支持)。交易支持奖励积分。 -涉及进程间通信 鉴于以上几点,我很难找到一个简洁的解决方案。我看到的是: 自己动手 我并不是真的打算这么做,但这方面的初步概念证明证
- 我需要将我的数据存储为一个blob(因为它本身不容易用于基于列的存储)
- 为工作轮询数据库似乎是错误的(是吗?)
- 锁定多个消费者似乎很棘手
更新
- 仅限窗口
- 目前,我甚至不需要进行机器间通信(即,生产者/消费者目前可能在一台机器上)
- 问题的关键部分,对我来说困难的任务是:我不能失去一份工作/一条信息,即使所有流程都停止了。DB会告诉我“免费”,消息队列可以设置为可靠的。Map/reduce虽然有趣,但并不能解决核心问题:如何确保消息/作业不会丢失
我也不认为数据库表是一个坏主意,只要你不需要每秒扩展超过几千个事务,你就可以了。如果你沿着数据库的路线走,你可以看看触发器。这在某种程度上取决于消息的稀疏程度以及处理它们的等待时间。对于第3点,您可以通过非常狂热的Jon Skeet来了解,这是一种将数据序列化为二进制blob的方法,可以轻松转储
关于进程间通信——我们在这里讨论的是什么平台,如果是windows与其他windows机器通信,WCF是否不合适?至于事务支持-大多数ADO.NET都有事务支持(根据文章),除非您根据本条目谈论的是文件系统事务支持,甚至可以使用System.Transaction名称空间,正如在分布式事务中所阐明的那样。MapReduce听起来非常适合这种情况,并且可以超级扩展,因为它是google用来索引网页的。不确定您的首选堆栈是什么,但您可能想查看Hadoop,我会选择SQL Server
createtablestack(Id-int-identity,Data-varbinary(MAX))的表。
SELECT*fromstack
BEGIN TRANSACTION
SELECT Data FROM Stack WHERE Id = (SELECT MAX(Id) FROM Stack)
DELETE FROM Stack WHERE Id = (SELECT MAX(Id) FROM Stack)
COMMIT
下面是一个更优雅的版本,它甚至不需要显式事务:
DELETE Stack
OUTPUT DELETED.Data
WHERE Id = (SELECT MAX(Id) FROM Stack)
如果希望一次批处理10个项目,可以使用如下SQL:
DELETE Stack
OUTPUT DELETED.*
WHERE Id IN (SELECT TOP 10 Id FROM Stack ORDER BY Id DESC)
轮询数据库进行工作并不一定是错误的。如果你的应用程序增长太快,它就不能很好地扩展。在这里,你想支持什么平台可能会很有用。@ChaosPandion:我根本不排除这个解决方案:这是我目前为止最好的潜在客户。我不喜欢“数据库中的blob”和“轮询数据库”之类的东西,但我可能可以接受。下一个问题是:竞争的消费者进程争夺作业似乎很棘手,但不会造成巨大的性能损失或锁定问题。我已经研究了一些消息队列实现(虽然不是AMQP,但到目前为止我已经研究了zeromq/msmq)他们似乎不支持我的要求:我发布的每一条新消息都会自动成为最重要的消息。不过,我会尝试在这方面寻找更多的替代方案,谢谢。我相信这背后有一个好主意,我只是缺乏洞察力,还不知道触发器会如何帮助我。基本上,除了“储存大量斑点”的气味,DB对我来说很难与竞争对手一起使用。我见过不少这样的把戏,但其中很多似乎都很老套。你知道一个比较体面的方法吗?这几乎都是临时的。竞争性消费者问题可以通过交易解决。我是在建议,而不是