【发布时间】:2022-01-16 11:49:20
【问题描述】:
我是 golang 的新手,并且有一个用例,其中对一个类型的值的操作必须以顺序方式运行,而对其他类型的值的操作可以同时运行。
- 假设数据来自流连接(按顺序)
key_name_1, value_1 key_name_2, value_2 key_name_1, value_1 - 现在
key_name_1和key_name_2可以同时被goroutine操作了。 - 但是由于下一个流式值(第 3 行)又是
key_name_1,所以这个操作应该只在前面的操作(第 1 行)已经完成的情况下由 goroutine 处理,否则它应该等待第一个操作完成才可以应用操作。 为了便于讨论,我们可以假设操作很简单 将新值添加到之前的值。
在 golang 中以尽可能高的性能实现这一目标的正确方法是什么?
确切的用例是数据库更改流式传输到队列中,现在如果值发生更改,重要的是在另一个数据库上对相同序列应用操作,否则一致性将受到影响。冲突很少见,但可能会发生。
【问题讨论】:
-
如果工作只是将新值添加到以前的值,那么同步成本将淹没实际工作。在这种情况下,按顺序执行所有操作是最简单且性能最高的设计。
-
这只是一个例子,工作很复杂,而且事件量很大,所以没有理由顺序执行所有事件,只有相同类型的事件应该顺序执行。否则处理的滞后将变得巨大。
-
在没有完整上下文的情况下,我能想到的最简单的方法是为每个操作创建一个通道,但是,如果键/操作的数量不受限制,这不是一个可扩展的解决方案,也是最好的方法将是上面的评论。
-
为了“尽可能高的性能”,我们需要更多的上下文。冲突发生的频率、每秒请求的数量、处理请求需要多长时间等。即使这样,最高性能通常也是凭经验实现的。
标签: go concurrency streaming goroutine