技术可靠,持久的堆栈

时间:2010-08-29 21:19:28

标签: c# .net data-structures

在这里尝试精神重置:我尝试用MSMQ创建一个可靠的持久堆栈,但是没有工作

所以用更一般的术语来说:

我有生产者(webservice,所以多线程虽然“只有一个”)/消费者(多个进程,尽可能多的)设置。关键问题是 - 需要以LIFO顺序(〜>堆栈)使用/处理数据 - 需要以可靠的方式存储/处理数据(即由磁盘,消息队列等支持)。交易支持的奖励积分。 - 涉及进程间通信

鉴于以上几点,我很难找到一个简洁的解决方案。我看了什么:

  1. 自己动手 没有真正打算这样做,但最初的概念证据确认这很难(对我而言)并帮助我更好地掌握所涉及的许多障碍。

  2. MSMQ 这将是好的和简单的,因为它很容易“可靠”,易于设置,已经是目标基础设施的一部分。不幸的是,“LIFO”/“Stack”在这里是一个杀手。这似乎是不可能的 - > Bzzzt。

  3. 数据库(SQL Server) 我试着看一下基于数据库的方法,但涉及到许多丑陋的事情:

    • 我需要将我的数据存储为blob(因为它不能轻易地将其自身用于基于列的存储)。
    • 轮询数据库工作似乎不对(是吗?)
    • 与多个消费者锁定似乎很棘手......
  4. 对于我应评估的技术的任何建议?到目前为止,基于数据库的方法似乎是最“有希望”的,但我仍然没有找到类似用例的好例子/成功案例。


    更新

    • 仅限Windows
    • 目前,我甚至不需要进行机器间通信(即生产者/消费者可能现在在一台机器上)
    • 问题的关键部分,对我来说最困难的任务是:即使所有流程都失败,我也不会丢失工作/消息。数据库会给我“免费”,消息队列可以设置为可靠。 Map / reduce虽然有趣,但并未解决核心问题:如何确保消息/作业不会丢失?

5 个答案:

答案 0 :(得分:2)

我会选择SQL Server。

  1. 显然你必须将数据序列化为blob,但任何解决方案都必须这样做(至少在幕后)。然后你就会有一个像CREATE TABLE Stack (Id int identity, Data varbinary(MAX))

  2. 这样的表格
  3. 无需轮询数据库。 SQL Server有一个查询通知服务,您只需给它一个查询,它会在结果不同时通知您。您的通知查询只是SELECT * FROM Stack

  4. 锁定是数据库的问题,而不是你的问题。您只需让每个使用者运行一个使用事务的查询(或存储过程)来返回最新的条目(具有最高Id的行)并同时删除它。如果查询返回结果,请对其进行处理并再次运行。如果查询未返回任何结果,请参阅#2。

  5. 以下是一个示例查询:

    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)
    

答案 1 :(得分:0)

您应该查看AMQP。我正在谷歌atm上挖掘,不幸的是没有理由相信它可以维持堆栈而不是队列,但是有几个开源实现,除了FIFO与LIFO问题之外,它非常适合你想。

我认为数据库表也不是一个坏主意,只要你不需要每秒扩展几千个事务就可以了。你应该没问题。

答案 2 :(得分:0)

如果你要沿着数据库路线走下去,你可以看看触发器。这取决于你的消息是多么稀疏以及你可以等待多长时间来处理它们。

答案 3 :(得分:0)

对于第3点,您可以通过SO狂热的Jon Skeet查看this,这是一种将数据序列化为可以轻松转储的二进制blob的方法....

关于进程间通信 - 我们在这里谈论的是什么平台,如果它的窗口与其他Windows机器通信,那么WCF不适合吗?至于事务支持 - 大多数ADO.NET都有事务支持(根据MSDN文章),除非您正在讨论根据此blog条目的文件系统事务支持,或者甚至使用System.Transaction命名空间关于分布式交易澄清here

答案 4 :(得分:0)

MapReduce听起来非常完美,可以超级扩展,因为它是google用于索引网页的内容。不确定你最喜欢的堆栈是什么,但你可能想看看Hadoop