V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 5 页 / 共 65 页
回复总数  1298
1  2  3  4  5  6  7  8  9  10 ... 65  
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@kneo 关于 go 协程这个叫法:
中文英文这些都有很多方言和约定俗成,在非学术环境,尤其是非严谨学术定义讨论的环境,你非要咬学术概念,那我只能认为你是杠精了。随便搜下 go 协程,只要不瞎你应该可以看到大量的标题文章和内容都是这么叫,一些 go 书籍里也是这么叫。如果你觉得这不算社区约定俗成,那请问你 goroutine 中文你给赐个什么名字?或者 goroutime 必须英文不配中文翻译?或者你自己所在的社区不是 go 社区, 至少不包括 go 的中文社区?
别觉得自己知道严格的理论概念就可以拿来咬文嚼字了,这种讨论环境下叫协程大家都知道说的是 goroutine, 就你在那为了杠而杠罢了.
其他一些概念, 例如 tcp 粘包, 我们也知道是错误的定义因为 tcp 本来就是 stream 就不是包, 包是 tcp 之上的层自己的事情, 但是我们讨论问题还是会经常用粘包来描述问题, 因为大家关注的核心点在于这个问题本身而不是这个叫法.
做工程的纠结这些很容易陷入孔乙己思维,茴字写法精通,做工程耽误事挖坑。我见过不少 cpper 对语言语义标准深入学习, 一聊起这些来, 头头是道,但不擅长踏踏实实搞工程实践,眼高手低。
我是搞工程实践的,讲究实践主义实用主义,不是搞咬文嚼字的,没那闲心跟学生在那讨论课本考试题概念定义, 你喜欢的话你继续咬文嚼字好了。
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@kneo #67

> 数据你不会看是吗?都画成图了你也看不懂是吗?

和着我们说的你都不看是吧?前提和方法错了,还需要看他的测试数据?走错方向了然后说走了很长距离所以虽然方向错了但是很正确很牛逼?

> 你一口一个 go 协程( goroutine 不是协程)

这里用的是生产实践约定俗成的概念为准,你不用咬理论概念,你当这写论文呢? go 社区很多人把 goroutine 叫协程是约定俗成的事情,较这个真有意思?
另外看了眼 wiki 里支持协程的语言列表里也有 go ,你要是非拿着早期一些老爷子的协程概念说事,我建议你把每个语言的协程定义都规范下然后去找各个语言社区推广下看看有没有人乐意花时间跟你咬文嚼字

> 说 goroutine 成本低,原帖的结论之一是 Java 的 virtual thread 比 go 的 goroutine 成本还要低。用最简单的代码,得出最简单的结论。

我说 goroutine 成本低是对比进程线程,我说 goroutine 比 java birtual thread 成本低了吗?你这咋还断章取义移花接木呢?
我说的是他这个测试没意义,结论里虽然没明说,但却是相当于拉踩
原来你就喜欢没意义的测试结论是吧?那你去给作者点赞吧,这种拉屎的 blog ,我是欣赏不来
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@kneo #64

> lesismal 拿出 time.AfterFunc()的时候来我看你也没不好意思啊,跟他上课去吧。

有什么不好意思的,比如 node 的测试代码,本质上就是定时器回调;
rust 和 py 的代码本质上应该也是类似的,如果不是类似、而是真的用 sleep ,那这个测试 rust 要跑很久了;

然后 go 这就不让用定时器回调、必须要用大量有栈协程是吧? time.AfterFunc 到时间了也是起个协程来执行的,但是是用的时候才起来,定时的功能没必要在到时之前就创建大量的协程去等待、白白浪费资源

非要用这种代码做这种测试,你还要赞同他的测试,如果所有业务都像你这么搞,那你们老板也是挺舍得花冤枉钱的啊


java 的 VirtualThreads 我不了解别后机制不乱说,另外就是,上下游的各种基础设施,比如请求 sql 是否也是 jvm 支持了出让 cpu 之类的,会不会导致线程阻塞的问题
这些需要上下游全套 io 相关之类的都避免线程阻塞才有更大意义,否则一个链条线程卡住了,就导致大量排队等待、cpu 利用不起来、性能起不来了
有哪位懂的可以讲解下让我顺便学习下
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@kneo #31

> 您还自己 at 上来。

我这个人不阴阳,有事就光明正大地聊,所以直接 at 你了

> 看您一个劲儿贴自己的库,想骗 star 是吧。

你是我用户吗?如果不是,你怎么知道我是骗 star 呢?
有实际用户在生产中使用,或便利,或提升,用户 issue 我都尽量详细回复,bug 我都努力修复,如果这都算骗 star ,那我没法跟你争论,因为你的水准实在太“高”了

> 我看了一眼,请问您这写个破库是干嘛的呢?能解决人家说的一百万个并发任务吗?不会是解决不了得靠排队了吧。您不会想说现实中大家都是排队的吧?您不会说别人不排队就能轻松并发是作弊,毫无意义吧?

这个涉及知识点,我继续认真给你聊.
不同语言的线程池/协程池/任务队列的排队是不一样的。

以 4c8g 的规格为例。

比如传统方式的 c/c++,100 个逻辑线程池 worker (或者多进程)+队列的方式,你的并发只有 100 ,如果任务里 io 或者 sleep 之类的,单个线程就被占用了,如果这组逻辑线程池全都执行这样的任务,就全同时都长时间阻塞了,cpu 不能得到充分有效利用。
因为 8 或者 100 这个并发度太低了,但是进程或者线程的成本太高了,普通配置的节点没法创建过多的进程或者线程。
所以这种传统方案要想高性能就得回调的方式。c/c++的协程库也有不少,但需要手动,代码比 go func 更复杂罢了

但是 go 协程的成本低,4c8g 这种 1-10w 个协程,runtime 也是 ok 的,调度和内存压力都不算大。这个并发度就可以是 10w 。
实际业务中,从上游到下游本身也会有访问限制,类似“限流”的机制,比如下游的数据库,上游如果 10w 并发都同时去请求数据库,数据库也受不了,所以数据库的使用通常都是长连接+连接池,连接池 size 有限,即使上游调用 sql 并发量吵了也要等空闲连接,而不是直接都丢给数据库把数据库干死
但 10w 并发本身并发度足够高,即使部分协程等待 sql 连接阻塞了出让 cpu 了,但并不是把线程阻塞了,runtime 会调度其他协程,不会让 cpu 干等着
然后业务上的协程池和下游资源动态平衡
具体需要多少并发度需要多大连接池 size 或者其他下游资源的类似”限流“配置,要自己项目实际情况来定,这里的 1-10w 只是举例子


> 说句不好听的,您连别人测的是啥都看不懂。

你看懂了?你觉得他这个 benchmark 很有意义?那我对你的自信表示万分钦佩。。。

> 人家的百万并行任务和你的百万连接是一个东西吗。但是不影响你有个什么破库,在那 BB 好像自己懂似的。在那一顿输出自己的“真才实学”,一边喷人“毫无意义”,

我说这俩一样了吗?但是 benchmark 是用来干嘛的?是用来为实际工程做参考的,联系实际业务场景扩展相关内容,不行吗?
分享自己的库的问题,我在 #34 结尾说了
我是在给开源社区做回报,给我的库的用户带来价值,你认为破还是不破是你的主观是你的自由,但不代表别人,所以我也根本不 care 你
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@xiaocaiji111

> 不想跟你对线

是没必要对线

> 建议去大公司体验下,看一个系统除了 curd 以外到底有多少其他技术

这个不用你建议,我就是大公司出身,也是大项目经验,否则我就不搞什么百万连接的解决方案了
我的主要工作不是 curd ,所以看到很多人只用 curd 的角度格局聊技术,不考虑整体工程,也是挺着急的

> 或者去看看 JCP 每次的提案有多少新技术,另外我不评价哪个语言好,哪个语言坏,谁工作中只会只用一门语言的。每个场景都有自己最优的选择。

我也从来没说过 golang 天下第一,我是 c cpp 写的最多,后来 c# node java lua as py 也是项目或者自己玩具一顿用,ruby php 之类的也是稍微玩过,直到用 go 以后就迈不开腿了,不想换其他的语言了。不想换其他语言也不是因为 go 天下第一,而是因为 go 的性能、占用、开发效率、工程性等各方面的平衡

> 只是看不惯上来就无脑说别人拉踩的,反而显得自己是个小丑。

我认为 blog 作者的结论是拉踩,如果你认为不是那就认为不是呗。
如果我认为别人拉踩我就是小丑,那认为”我拉踩我就是小丑“的你也差不多是个小丑吧?没必要这样子
82 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@wysnxzm #40 所以,抛开两个话题了的具体内容和前提不谈,拿出两段来进行断章取义的对比,你想表达什么逻辑?
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@ykrank #32

> 学个语言学得像粉圈和宗教一样

宗教的问题我上面说过了, 我聊的都是技术干货, 你这评论不能说是没有技术的干货, 只能说事和技术点毫无关系, 而且是属于扣帽子.

> 对,我说的就是上蹿下跳的那位,绕着绕着就开始推销自己的实现了,这就是粉圈头子吧

go 社区暂时没有其他完整方案, evio gnet gev 之类的他们都只支持少量功能, 都不支持 tls http 之类的这样完整的功能, nbio 暂时算是独一份
推销就是错吗? 把好的方案分享给别人, 总比你这种什么干货不输出上来就是阴阳扣帽子强吧? 而且我的项目已经有很多用户确实改造优化带来了提升, 这是坏事情?
另外, 我也很久没发单独的帖子来推广了, 不需要这个 KPI 挣钱, 所以比较佛系, 但是看到相关的提一嘴, 怎么了, 你是想让别人都闭嘴不能说自家的好是吗? 你可真是霸道呢, 你咋不去当总统呢?
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@xiaocaiji111 和前面那位一样, 只评论和阴阳, 丝毫不讲技术的点了是吧? 要是只想搞搞 curd, 用 curd 的思维思考技术和工程, 只需要挣钱养家不求技术发育, 那我祝你幸福, 咱们大路朝天

懒得浪费时间, 如果后续再有想阴阳的人, 建议/请先认真看下我前几层的回复
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@xiaocaiji111
所以你自己或者你曾经呆过的团队的 go 方案不好, 就是 go 不好是吗?
在 java 电商系大量人才, java 大量成熟社区方案的前提下, 为啥还有大量新公司新业务用 go 有思考过吗?
java 的繁冗, 面向对象顶层设计面对快速迭代的业务频繁变更的需求时的无力你是没考虑过吧?
大中小厂的负责技术的人带头把很多业务/项目尽量往 go 上转, 这些人都不如你是吧?

go 的人力不如其他语言那么多, 很多人是其他语言转过来没那么多经验带着其他语言的舒适圈非要照猫画虎用错误的方式写 go 或者找 go 里对应其他语言的解决方案, 姿势都错了还拿来当道理, 你自己想下合理吗? 什么叫入乡随俗, 用 go 来请用 go 的方式不懂吗? 那我反过来问一句, go 的协程和 chan 这么方便, 我用习惯了, 换到其他语言里都没有 go 的协程和 chan, 其他语言也太垃圾了! 你说这合理吗?

很多不够专业的 gopher 组成的团队踩坑积累经验很正常, 等这部分人都熟练了再拿来对比说事, 而且说事也应该区分一些, 比如各自语言解决了哪些问题. 多了不说, go 解决的很多其他语言的性能问题, 明星企业大量拥抱 go, 和着在你们眼里都不合理是吧, 这种眼界就真的适合留在 curd 的舒适圈或者小项目里养老算了, 但凡有大点的项目性能要求高的方案都解决不了, 只能等着上面的人出了方案给你们然后你们照着实现. 怪不得叫 IT 民工
@DefoliationM

> 能泛型就泛型,对自己和别人都好点

那些基础库, 例如数学的不同类型的, 或者涉及数组或 map 之类的容器遍历的, 用范型能简化代码
其他不必要性的场景, 硬上范型就是坑队友了
滥用范型会让代码越来越丑
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@kneo 在这说我呢是吧? 你先看下 #6, 其他语言测试的方式的本质都是少量线程或者无栈协程/线程或者异步回调, 就 go 用有栈协程拿来对比, 你觉得公平? 我 #6 和其他几层里说的很清楚了, 这种测试 golang 你就直接 time.AfterFunc 占用直接省掉绝大部份, 甚至再订制下可以更省, 简单的正确的解题答案你不用, 非要用非常复杂浪费的方式去解答, 然后说 golang 语言不行?

> 测的什么人家写的很清楚

他出个测试他就专业吗? 他的测试方法正确吗?

说句不好听的, 你懂吗? 你懂多少?
系统, 底层知识不了解, 只知道看个半吊子脑残的老外的 blog 就在那人云亦云? 还很自豪?

要讨论辩论技术就拿出真材实料来聊技术的这些点, 我的输出都是围绕这个事情本身讲清楚原因和答案, 你在这需空打靶只输出一点阴阳的词语, 丝毫技术的论点论据都没有, 好意思出来讨论?
我说的技术点知识点你可是丝毫不看, 只看我一句观点的就给我扣帽子是吧?
就是你们这种人多了, 才把技术讨论搞得乌烟瘴气!

送你一句: 菜就多练, 不懂就学, 否则就少出来丢人现眼
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@grzhan #13

嗯嗯

> 以及几个组件的 LeaderElection 都会用到,确实还蛮常见的。

election 这种, 我记得不太清楚了, 但好像记得个大概.
分布式一致性算法里的选举, 通常要避免各个节点都在相同的时间参选(发出自己选举的协议给其他节点), 因为如果大家都同时参选, 同时以相同的概率获得其他人的选票, 就会更难选出 leader.
所以在参选过程中, 例如启动, leader 掉线时的重新选举, 或者选举失败时的重选, 是可以每个节点自己随机一个时间抖动来尽量避免选举冲突的
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@hez2010

> 标准库目前有计划改善这个问题吗?毕竟标准库用起来最简单,如果标准库能解决这个问题的话那岂不是不需要 nbio 这类的方案优化了。

如我前面提到的, 标准库目前的 net.Conn 这些只提供了阻塞的 io 接口, 除非是特别简单的场景, 否则没法避免一个连接一个协程. 例如读, 不一定什么时候读到一个完整 request, 就只能阻塞在那等待, 这就需要占用一个协程.

> 另外看了一眼 nbio ,似乎是针对 client-server 网络场景特化的,牺牲了通用性。例如通过 goroutine 来代替多线程进行并行计算也是一个有效的场景。

nbio 的 http 与标准库基本兼容, 写法和标准库基本一样的:
https://github.com/lesismal/nbio-examples/blob/master/http/server/server.go

少量特殊情况不能像标准库那样, 例如 nbio 的 epoll 部分负责的 conn 是非阻塞的, 不适合拿去像标准库那样 io.Copy.
因为 nbio 本来就是为了避免持续占用协程, 如果还像标准库那样提供阻塞的 io 接口可以去 io.Copy, nbio 就没有意义了
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@grzhan #8
可能作者本意不是拉踩, 或者不是故意拉踩. 但不正确的方法, 得出的结论就会误导很多人. 因为绝大部分开发者不了解系统知识, 不了解不同语言在这个不适合的测试场景与实际应用中的区别, 却给他们造成了错误的印象——例如 java 虚拟线程优秀, 然后可能误解 java 就是比 go 好.

刚看了下文章作者的 github, 主要是 rust java, 所以可能他自己也是默认偏好 rust 和 java 多些, 所以也没考虑过要对 go 的做多一些说明吧, 非故意的默认的放纵某些他以为的`正确`结论
所以我出来澄清一下

OP 或者其他人不要误解, 这并不是 go 邪教, 而只是实事求是
如果有人说 go 性能比 c/cpp/rust 强, 我要是有时间有兴趣也是会出来反驳的, 所以请 OP 或者其他人不要拿"我认为"golang 天下第一"说事
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@grzhan #9

> 所以一般定时要求不严格的话很多 Golang 开源项目会给定时 duration 加个 10% 左右的随机抖动吧
例如 VictoriaMetrics 的 timeutil.AddJitterToDuration -

通常的定时功能没必要加抖动, 这个库的具体内容我没看. 定时加抖动有可能是为了避免同时创建大量具有相同超时时间的内容, 后续同时到期去创建大量协程异步删除内容导致 goroutine 过多造成不稳定, 或者其他什么特殊的需要
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@hez2010 #5

这个确实是毫无意义的测试, 你可以看下 #6, 当然, 其他语言也一样可以不用虚拟线程或者协程之类的, 都没必要用这么多内存. 但文章却非要选择使用虚拟线程和协程来对比, 然后海量的有栈 goroutine 就劣势了, 这不搞笑呢嘛

> `从结果来看 Java 的 Virtual Thread 要远比 Goroutine 更轻量。`

这个是文章里的结论之一, 用错误的测试方法, 得出一个作者想要的`正确`结论, 有意思?
别说什么都各自有褒贬, 方法和结论都不正确的前提下, 褒贬也都是不准确的. 然后这个所谓的结论对于大多数读者而言, 就是 java 的虚拟线程更优秀, 这本身算不算误导就各自琢磨吧

> 如果你认为 Go 就是天下第一,一切 Go 表现不好的测试都是因为测试不好,而 Go 没有任何问题的话那我也没话说。

我可从来没说过这个, go 标准库海量并发占用高我自己就知道, 所以我才搞 nbio 之类的方案优化, 而且相对成熟了, 可以替换标准库方案, 但是你们非要"只用标准库方案"的方式来评价整个 golang, 就不合理了

> 况且这测试也不是我设计的。

那你可以看下我的观点, 顺便多思考下, 避免只看表象, 避免不知其中深意, 避免人云亦云

这个测试如果是哪个老外设计的, 那他是不专业的, 我本来也是说这个测试而不是针对你
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
试了下这个:
var wg sync.WaitGroup
for i := 0; i < 1000000; i++ {
wg.Add(1)
time.AfterFunc(10*time.Second, func() {
wg.Done()
})
}
wg.Wait()

macos m3 占用 150M, 应该是有不少定时器到时然后并发创建的 goroutine 较多
如果改用时间轮或者堆的定时器, 数量可控的协程池, 这个占用会降更多.

@server 可以看下这个帖子: /t/1089474
实际对比下其他的看看, 我和一些朋友测试, ants 跟其他实现方式相比没有优势, 甚至是劣势, 以及实现复杂可能存在的不确定性
83 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
1. 实际场景里也不可能全是 cpu 消耗的 task, 所以 sleep 类型的 task 是合理的
2. 并发度极大超过系统核心数量的情况下, go 全用标准库直接 go func()是不公平的, 因为协程数量太大了, 这种完全可以优化成 size 可控的协程池, sleep 可以 timer 回调
3. 如果 sleep 是为了模拟实际场景里的 io 消耗例如网络 io, go 标准库主要是提供同步 io 接口, 那么多数需求确实需要每个 conn 一个协程, 但是, 你可以选择不用标准库, 例如我的 nbio, 百万连接 websocket echo 1k payload 压测, server 部署在 4c 8g ubuntu vm 上, 实际内存占用可以控制到 1g 以内:
https://github.com/lesismal/go-websocket-benchmark?tab=readme-ov-file#1m-connections-1k-payload-benchmark-for-nbiogreatws

请注意, 3 里说的百万链接占用 1g 内存, 比 OP 的这种简单 task 占用多, 不代表相同 task 测试优化后的方案就比其他语言多这么多.


另外, 不同语言的这个测试, OP 用的都是未经优化的方式, 方案并不是好的解决方案, 所以这个测试本身就是不合理的.
比如, 如果只是用这种 sleep task, go 直接用 for { time.AfterFunc() } 占用很低的. 但我相信这并不对应任何实际应用场景.

毫无意义的测试, 却顺便拉踩, 捧 java 踩 go, 实在看不下去了我才必须出来澄清下.
说脏话不太好, 所以没有在 h 同学下面评论
给 ASCII-generator star 了
95 天前
回复了 IIInsomnia 创建的主题 Go 编程语言 从 0 到 1 手撸一个协程池
@IIInsomnia #42

> 还有退出的资源也不会及时 GC ,有等待期

不管是用协程池协程常驻去执行 func()还是 go func(), 在 func()内创建的资源都是相同的, 这些资源应该都是 func() return 后可以被 gc, 如果不及时两者也都是不及时, 要想优化 func()内的资源还是得自己加 Pool 之类的

所以主要区别应该还是常驻协程复用和 runtime 复用协程的区别吧
1  2  3  4  5  6  7  8  9  10 ... 65  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5439 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 20ms · UTC 07:39 · PVG 15:39 · LAX 23:39 · JFK 02:39
Developed with CodeLauncher
♥ Do have faith in what you're doing.