问题标签 [contention]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
182 浏览

postgresql - 在插入和更新时增加计数器列的可靠、低争用策略

我有一个关于序列的补救问题。我已经使用了一些它们并查阅了文档,并希望这对小组来说是一个简单的问题。我们现在使用的是 Postgres 11.4,只要它在 RDS 上可用,我们就会迁移到 PG 12。

目标是让一组数字在每次插入或更新一行时增加。我们为这种计数器使用字段名称“con_id”(并发 ID)。所以第一次在空表中插入一行时,值为 1,第二行得到 2,依此类推。听起来像SEQUENCE. 我在这个角色中有一个标准序列,然后切换到AS IDENTITY......但现在意识到这可能是一个错误。

更新时,计数器应继续工作。因此,如果第一行被更新,con_id 从 1 变为 3 current max()+1,. ON CONFLICT(id) SET作为记录,我们所有的更新都使用UPDATE.

数字系列的要点是为各种操作定义起止界限:

然后,当需要执行这些操作之一时,您只需从 last_number_processed+1 到 max(con_id) 中选择 con_id 即可找到正确的记录块。操作完成后,您必须使用该 max(con_id) 更新操作跟踪器。

然后,“sync_to_domo”的范围类似于 124557-128923。

这里不需要唯一性,尽管它是可取的。差距根本不重要。保持数字顺序是必不可少的。

如果我搞砸了,这种更新操作很容易成为可怕的瓶颈。谁能建议最佳可靠、低争用策略来维护一个计数器,该计数器在每次插入或更新时从表 +1 中获取最大值?

而且,是的,时间戳可以用于此目的,它只是另一种数字线。整数的原因是为了匹配我们编码其他系统的方式。当跨平台的数据类型保持相同时,更容易解释和推理这些东西。或者看起来,在这种情况下。

测试代码

我正在向我的原始问题添加一些测试代码和结果。这行得通,但我怀疑它是否超级有效。下面的测试是一个最小版本,并没有用......我只是想确定我是否可以获得越来越多的插入和修订。快速检查一下,这项工作看起来还不错,但是我没有内化 Postgres 的争用方法,所以我主要包括它,以便人们可以告诉我为什么它很糟糕。所以,请做;-)

设置是有一个自动分配的序列 onINSERT和通过 per ROWtrigger on UPDATE。听起来不太理想,有没有更好的方法?它在单连接测试中工作,但在UPDATE. 这对我来说不是问题,但我不明白为什么会这样。

这是独立的测试代码:

结果如下:

这行得通,创建 1-10,更新 1-5 并使其 con_id 计数器值递增。2 出于某种原因(?),但至少它们的顺序是有用的,这是我们需要的。

任何人都可以就如何更有效地获得这种行为提供建议吗?目标是为反映最后一次INSERTUPDATE活动的记录建立一个不断增加的数字线。而且,因为我们在其他任何地方都使用整数,所以我们试图坚持使用整数而不是时间戳。但是,老实说,这在很多方面都是装饰性的。我正在研究的另一个原因SEQUENCE是,除非我误解了,否则它不会在交易中绑定。这非常适合……我们不需要一个无间隙的数字系列,只需要一个连续的数字系列。

Postgres 12 测试

按照 Belayer 的建议,我创建了一个 PG 12 数据库作为实验。我使用默认值,所以一切都在public. (在现实世界中,我去掉了public。)是的,生成的列似乎可以工作,只要你有一个不可变的函数。我在 Postgres 中读过IMMUTABLE好几次……但我不明白。所以,我不能说这个功能是安全的。似乎应该如此。我遵循了这篇有价值的文章中使用的模式:

https://www.2ndquadrant.com/en/blog/generated-columns-in-postgresql-12/

上面的示例确实适用于生成的列,但我不知道 PG 12 计算列与触发器的性能特征。

更可悲的是,我认为这对我来说可能根本行不通。我真的需要一个提交时间戳,它只能通过逻辑解码获得。这就是为什么,通过一个例子。

  • 我正在汇总数据并希望获取未处理的更新或插入的行。
  • 我得到的最后一个数字来自于上午 01:00:00 添加的记录。现在我想得到所有更高的数字。
  • 好吧...我这样做。
  • 哦,等等,一个不完整的交易进来并提交了之前的时间戳/派生数字。

ASEQUENCE在这里也不起作用,因为在事务提交之前,我的收集器进程再一次看不到行/元组。

所以我认为这是逻辑解码,更新汇总表,或者破产。

0 投票
0 回答
18 浏览

c# - 使用 Visual Studio 分析器分析争用时如何忽略长时间运行的信号等待?

我尝试使用 Visual Studio 分析器分析应用程序以查看潜在的线程争用问题,但问题是分析器将信号等待视为最严重的违规者(因为消耗线程大部分时间都在等待信号),而在现实中,看到生产方面的竞争会更有趣。

例如,我正在使用 log4net 的异步附加程序来减少日志记录对实际工作人员的影响,它基本上是一个包装器BlockingCollection<T>

长时间运行的任务是将事件转发到实际附加程序的地方:

我的问题是:我做错了什么吗?使用分析器识别实际热点的正确方法是什么?

0 投票
1 回答
629 浏览

java - 线程饥饿与争用?

根据有关“线程饥饿”的Oracle 文档,

饥饿描述了线程无法定期访问共享资源并且无法取得进展的情况。当共享资源被“贪婪”线程长时间不可用时,就会发生这种情况。

在关于线程“线程争用”的Oracle 文档中,

如果一个线程试图获取一个已经被另一个线程持有的锁,那么它必须等到锁被释放。发生这种情况时,就会出现所谓的锁“争用”。

其实,上面的定义是有一定道理的,我无法得到一个明确的定义来对比它们。谁能解释一下上述术语之间的区别以及它们之间的关系(如果有的话)?

注意:通过参考什么是线程争用的一些答案 ,我觉得这些答案也不适用于“线程饥饿”吗?

0 投票
1 回答
73 浏览

c++ - 即使没有锁,也会存在内存争用吗?

我正在编写一个多线程代码,其中一堆std::async调用在整个程序期间产生固定数量的线程。每个线程都const BigData以只读方式处理相同的结构。有频繁的随机读取,const BigData但线程是完全独立的。是否可以合理地期望获得完美的扩展,或者是否可以预期更多的内存访问会减慢?

编辑:经过一些分析,这似乎是罪魁祸首:

operator+在重构我的代码以避免对and的不必要调用之后operator-,我似乎获得了更好的扩展性。

0 投票
1 回答
24 浏览

java - 我的 Java 应用程序中对 Jar 文件访问的高度争用

我们开发一个基于 JMS 的应用程序,该应用程序从 JMS 队列接收 XML 格式的消息。该应用程序部署在 Weblogic 服务器 (12c) 上。

以大约 400-500 msgs/sec 的速率,我们正在经历糟糕的性能并在 JMS 队列上积累积压。

我尝试使用Java Mission Control对应用程序进行概要分析,在记录了系统一分钟的活动后,我发现 Weblogic 类加载器对 Zip (Jar) 文件的访问阶段存在很多争用。

当检测到争用时,我的 JMS MDB 执行的操作是使用 JAXB 解组 XML 文件内容。

关于什么可能导致问题的任何提示?

0 投票
1 回答
278 浏览

locking - Infinispan 9.4.16,JBoss EAP 7.3 与复制缓存 2 节点线程的锁争用是 TIMED_WAITING(停车)

我有一个应用程序当前依赖 infinispan 复制缓存在所有节点之间共享一个工作队列。队列非常标准,头、尾和大小指针都保留在 infinispan 映射中。

我们已经从 Infinispan 7.2.5 升级到 9.4.16 并且注意到锁定性能比以前差了很多。当他们都试图同时初始化队列时,我已经设法从 2 个节点获取线程转储。Infinispan 7.2.5 的锁定和同步性能非常好,没有任何问题。现在我们看到了锁超时和更多的失败。

来自线程转储 2021-04-20 13:45:13 的节点 #1 部分堆栈跟踪:

来自线程转储的 Node#2 部分堆栈跟踪:2021-04-20 13:45:04:

在运行节点 #1 的机器的控制台上弹出客户端错误:

Infinispan 配置:

我们默认使用 udp 多播,这里是 udp 配置:

任何关于配置的想法都会很棒。发生的情况是两个节点都超时并且队列没有正确初始化(空键)。提前致谢。顺便说一句,每个节点上最多有 24 个线程(总共 48 个)可以访问共享队列。

0 投票
0 回答
25 浏览

multithreading - 估计总线争用前的最大线程数

假设我有任意数量的线程需要从不同的内存位置读取。我需要哪些参数来估计可以在不发生总线争用的情况下同时执行此操作的最大线程数?在哪里可以找到有关商用硬件的信息?

0 投票
2 回答
167 浏览

db2 - 大型机:如何防止批处理作业和 CICS 事务之间的 DB2 争用?

我有一个批处理作业和一个使用相同 db2 表的 CICS 事务。两者都定期运行,并且批处理作业有时会由于与共享 DB2 表的争用而异常终止。

有没有办法在 CA7(作业调度工具)中调度作业,以防止它在事务处于活动状态时运行?

0 投票
1 回答
48 浏览

google-cloud-firestore - Cloud Firestore 数据存储模式 - 没有复合索引的事务争用

在我目前正在处理的应用程序中,我们需要确保特定种类中三个属性的元组的唯一性。因此,在创建新实体时,我们需要确保不存在具有给定元组的那种实体。

我对这个问题的幼稚方法是创建一个简单的查询,根据三个字段过滤相等性。如果找到具有给定字段的实体,则操作将中止,否则将插入具有这些字段和其他相关数据的新实体。但是,当尝试并行插入许多实体时,会出现事务争用。

但是,只要我添加了这三个属性的复合索引,就不会发生争用。我没有改变代码,我只是为这些字段添加了一个复合索引。

我一直在挖掘所有文档并四处寻找遇到类似问题的人,但没有人提到过这种“解决方法”。

我错过了什么吗?或许发现了什么?或者这是预期的行为;内置索引还不够吗?

0 投票
0 回答
17 浏览

google-docs - 如何在利用操作转换的协作编辑软件中解决冲突

场景 - 两个人(P1、P2)在 Google Docs 中编辑同一个 word 文档。在他们开始编辑之前,该文档包含一个词——“ADAM”。P1 决定删除第一个字符“A”,P2 决定在现有第一个字符前面添加另一个字符“A”。P1 和 P2 在完全相同的时间执行它们的操作(同时被定义为 Google Docs 服务器识别的时钟的最大精度)。我了解服务器和客户端在应用它们之前都会对其传入操作进行操作转换。
但是 Google Doc 服务器如何决定先执行哪个操作呢?注意 - 我对文档/全局真相的最终状态不感兴趣,但更重要的是,考虑到用户操作的相似时间戳,Google Docs 服务器将首先处理哪个用户的操作。