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

スマートニュースの世界進出を支えるログ解析基盤 #jawsdays #tech

スマートニュースの世界進出を支えるログ解析基盤 #jawsdays #tech

スマートニュースは昨年の 10/1 に米国版をローンチするにあたり、ログ解析基盤のリニューアルを行いました。日本に加えて米国やその他の国が入ってくることにより、単なるユーザ数の増加に加え、OS x 国 x タイムゾーン x 多種多様なメトリクスのような集計軸が増えることで、ログの前処理、集計、可視化に様々な工夫が必要になってきます。本セッションでは、会社の成長に応じたログ集計基盤の転換を振り返りながら、世界進出にあたってどのようなことを考え、どのようにログ集計基盤をリニューアルしていったか、および、そのログ解析基盤を支える Amazon EMR, Hive, Presto, Azkaban, Shib, Chartio などのツールについてお話します。

Avatar for Takumi Sakamoto

Takumi Sakamoto

March 22, 2015
Tweet

More Decks by Takumi Sakamoto

Other Decks in Programming

Transcript

  1. ΞϓϦ͔Βૹ৴͞ΕΔϩά w Ϣʔβͷߦಈ w χϡʔεهࣄΛಡΜͩ w Ϣʔβͷߦಈʹجͮ͘ϓϩύςΟ w هࣄͷ63-ɺهࣄͷ଺ࡏ࣌ؒ w

    ͦͷ΄͔ɺσόΠεͰ͔͠஌Γಘͳ͍৘ใ w σόΠε৘ใɺ04ͷόʔδϣϯɺΞϓϦͷόʔδϣϯ
  2. +40/ϩάͷྫ { "event" : "viewArticle", "timestamp" : "2014-11-28 12:45:14", "properties"

    : { "userId" : 1224434, "os" : "android", "country" : "Japan", "url" : "http://www.example.com/", "duration" : 224.8 } }
  3. ΞϓϦ͔Βαʔό΁ͷૹ৴ w όοϑΝϦϯάͯ͠όϧΫૹ৴ w ΫοΫύου͞Μͷ1VSFF ˞ తͳ w ΦϑϥΠϯ࣌͸ΦϯϥΠϯʹͳͬͨλΠϛϯάͰૹ৴ w

    ඞཁʹԠͯ͡αʔόଆͰ৘ใΛ෇༩ w "#ςετͷࢀՃঢ়گͳͲ ※ http://techlife.cookpad.com/entry/2014/11/25/132008
  4. Collect Process Visualize Store ΞϓϦͰϩάΛऔಘ "1*αʔόͰड৴ ετϨʔδʹӬଓԽ લॲཧ &5- 

    ूܭ #*πʔϧͳͲͰՄࢹԽ %BUB1JQFMJOFT ձࣾͷঢ়گ΍ٕज़ಈ޲ʹΑͬͯมԽ ࣌ܥྻͰৼΓฦͬͯΈΔ ˞ೖࣾҎલͷ࿩͸఻ฉͰ͢
  5. ౰࣌ͷ՝୊ͱղܾࡦ w ϩάղੳܥͷλεΫ͕ಛఆͷݸਓʹूத w ඇΤϯδχΞʹπϥ͍ɻαʔόʹ44)ʁ.POHP%#ʁ w 3BJMTͷՄࢹԽπʔϧͷϝϯςΛͰ͖Δਓ͕গͳ͍ w Ϗϡʔͷ௥Ճґཔʹ͍͍͚ͭͯͳ͍ w

    ͞ΒʹΞυϗοΫͳػೳ௥ՃͰϝϯςίετ͕૿େ w օ͕ࣗ༝ʹσʔλʹΞΫηεͰ͖ΔΑ͏ʹ͍ͨ͠ w $IBSUJP΍4IJCͳͲͷπʔϧΛಋೖ
  6. %BUB4DIFNB user_id action url 1 readArticle http://example.com/1 2 readArticle http://example.com/2

    3 readArticle http://example.com/3 Actions user_id os 1 ios 2 android 3 ios User OS user_id country 1 US 2 JP 3 GB User Location user_id identifier behavior 1 tutorial_04 A 2 tutorial_04 B 3 tutorial_04 A User A/B Test user_id version 1 2.2.1 2 1.9.8 3 2.2.0 User App Version
  7. SELECT date, behavior, count(distinct ac.user_id) as DAU, count_if(action='readArticle') as DPV

    FROM actions facts LEFT JOIN abtest_users dimensions ON facts.user_id = dimensions.user_id WHERE definition = 41 AND date BETWEEN '2015-01-01' AND '2015-01-31' GROUP BY date, behavior ORDER BY date, behavior ; "#ςετผͷ,1*ΛٻΊΔ
  8. ઃܭࢥ૝ w ։ൃऀɾඇΤϯδχΞɾܦӦऀ w ୭΋͕؆୯ʹେن໛ͳσʔληοτʹΞΫηεͰ͖Δ w 42- )2- Λڞ௨ݴޠʹ͢Δ w

    σʔλΛݟ͍ͨਓ͕ݟ͍ͨܗͰՄࢹԽ w ඞཁͰ͋Ε͹؆୯ʹυϦϧμ΢ϯ͍͚ͯ͠Δ w ӡ༻ऀ w ϩάΛઐ೚Ͱ΍Δਓ͸͍ͳ͍ɺӡ༻ίετ࠷খԽ
  9. ઃܭࢥ૝ w ετϨʔδ૚ͱΞϓϦέʔγϣϯ͸෼཭͓ͯ͘͠ w SF*OWFOUͰ"VSPSB΍/FUqJYͷηογϣϯ w ےͷΑ͍ઃܭͩͱײͨ͡ w Ϋϥ΢υΒ͍͠ɺ༷ʑͳϝϦοτ w

    ඞཁʹԠͯ͡ॊೈʹΩϟύγςΟ௥Ճ͕Մೳ w ͍ͭམͪͯ΋͍͍ͷͰεϙοτΠϯελϯεΛ׆༻Ͱ͖Δ w ϛυϧ΢ΣΞͷόʔδϣϯΞοϓݕূ͕؆қʹ
  10. )JWF w &.3Ͱ)JWFͷΫϥελΛ্ཱͪ͛Δ w &YUFSOBM5BCMFʹύʔςΟγϣϯΛ௥Ճ͍ͯ͘͠ w 'BDUT w 4ʹอଘ͞ΕͯΔੜϩάͷύεΛࢦఆ͢Δ͚ͩ w

    %JNFOTJPOT w 3%4ͷUBCMFEVNQΛ4ʹஔ͖ɺͦͷύεΛࢦఆ w ΧϥϜφετϨʔδʹม׵ͯ͠4ʹอଘ w 03$1BSRVFUͳͲͷσʔλղੳʹదͨ͠ϑΥʔϚοτ
  11. )JWFΫϥελͷىಈ Old Hive Cluster New Hive Cluster User A User

    B MetaStore Archive Bucket Analysis Bucket launch launch read write )JWFͷ.FUBTUPSF͸3%4Ͱڞ༗͍ͯ͠Δ ৽͘͠ΫϥελΛىಈͯ͠4ͷॻ͖ࠐΈઌΛมߋ͢Ε͹ݕূ͕༰қ read write
  12. )JWFʹΑΔ&5- -- External Table ͱͯ͠ɺFluentd ͷϩάܗࣜΛఆٛ CREATE EXTERNAL TABLE IF

    NOT EXISTS raw_actions ( timestamp STRING, tag STRING, data STRING ) PARTITIONED BY ( date STRING, hour STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION 's3://smartnews/log/production/raw_actions/'; ; -- ύʔςΟγϣϯΛ௥Ճ͢Δ ALTER TABLE raw_actions ADD IF NOT EXISTS PARTITION (`date`='${DATE}', `hour`='${HOUR}') LOCATION 's3://smartnews/log/production/raw_actions/date=${DATE}/hour=${HOUR}'; 'MVFOUEͷϩάΛಡΉͨΊͷςʔϒϧΛఆٛ͠ɺύʔςΟγϣϯΛ௥Ճ
  13. )JWFʹΑΔ&5- -- ΧϥϜφετϨʔδͷ External Table Λఆٛ CREATE EXTERNAL TABLE IF

    NOT EXISTS orc_actions ( timestamp INT, user_id INT, os STRING, country STRING, action STRING, data STRING ) PARTITIONED BY ( date STRING, hour STRING ) STORED AS ORC LOCATION 's3://smartnews/log/production/raw_actions/'; TBLPROPERTIES ("orc.compress"="SNAPPY"); ΧϥϜφετϨʔδͷςʔϒϧΛఆٛ
  14. -- ΧϥϜφετϨʔδͷ External Table ʹΠϯϙʔτ INSERT OVERWRITE TABLE orc_actions PARTITION

    (`date` = '${DATE}', `hour` = '${HOUR}') SELECT user_id, timestamp, COALESCE(os, "undefined"), COALESCE(country, "undefined"), action modify_json(data, 'unnecessary1', 'unnecessary2') FROM raw_actions LATERAL VIEW json_tuple( raw_actions.json, 'userId', 'timestamp', 'platform', 'country', 'action', 'data' ) a as user_id, timestamp, os, country, action, data WHERE date = '${DATE}' and hour = '${HOUR}' ORDER BY os,country, action, user_id; )JWFʹΑΔ&5- KTPO@UVQMFؔ਺΍FYQMPEFؔ਺ͳͲͰ+40/Λల։͢Δ ࣗ࡞6%'ͰɺಛఆϑΟʔϧυͷ+40/͔ΒෆཁͳϑΟʔϧυ࡟আ
  15. "[LBCBO w δϣϒϑϩʔ؅ཧπʔϧ w -JOLFE*O͕044ͱͯ͠ެ։͍ͯ͠Δ w ओͳػೳ w ґଘఆٛɺґଘؔ܎ͷՄࢹԽ w

    δϣϒͷఆظ࣮ߦɺΞυϗοΫ࣮ߦɺϦτϥΠ w ੒ޭɾࣦഊ࣌ʹϝʔϧ௨஌
  16. "[LBCBOͷ͍͍ͱ͜Ζ w δϣϒ؅ཧ͕͠΍͍͢ w δϣϒͷґଘؔ܎ͱͲ͜·Ͱ׬͔ྃͨ͠ͷՄࢹԽ w δϣϒΛίʔυͱͯ͠؅ཧ w λΠϜΞ΢τ 4-"

    ઃఆ ྫ࣌ؒͰऴྃ͠ͳ͚Ε͹௨஌  type=command command=hive-wrapper -d 2015-02-02 -q query_c dependencies=query_a, query_b δϣϒఆٛϑΝΠϧͷྫ
  17. "[LBCBOΛ࢖͏্Ͱͷ޻෉ Production Hive Cluster Development Hive Cluster User A User

    B Archive Bucket Analysis Bucket read write submit job register job beeline azkaban Temp Hive Cluster &.3ͷλά͔ΒCFFMJOFʹ౉͢ϗετ໊ΛٻΊ࣮ͯߦ
  18. 1SFTUPͷ͍͍ͱ͜Ζ w ӡ༻͕Χϯλϯ w "84͕&.3ͷCPPUTUSBQBDUJPOΛఏڙ w IUUQTHJUIVCDPNBXTMBCTFNSCPPUTUSBQBDUJPOT w ࣾ಺޲͚ʹҰ෦֦ு͍ͯ͠Δ w

    #MVF(SFFO%FQMPZNFOUͰόʔδϣϯΞοϓ w ৽όʔδϣϯ͕ग़ͨΒ৽ͨʹΫϥελىಈ w ݕূͯ͠໰୊ͳ͚Ε͹ɺ%/45BHΛ੾Γସ͑Δ
  19. $IBSUJP w ༷ʑͳσʔλιʔεΛ૊Έ߹ΘͤͯμογϡϘʔυ࡞ΕΔ w όοΫΤϯυ͕੾Γସ͑ΒΕΔ,JCBOBͷΠϝʔδ w .Z42-ɺ3FETIJGUɺ(PPHMF"OBMZUJDT #JH2VFSZ FUD w

    1SFTUP͸1SFTUPHSFTPSTTIUVOOFMͰ઀ଓ w ՄࢹԽपΓͷ࢓ࣄΛָʹͯ͘͠ΕΔ w υϥοάυϩοϓ42-Ͱνϟʔτ࡞੒ w 6*΋ΩϨΠͰຖ೔ݟΔؾ͕ى͖Δ
  20. શ෦#2೚ͤͰ͍͍ͷ͔ʁ w ԿΛࣗ෼ͨͪͰ΍ΓɺԿΛଞਓʹ೚ͤΔͷ͔ҙࣝ͢Δ w ࣗ෼Ͱ΍Ε͹ܦݧ΍஌͕ࣝ஝ੵ͞Ε͍ͯ͘ w ଞਓʹ೚ͤΔͱֶͼ͸গͳ͍͕ίετ͸Լ͕Δ w ๻Βʹͱͬͯ͸σʔλΛѻ͏ٕज़͸େࣄʹ͢΂͖ཁૉ w

    ͋Δఔ౓͸ࣗ෼ͨͪͰ΋௥͍͔͚Δ΂͖ w ݁Ռͱͯ͠)JWFNBMM΍4QBSL.-MJC͕ར༻Ͱ͖ͨΓ w Ͱ΋ɺ#2͕׆༻Ͱ͖Δ෦෼͸ੵۃతʹ࢖͍ͬͯ͘༧ఆ w 6%'΋ग़Δͱ͍͏΢ϫα
  21. 4NBSU/FXT5(*' w 4NBSU/FXT5(*'ͱ͸ʁ w ֎෦ͷਓΛট଴ͯ͠ΦϑΟεͰަྲྀձ w ඒຯ͍͠έʔλϦϯάͱΞϧίʔϧ͕ग़·͢ʢແྉʂʣ w ڵຯ͕͋Δํ͸!UBLVT·Ͱ࿈བྷ͍ͩ͘͞ w

    ࠓ೔ͷ࿩Λ΋ͬͱৄ͘͠ฉ͖͍ͨ w ΞϓϦͰ"#ςετΛ͕Γ͕Γճ͢࿩͕ฉ͖͍ͨ w ޿ࠂαΠυͷϩά΍"#ςετͷ࿩͕ฉ͖͍ͨ