Slide 1

Slide 1 text

Tuning GraphQL on Rails - 10.26 ༗໌ίϩγΞϜ ిྲྀരഁσεϚον -

Slide 2

Slide 2 text

ࢁԼ࿨඙!QZBNB (.0ϖύϘٕज़ج൫νʔϜ γχΞɾϓϦϯγύϧ ɹΩϟϯϓɺཱྀߦɺώϧτϯ८ΓɺεϚϒϥ ػցֶशɺ$*$%

Slide 3

Slide 3 text

Kaigi on Rails 2024 ࠷ߴͰ͢!!1

Slide 4

Slide 4 text

ࠓ೔࿩͢͜ͱ 1. ݱ৔঺հ 2. ൃੜ͍ͯͨ͠՝୊ 3. ͲͷΑ͏ʹղܾ͔ͨ͠ 4. ࣮ફN+1ղফ 5. ೔ʑͷӡ༻ 6. զ͕Ոʹ͓͚Δચ୕पظͷ໰୊Λ͍͔ʹղܾ͔ͨ͠

Slide 5

Slide 5 text

ίʔυαϯϓϧʹ͍ͭͯ • ձ৔ͰͷΈ΍͢͞Λ༏ઌͯ͠ɺຊདྷඞཁͳ࣮૷Λ࡟ͬͯίʔυαϯϓϧͱ ͍ͯࣔͯ͠͠ΔՕॴ͕ଟʑ͋Γ·͢ɻ • ͦΕΒ͍͠ίʔυ͸github.com/pyama86/kaigi-on-rails-2024
 Λ֬ೝ͍ͯͩ͘͠͞ɻ

Slide 6

Slide 6 text

ݱ৔Ұے ೥

Slide 7

Slide 7 text

minne ϋϯυϝΠυϚʔέοταʔϏε 1. ࡞඼ൢച 2. ࡞Ոࢧԉ 3. ϝσΟΞɾ޿ࠂ

Slide 8

Slide 8 text

minneͷΞϓϦέʔγϣϯߏ੒֓ཁ browser mobile app Web UI Rails Next.js Rails API ϞϊϦεߏ੒ͳRails ※ਤ্͸Rails͕̎ͭ͋ΔΑ͏ʹݟ͑·͕͢ɺͦΕ͸࢒૾Ͱ͋Γɺ࣮ࡍ͸1ϦϙδτϦͰಉ͡ίʔυͰ͢ɻ WEB UIͷϨϯμϦϯάͱɺAPIͷෛՙɺτϥϑΟοΫ͕ҟͳΔͨΊɺϦιʔε෼཭͍ͯ͠·͢ɻ

Slide 9

Slide 9 text

minneͷγεςϜߏ੒֓ཁ ΦϯϓϨϛεͱAWSͷϚϧνΫϥ΢υߏ੒ on premises AWS NKE(k8s) OpenStack Web Web API API EKS(k8s) EC2 Batch Direct
 Connect RDS Elastic xxx ѹ౗తͳ௿ίετ͕ͩɺ ϓϥοτϑΥʔϜͷ؅ཧίετ͕͋Δ ίετ͸ֻ͔Δ͕ɺσʔλετΞͷ ϚωʔδυɾαʔϏεͳͲӡ༻ෛՙܰݮ Web API

Slide 10

Slide 10 text

ൃੜ͍ͯͨ͠ ՝୊

Slide 11

Slide 11 text

૿͑ଓ͚ΔVM ΦϯϓϨϛε: 120VM(16vCPU/32GB Memory) AWS: 20ʙ80VM※(8vCPU/16G Memory) ※AWS͸ϐʔΫλΠϜʹΦϯϓϨϛεͷτϥϑΟοΫΛΦϑϩʔυ͓ͯ͠Γɺ
 ΦʔτεέʔϧʹΑͬͯ୆਺͕૿ݮ͢Δ ෛՙ͕ߴ͍ˠͱΓ͋͑ͣVM૿΍͢ͷ࿈࠯

Slide 12

Slide 12 text

https:// fi nance.yahoo.co.jpΑΓҾ༻ ݮΓଓ͚Δۚ Կ΋ͯ͠ͳ͍ͷʹ རӹݮͬͨΜͰ͚͢Ͳɾɾɾʁ

Slide 13

Slide 13 text

???????????????????????????

Slide 14

Slide 14 text

!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

Slide 15

Slide 15 text

͍ͭ͜ɺN+5000͡ΌͶ͔͐ʂʂʂ

Slide 16

Slide 16 text

ͲͷΑ͏ʹ վળ͔ͨ͠

Slide 17

Slide 17 text

ͲͷΑ͏ʹվળ͔ͨ͠ʁ query { orders { id customer { name } } } select * from orders; select * from customers where customers_id = 1; select * from customers where customers_id = 2; select * from customers where customers_id = 3; … select * from customers where customers_id = 5000; GraphQLͰΑ͋͘ΔN+1ͳΫΤϦ

Slide 18

Slide 18 text

ͲͷΑ͏ʹվળ͔ͨ͠ʁ • lookaheadΛར༻͢Δ • όονϩʔυΛར༻͢Δ • Shopify/graphql-batch • GraphQL::Dataloader select * from orders; select * from … where customers_id in(1, 2…5000);

Slide 19

Slide 19 text

lookaheadΛར༻ͨ͠ઌಡΈ lookahead͕γϯϓϧʹॻ͚Δ

Slide 20

Slide 20 text

HSBQIRMCBUDI

Slide 21

Slide 21 text

promise.rb RubyͷPromises/A+४ڌͷϥΠϒϥϦ https://github.com/lgierth/promise.rb thenʹ౉͞ΕͨϒϩοΫ͕஗Ԇ࣮ߦ͞ΕΔ

Slide 22

Slide 22 text

select * from orders; select * from customers where customers_id = 1; select * from customers where customers_id = 2; select * from customers where customers_id = 3; … select * from customers where customers_id = 5000; Ͳ͜Λ஗Ԇ࣮ߦͤ͞Δ͔ʁ ID͚ͩઌʹूΊͱ͍ͯɺ ΫΤϦ͸͋ͱ͔Β஗Ԇ࣮ߦͯ͠ ·ͱΊͯ౤͍͛ͨ

Slide 23

Slide 23 text

https://github.com/Shopify/graphql-batch/blob/main/examples/association_loader.rb customer_idΛΩϡʔʹ௥Ճͯ͠ɺ PromiseΛฦ٫ queue = [1, 2, 3, 4 … 5000]

Slide 24

Slide 24 text

Promise.sync=Promiseͷ࣮ߦ query { orders { id customer { name } } } ্͔Βॱ൪ʹઙ͍ॱʹPromise.sync͕ίʔϧ͞ΕΔ 1. Ordersͷϓϩϛε͕࣮ߦ͞ΕΔ 2. Customerͷϓϩϛε͕ ࣮ߦ͞ΕΔ

Slide 25

Slide 25 text

Promise.sync 1.recordsʹ͸loadͰ queueʹཷ·͍ͬͯͨ஋͕౉Δɻ ஗Ԇ࣮ߦର৅ͷϨίʔυΛ ·ͱΊͯpreload 2.Ϩίʔυ͝ͱʹ݁ՌΛ ෼ׂͯ͠ຒΊࠐΉ

Slide 26

Slide 26 text

in۟ʹ5000΋Ҿ਺౉͢ͳ͸ॾઆ͋Δ select * from orders; select * from … where customers_id in(1, 2…5000); ActiveRecord::Associations::PreloaderͰ in۟ʹ·ͱΊΒΕΔ

Slide 27

Slide 27 text

࣮ફ/ ղফ

Slide 28

Slide 28 text

Πϯελϯεϝιου query { orders { id customer { name isLoyal } } } select 1 As one from sales where customers_id = 1; select 1 As one from sales where customers_id = 2; select 1 As one from sales where customers_id = 3; … ഁ໓ϩυϦήεʂʂʂʂʂ

Slide 29

Slide 29 text

Πϯελϯεϝιου զʑʹ͸஗Ԇ࣮ߦ͕͋Δ͡Όͳ͍͔

Slide 30

Slide 30 text

ଠ٬͕ա͗Δ

Slide 31

Slide 31 text

LoaderΛॻ͘ REST API͔ΒͷҠߦ࣌ͳͲ طଘͷϝιου͸ खΛೖΕͮΒ͍

Slide 32

Slide 32 text

LoaderΛॻ͘ customer_id ͝ͱʹɺsalesͰιʔτͨ݁͠Ռͷ ্͔Βॱʹ1,2,3…ͷΑ͏ʹ൪߸Λ;Δ existsʁͷ൑ఆΛ͍ͨ͠ͷͰɺcustomer_id͋ͨΓ 1͚݅ͩऔΕ͹OK

Slide 33

Slide 33 text

LoaderΛॻ͘ ΫΤϦͷ݁ՌΛPromiseͷ໭Γ஋ʹઃఆ

Slide 34

Slide 34 text

LoaderͷϝϦοτɾσϝϦοτ 1. LoaderͰεοΩϦ͔͚Δ 2. Loaderཚཱ͢ΔͱLoaderʹϏδωε ϩδοΫ͕ຒΊࠐ·ΕͯɺϞσϧͱ
 ࠩҟ͕ੜ·ΕΔ͜ͱ͕͋Γɺ
 όάͷԹচͱͳΓ͑Δ

Slide 35

Slide 35 text

ύϑΥʔϚϯεͷ໰୊ͷ୳͠ํ APMΛ࢖͏ͷ͕͓͢͢Ί

Slide 36

Slide 36 text

ύϑΥʔϚϯεͷ໰୊ͷ୳͠ํ query { orders { id customer { name isLoyal } } } ΫΤϦͷਂ͕͞ઙ͍ॱʹΫΤϦ͕࣮ߦ͞ΕΔ

Slide 37

Slide 37 text

ύϑΥʔϚϯεͷ໰୊ͷ୳͠ํ APMͷεύϯΛ෼͚ΔͱɺΑΓ୳͠΍͍͢

Slide 38

Slide 38 text

࣮੷঺հ ΦϯϓϨϛε: 120VM -> 30VM AWS: 20ʙ80VM -> 20VM(εέʔϧΞ΢τ͕ෆཁʹͳͬͨ) minneʹ͓͍ͯ͸ύϑΥʔϚϯε͕޲্

Slide 39

Slide 39 text

ϝτϦΫε΋େ෯ʹվળ ΤϯυϙΠϯτͷϨΠςϯγɺDBͷCPU࢖༻཰͕վળ

Slide 40

Slide 40 text

೔ʑͷӡ༻

Slide 41

Slide 41 text

ͳΜͰͳΜʁʁʁ ਆ͕͔ͬͨνϡʔχϯά ೔ʑগͮͭ͠αʔϏε͸஗͘ͳΔ

Slide 42

Slide 42 text

೔ʑαʔϏε͸ॱௐʹ੒௕ɺ ͓٬ͷসإͰ͞ΒͳΔඈ༂Λ໨ඪ • minne޿ࠂ • ಈըίϯςϯπ • minne PLUS https://tech.pepabo.com/2024/08/05/minne-movie/ ৽ػೳ͕૿͑Δ=৽͍͠ΫΤϦ͕૿͑Δ

Slide 43

Slide 43 text

SLIͱSLO SLI = Service Level Indicator αʔϏεϨϕϧࢦඪ SLO = Service Level Objective αʔϏεϨϕϧ໨ඪ GraphQLͷϨΠςϯγΛSLIʹઃఆ

Slide 44

Slide 44 text

SLIͱSLOͷܾΊํ αʔϏεͷKPI͔ΒϒϨΠΫμ΢ϯܾͯ͠ΊΔ minneʹ͓͚ΔΧʔτΠϯͱϨεϙϯελΠϜͷ૬ؔ ੺͍఺=ΧʔτΠϯ ੨͍఺=཭୤

Slide 45

Slide 45 text

ϞχλϦϯάख๏ • SaaS(Datadog/New Relic/Sentry) • OpenTelemetry with Grafana Stack ͍ΘΏΔAPMͰՄ؍ଌੑΛ্͛Δͷ͕ྑ͍

Slide 46

Slide 46 text

OpenTelemetry چདྷɺ4BB4΍044͝ͱʹ࣮૷͞Ε͍ͯͨςϨϝτϦσʔλͷඪ४Խ IUUQTDMPVEOBUJWFEBZTKQPZ https://opentelemetry.connpass.com/

Slide 47

Slide 47 text

OpenTelemetry https://opentelemetry.io/docs/ ֤ݴޠͷSDK΍ ࣗಈܭ૷ɺखಈܭ૷ ΍ϛυϧ΢ΣΞ͔Β ςϨϝτϦσʔλΛ ग़ྗ

Slide 48

Slide 48 text

OpenTelemetry https://opentelemetry.io/docs/ ඪ४Խ͞Εͨϓϩτίϧʹ ରԠͨ͠ΤʔδΣϯτ

Slide 49

Slide 49 text

OpenTelemetry https://opentelemetry.io/docs/ 4BB4΍ ϗετ͞Εͨ044 ࠩ͠ସ͑Մೳ

Slide 50

Slide 50 text

μογϡϘʔυ ͖͍͠஋؂ࢹ & ຖिΈΜͳͰோΊΔ • ϦϦʔεʹىҼͨ͠ϨεϙϯεѱԽ • αʔϏεͷ݈શੑͷ೴಺ಉظ

Slide 51

Slide 51 text

ࠓ೔࿩ͨ͜͠ͱ • N+1ͷ໰୊͸graphql-batchͷAssociation Loader΋͘͠͸ GraphQL::DataLoaderͷͦΕʹ४͡Δ࣮૷Ͱ͍͍ͩͨย෇͘ • ҆қʹઌಡΈ͢ΔͱɺϨίʔυ਺ͷଟ͍ςʔϒϧΛେྔʹϩʔυͯ͠͠· ͏͜ͱ͕͋ΔͷͰͦ͏͍͏έʔεͰ͸ࣗ࡞ͷLoaderΛॻ͘ • LoaderΛཚཱ͢ΔͱɺϞσϧͱͷ࣮૷ࠩҟ͕ੜ·ΕΔ͜ͱ΋͋ΔͷͰɺҰ ؏ੑΛ࣮࣋ͭ૷ʹ͢Δ • ೔ʑͷϞχλϦϯάͰύϑΥʔϚϯεͷྼԽʹରॲ͢Δ

Slide 52

Slide 52 text

ਓྨͷΞ΢τϓοτΛ૿΍͠·͠ΐ͏ ࠷৽ͷ࠾༻৘ใΛνΣοΫˠ !QC@SFDSVJU