Share
Embed
分散システム内のプロセス間の関係性に着目したObservabilityツールの設計と実装 / Transtracer CNDK2019
CloudNative Days KANSAI 2019
Yuuki Tsubouchi (yuuk1)
November 28, 2019
Transcript
55 slides
-
͘͞ΒΠϯλʔωοτ גࣜձࣾ (C) Copyright 1996-2019 SAKURA internet Inc ͘͞ΒΠϯλʔωοτ ݚڀॴ
ࢄγεςϜͷϓϩηεؒͷؔੑʹ ணͨ͠Observabilityπʔϧͷઃܭͱ࣮ ͘͞ΒΠϯλʔωοτݚڀॴ Yuuki Tsubouchi / @yuuk1t CloudNative Days Kansai 2019 2019.11.28 -
2 ࣗݾհ Yuuki Tsubouchi / Ώ͏͏͖ https://yuuk.io/ ܦྺ גࣜձࣾͯͳ WebΦϖϨʔγϣϯΤϯδχΞɾSRE
͘͞ΒΠϯλʔωοτגࣜձࣾ ͘͞ΒΠϯλʔωοτݚڀॴ ݚڀһ WebαʔϏεͷ ։ൃɾӡ༻ Πϯλʔωοτ ج൫ٕज़ݚڀ 5 ݱࡏ Site Reliability Engineering(SRE) Researcher @yuuk1t ใॲཧֶձ Πϯλʔωοτͱӡ༻ٕज़ݚڀձ ӡӦҕһ ηΩϡϦςΟɾΩϟϯϓશࠃେձߨࢣ id:y_uuki -
7 ࢄΞϓϦέʔγϣϯͷෳࡶԽͷഎܠ ظؒͷαʔϏεఏ ڙதͷػೳՃ Ϣʔβʔ͔ΒͷΞΫ ηε૿Ճ ୯ҰͷαʔϏεࣄۀ ऀ͕ෳͷαʔϏε Λఏڙ (SNS,ECαΠτͳͲ)
༻్ಛԽͷϛυϧΣΞՃ ৽چγεςϜͷࠞ߹ εέʔϧΞτʹΑΔϗετ ͷ૿Ճ ෳͷαʔϏεͷҰ෦Λڞ༗ (Ϣʔβʔೝূج൫ͳͲ) Microservices -
9 ɾL7ͷϦΫΤετ͕γεςϜͷͲͷܦ࿏ΛͨͲΔ͔Λ͢Δ ɾ௨৴ܦ࿏্ͰϦΫΤετʹࣝผࢠΛຒΊࠐΉॲཧͱτϨʔεσʔλ Λه͢Δॲཧ͕ඞཁ ɾԆΦʔόϔου: ࣝผࢠຒΊࠐΈॲཧͷͨΊͷΦʔόϔου ɾِӄੑ: ࣄલʹґଘΛѲ্ͨ͠ͰࣝผࢠΛຒΊࠐΉͨΊɼະͷ ϓϩηεΛൃݟ͢Δతʹద͞ͳ͍ ɾܭଌ४උίετ:
طଘͷίϯϙʔωϯτʹͷͨΊͷॲཧΛՃ ͢Δख͕ؒ͋Δ طଘͷࣗಈٕज़ - ࢄτϨʔγϯά -
10 ՝Λղܾ͢ΔΞΠσΞ త: ཧऀʹͱͬͯະͷϓϩηεͱͷґଘΛ͢Δ ՝: 1.ґଘͷِӄੑ 2.ԆΦʔόʔϔου Linux OS Kernel
Process Process TCP/UDP Flows … . . . User ιέοτΛ ࢹ ղܾ: TCP/UDPଓͷऴ Ͱ͋ΔιέοτΛ ࢹ͠ϑϩʔΛࣗಈ ɾιέοτΛ͍ͬͯ͑͞Ε ཏతʹՄೳ ɾιέοτͷࢹϓϩηε ͷ௨৴ͱಠཱ͍ͯ͠Δͨ ΊɼԆΦʔόϔουͳ͍ -
14 ͜͜10΄ͲͷࢄΞϓϦέʔγϣϯͷߏ External DNS Server Application flow DNS flow RDB
server Application server Web server Internal DNS server Full text search server KVS server Batch server ɾWeb3ߏʹՃ͑ͯɼNoSQLαʔόͳͲͷՃ -
15 ୯ҰͷHost/Podͷߏ Log collector agent Main network process Monitoring agent
Proxy User Authentication DNS forwarder ɾϦόʔεϓϩΩγɼαΠυΧʔϓϩΩγͷଓཧͷҕৡ ɾϗετಉډܕͷϩάऩूΤʔδΣϯτɼϞχλϦϯάΤʔδΣϯτ -
18 Observability (Մ؍ଌੑ) ࢀߟ: [Sridharan 17] Cindy Sridharan, Monitoring in
the time of Cloud Native, Velocity, 2017. Low Observability Human Systems Monitoring Systems High Observability Logs Metrics Alerting Checking Investigating Human Systems Monitoring Systems Logs Metrics Alerting Checking Investigating Traces Observability Systems top, sar, iostat, tail … -
19 SREͱ৴པੑΛ੍ޚ͠ɼมߋΛ্ͤ͞Δٕज़ମܥ SREͷจ຺͔ΒΈΔObservability Reliability 100% 99% ੍ޚ෯ ҰൠʹγεςϜมߋ࣌ʹ৴པੑΛԼͤ͞ΔϦεΫ͕͋Δ ͍͔ʹϦεΫΛখ੍ͯ͘͞͠ޚ෯Λখ͘͞Ͱ͖Δ͔͕伴 ObservabilityΛߴΊΔ͜ͱʹΑΓ
ɾϦεΫͷنΛ༧ଌͰ͖Δ (Transtracerͷత) ɾൃੜͨ͠ϦεΫΛ࠷খݶʹཹΊΒΕΔ -
21 Tracingٕज़ͷྨ ϦΫΤετϕʔε Ξϓϩʔν ΞϓϦέʔγϣϯͷϦΫΤετ͕ Ͳͷ௨৴ܦ࿏ΛͨͲΔ͔Λ͢Δख๏ ίωΫγϣϯϕʔε Ξϓϩʔν ऴϗετ্Ͱτϥϯεϙʔτଓͷঢ়ଶΛ औಘ͢Δ͜ͱʹΑΓґଘؔΛ͢Δख๏
ύέοτϕʔε Ξϓϩʔν ϗετ্εΠον্ͰύέοτϔομΛ؍ଌ ͢Δ͜ͱʹΑΓɼ ґଘؔΛ͢Δख๏ -
22 ɾLayer7ͷ֤ϦΫΤετʹࣝผࢠΛׂΓৼΓɼޙଓͷϦΫΤετʹຒ ΊࠐΜ্ͩͰɼޙଓͷϓϩηεൖͤ͞Δ ɾࣝผࢠΛཔΓʹɼϦΫΤετ͕γεςϜͷͲͷϓϩηεΛܦ༝͠ ͯॲཧ͞Ε͔ͨΛ ɾར: ΞϓϦέʔγϣϯॲཧ༰L7ϓϩτίϧͷใΛՄೳ ɾ՝: ԆΦʔόϔουɼِӄੑɼܭଌ४උίετ (p.8ͱಉ༷)
ϦΫΤετϕʔεΞϓϩʔν M. Y. Chen, et al., Pinpoint: Problem Determination in Large, Dynamic Internet Services, IEEE/IFIP International Conference on DSN, pp. 595–604 2002. P. Barham, et al., Magpie: Online Modelling and Performance-aware Systems, HotOS, pp. 85–90 2003. R. Fonseca, et al., X-Trace: A Pervasive Network Tracing Framework, USENIX Conference on NSDI, pp. 20–20 2007. B. H. Sigelman, et al., Dapper, a Large-Scale Distributed Systems Tracing Infrastructure, Technical report, Google 2010. -
23 ɾݱࡏͷࢄτϨʔγϯάٕज़(OpenTelemetryͳͲ)ͷݪܕ ɾΦʔόʔϔουͱΞϓϦέʔγϣϯಁաੑ͕ಛ Google Dapper [Sigelman 2010] [Sigelman 2010]: B.
H. Sigelman, et al., Dapper, a Large-Scale Distributed Systems Tracing Infrastructure, Technical report, Google 2010. Figure 5. Dapper collection pipeline ɾదԠతαϯϓϦϯά ɾτϥϑΟοΫͷྲྀྔʹԠͯ͡Ϩʔτ มߋՄೳ ɾRPCܭଌϥΠϒϥϦ ɾεύϯͷ࡞ɼϩάΛॻ͖ग़͢ɼα ϯϓϦϯά͢ΔC++ͷϥΠϒϥϦ -
24 ɾϒϥβɼϞόΠϧΞϓϦɼόοΫΤ ϯυΛؚΉe2eτϨʔγϯά ɾ՝1. ec2ͷੑೳσʔλ࣮ߦϞσϧ ཻ࣭͕ҟछࠞ߹ ɾ՝2. େͳτϨʔεσʔλ ɾελοΫશମͷੑೳσʔλΛநग़͢Δ ͨΊͷύΠϓϥΠϯΛߏங
ɾύΠϓϥΠϯͷ֤ஈ֊ͰΧελϚΠζ Facebook Canopy [Kaldor 2010] [Kaldor 2017]: J. Kaldor, et al., Canopy: An end-to-end performance tracing and analysis system, USENIX SOSP, 2017. Dapperͷ֦ு: ҟछࠞ߹σʔλͷ݁߹ΛՄೳ Figure 2. -
25 ɾLinuxͷύέοτϑΟϧλ(iptables)Λར༻ͯ͠ɼLayer4ଓΛݕग़ ɾiptablesͰଓ։࢝ϩάΛऩू͠ɼϩάίϨΫλͰதԝͷσʔλ ϕʔεʹอଘ ɾLinuxΧʔωϧͷL4௨৴ػߏΛར༻͢ΔݶΓɼґଘΛՄೳ ɾ՝1: LinuxΧʔωϧͷύέοτ୯Ґͷॲཧʹհೖ͢ΔͨΊɼϓ ϩηεͷ௨৴ʹԆΦʔόϔουΛ༩͑Δ ɾ՝2: Ұ୴ӬଓԽ͞ΕͨଓΛ్த͔Βݕग़Ͱ͖ͳ͍
ɾ՝3: ϗετ୯ҐͰͷͰ͖Δ͕ϓϩηε୯ҐͰͰ͖ͳ͍ ίωΫγϣϯϕʔεΞϓϩʔν [Clawson 15] [Clawson 15] J. K. Clawson, Service Dependency Analysis via TCP/UDP Port Tracing, Master’s thesis, Brigham Young University-Provo 2015. -
26 ɾLayer3ͷύέοτΛͱʹґଘΛ͢Δ ɾطଘͷτϥώοΫ͔Βύ έοτΛऩू͠ɼύέοτϔομ্ͷૹ৴ ݩͱૹ৴ઌͷϗετͱϙʔτɼύέοτͷૹड৴ͷ࣌ࠁͳͲͷใ Λղੳ͢Δ ɾΫϥυ্ͷ࣮ڥͰͷར༻ࣄྫ·ͩݟͨ͜ͱ͕ͳ͍ ɾৄࡉলུ ύέοτϕʔεΞϓϩʔν P.
Bahl, et.al.: Towards Highly Reliable Enterprise Network Services via Inference of Multi-Level Dependencies, ACM SIGCOMM Review, Vol. 37, No. 4, pp.13–24 2007. X. Chen, et.al.: Automating Network Application Dependency Discovery: Experiences, Limitations, and New Solutions, USENIX Symposium on OSDI, pp.117–130 2008. P. Lucian, etl.al.: Macroscope: End-Point Approach to Networked Application Dependency Discovery, CoNEXT, pp.229–240 2009. A. Natarajan, et.al.: NSDMiner: Automated Discovery of Network Service Dependencies, IEEE INFOCOM, pp. 2507–2515 2012. A. Zand, et.al.: Rippler: Delay Injection for Service Dependency Detection, IEEE INFOCOM, pp. 2157–2165 2014. -
27 ɾܭଌ४උίετ ɾطଘͷίϯϙʔωϯτʹ ͷͨΊͷॲཧΛՃ͢Δखؒ ɾِӄੑ ɾखಈͰॲཧΛՃ͢Δͨ Ίɼཏੑʹ͚ܽΔ ɾܭଌ४උίετʹΑΓҰ෦ͷ ΈͷಋೖʹͳΓ͕ͪ ֤Ξϓϩʔνͷ՝ཧ
ϦΫΤετϕʔεΞϓϩʔν ίωΫγϣϯϕʔεΞϓϩʔν ԆΦʔόϔου: ௨৴ܦ࿏தʹՃͷॲཧΛڬΈࠐΉΦʔόϔου ɾِӄੑ ɾҰ୴ӬଓԽ͞ΕͨଓΛ్ த͔Βݕग़Ͱ͖ͳ͍ ɾ୯Ґ͕ϓϩηεͰͳ͘ IPΞυϨε -
30 1. ܭଌ४උίετͷݮ ɾίωΫγϣϯϕʔεΞϓϩʔνͷ࠾༻ 2. ϓϩηε୯ҐͰͷґଘؔ ɾଓऴͰ͋Διέοτ͔ΒଓใΛऔಘ 3. ଓͷӬଓԽڥʹ͓͚Δِӄੑͷݮ ɾιέοτ͕อ࣋͢ΔଓใΛϙʔϦϯάࢹ
4. ԆΦʔόʔϔου ɾιέοτࢹϓϩηεॲཧͱಠཱ͍ͯ͠Δ Transtracerͷཁ݅ͱղܾ -
31 TranstracerͷγεςϜߏ Host 1 Host 2 Host N CMDB Tracer
Tracer Tracer Systems Administrator ɾϗετPod্ʹTracerΤʔδΣϯτΛ ஔ ɾ֤ΤʔδΣϯτऔಘͨ͠ଓใΛ CMDB(Connection Management DataBase)ʹอଘ ɾγεςϜཧऀCMDBʹΞΫηε͠ɼ ෳͷϗετPodʹ·͕ͨΓґଘؔ Λऔಘ -
32 TCPͷଓใͷऩू Host Kernel Process Process TCP/UDP Connections … Tracer
Polling ɾTracerϓϩηε͕LinuxΧʔωϧʹ͍߹Θ ͤɼTCP/UDPιέοτใΛϙʔϦϯάऔಘ ɾଓΛऴ͢ΔOSϓϩηεใ͋Θͤͯ औಘ ɾιέοτใ: /proc/net/tcpNetlink sock_diag ɾϓϩηεใ: /proc/<pid>/{stat,fd} . . . ॲཧʹհೖ͠ͳ͍ͨΊ Φʔόʔϔου -
33 TCPଓͷґଘͷํͷܾఆ Host Y Port N Process B CONNECT Host
X Port M Process A LISTEN ɾଓΛཁٻ͢ΔϗετYɼଓΛड͚͚ΔϗετXʹґଘ͢Δ ɾϗετY͔ΒΈͯѼઌϙʔτ͕LISTENϙʔτMͰ͋ΕɼHost Y ͔ΒଓΛཁٻ͍ͯ͠Δ͜ͱ͕Θ͔Δ ɾLISTENϙʔτɼϗετXͷOSʹ͍߹Θͤͯऔಘ͢Δ -
34 ɾͯ͢ͷଓใΛऩू͢ΔͱɼCMDBʹ֨ೲ͢Δσʔλྔ͕େ͖͘ ͳΔͨΊɼͳใΛݮ͢Δ ɾΤϑΣϝϥϧϙʔτ: Χʔωϧ͔ΒׂΓͯΒΕΔϥϯμϜͳૹ৴ݩ ϙʔτ ɾಛఆͷLISTENϙʔτෳͷΤϑΣϝϥϧϙʔτ͔Βଓ͞ΕΔ ɾ͜ΕΒͷϑϩʔΛू͠ɼ1ݸͷूϑϩʔͱΈͳ͢ ΤϑΣϝϥϧϙʔτͷू Host
Port Process Port Port Host Port Process 1ݸͷϑϩʔ ͱͯ͠ू LISTEN ΤϑΣϝϥϧ -
36 ߏιϑτΣΞ ɾCMDB: PostgreSQL 11.3 ɾttracerd: TracerΤʔδΣϯτ ɾttctl: CMDBʹ͍߹ΘͤΔCLI Host/Pod
PostgreSQL ttracerd ttctl CMDB Send trace data -
37 Transtracerͷར༻ྫ $ ttctl --dbhost 10.0.0.20 --ipv4 10.0.0.10 10.0.0.10:80 (’nginx’,
pgid=4656) ᵋ<-- 10.0.0.11:many (’wrk’, pgid=5982) 10.0.0.10:80 (’nginx’, pgid=4656) ᵋ--> 10.0.0.12:8080 (’python’, pgid=6111) 10.0.0.10:many (’fluentd’, pgid=2127) ᵋ--> 10.0.0.13:24224 (’fluentd’, pgid=2001) 10.0.0.10 nginx 10.0.0.11 wrk 10.0.0.12 python 10.0.0.13 fluentd :80 fluentd :8080 :24224 -
38 ϓϩηεͷσʔλߏ ᶃ LinuxͷϓϩηεάϧʔϓΛ ϊʔυͷ࠷খ୯Ґͱ͢Δ ᵓᴷnginx,627,627 ᴹ ᵓᴷnginx,628,627 ᴹ ᵋᴷnginx,629,627
$ pstree -apg | grep nginx ᶄ (machine-id, ipv4, pgid, pname) ͰϓϩηεʹҰҙ੍Λ͔͚Δ ϓϩηε࠶ىಈ͢ΔͱID͕มԽ ͯ͠͠·͏ͨΊɼ͍߹Θͤ࣌ʹ pgid͕ҟͳΔͷΛॏෳഉআ IPΞυϨεͷ࠶ར༻ʹରԠ͢Δͨ Ίʹmachine-idΛར༻ (machine-idະ࣮) -
39 ଓཧͷͨΊͷσʔλߏ ᶅ ActiveͱPassiveʹϊʔυΛྨ ᶆ Active => PassiveͷϑϩʔΛอଘ Active Passive
ActiveଆͷϙʔτूࡁΈ ͳͷͰอ࣋͠ͳ͍ (p.33) PassiveଆͷΈϦοεϯϙʔτ Λอ࣋ Process Passive Active Port N Port M Active ಉҰϓϩηε͕Activeʹ PassiveʹͳΓ͑Δ ಉҰϓϩηε͕ෳͷϙʔτ ΛϦοεϯ͢Δ͜ͱ͕͋Δ -
40 CMDBͷςʔϒϧεΩʔϚ(ൈਮ) ςʔϒϧ໊ Ωʔ આ໌ processes process_id ipv4 pgid pname
ϢχʔΫ੍ ϓϩηεΛࣝผ͢ΔओΩʔ ϓϩηε͕ಈ࡞͢Δϗετ্ͷIPΞυϨε LinuxͷϓϩηεάϧʔϓID ϓϩηε໊ (ipv4, pgid, pname) active_nodes node_id process_id ϢχʔΫ੍ ϊʔυΛࣝผ͢ΔओΩʔ processesςʔϒϧʹର͢Δ֎෦Ωʔ (process_id) passive_nodes node_id process_id port ϢχʔΫ੍ ϊʔυΛࣝผ͢ΔओΩʔ processesςʔϒϧʹର͢Δ֎෦Ωʔ Ϧοεϯϙʔτ൪߸ (process_id, port) flows flow_id active_node_id passive_node_id ϢχʔΫ੍ ϊʔυಉ࢜ͷଓΛࣝผ͢ΔओΩʔ active_nodesςʔϒϧͷ֎෦Ωʔ passive_nodesςʔϒϧͷ֎෦Ωʔ (active_node_id, passive_node_id) -
43 ࣮ݧڥ ߲ ༷ Client CPU Memory Benchmarker Intel Xeon
CPU E5-2650 v3 2.30GHz 2core 1 GB wrk 4.1.0-4 Server CPU Memory HTTP Server Intel Xeon CPU E5-2650 v3 2.30GHz 4core 1GB nginx 1.17.3 CMDB CPU Memory Database Intel Xeon CPU E5-2650 v3 2.30GHz 1core 1 GB PostgreSQL 11.3 ɾΠϯελϯεͯ͘͢͞ΒͷΫϥυ্ʹߏங ɾLinux Kernel 4.15 (Ubuntu Server 18.04.3 LTS) -
44 ɾNormal: ॲཧ͕ͳ͍ঢ়ଶ ɾTranstracer: TranstracerʹΑΔॲཧ͕͍ͬͯΔঢ়ଶ ɾiptables NEWϑΟϧλํࣜ: ৽نଓͷΈϩάΛग़ྗ ɾ-I INPUT
-m state --state NEW -m limit -j TRACE-LOG ɾiptables ESTBϑΟϧλํࣜ: ଓཱ֬தʹΓͱΓ͞ΕΔύέοτ ͷϩάΛͯ͢ग़ྗ ɾ-I INPUT -m state --state ESTABLISHED -m limit -j TRACE-LOG ֤࣮ͷઃఆ -
45 ԠԆΦʔόʔϔου 50 100 150 200 250 300 350 400
450 500 5000 10000 15000 20000 Average Latency (ms) Connections Normal 93.1 191.6 279.3 353.8 Transtracer 94.7 188.3 291.8 401.2 ESTB filter 115.0 236.0 359.0 462.5 NEW filter 113.1 214.4 310.0 449.3 ɾNormalʹରͯ͠transtracer͕ 1.7~13.4%ͷΦʔόϔου૿Ճ ɾiptables࣮ͷESTBϑΟϧλํࣜ ʹରͯ͠ɼtranstracer͕13-20% ͷΦʔόϔουݮগ -
46 CPUར༻Φʔόʔϔου 0 10 20 30 40 50 60 70
80 90 100 5000 10000 15000 20000 0 50 100 150 200 250 300 350 400 450 500 CPU usage (%) Reading sockets time(ms) Connections ttracerd’s CPU usage 13.2 23.0 34.2 44.4 ESTB filter’s CPU usage 72.2 75.9 78.8 78.6 Reading sockets time 102.3 199.1 317.8 408.6 ɾ20,000ଓʹ͓͍ͯɼTranstracer ͷCPUར༻44.4%ɼESTBϑΟϧ λํࣜͷCPUར༻78.6% ɾ43.5%ͷCPUར༻ͷݮ ɾNEWϑΟϧλํࣜଓཱ֬࣌ͷ ΈCPUΛར༻͢ΔͨΊ༗ར -
47 ɾ20,000ଓ࣌ʹϙʔϦϯάؒ ִΛ૿Ճͤ͞ΔͱCPUར༻ ͕Ͳͷఔݮ͞ΕΔ͔ ɾ5ඵҎͷ໋ͳଓΛݕग़Ͱ ͖ͳ͘ͳΔՄೳੑ͕͋Δ͔Θ Γʹ8.6%·ͰݮՄೳ ɾHTTP/2ͷΑ͏ʹଓΛӬଓԽ ͢ΔڥͰ໋ͳଓΛݟ ಀͯ͠ʹͳΒͳ͍
ϙʔϦϯάִؒͱCPUར༻ͷؔ 0 5 10 15 20 25 30 35 40 45 50 55 1 2 3 4 5 CPU usage (%) Polling interval CPU usage 44.4 21.6 13.0 10.8 8.6 -
50 ɾϙʔϦϯά͕ݟಀ໋͢ͳ ଓΛݕग़͢ΔͨΊʹετ ϦʔϛϯάΛΈ߹ΘͤΔ ɾeBPFʹΑΓɼconnect(2)ͱ accept(2)ΠϕϯτΛऔಘ ͠ɼϑϩʔใΛऔಘ͢Δ ɾUDPͷ߹send_msg(2), recv_msg(2)Πϕϯτ ετϦʔϛϯάʹΑΔଓͷݕग़
Linux Host Kernel Process Process TCP/UDP Flows … . . . User Streaming Tracer -
51 ɾiovisor/bccͷtcpacceptͰɼඇӬଓԽڥͰͷෛՙ࣮ݧ ɾwrk (HTTP KeepAlive off)Ͱಉ࣌ଓ1000ͰnginxʹϕϯνϚʔΫ ɾCPUར༻45~50%/coreఔ ɾԠԆͷΦʔόϔου༗ҙͳѱԽݟΒΕͳ͔ͬͨ ɾeBPFͷΠϕϯτΛͯ͢Ϣʔβʔϥϯυʹίϐʔ͍ͯ͠Δ͜ͱ͕ CPUෛՙ͕ߴ͍ཁҼ͔͠Εͳ͍
eBPFͷετϦʔϛϯάෛՙͷ༧උ࣮ݧ ৄࡉ࣮ݧϊʔτ https://www.notion.so/yuuk1/iovisor-bcc-tcpconnect-tcpaccept-af2d1fdce35c49fb945b548db373213d -
TranstracerͰղܾͰ͖ͦ͏ͳ՝ ͕͋Γ·ͨ͠Β ϑΟʔυόοΫ͍͚ͨͩΔͱتͼ·͢ Thank id:masayoshi / @yoyogidesaiz for their ideas
related with this presentation.