Nginx多进程高并发、低时延、高可靠机制在缓存twemproxy代理中的应用(3)
配置下发过程:主进程接收实时配置信息,然后通过channel机制发送给所有的worker进程,各个worker进程收到配置信息后应答给工作进程。流程如下: 获取监控信息流程和配置下发流程基本相同,master进程收到各个工作进程的应答后,由master进程做统一汇总,然后发送给客户端。 4.3.4 如何减少worker进程在不同cpu切换的开销 CPU 亲和性(affinity) 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。 Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。具体参考sched_setaffinity函数。 4.3.5 worker进程异常如何减少对业务的影响? 在实际线上环境中,经常出现这样的情况:某个多线程服务跑几个月后,因为未知原因进程挂了,最终造成整个服务都会不可用。 这时候,master+多worker的多进程模型就体现了它的优势,如果代码有隐藏的并且不容易触发的bug,某个时候如果某个请求触发了这个bug,则处理这个请求的worker进程会段错误退出。但是其他worker进程不会收到任何的影响,也就是说如果一个改造后的twemproxy起了20个worker进程,某个时候一个隐藏bug被某个请求触发,则只有处理该请求的进程段错误异常,其他19个进程不会受到任何影响,该隐藏bug触发后影响面仅为5%。如果是多线程模型,则影响面会是100%。 如果某个worker进程挂了,master父进程会感知到这个信号,然后重新拉起一个worker进程,实现瞬间无感知”拉起”恢复。以下为模拟触发异常段错误流程: 如上图所示,杀掉31420 worker进程后,master进程会立马在拉起一个31451工作进程,实现了快速恢复。 多进程异常,自动”拉起”功能源码,可以参考如下demo: https://github.com/y123456yz/reading-code-of-nginx-1.9.2/blob/master/nginx-1.9.2/src/demo.c 5 网络优化5.1 网卡多队列 在实际上线后,发现软中断过高,几乎大部分都集中在一个或者几个CPU上,严重影响客户端连接和数据转发,qps上不去,时延抖动厉害。 RSS(Receive Side Scaling)是网卡的硬件特性,实现了多队列,可以将不同的流分发到不同的CPU上。支持RSS的网卡,通过多队列技术,每个队列对应一个中断号,通过对每个中断的绑定,可以实现网卡中断在cpu多核上的分配,最终达到负载均衡的作用。 5.2 可怕的40ms 原生twemproxy在线上跑得过程中,发现时延波动很大,抓包发现其中部分数据包应答出现了40ms左右的时延,拉高了整体时延抓包如下(借助tcprstat工具): 解决办法如下:在recv系统调用后,调用一次setsockopt函数,设置TCP_QUICKACK。代码修改如下: 6 Twemproxy改造前后性能对比 (时延、qps对比)6.1 线上真实流量时延对比 6.1.1 改造前线上twemproxy集群时延 线上集群完全采用开源twemproxy做代理,架构如下: 未改造前线上twemproxy+memcache集群,qps=5000~6000,长连接,客户端时延分布如下图所示: 在twemproxy机器上使用tcprstat监控到的网卡时延如下: 从上面两个图可以看出,采用原生twemproxy,时延高,同时抖动厉害。 6.1.2 参照nginx改造后的twemproxy时延 线上集群一个twemproxy采用官方原生twemproxy,另一个为改造后的twemproxy,其中改造后的twemproxy配置worker进程数为1,保持和原生开源twemproxy进程数一致,架构如下: 替换线上集群两个代理中的一个后(影响50%流量),长连接,qps=5000~6000,客户端埋点监控时延分布如下: 替换两个proxy中的一个后,使用tcprstat在代理集群上面查看两个代理的时延分布如下: (编辑:ASP站长网) |