Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可靠、持久的堆栈技术_C#_.net_Data Structures - Fatal编程技术网

C# 可靠、持久的堆栈技术

C# 可靠、持久的堆栈技术,c#,.net,data-structures,C#,.net,Data Structures,在这里尝试心理重置:我试图用MSMQ创建一个可靠、持久的堆栈,但没有成功 因此,更笼统地说: 我有producer(一个webservice,虽然“只有一个”)/consumer(多个进程,视需要而定)设置,但它是多线程的。关键问题是 -数据需要按后进先出顺序消费/处理(~>堆栈) -数据需要以可靠的方式存储/处理(即由磁盘、消息队列等支持)。交易支持奖励积分。 -涉及进程间通信 鉴于以上几点,我很难找到一个简洁的解决方案。我看到的是: 自己动手 我并不是真的打算这么做,但这方面的初步概念证明证

在这里尝试心理重置:我试图用MSMQ创建一个可靠、持久的堆栈,但没有成功

因此,更笼统地说:

我有producer(一个webservice,虽然“只有一个”)/consumer(多个进程,视需要而定)设置,但它是多线程的。关键问题是 -数据需要按后进先出顺序消费/处理(~>堆栈) -数据需要以可靠的方式存储/处理(即由磁盘、消息队列等支持)。交易支持奖励积分。 -涉及进程间通信

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

  • 自己动手 我并不是真的打算这么做,但这方面的初步概念证明证明了这一点(对我来说)很难,并帮助我更好地掌握了所涉及的许多障碍

  • MSMQ 这会很好,也很容易,因为它很容易“可靠”,很容易设置,并且已经是目标基础设施的一部分。不幸的是,“后进先出”/“堆栈”是这里的杀手。这似乎是不可能的->Bzzzt

  • 数据库(SQL Server) 我试着研究一种基于数据库的方法,但其中涉及到很多丑陋的东西:

    • 我需要将我的数据存储为一个blob(因为它本身不容易用于基于列的存储)
    • 为工作轮询数据库似乎是错误的(是吗?)
    • 锁定多个消费者似乎很棘手
  • 对我应该评估的技术有什么建议吗?基于数据库的方法似乎是迄今为止最“有希望的”,但我仍然没有找到类似用例的好例子/成功案例


    更新
    • 仅限窗口
    • 目前,我甚至不需要进行机器间通信(即,生产者/消费者目前可能在一台机器上)
    • 问题的关键部分,对我来说困难的任务是:我不能失去一份工作/一条信息,即使所有流程都停止了。DB会告诉我“免费”,消息队列可以设置为可靠的。Map/reduce虽然有趣,但并不能解决核心问题:如何确保消息/作业不会丢失

    您应该查看AMQP。我在谷歌atm上翻了翻,不幸的是,我没有理由相信它可以维护堆栈而不是队列,但是有几种开源实现,除了FIFO和LIFO的问题,它非常适合你想要的东西


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

    如果你沿着数据库的路线走,你可以看看触发器。这在某种程度上取决于消息的稀疏程度以及处理它们的等待时间。

    对于第3点,您可以通过非常狂热的Jon Skeet来了解,这是一种将数据序列化为二进制blob的方法,可以轻松转储


    关于进程间通信——我们在这里讨论的是什么平台,如果是windows与其他windows机器通信,WCF是否不合适?至于事务支持-大多数ADO.NET都有事务支持(根据文章),除非您根据本条目谈论的是文件系统事务支持,甚至可以使用System.Transaction名称空间,正如在分布式事务中所阐明的那样。

    MapReduce听起来非常适合这种情况,并且可以超级扩展,因为它是google用来索引网页的。不确定您的首选堆栈是什么,但您可能想查看Hadoop,我会选择SQL Server

  • 显然,您必须将数据序列化为blob,但任何解决方案都必须这样做(至少在幕后)。然后,您将拥有一个类似于
    createtablestack(Id-int-identity,Data-varbinary(MAX))的表。

  • 不需要轮询数据库。SQLServer有一个查询通知服务,您只需向它发出查询,它就会在结果不同时通知您。您的通知查询将是
    SELECT*fromstack

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

  • 下面是一个示例查询:

    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对我来说很难与竞争对手一起使用。我见过不少这样的把戏,但其中很多似乎都很老套。你知道一个比较体面的方法吗?这几乎都是临时的。竞争性消费者问题可以通过交易解决。我是在建议,而不是