тАЬ@Cloudflare рдЯреАрдо рдиреЗ рдЕрднреА-рдЕрднреА рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рд╣реИрдВ рдЬрд┐рд╕рд╕реЗ рд╣рдорд╛рд░реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдХрд╛рдлреА рд╕реБрдзрд╛рд░ рд╣реБрдЖ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдмрд╕реЗ рдзреАрдореА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдПред рдХрд┐рддрдирд╛ рддреЗрдЬ рд╣реИ? рд╣рдо рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдкреНрд░рддрд┐ рджрд┐рди рд▓рдЧрднрдЧ 54 рд╡рд░реНрд╖реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдиреЗрдЯ рдХреА рдмрдЪрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдпрдерд╛ рд╕рд╛рдЗрдЯреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ ред
тАЭ - рдореИрдереНрдпреВ рдкреНрд░рд┐рдВрд╕
рдЯреНрд╡реАрдЯ , 28 рдЬреВрди 2018
10 рдорд┐рд▓рд┐рдпрди рд╕рд╛рдЗрдЯ, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рдПрдкреАрдЖрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рдбрд╛рдЙрдирд▓реЛрдб рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рдЙрдбрдлреЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЪрд░рдо рдкрд░, рд╣рдо 151 рдбреЗрдЯрд╛ рдХреЗрдВрджреНрд░реЛрдВ рдореЗрдВ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 10 рдорд┐рд▓рд┐рдпрди рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреБрд░реЛрдз рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ, рд╣рдордиреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Nginx рдХреЗ рдЕрдкрдиреЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХрдИ рдмрджрд▓рд╛рд╡ рдХрд┐рдП рд╣реИрдВред рдпрд╣ рд▓реЗрдЦ рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред
рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
Nginx рдЙрди рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ
рдЬреЛ C10K рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд▓реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛
рд╣реИ ред рдЬрдм рднреА рдХреЛрдИ рдиреЗрдЯрд╡рд░реНрдХ рдИрд╡реЗрдВрдЯ рдЖрддрд╛ рд╣реИ (рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдХрдиреЗрдХреНрд╢рди, рдЕрдиреБрд░реЛрдз рдпрд╛ рдЕрдзрд┐рд╕реВрдЪрдирд╛), рдирдЧреНрдиреЗрдХреНрд╕ рдЙрдарддрд╛ рд╣реИ, рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рджреВрд╕рд░реА рдиреМрдХрд░реА рдкрд░ рд▓реМрдЯрддрд╛ рд╣реИ (рдпрд╣ рдЕрдиреНрдп рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ)ред рдЬрдм рдХреЛрдИ рдШрдЯрдирд╛ рдЖрддреА рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╕рд╛рде рдХрдИ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдХреБрд╢рд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
num_events = epoll_wait(epfd, events, events_len, -1); // events is list of active events // handle event[0]: incoming request GET http://example.com/ // handle event[1]: send out response to GET http://cloudflare.com/
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛрдб рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдХреИрд╕рд╛ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
// we got a read event on fd while (buf_len > 0) { ssize_t n = read(fd, buf, buf_len); if (n < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { // try later when we get a read event again } if (errno == EINTR) { continue; } return total; } buf_len -= n; buf += n; total += n; }
рдпрджрд┐ fd рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЙрдХреЗрдЯ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдмрд╛рдЗрдЯреНрд╕ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдВрдЧреЗред рдЖрдЦрд┐рд░реА рдХреЙрд▓
EWOULDBLOCK
ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕реНрдерд╛рдиреАрдп рд░реАрдб рдмрдлрд░ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдЗрд╕ рд╕реЙрдХреЗрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рддрдХ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдбрд┐рд╕реНрдХ I / O рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рдЕрд▓рдЧ рд╣реИ
рдпрджрд┐ fd рд▓рд┐рдирдХреНрд╕ рдкрд░ рдПрдХ рдирд┐рдпрдорд┐рдд рдлрд╝рд╛рдЗрд▓ рд╣реИ, рддреЛ
EWOULDBLOCK
рдФрд░
EAGAIN
рдХрднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рд░реАрдб рдСрдкрд░реЗрд╢рди рд╣рдореЗрд╢рд╛ рдкреВрд░реЗ рдмрдлрд░ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдлрд╝рд╛рдЗрд▓
O_NONBLOCK
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦреЛрд▓реА
O_NONBLOCK
ред рдЬреИрд╕рд╛ рдХрд┐
рдЦреБрд▓реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ
(2) рдореИрдиреБрдЕрд▓:
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдзреНрд╡рдЬ рдирд┐рдпрдорд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рдмреНрд▓реЙрдХ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИред
рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
if (read(fd, buf, buf_len) > 0) { return buf_len; }
рдпрджрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдХреЛ рддрдм рддрдХ рдмреНрд▓реЙрдХ рдХрд░рддрд╛ рд╣реИ рдЬрдм рддрдХ рд░реАрдб рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдмрд╛рдж рдореЗрдВ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝рдирд╛ рдЖрдорддреМрд░ рдкрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рдПрдХ рдкреИрдХреЗрдЯ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рддреЗрдЬ рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЕрдм рдЬрдм рд╕рднреА рдХреЗ рдкрд╛рд╕ рдПрд╕рдПрд╕рдбреА рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рд╕рднреА рдХреИрд╢ рдПрд╕рдПрд╕рдбреА рдкрд░ рд╣реИрдВред рдЖрдзреБрдирд┐рдХ рдПрд╕рдПрд╕рдбреА рдореЗрдВ, рдмрд╣реБрдд рдХрдо рджреЗрд░реА, рдЖрдорддреМрд░ рдкрд░ рджрд╕рд┐рдпреЛрдВ рдорд╛рдЗрдХреНрд░реЛрд╕реЗрдХрдВрдб рдореЗрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк Nginx рдХреЛ рдХрдИ рд╡рд░реНрдХрдлрд╝реНрд▓реЛрдЬрд╝ рдХреЗ рд╕рд╛рде рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдПрдХ рдзреАрдорд╛ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдЕрд╡рд░реБрджреНрдз рди рдХрд░реЗред рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдЖрдк Nginx рдкрд░ рдЬрд▓реНрджреА рдФрд░ рдХреБрд╢рд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрд░реЛрдзреЛрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдПрд╕рдПрд╕рдбреА рдкреНрд░рджрд░реНрд╢рди: рд╣рдореЗрд╢рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рджрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рд╣реЛрдЧрд╛, рдпреЗ рд░рд╕реАрд▓реА рдзрд╛рд░рдгрд╛рдПрдВ рд╣рдореЗрд╢рд╛ рд╕рдЪ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред рдпрджрд┐ рдкреНрд░рддреНрдпреЗрдХ рд░реАрдбрд┐рдВрдЧ рдореЗрдВ рд╣рдореЗрд╢рд╛ 50 ╬╝s рд▓рдЧрддреЗ рд╣реИрдВ, рддреЛ 4 рдХреЗрдмреА рдХреЗ рдмреНрд▓реЙрдХ рдореЗрдВ 0.19 рдПрдордмреА (рдФрд░ рд╣рдо рдмрдбрд╝реЗ рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рднреА рдкрдврд╝рддреЗ рд╣реИрдВ) рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ 2 рдПрдордПрд╕ рд▓рдЧреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдкрд╣рд▓реА рдмрд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рд╕рдордп рдХрднреА-рдХрднреА рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реЛрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ 99 рд╡реЗрдВ рдФрд░ 999 рд╡реЗрдВ рдкреНрд░рддрд┐рд╢рдд рдореЗрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ 100 (рдпрд╛ 1000) рд░реАрдбрд┐рдВрдЧ рдореЗрдВ рд╕реЗ рд╕рдмрд╕реЗ рдзреАрдорд╛ рдкрдврд╝рдиреЗ рдореЗрдВ рдЕрдХреНрд╕рд░ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред
рдареЛрд╕ рд░рд╛рдЬреНрдп рдбреНрд░рд╛рдЗрд╡ рдмрд╣реБрдд рддреЗрдЬ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрдирдХреЗ рдкрд╛рд╕ рдЙрд╕ рдХрддрд╛рд░ рдХреЗ рдЕрдВрджрд░ рдХрдВрдкреНрдпреВрдЯрд░ рд╣реИрдВ рдФрд░ I / O рдХреЛ рдкреБрди: рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛рд░реНрдп рднреА рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣ рдФрд░ рдбреАрдлрд╝реНрд░реИрдЧреНрдореЗрдиреНрдЯреЗрд╢рдиред рд╕рдордп-рд╕рдордп рдкрд░, рдЕрдиреБрд░реЛрдз рдзреАрд░реЗ-рдзреАрд░реЗ рдХрдо рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдореЗрд░реЗ рд╕рд╣рдХрд░реНрдореА
рдЗрд╡рд╛рди рдмреЛрдмреНрд░реЛрд╡ рдиреЗ рдХрдИ I / O рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓реЙрдиреНрдЪ рдХрд┐рдП рдФрд░ 1 рд╕реЗрдХрдВрдб рддрдХ рдХреА рд░реАрдб рдХреА рджреЗрд░реА рджрд░реНрдЬ рдХреАред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдХреБрдЫ SSD рдХреЗ рдкрд╛рд╕ рдЕрдиреНрдп рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдРрд╕реЗ рдкреНрд░рджрд░реНрд╢рди рд╕реНрдкрд╛рдЗрдХреНрд╕ рд╣реИрдВред рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдо рдПрд╕рдПрд╕рдбреА рдЦрд░реАрджрддреЗ рд╕рдордп рдЗрд╕ рд╕рдВрдХреЗрддрдХ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдореЗрдВ рдореМрдЬреВрджрд╛ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
SO_REUSEPORT
рд╕рд╛рде рд╕рдорд╛рди рд▓реЛрдб рд╡рд┐рддрд░рдг
рдкреНрд░рддрд┐ 1000 рдЕрдиреБрд░реЛрдзреЛрдВ рдкрд░ рдПрдХ рдзреАрдореА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдмрдЪрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреЛ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рд╢реЗрд╖ 1000 рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд▓рд┐рдП рд░реЛрдХрдирд╛ рд╣реИред рд╡реИрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ, Nginx рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдХрдИ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╕рдордп рдореЗрдВ 1 рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореАрдЯреНрд░рд┐рдХ рдЬреЛрдбрд╝реА:
gettimeofday(&start, NULL); num_events = epoll_wait(epfd, events, events_len, -1); // events is list of active events // handle event[0]: incoming request GET http://example.com/ gettimeofday(&event_start_handle, NULL); // handle event[1]: send out response to GET http://cloudflare.com/ timersub(&event_start_handle, &start, &event_loop_blocked);
99 рд╡рд╛рдБ рдкреНрд░рддрд┐рд╢рддрдХ (p99)
event_loop_blocked
рд╣рдорд╛рд░реЗ TTFB рдХреЗ 50% рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЕрдиреБрд░реЛрдз рдХреА рд╕реЗрд╡рд╛ рдХрд░рддреЗ рд╕рдордп рдЖрдзрд╛ рд╕рдордп рдЕрдиреНрдп рдЕрдиреБрд░реЛрдзреЛрдВ рджреНрд╡рд╛рд░рд╛ рдШрдЯрдирд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЪрдХреНрд░ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред
event_loop_blocked
рдХреЗрд╡рд▓ рдЖрдзреЗ рд▓реЙрдХ рдХреЛ рдорд╛рдкрддрд╛ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рд▓рдВрдмрд┐рдд рдХреЙрд▓
epoll_wait()
рдорд╛рдкрд╛ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рдЕрд╡рд░реБрджреНрдз рд╕рдордп рдХрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрдкрд╛рдд рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИред
рд╣рдорд╛рд░реА рдкреНрд░рддреНрдпреЗрдХ рдорд╢реАрди 15 рд╡рд░реНрдХрдлрд╝реНрд▓реЛрдЬрд╝ рдХреЗ рд╕рд╛рде рдирдЧреНрдиреЗрдХреНрд╕ рдЪрд▓рд╛рддреА рд╣реИ, рдпрд╛рдиреА рдПрдХ рдзреАрдорд╛ I / O рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ 6% рд╕реЗ рдЕрдзрд┐рдХ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╡рд┐рддрд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ 11% рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред
SO_REUSEPORT
рдЕрд╕рдорд╛рди рд╡рд┐рддрд░рдг рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдорд╛рд░реЗрдХ рдорд╛рдпрдХреЛрд╡рд╕реНрдХреА рдиреЗ рдкрд╣рд▓реЗ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдЕрдиреНрдп рдирдЧреНрдиреЗрдХреНрд╕ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ
рдХрдорд┐рдпрд╛рдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдЖрдк рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЗрд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдХреИрд╢ рдореЗрдВ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдХрдиреЗрдХреНрд╢рди рдЯрд┐рдХрд╛рдК рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рддреЗ рд╕рдордп рджреЗрд░реА рдореЗрдВ рдереЛрдбрд╝реА рд╡реГрджреНрдзрд┐ рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
SO_REUSEPORT
рд╕реБрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдЕрдХреЗрд▓реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ p99 33% рдмреЗрд╣рддрд░ рд╣реЛ рдЧрдпрд╛ рд╣реИред
рдереНрд░реЗрдб рдкреВрд▓ рдХреЗ рд▓рд┐рдП рдкрдврд╝рдирд╛ () рдЪрд▓рдирд╛: рдЪрд╛рдВрджреА рдХреА рдЧреЛрд▓реА рдирд╣реАрдВ
рд╕рдорд╛рдзрд╛рди рдХреЛ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдмрдирд╛рдирд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди
рд╕рд╛рдорд╛рдиреНрдп рдирдЧреНрдиреЗрдХреНрд╕ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ! рдирд┐рдореНрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдкрдврд╝реЗрдВ () рдФрд░ рд▓рд┐рдЦреЗрдВ () рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдИрд╡реЗрдВрдЯ рд▓реВрдк рдХреЛ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ:
aio threads; aio_write on;
рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдФрд░ 33 рдмрд╛рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдордиреЗ p99 рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдмрджрд▓рд╛рд╡ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛, рдЕрдВрддрд░ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рд░реНрдЬрд┐рди рдХреЗ рднреАрддрд░ рд╣реИред рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рд╣рддреЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░ рджрд┐рдпрд╛ред
рдРрд╕реЗ рдХрдИ рдХрд╛рд░рдг рд╣реИрдВ рдХрд┐ рд╣рдордиреЗ Nginx рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреА рддрд░рд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реБрдзрд╛рд░ рдирд╣реАрдВ рдХрд┐рдП рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдЪрдбреАрдбреА рдХреЗ рд▓рд┐рдП 4 рдПрдордмреА рдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 200 рдПрдХ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред Winchesters рдореЗрдВ I / O рд╡рд┐рд▓рдВрдмрддрд╛ рдЕрдзрд┐рдХ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдореБрдЦреНрдп рд░реВрдк рд╕реЗ p99 (рдФрд░ p999) рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд┐рдд рд╣реИрдВред рдФрд╕рдд рджреЗрд░реА рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдЪреЛрдЯреА рдХреЗ рдЙрддреНрд╕рд░реНрдЬрди рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╣реЛред
рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝рд╛рдЗрд▓ рдЖрдХрд╛рд░ рдмрд╣реБрдд рдЫреЛрдЯреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдХреИрд╢ рд╣рд┐рдЯ рдХрд╛ 90% 60KB рд╕реЗ рдХрдо рд╣реИред рдлрд╝рд╛рдЗрд▓реЗрдВ рдЬрд┐рддрдиреА рдЫреЛрдЯреА рд╣реЛрдВрдЧреА, рдЕрд╡рд░реБрджреНрдз рд╣реЛрдиреЗ рдХреЗ рдХрдо рдорд╛рдорд▓реЗ (рдЖрдорддреМрд░ рдкрд░ рд╣рдо рдкреВрд░реА рдлрд╛рдЗрд▓ рдХреЛ рджреЛ рд░реАрдб рдореЗрдВ рдкрдврд╝рддреЗ рд╣реИрдВ)ред
рдЖрдЗрдП рдХреИрд╢ рдореЗрдВ рд╣рд┐рдЯ рд╣реЛрдиреЗ рдкрд░ рдбрд┐рд╕реНрдХ I / O рджреЗрдЦреЗрдВ:
// https://example.com 0xCAFEBEEF fd = open("/cache/prefix/dir/EF/BE/CAFEBEEF", O_RDONLY); // 32 // , "aio threads" read(fd, buf, 32*1024);
32K рд╣рдореЗрд╢рд╛ рдкрдврд╝рд╛ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣реЗрдбрд░ рдЫреЛрдЯреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ 4 рдХреЗрдмреА рдкрдврд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ (рд╣рдо рд╕реАрдзреЗ рдЖрдИ / рдУ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдХрд░реНрдиреЗрд▓ 4 рдХреЗрдмреА рдХреЗ рдЪрдХреНрдХрд░ рд▓рдЧрд╛рддрд╛ рд╣реИ)ред
open()
рд╣рд╛рдирд┐рд░рд╣рд┐рдд рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдВрд╕рд╛рдзрди рд▓реЗрддрд╛ рд╣реИред рдХрдо рд╕реЗ рдХрдо, рдХрд░реНрдиреЗрд▓ рдХреЛ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдлрд╝рд╛рдЗрд▓ рдореМрдЬреВрдж рд╣реИ рдФрд░ рдХреНрдпрд╛ рдХреЙрд▓рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЗрд╕реЗ рдЦреЛрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЙрд╕реЗ
/cache/prefix/dir/EF/BE/CAFEBEEF
рд▓рд┐рдП
/cache/prefix/dir/EF/BE/CAFEBEEF
, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрд╕реЗ
CAFEBEEF
/cache/prefix/dir/EF/BE/
рдореЗрдВ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╕рдмрд╕реЗ рдмреБрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрд░реНрдиреЗрд▓ рдЗрд╕ рдЦреЛрдЬ рдХреЛ рдХрд░рддрд╛ рд╣реИ:
/cache /cache/prefix /cache/prefix/dir /cache/prefix/dir/EF /cache/prefix/dir/EF/BE /cache/prefix/dir/EF/BE/CAFEBEEF
рдпреЗ 6 рдЕрд▓рдЧ-рдЕрд▓рдЧ рд░реАрдб рд╣реИрдВ рдЬреЛ 1
read()
рдХреА рддреБрд▓рдирд╛ рдореЗрдВ
open()
рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ
read()
! рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЦреЛрдЬ
рдбреЗрдВрдЯреНрд░реА рдХреИрд╢ рдореЗрдВ рдЧрд┐рд░ рдЬрд╛рддреА рд╣реИ рдФрд░ рдПрд╕рдПрд╕рдбреА рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪрддреА рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдПрдХ рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ
read()
рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг
read()
рдХреЗрд╡рд▓ рдЖрдзреА рддрд╕реНрд╡реАрд░ рд╣реИред
рдЕрдВрддрд┐рдо рд░рд╛рдЧ: рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдиреЙрди-рдмреНрд▓реЙрдХрд┐рдВрдЧ рдУрдкрди ()
рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ Nginx рдореЗрдВ рдПрдХ рдмрджрд▓рд╛рд╡ рдХрд┐рдпрд╛ рддрд╛рдХрд┐
open()
рдЬреНрдпрд╛рджрд╛рддрд░ рдереНрд░реЗрдб рдкреВрд▓ рдХреЗ рдЕрдВрджрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛ рдФрд░ рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдХреЛ рдмреНрд▓реЙрдХ рди рдХрд░реЗрдВред рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдЦреБрд▓рд╛ () рдФрд░ рдкрдврд╝рдиреЗ () рд╕реЗ рдкрд░рд┐рдгрд╛рдо рд╣реИ:

26 рдЬреВрди рдХреЛ, рд╣рдордиреЗ 5 рд╡реНрдпрд╕реНрддрддрдо рдбреЗрдЯрд╛ рдХреЗрдВрджреНрд░реЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдпрд╛, рдФрд░ рдЕрдЧрд▓реЗ рджрд┐рди - рджреБрдирд┐рдпрд╛ рднрд░ рдХреЗ рдЕрдиреНрдп рд╕рднреА 146 рдбреЗрдЯрд╛ рдХреЗрдВрджреНрд░реЛрдВ рдкрд░ред рдХреБрд▓ рд╢рд┐рдЦрд░ p99 TTFB 6 рдЧреБрдирд╛ рдШрдЯ рдЧрдпрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрджрд┐ рд╣рдо рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 8 рдорд┐рд▓рд┐рдпрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд╣рд░ рд╕рдордп рд╕рд╛рд░рд╛рдВрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╣рд░ рджрд┐рди рдЗрдВрдЯрд░рдиреЗрдЯ рдХреЗ 54 рд╡рд░реНрд╖реЛрдВ рдХреЗ рдЗрдВрддрдЬрд╛рд░ рдХреЛ рдмрдЪрд╛рддреЗ рд╣реИрдВред
рдШрдЯрдирд╛рдУрдВ рдХреА рд╣рдорд╛рд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдЕрднреА рддрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддрд╛рд▓реЗ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдмреНрд▓реЙрдХрд┐рдВрдЧ рддрдм рднреА рд╣реЛрддреА рд╣реИ рдЬрдм рдлрд╝рд╛рдЗрд▓ рдХреИрд╢реНрдб рд╣реЛрддреА рд╣реИ (рджреЛрдиреЛрдВ
open(O_CREAT)
рдФрд░
rename()
) рдпрд╛
open(O_CREAT)
рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордпред рд▓реЗрдХрд┐рди рдРрд╕реЗ рдорд╛рдорд▓реЗ рдХреИрд╢ рдПрдХреНрд╕реЗрд╕ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рджреБрд░реНрд▓рдн рд╣реИрдВред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдо рдЗрди рдХрд╛рд░рдХреЛрдВ рдХреЛ рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд▓реВрдк рдХреЗ рдмрд╛рд╣рд░ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рд╡рд┐рд▓рдВрдм рдХрд╛рд░рдХ p99 рдХреЛ рдФрд░ рдмреЗрд╣рддрд░ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗред
рдирд┐рд╖реНрдХрд░реНрд╖
Nginx рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╣реИ, рд▓реЗрдХрд┐рди рдЕрддреНрдпрдзрд┐рдХ рдЙрдЪреНрдЪ рд▓рд┐рдирдХреНрд╕ I / O рднрд╛рд░ рдХреЛ рд╕реНрдХреЗрд▓ рдХрд░рдирд╛ рдПрдХ рдХрдард┐рди рдХрд╛рдо рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕реНрдЯреИрдВрдбрд░реНрдб рдирдЧреНрдиреЗрдХреНрд╕ рдЕрд▓рдЧ рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рдкрдврд╝рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рд╣рдореЗрдВ рдЕрдХреНрд╕рд░ рдПрдХ рдХрджрдо рдЖрдЧреЗ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред