Bright Chen
Bright Chen
> cpu 似乎全花在了调度跟空转和争抢上。 > > 总结下就是超过一定阈值后增加并发数,latency 会上升,带来 qps 下降,似乎是调度带来的开销。现在看来每次部署都要专门调试选择最佳的配置。brpc 的潜力还是很大的,请问该怎么进一步分析,以及如何能让 cpu 能够真正地发挥呢? @MrGuin 可以试一下 #2819 。
Related issues: #2817 Related PR: #2819 #2398
@MJY-HUST 可以试试#2907 看能不能解决问题?
> > [@MJY-HUST](https://github.com/MJY-HUST) 可以试试[#2907](https://github.com/apache/brpc/pull/2907) 看能不能解决问题? > > 没效果 @GreateCode #2819 呢?
> 我看现在parking_lot的数量是写死的,一个tag内只有四个;一旦worker数量多了,futex中锁的竞争就上来了,想问一下这个值改成一个可配的参数或者根据tag所属的worker总数来动态调大会有什么负面影响吗?(比如parking_lot的数量 = bthread_concurrency_by_tag / 4 or 8)。 我自己做了一些测试,除了上述的做法之外,减少无效的signal和在wait前先steal一次也能解决一部分问题。 相同的负载: 启动四个rpc_press ./rpc_press -proto=echo_c++/echo.proto -method=example.EchoService.Echo -input='{"message":"hello"}' -qps=100000 -server=0.0.0.0:8000 -timeout_ms=-1 服务端使用example/echo_c++中的,server,worker线程数量为64个,但是在服务内增加了使用bthread_start_background创建两个bthread来模拟触发signal的行为,优化前后: 前:    > > 后:parking_lot改为16个    @MJY-HUST...
@Huixxi @wwbmmm 是不是有关于lb E61的优化,可以提个PR吗?
> @Huixxi 能给解释一下,当前的代码是因为bug还是因为设计上导致的E112无法恢复吗?想知道根音,然后目前的方案是解决设计问题,还是做一个兜底。 我计较好奇“E112无法恢复”的原因。我理解上“E112无法恢复”有两种场景: 1. 健康检查一直失败; 2. E112后经健康检查恢复后,又出现E112,一直反复。
> 那通过健康检查来兜底可行吗?或者使用熔断策略,或者tcp keepalive这些能避免这个问题吗? 现在问题就是熔断导致没有可用的实例吧。所有实例不可用,都在做健康检查,所以导致E112失败。 在RPC的角度,在所有实例都不可用的时候,相比直接E112失败,还不如选一个实例进行通信,还有成功的机会。 但是我觉得该PR在集群模式下,只保留了一个实例来接受所有流量,在负载均衡方面不太友好。
> 解决该问题的根本办法是将单连接的main socket和rpc通信的socket进行拆分(有点类似于只有一个连接的连接池),当rpc通信socket SetFailed之后,可以从main socket新建新的socket进行连接,但这个方案对brpc的改动较大。 我思考过这个方案,改动很大且复杂。 或许可以从LB的角度来实现,ServerId增加EndPoint字段,在E112期间构造出备用Socket(管理策略得再详细设计一下)来进行通信了,这样实现会简单很多。 LB选实例的时候,记录下第一次选到的实例EndPoint,用于E112的时候通信。另外,在E112期间,也能保持一定的负载均衡。更近一步,或许可以参考[Envoy的恐慌策略](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/panic_threshold),当不可用实例比例超过阈值,使能恐慌策略。但是Envoy的连接的实现跟bRPC Socket的实现不一样,所以恐慌策略不一定合适,得做一些权衡。 @wwbmmm 有空看看这个方案可行性?
> 好像从已有的Failed的Socket上也能够获取到EndPoint字段? 可以使用AddressFailedAsWell。 > 需要区分Socket的连接状态和屏蔽状态,LB看的是屏蔽状态,实际连接的时候,再看连接状态,如果连接状态是Failed时再启动备用连接之类的。 目前LB将会屏蔽Failed连接状态的Socket,除此之外,还会屏蔽ExcludedServers和Socket::IsAvailable(目前只有logff是unavailable)的Socket。 bRPC的恐慌策略可以这样设计:**保持LB屏蔽策略不变**,当LB选不出实例的时候,不返回E112,而是使用第一次选到实例的信息构造出一个备用Socket用于通信。在E112期间,负载均衡也是生效的,开销也比较小,只是多一次创建Socket的开销,这个Socket在恐慌周期内是可以复用的,完全可接受。 跟Envoy的可调整的恐慌阈值不同,bRPC的恐慌阈值为100%,是这样考虑的:虽然Envoy区分连接状态和屏蔽状态,但是在LB处只看到屏蔽状态。触发恐慌的时候(阈值小于100%),会跟一些完全不可用的实例通信(连接错误码是ECONNREFUSED、ENETUNREACH、EHOSTUNREACH),这是没有意义,会浪费一次通信机会。 @wwbmmm 有什么建议吗?