Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goで実装された高速な
仮想待合室サーバの実装と詳解

 Goで実装された高速な
仮想待合室サーバの実装と詳解

ペパボのテックカンファレンスで話しました。

Kazuhiko Yamashita

September 14, 2023
Tweet

More Decks by Kazuhiko Yamashita

Other Decks in Technology

Transcript

  1. γεςϜߏ੒֓ཁ OpenStack Managed LB Backend APIs nginx proxy role proxy

    roleͰෳ਺ͷछྨͷapp roleʹϓϩΩγ nginx app unicorn 
 php-fpm app role nginx app unicorn 
 php-fpm app role nginx app unicorn 
 php-fpm app role nginx app unicorn 
 php-fpm app role
  2. Ծ૝଴߹ࣨ OpenStack Managed LB Backend APIs ଴߹ࣨAPIΛ։ൃͨ͠ nginx app unicorn

    
 php-fpm app role nginx app unicorn 
 php-fpm app role nginx app unicorn 
 php-fpm app role nginx app unicorn 
 php-fpm app role proxy role nginx waiting room
  3. Ծ૝଴߹ࣨ֓ཁ proxy role nginx waiting room proxy role nginx waiting

    room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room ڐՄϦετ Site A 200 Site B ... Site C ... ΫϥΠΞϯτʹ଴ͪ൪߸Λ࠾൪ͯ͠ɺڐՄϦετͷ൪߸ΑΓ খ͍͞൪߸Λ͍࣋ͬͯΕ͹Ұఆ࣌ؒΞΫηε͕Մೳ Client A ΫϥΠΞϯτ൪߸:100 ΞΫηεڐՄ Client B ΫϥΠΞϯτ൪߸:300 ଴߹ࣨ΁
  4. ଴߹ࣨىಈܖػ location / { limit_req zone=example nodelay; limit_req_status 512; error_page

    512 =200 @waitingroom; root /var/www/nginx; } ϨʔτϦϛοτʹ֘౰ͨ͠Β
 ಛఆͷΤϯυϙΠϯτʹ
 ϦμΠϨΫτ OHJOYͷSBUFMJNJUNPEVMFΛར༻͠ɺ ա৒ΞΫηεΛݕ஌
  5. ଴߹ࣨىಈܖػ location @waitingroom { mruby_rewrite_handler enable_waitingroom.rb; proxy_pass origin_backend/$request_uri; internal; }

    location ~ ^/queues { proxy_pass waitingroom; internal; } ଴߹ࣨAPI͸mrubyͰ
 ίʔϧͯ͠ɺ଴߹ࣨΛ
 ىಈ͢Δ
  6. ngx_http_subrequest location / { # subrequest } location /subreqest {

    puts "hello" } # http://localhost/ => hello ͋ΔϩέʔγϣϯʹདྷͨϦΫΤετΛ ଞͷϩέʔγϣϯʹϦΫΤετͨ݁͠ՌͰ Ԡ౴͢ΔΑ͏ͳ࢖͍ํ
  7. ଴߹ࣨىಈܖػ location @waitingroom { mruby_rewrite_handler enable_waitingroom.rb; proxy_pass origin_backend/$request_uri; internal; }

    location ~ ^/queues { proxy_pass waitingroom; internal; } /queuesΛ࣮ߦ͍ͯ͠Δ
 API͸nginxΛϒϩοΫ͠ͳ͍
  8. ଴߹੍ࣨݶ࣌ͷϦΫΤετભҠ Waiting Room nginx Client Origin 1.ϦΫΤετ 2.ىಈ͞Ε͍ͯΔ͔ʁ 3.ىಈத͔ͭɺ
 ະڐՄΫϥΠΞϯτ

    4.503Ϩεϙϯε ଴߹ࣨىಈঢ়ଶͷͱ͖͸ϨʔτϦϛοτʹؔ܎ͳ͘ 
 Ұఆ࣌ؒɺ଴߹ࣨʹҊ಺͢Δ
  9. ଴߹ࣨىಈ 4&5/9 &91*3& ;"%% ܭࢉྔ:O(1) Ωʔྫ: a.com
 SET if Not

    eXistsͷུͰɺΩʔ͕ଘࡏ͠ͳ͍৔߹ͷΈ஋Λઃఆ͢Δɻ Ωʔ͕ଘࡏ͢Δ৔߹ʹ1ɺΩʔ͕ͳ͍৔߹ʹ0Λฦ٫͢ΔͷͰɺϩοΫͷΑ͏ʹར༻Ͱ͖Δɻ BDPNͰ଴߹ࣨΛىಈ͢Δ৔߹ ܭࢉྔ: O(log(N)) Ωʔྫ: queue-domains
 ϝϯόʔ+είΞͰϋογϡͷΑ͏ʹѻ͏͜ͱ͕Ͱ͖Δɻܭࢉྔ΋௿͘ɺॏෳഉআͰ͖ΔͷͰɺ ଴߹͕ࣨىಈ͍ͯ͠ΔυϝΠϯͷϦετʹར༻͍ͯ͠Δɻ ܭࢉྔ:O(1) Ωʔྫ: a.com
 TTLΛઃఆ͢ΔAPIɻυϝΠϯ໊ΛΩʔʹઃఆ͢Δ͜ͱͰɺ଴߹ࣨͷىಈ࣌ؒΛ TTLΛ༻੍͍ͯޚ͢Δ͜ͱ͕Ͱ͖Δɻྫ͑͹TTL=300ʹ͢Δͱ5෼ؒ͸଴߹͕ࣨىಈɻ
  10. σʔλߏ଄ key value queue-domains [a.com, b.com, c.com] a.com 200 b.com

    300 c.com 400 ͳΔ΂͘υϝΠϯΛى఺ʹ0  ͰΞΫηεͰ͖Δߏ଄ ZADD SETNX
  11. ଴ͪ൪߸ͷ࠾൪ ·ͣ͸࠾൪࣌ࠁΛ෷͍ग़͠ϖʔδʹϦμΠϨΫτͯ͠ɺ 
 KBWBTDSJQUͰ਺ඵ͓͖ʹϙʔϦϯά͠ 
 ࠾൪࣌ࠁʹͳͬͨΒ࠾൪͢Δ͜ͱͰଟॏ࠾൪Λ੍ݶ 1.index.html,main.cs.. 2.redirect 503.hml ΫϥΠΞϯτ൪߸:

    NULL ΫϥΠΞϯτID: NULL ࠾൪࣌ࠁ: 10ඵޙ waiting room client 3.̐ඵ͝ͱʹ503.html΁ϦΫΤετ ΫϥΠΞϯτ൪߸: 1 ΫϥΠΞϯτID: UUID ࠾൪࣌ࠁ: DONE 4.࠾൪
  12. ڐՄ൪߸ͷߋ৽ proxy role nginx waiting room proxy role nginx waiting

    room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room proxy role nginx waiting room ڐՄ൪߸Ϧετ Site A 200 Site B 1000 Site C 440 ҰͭͷڐՄϦετΛෳ਺ͷQSPYZSPMF͕ࢀর͢Δ৔߹ʹɺ ͲͷΑ͏ʹߋ৽͢Δ͔ʁ 1෼͝ͱʹ200ΫϥΠΞϯτͣͭ ڐՄ͢Δͱ͍͏Α͏ͳ 
 ੍ޚΛ͍ͨ͠ 200→400→600....
  13. զʑʹ͸goroutine͕͋Δ͡Όͳ͍͔ waiting room http server access controller ڐՄ൪߸Ϧετ Site A

    200 Site B 1000 Site C 440 ࢦఆִؒͰϦετΛࢀর͠ɺڐՄϦετΛߋ৽͢Δ goroutineΛىಈ͢Δ ߋ৽
  14. ڐՄ൪߸Ϧετͷഉଞ੍ޚ waiting room http server access controller ڐՄ൪߸Ϧετ Site A

    200 Site B 1000 Site C 440 SETNXΛ׆༻͢Δ͜ͱͰඞͣυϝΠϯ͋ͨΓͷ
 ߋ৽ϓϩηε͸ඞͣҰͭʹͳΔ waiting room http server access controller SETNX ok SETNX ng
  15. ڐՄ൪߸ͷߋ৽ ;3"/(& &91*3& 4&5/9 ܭࢉྔ: O(log(N)+M) Ωʔྫ queue-domains
 ଴߹͕ࣨىಈ͞Ε͍ͯΔ͢΂ͯͷυϝΠϯΛϦετͰऔಘ͢Δɻ HPSPVUJOFͰࢦఆඵ਺ײִؒͰϧʔϓ͢Δ

    ܭࢉྔ:O(1) Ωʔྫ: a.com_lock ϩοΫΛऔΕͨproxy roleͷΈ͕ɺڐՄ൪߸Λߋ৽Մೳɻ ෳ਺ͷproxy role͕ಉ࣌ʹߋ৽͢Δ͜ͱΛഉଞ੍ޚ͢Δɻ ܭࢉྔ O(1) Ωʔྫ:a.com_lock ࣍ճͷڐՄ൪߸ߋ৽࣌ؒ·Ͱͷ஋ΛTTLʹઃఆ͢Δ͜ͱͰϩοΫ͕औΒΕͨ··ʹͳΔͨΊ ߋ৽ִؒΛTTLͰ੍ޚͰ͖Δɻ60ඵִؒͰڐՄ൪߸Λߋ৽͍ͨ͠ͳΒ60ඵΛઃఆɻ 4&5&9 ܭࢉྔ O(1)Ωʔྫ:a.com ݱࡏͷڐՄ൪߸ʹ௥ՃڐՄ͍ͨ͠ΫϥΠΞϯτ਺Λ௥Ճͯ͠ɺTTLͱͱ΋ʹॻ͖ࠐΈɻ
  16. ΞΫηεڐՄ ڐՄ൪߸Ϧετ Site A 200 Site B 1000 Site C

    440 ΫϥΠΞϯτͷΞΫηεΛڐՄͨ͠৔߹͸ɺ ΫϥΠΞϯτIDΛΩʔʹRedisʹอଘ͠ɺ TTLͷظؒΞΫηεڐՄ Site A ΫϥΠΞϯτ൪߸:100 ΫϥΠΞϯτID: UUID1 waiting room ࢀর Ωʔ TTL UUID1 600 ॻ͖ࠐΈ Client