当前位置: 首页 > 知识库问答 >
问题:

何时使用破坏者模式,何时本地存储和工作窃取?

施飞雨
2023-03-14

以下是否正确?

  • 如果必须以多种方式(io操作或注释)处理每个条目,则中断器模式具有更好的并行性能和可扩展性,因为可以使用多个消费者进行并行化而无需争用。
  • 相反,如果必须仅以单一方式处理每个条目,则工作窃取(即在本地存储条目并从其他线程窃取条目)具有更好的并行性和可扩展性,因为将条目不相交地分布到中断器模式中的多个线程上会导致争用。

(当涉及多个生产者(即CAS运营)时,破坏者模式是否仍比其他无锁多生产者多消费者队列(例如来自boost)快得多?)

我的详细情况:

处理一个条目可能会产生几个新条目,最终也必须处理这些条目。性能具有最高优先级,按FIFO顺序处理的条目具有第二优先级。

在当前实现中,每个线程都使用本地FIFO,并在其中添加新条目。空闲线程从其他线程的本地FIFO窃取工作。线程处理之间的依赖关系使用无锁、机械交感哈希表(写入时的CAS,具有桶颗粒度)来解决。这导致非常低的争用,但FIFO顺序有时会被破坏。

使用中断器模式将保证FIFO顺序。但是,将条目分发到线程上是否会导致比本地FIFO更高的争用(例如,读取游标上的CAS)以及工作窃取(每个线程的吞吐量大致相同)?

我找到的参考资料

关于干扰器的标准技术文件(第5章和第6章)中的性能测试不包括不相交的工作分配。

https://groups.google.com/forum/?fromgroups=#!topic/lmax disruptor/tt3wQthBYd0是我找到的关于disruptor工作盗窃的唯一参考资料。它指出,如果存在任何共享状态,则每个线程的队列速度会显著降低,但没有详细说明或解释原因。我怀疑这句话是否适用于我的情况:

  • 使用无锁哈希表解析共享状态;
  • 必须在消费者之间不一致地分发条目;
  • 除了工作窃取,每个线程只在其本地队列中读取和写入。

共有1个答案

尹承业
2023-03-14

更新-为获得最大性能而预先列出的底线:您需要使用中断器和工作窃取的惯用语法编写,然后进行基准测试。

对我来说,我认为区别主要在于消息和任务焦点之间的区别,因此是您想要思考问题的方式。尝试解决您的问题,如果它是以任务为中心的,那么Disruptor是一个很好的选择。如果问题是以消息为中心的,那么您可能更适合另一种技术,例如工作窃取。

>

当您的实现以任务为中心时使用中断器。每个线程都可以在处理的特定阶段工作。另一个例子:对于任务焦点,处理将被划分为阶段,因此您将拥有一个执行日志记录的线程、一个用于安全控制的线程、一个用于vhost查找的线程等;每个线程都专注于其任务并将请求传递给管道中的下一个线程。阶段可以并行化,但整体结构是一个专注于特定任务的线程,并在线程之间传递消息。

当然,您可以更改实现以更好地适应每种方法。

在您的情况下,如果您想使用Disruptor,我会以不同的方式构造问题。通常,您可以通过让一个线程拥有状态并通过该工作线程传递所有任务来消除共享状态——在SEDA中查找许多类似的图。这可能有很多好处,但同样,这取决于您的实现。

更详细一些:

  • Disruptor-当需要严格的阶段排序时非常有用,当所有任务的长度一致时会带来额外的好处,例如:外部系统没有阻塞,每个任务的处理量非常相似。在这个场景中,您可以假设所有线程都将在系统中均匀工作,因此每N条消息都会安排N个线程来处理。我喜欢将Disruptor视为实现类SEDA系统的一种有效方法,其中线程处理阶段。当然,您可以有一个具有单个阶段和多个并行单元的应用程序,这些单元在每个阶段执行相同的工作,但在我看来,这并不是真正的观点。这将完全避免共享状态的成本
 类似资料:
  • 使用avro的Kafka模式管理为我们提供了向后兼容性的灵活性,但我们如何处理方案中的突破性更改? 假设生产者A向消费者C发布消息M 假设消息M的方案发生了重大变化(例如名称字段现在被拆分为名字和姓氏),我们有了新方案M-new 现在我们正在部署producer A-New和Consumer C-New 问题是,在我们的部署过程完成之前,我们可以让生产者发布一条新消息M-new,消费者C(旧的那个

  • 问题内容: 我知道Go中没有析构函数,因为从技术上讲没有类。这样,我用来执行与构造函数相同的功能。但是,有没有办法在终止的情况下创建某些东西来模仿析构函数,例如使用关闭文件?现在,我只是打电话给我,但这有点荒唐,我认为设计很差。正确的方法是什么? 问题答案: 在Go生态系统中,存在一种处理包装了宝贵(和/或外部)资源的对象的惯用语:一种专门用于释放该资源的特殊方法,通常通过该机制进行 显式 调用。

  • 我已经编辑了php配置以保存Redis上的会话。一切正常,但我意识到,有一天已经过去了,通过在redis-cli上运行命令键*,显示了一个巨大的php-session条目列表。我的问题是php是否会在任何时候删除这些键,或者我必须做一些事情来防止这种情况发生。我对此很担心。

  • 如果我不在合适的StackExchange论坛,请建议我在哪里提问: 我在一家公司工作,他编写了处理敏感数据的软件。为了防止软件被复制(软件盗版),很久以前就决定使用许可证制度。 这个系统运行良好,但对我的公司和客户来说都是一个很大的负担,因此我正在寻找其他方法。 我发现的一种方法是SaaS,但我看到了一个巨大的缺点:Saas在互联网上工作,这意味着本地数据被上传到云上(因此是互联网),这让客户感

  • 我读过很多关于的文章。这里有一个很好的。本文建议将datetime存储在两个独立的列中,一个列用于UTC datetime,另一个列用于本地datetime,另一个列用于本地时区。如果我正确理解的话,datetime指的是用户/客户机的datetime和时区。现在我知道可以使用保存UTC日期时间。但是如何使用PHP保存本地日期时间和时区呢?我需要一个方向。

  • 我从一个博客示例中使用react作为本地存储来编写这段代码,但刷新后它无法实时工作。我怎么能实时做呢?我认为它可以使用以前解决的效果挂钩,但我无法实现,有人帮我解决这个问题吗 这个代码没有问题,但我想与实时工作,当我点击完成它显示实时我该怎么做?