加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Nginx多进程高并发、低时延、高可靠机制在缓存twemproxy代理中的应用

发布时间:2019-03-14 16:11:59 所属栏目:建站 来源:y123456yz
导读:1. 开发背景 现有开源缓存代理中间件有twemproxy、codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能。 由于twemproxy无法利用多核特性,因此性能低下,短连接QPS大约为3W,长连接QPS大约为13W,同时某些

因此“惊群”问题通过非阻塞的accept锁来实现进程互斥accept(),其原理是:在worker进程主循环中非阻塞trylock获取accept锁,如果trylock成功,则此进程把监听端口对应的fd通过epoll_ctl()加入到本进程自由的epoll事件集;如果trylock失败,则把监听fd从本进程对应的epoll事件集中清除。

Nginx实现了两套互斥锁:基于原子操作和信号量实现的互斥锁、基于文件锁封装的互斥锁。考虑到锁的平台可移植性和通用性,改造twemproxy选择时,选择文件锁实现。

如果获取accept锁成功的进程占用锁时间过长,那么其他空闲进程在这段时间内无法获取到锁,从而无法接受新的连接。最终造成客户端连接相应时间变长,qps低,同时引起负载严重不均衡。为了解决该问题,选择通过post事件队列方式来提高性能,trylock获取到accept锁成功的进程,其工作流程如下:

  1. trylock获取accept锁成功
  2. 通过epoll_wait获取所有的事件信息,把监听到的所有accept事件信息加入accept_post列表,把已有连接触发的读写事件信息加入read_write_post列表。
  3. 执行accept_post列表中的所有事件
  4. Unlock锁
  5. 执行read_write_post列表中的事件。

Worker进程主循环工作流程图如下:

Nginx多进程高并发、低时延、高可靠机制在缓存twemproxy代理中的应用

从上图可以看出,worker进程借助epoll来实现网络异步收发,客户端连接twemproxy的时候,worker进程循环检测客户端的各种网络事件和后端memcached的网络事件,并进行相应的处理。

twemproxy各个进程整体网络i/o处理过程图如下:

Nginx多进程高并发、低时延、高可靠机制在缓存twemproxy代理中的应用

4.3.1.2 如何解决“负载均衡“问题

在多个子进程争抢处理同一个新连接事件时,一定只有一个worker子进程最终会成功建立连接,随后,它会一直处理这个连接直到连接关闭。这样,如果有的子进程“运气”很好,它们抢着建立并处理了大部分连接,其他子进程就只能处理少量连接,这对多核cpu架构下的应用很不利。理想情况下,每个子进程应该是平等的,每个worker子进程应该大致平均的处理客户端连接请求。如果worker子进程负载不均衡,必然影响整体服务的性能。

nginx通过连接阈值机制来实现负载均衡,其原理如下:每个进程都有各自的最大连接数阈值max_threshold和当前连接阈值数local_threshold,和当前连接数阈值,进程每接收一个新的连接,local_threshold增一,连接断开后,local_threashold减一。如果local_threshold超过max_threshold,则不去获取accept锁,把accept机会留给其他进程,同时把local_threshold减1,这样下次就有机会获取accept锁,接收客户端连接了。

在实际业务应用中,有的业务采用长连接和twemproxy建立连接,连接数最大可能就几百连接,如果设置max_threshold阈值过大,多个连接如果同时压到twemproxy,则很容易引起所有连接被同一个进程获取从而造成不均衡。

为了尽量减少负载不均衡,在实际应用中,新增了epoll_wait超时时间配置选项,把该超时时间设短,这样减少空闲进程在epoll_wait上的等待事件,从而可以更快相应客户端连接,并有效避免负载不均衡。

4.3.2 Linux内核高版本TCP REUSEPORT特性如何利用

4.3.2.1 什么是reuseport?

reuseport是一种套接字复用机制,它允许你将多个套接字bind在同一个IP地址/端口对上,这样一来,就可以建立多个服务来接受到同一个端口的连接。

4.3.2.2 支持reuseport和不支持reuseport的区别

如果linux内核版本小于3.9,则不支持reuseport(注:部分centos发行版在低版本中已经打了reuseport patch,所以部分linux低版本发行版本也支持该特性)。

不支持该特性的内核,一个ip+port组合,只能被监听bind一次。这样在多核环境下,往往只能有一个线程(或者进程)是listener,也就是同一时刻只能由一个进程或者线程做accept处理,在高并发情况下,往往这就是性能瓶颈。其网络模型如下:

在Linux kernel 3.9带来了reuseport特性,它可以解决上面的问题,其网络模型如下:

reuseport是支持多个进程或者线程绑定到同一端口,提高服务器程序的吞吐性能,其优点体现在如下几个方面:

i)允许多个套接字 bind()/listen() 同一个TCP/UDP端口

ii)每一个线程拥有自己的服务器套接字

iii)在服务器套接字上没有了锁的竞争,因为每个进程一个服务器套接字

iiii)内核层面实现负载均衡

iiiii)安全层面,监听同一个端口的套接字只能位于同一个用户下面

4.3.3 Master进程和worker进程如何通信?

由于master进程需要实时获取worker进程的工作状态,并实时汇总worker进程的各种统计信息,所以选择一种可靠的进程间通信方式必不可少。

在twemproxy改造过程中,直接参考nginx的信号量机制和channel机制(依靠socketpair)来实现父子进程见通信。Master进程通过信号量机制来检测子进程是否异常,从而快速直接的反应出来;此外,借助socketpair,封装出channel接口来完成父子进程见异步通信,master进程依靠该机制来统计子进程的各种统计信息并汇总,通过获取来自master的汇总信息来判断整个twemproxy中间件的稳定性、可靠性。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读