Slide 1

Slide 1 text

freee גࣜձࣾ σʔλͷߏ଄͔Β࠶ݕ౼͢ΔύϑΥʔϚϯενϡʔχϯά 2019.01.21

Slide 2

Slide 2 text

takuya kubo @tkuboma ॴଐνʔϜʢࡶձܭ ਓؒνʔϜʣ 2 ܦྺ ● Sierͱͯ͠ෳ਺اۀΛసʑ ○ ओʹ௨৴ܥͷόοΫΤϯυ ● ࣄۀձࣾͰհޢ੥ٻιϑτͷ։ൃʹैࣄ ○ ৽نɾอक։ൃɺࢢ৔ௐࠪɺίʔϧηϯλʔͳͲ ● 2017೥7݄ freee ʹ join ○ ձܭνʔϜॴଐ ■ ৽نɾอक։ൃ ○ νʔϜ஍ࠈ ͔Β νʔϜਓؒ ΁ ■ ਃ੥υϝΠϯͷϚΠΫϩαʔϏεԽ ■ ܾࢉυϝΠϯपลͷอक։ൃ झຯ ● ͓ञ ● ࢠڙ

Slide 3

Slide 3 text

ɹ02ɹDBपΓͷύϑΥʔϚϯεվળ ɹ01ɹfreeeͷ؂ࢹपΓʹ͍ͭͯ؆୯ʹ Agenda 03ɹ·ͱΊ

Slide 4

Slide 4 text

01 Section freeeͷ؂ࢹपΓʹ͍ͭͯ؆୯ʹ

Slide 5

Slide 5 text

5 ● Mackerel ○ ֎ܗ؂ࢹɾαʔόʔϨϕϧͰ؂ࢹ ○ Slackʹ௨஌ ● NewRelic ○ ΞϓϦέʔγϣϯͷੑೳ؂ࢹ ○ ϘτϧωοΫͱͳ͍ͬͯΔ End-point ֬ೝ ● Monyog ○ queryϨϕϧͰ؂ࢹ ○ ϝʔϧ௨஌ ● Datadog (࠷ۙಋೖ࢝͠Ίͨ) ○ Kubernetes؀ڥͷ؂ࢹʹɺΑΓద੾ͳSaaSͱͯ͠ಋೖ freeeͷ؂ࢹपΓʹ͍ͭͯ؆୯ʹ

Slide 6

Slide 6 text

02 Section DBपΓͷύϑΥʔϚϯεվળ

Slide 7

Slide 7 text

7 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. σʔλͷ࣋ͪํͷݟ௚͠ 4. ςʔϒϧߏ੒ͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 8

Slide 8 text

8 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. σʔλͷ࣋ͪํͷݟ௚͠ 4. ςʔϒϧߏ੒ͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 9

Slide 9 text

9 ● ಺༰ ○ ୯७ʹindexΛషΔඞཁ͕͋Δ ○ indexΛར༻Ͱ͖͍ͯͳ͍ DBपΓͷύϑΥʔϚϯεվળ explain SELECT * FROM औҾઌ WHERE ໊લ = 'גࣜձࣾA' ************* 1. row ************* id: 1 select_type: SIMPLE table: औҾઌ partitions: NULL type: ALL explain SELECT औҾ.* FROM औҾ INNER JOIN ࢓༁ ON ࢓༁.id = ࢓༁.औҾ_id WHERE औҾ.ࣄۀॴ_id = 111 AND ࢓༁.࢓༁೔ >= '2019-10-10'; *************** 1. row **************** key: index=औҾ_ࣄۀॴ_id

Slide 10

Slide 10 text

10 ● ରԠ ○ ඞཁͳΧϥϜʹindexΛషΔ ○ ࣮ߦܭըΛݟͯద੾ͳindexΛར༻Ͱ͖͍ͯͳ͍ΫΤϦͷमਖ਼ SELECT औҾ.* FROM औҾ INNER JOIN ࢓༁ ON ࢓༁.id = ࢓༁.औҾ_id WHERE औҾ.ࣄۀॴ_id = 111 AND ࢓༁.ࣄۀॴ_id = 111 AND ࢓༁.࢓༁೔ >= '2019-10-10'; mysql> SHOW INDEX FROM औҾ; +-------+-----------------------------+------------------+---------------------+----------------+ | Table | Key_name | Seq_in_index | Column_name | Cardinality | +-------+-----------------------------+------------------+---------------------+----------------+ | ࢓༁ | PRIMARY | 1 | id | 936 | | ࢓༁ | ࣄۀॴ_ID | 1 | ࣄۀॴ_id | 29 | +-------+-----------------------------+------------------+---------------------+----------------+ mysql> SHOW INDEX FROM ࢓༁; +-------+-----------------------------+------------------+---------------------+----------------+ | Table | Key_name | Seq_in_index | Column_name | Cardinality | +-------+-----------------------------+------------------+---------------------+----------------+ | ࢓༁ | PRIMARY | 1 | id | 2627 | | ࢓༁ | ࣄۀॴ_ID_࢓༁೔ | 1 | ࣄۀॴ_id | 29 | | ࢓༁ | ࣄۀॴ_ID_࢓༁೔ | 2 | ࢓༁೔ | 467 | +-------+-----------------------------+------------------+---------------------+----------------+ SELECT औҾ.* FROM औҾ INNER JOIN ࢓༁ ON ࢓༁.id = ࢓༁.औҾ_id WHERE औҾ.ࣄۀॴ_id = 111 AND ࢓༁.࢓༁೔ >= '2019-10-10'; ○ Cardinality͕ߴ͍indexΛར༻Ͱ͖ΔΑ͏ʹ͢Δ DBपΓͷύϑΥʔϚϯεվળ

Slide 11

Slide 11 text

11 ࢓༁model scope :࢓༁೔Ҏ্, ->(೔෇) do where('࢓༁೔ΧϥϜ >= ?', ೔෇) end ● ͳͥ࿙ΕΔʁ ○ ActiveRecord ͷ scope Λར༻͍ͯ͠Δ ○ ࢓༁model͸ࣄۀॴmodelͱͷؔ࿈͕͋Γɺʮࣄۀॴ.࢓༁.scopeʯͱݺͼग़͢ҝ index͸࢖ΘΕΔ ○ joinͷ࣌͸ࣄۀॴ৘ใ͕ೖΒͳ͍ҝɺվળલͷΫΤϦͱͳΔ > ࣄۀॴ.࢓༁.࢓༁೔Ҏ্('2019-10-10') SELECT * FROM ࢓༁ WHERE ࢓༁.ࣄۀॴ_id = '111' AND ࢓༁.࢓༁೔ >= '2020-01-01' > ࣄۀॴ.औҾ.joins(࢓༁).merge(࢓༁.࢓༁೔Ҏ্('2019-10-10')) SELECT * FROM औҾ ɹINNER JOIN ࢓༁ ON ࢓༁.औҾ_id = औҾ.id WHERE औҾ.ࣄۀॴ_id = '111' AND ࢓༁.࢓༁೔ >= '2020-01-01' ࢓༁model scope :࢓༁೔Ҏ্, ->(ࣄۀॴ_id, ೔෇) do where('ࣄۀॴ_id = ? AND ࢓༁೔ΧϥϜ >= ?', ࣄۀॴ_id, ೔෇) end > ࣄۀॴ.औҾ.joins(࢓༁).merge(࢓༁.࢓༁೔Ҏ্(111, '2019-10-10')) SELECT * FROM औҾ ɹINNER JOIN ࢓༁ ON ࢓༁.औҾ_id = औҾ.id WHERE ɹऔҾ.ࣄۀॴ_id = '111' AND ࢓༁.ࣄۀॴ_id = '111' AND ࢓༁.࢓༁೔ >= '2020-01-01' DBपΓͷύϑΥʔϚϯεվળ

Slide 12

Slide 12 text

12 ● ஫ҙ͍ͯ͠Δࣄ ○ indexΛషΔ࣌ؒ(௨ৗσϓϩΠͰ࣮ࢪ͢Δ͔ɺϝϯςͰ΍Δ͔) ○ ۀ຿ɺσʔλΛߟ͑ແବʹindexΛషΒͳ͍ ○ मਖ਼Λݕূ͢Δࡍ͸ຊ൪૬౰ͷσʔλͰݕূ͢Δ DBपΓͷύϑΥʔϚϯεվળ

Slide 13

Slide 13 text

13 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. σʔλͷ࣋ͪํͷݟ௚͠ 4. ςʔϒϧߏ੒ͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 14

Slide 14 text

14 ● ಺༰ ○ ର৅σʔλͷrow͕େ͖͗͢Δ mysql> SELECT DISTINCT ࢓༁.औҾઌ_id FROM ࢓༁ WHERE ࢓༁.Ϣʔβʔ_id = 111; ----------- 4001 rows in set (12.37 sec) explain SELECT DISTINCT ࢓༁.औҾઌ_id FROM ࢓༁ WHERE ࢓༁.ࣄۀॴ_id = 111; ***** 1. row ***** rows: 20000000 ○ ࢓༁͸Ϣʔβ಺Ͱ࠷େڃͷϨίʔυΛތΔςʔϒϧ DBपΓͷύϑΥʔϚϯεվળ

Slide 15

Slide 15 text

15 ● ରԠ ○ row͕ߜΒΕΔςʔϒϧΛΫΤϦʹՃ͑Δ mysql> SELECT DISTINCT ࢓༁.औҾઌ_id FROM ࢓༁ WHERE ࢓༁.ࣄۀॴ_id = 111; ----------- 4001 rows in set (12.37 sec) mysql> SELECT DISTINCT औҾઌ.id FROM औҾઌ INNER JOIN ࢓༁ ON partners.id = ࢓༁.औҾઌ_id WHERE औҾઌ.ࣄۀॴ_id = 111; ----------- 4000 rows in set (0.10 sec) ***** 1. row ***** rows: 20000000 ***** 1. row ***** rows: 3000 ***** 2. row ***** rows: 40 ○ ΑΓগͳ͍औҾઌͷςʔϒϧΛ৚݅ʹೖΕΔ͜ͱʹΑΓrow͕΁Γܶతʹૣ͘ͳΔ DBपΓͷύϑΥʔϚϯεվળ

Slide 16

Slide 16 text

16 ● ஫ҙ͍ͯ͠Δࣄ ○ ςʔϒϧͷσʔλͷ૿Ճͷ֯౓ ○ ΫΤϦͷ݁Ռ͕มΘΒͳ͍͔൱͔ ○ ΞϓϦέʔγϣϯଆʹॲཧΛҕ೚͢ΔܗʹͳΔҝɺΞϓϦέʔγϣϯଆ΁ͷෛՙ૿ DBपΓͷύϑΥʔϚϯεվળ

Slide 17

Slide 17 text

17 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. σʔλͷ࣋ͪํͷݟ௚͠ 4. ςʔϒϧߏ੒ͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 18

Slide 18 text

18 ● ಺༰ ○ idͰ͸ͳ͘StringͰjoin͍ͯ͠Δ ○ Ϛελʔσʔλͱڞଘ͢Δ৘ใ͕ଘࡏ͢Δ SELECT צఆՊ໨.* FROM צఆՊ໨ WHERE צఆՊ໨.Ϣʔβʔ_id = γεςϜϢʔβʔ.id UNION SELECT צఆՊ໨.* FROM צఆՊ໨ WHERE צఆՊ໨.Ϣʔβʔ_id = Ϣʔβʔ.id; DBपΓͷύϑΥʔϚϯεվળ

Slide 19

Slide 19 text

19 ● ରԠ ○ ؔ࿈idͷΧϥϜΛ௥Ճ͠idͰjoin͢Δ ○ ϚελʔσʔλΛϢʔβଆʹίϐʔ͠read͸ϢʔβʔσʔλͷΈʹ͢Δ SELECT צఆՊ໨.* FROM צఆՊ໨ WHERE צఆՊ໨.Ϣʔβʔ_id = Ϣʔβʔ.id; DBपΓͷύϑΥʔϚϯεվળ

Slide 20

Slide 20 text

20 ● ஫ҙ͍ͯ͠Δࣄ ○ ϚελʔσʔλΛίϐʔ͢ΔλΠϛϯά ○ ͋Δఔ౓αʔϏε͕େ͖͘ͳ͔ͬͯΒͩͱमਖ਼ίετ͕ߴ͍ҝɺઃܭஈ֊Ͱݕ౼͍ͨ͠ ○ සൟʹϚελʔσʔλ͕มߋ͞ΕΔςʔϒϧͷ৔߹ɺϝϯςίετ͕ߴ͘ͳΔҝผͷରॲΛݕ౼ ■ ࠷ॳ͔ΒΫΤϦΛ෼͚ΔͳͲ DBपΓͷύϑΥʔϚϯεվળ

Slide 21

Slide 21 text

21 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. σʔλͷ࣋ͪํͷݟ௚͠ 4. ςʔϒϧߏ੒ͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 22

Slide 22 text

22 ● ಺༰ ○ େྔσʔλΛ౎౓ूܭͯ͠ද͍ࣔͯ͠Δ DBपΓͷύϑΥʔϚϯεվળ

Slide 23

Slide 23 text

23 ● ରԠ ○ ूܭςʔϒϧΛ࡞੒ʢѹॖ཰ͷߴ͍ςʔϒϧΛ࡞੒ʣ ○ ࢓༁σʔλొ࿥ɺߋ৽࣌ʹ1೥෼ͷσʔλΛूܭͯ͠อଘ͢Δ DBपΓͷύϑΥʔϚϯεվળ

Slide 24

Slide 24 text

24 ● ৽ͨͳ໰୊΋ൃੜ ○ ొ࿥࣌ͷύϑΥʔϚϯε ○ ָ؍ϩοΫΤϥʔ ○ ΪϟοϓϩοΫʹΑΔϩοΫ଴ͪ ○ ϑΝϯτϜϦʔυʹΑΔσʔλෆ੔߹ ● ରࡦ ○ ूܭσʔλͷอଘΛผτϥϯβΫγϣϯͰඇಉظʹ ○ ࣄۀॴɺूܭ୯ҐͱͳΔଐੑΛΩʔͱͯ͠ॲཧΛγϟʔσΟϯάͯ͠ɺಉ͡΍ͭ͸௚ྻʹ·ͱΊ࣮ͯߦ͢Δ ࢓༁σʔλ ͷอଘ ूܭσʔλ
 ͷอଘ DBपΓͷύϑΥʔϚϯεվળ

Slide 25

Slide 25 text

KinesisΛར༻ͨ͠ूܭςʔϒϧͷߋ৽ Kinesis Stream RDS ूܭ Server ձܭfreee Server 1. ݩσʔλUpdate 2. ूܭϦΫΤετQueuing 3. Polling 4. Data Fetch 5. ूܭσʔλUpdate DBपΓͷύϑΥʔϚϯεվળ

Slide 26

Slide 26 text

26 ● ஫ҙ͍ͯ͠Δࣄ ○ ूܭςʔϒϧͷσʔλͷ੾Γํ ○ ొ࿥࣌ͷίετ૿ ○ ूܭσʔλදࣔͷϦΞϧλΠϜੑΛଛͳ͏ͨΊϢʔβʔ΁ͷࠂ஌ͳͲ ○ վળʹ͸͔ͳΓͷ͕͔͔࣌ؒΔ DBपΓͷύϑΥʔϚϯεվળ

Slide 27

Slide 27 text

27 DBपΓͷύϑΥʔϚϯεվળ 1. indexͰνϡʔχϯά 2. ΫΤϦͷมߋͰνϡʔχϯά 3. ςʔϒϧߏ੒ͷݟ௚͠ 4. σʔλͷ࣋ͪํͷݟ௚͠ 5. ػೳͷݟ௚͠

Slide 28

Slide 28 text

28 ● ಺༰ ○ ඞཁҎ্ʹ࣮ߦ͞Ε͍ͯΔՄೳੑΛٙ͏ ■ Homeը໘ΞΫηεͰݺ͹ΕΔ DBपΓͷύϑΥʔϚϯεվળ

Slide 29

Slide 29 text

29 ● ରԠ ○ ϢʔβʔΞΫγϣϯϕʔεͰͷऔಘʹมߋ ○ ඇಉظԽ ● ஫ҙ͍ͯ͠Δࣄ ○ ϏδωεαΠυ(Ϣʔβʔ)ͱͷίϛϡχέʔγϣϯ ○ ϢʔβʔϝϦοτͱӡ༻ίετʹ͍ͭͯ DBपΓͷύϑΥʔϚϯεվળ

Slide 30

Slide 30 text

30 ● slave΁ ○ Өڹͳ͍selectܥ͸slave΁ ○ write͕ଟ͍αʔϏε͸ replication latency ʹ஫ҙ ● N + 1ͷղফ ○ bullet ͷಋೖ ● ݕࡧ෦෼ͷ Elasticsearch Խ ○ େྔσʔλͷ৚݅ݕࡧ࣌ ○ ᐆດݕࡧ࣌ ● γϟʔσΟϯάͷݕ౼ DBपΓͷύϑΥʔϚϯεվળ

Slide 31

Slide 31 text

03 Section ·ͱΊ

Slide 32

Slide 32 text

32 ● νϡʔχϯά͸ద࣮ٓࢪ͠·͠ΐ͏ ● Ϛελʔσʔλͱͷڞଘ͸ՄೳͳݶΓආ͚·͠ΐ͏ ● ߏ੒ͷݟ௚͠͸ૣΊʹ͠·͠ΐ͏ ·ͱΊ

Slide 33

Slide 33 text

εϞʔϧϏδωεΛɺ ੈքͷओ໾ʹɻ