날고싶은 커피향
Redis, MongoDB 그리고 MySQL 과 함께하는 모바일 애플리케이션 서비스에서의 로그 수집과 분석 관련된 자료입니다.
내용 참고 하시기 바랍니다.
Transcript
1. Redis, MongoDB 그리고 MySQL모바일 애플리케이션 서비스에서의 로그 수집과 분석 박현우 (@lqez) / 스마트스터디
2. lqez
3. NoSQL
4. NoSQL?NoRDB?
5. NoSQL = Not only SQL ≠ Do not use SQL via http://nosql-database.org/
6. In-memory Document Store ACIDRedis, MongoDB 그리고 MySQL NoSQL RDBMS
7. In-memory Document Store ACIDRedis, MongoDB 그리고 MySQL Salvatore NoSQL Dwight Monty RDBMS
8. vs
9. 10년 전으로 돌아갑니다.
10. “로그를 보려면 한 달 정도 걸립니다.그래도 어제 동접은 나오잖아요.” “동접이 중요한게 아닙니다. 왜, 언제 이탈하는지 알아야죠.”
11. 1일 최소 5일 (반복됨)지표요청 로그가 있는가? 스키마 설계! DBA가 반려 1 + 5 = 6일
12. 1일 2일 3일테이블 생성 프로토콜 추가/테스트 점검일 대기 서버 재시작 1 + 2 + 3 = 6일
13. 최소 5일 1일서버팀에 로그 요청 CSV로 받음 엑셀에 넣음 끝! 5 + 1 = 6일
14. 좀 과장되게 얘기해서6 + 6 + 6 = 18일
15. IL E D FA엑셀 65,536행 초과
16. 뭐가 문제인지 모르겠어
17. 2년 뒤목마른 사람이 우물을 팝니다
18. WBERS•LAMP 기반 웹 서비스•스키마 저작 도구 ≒ phpMyAdmin•HTTP / HTTPS로 로그 쌓기•클라이언트 덤프 수집 / 분석•자주 사용하는 스키마 / 쿼리 저장•일 / 월 / 버전 단위 테이블 파티셔닝
19. 덤프 수집기 & 분석기 쿼리 작성
20. 1일 1일지표요청 로그가 있는가? 스키마 설계 클라이언트 수정 1 + 1 = 2일
21. 1일로그 확인 쿼리 작성 지표 도출 끝! 1일
22. 거짓말 조금 보태서2 + 1 = 3일
23. 30일 내에 승부via KTH H3 2012 기획/디자인/개발자 모두 알아야 하는 대박앱의 비밀’, http://dev.kthcorp.com/2012/11/02/h3-2012-ebook/
24. LOG•필요한 사람이 설계해야 하고,•필요한 시점에 수집해야 하고,•필요한 시기에 활용해야 한다.
25. 그래도 동접이 떨어져요
26. 괜찮아! 망했어요 흑흑 mysqldump -uroot -p -e --opt -c log | gzip -c log-20121114.sql.gz로그를 잘 쌓으면 망해도 준치 다음 번 서비스 지표로 활용 가능
27. 단점•MySQL은 지속적으로 확장하기 어렵다.•어쨌든 스키마를 매번 만들어야 한다.•쌓는 중엔 형식 변경 비용이 비싸다.
28. 모바일 환경•항상 로그 전송이 가능한 상태는 아님.•JSON 형태로 로컬 저장소에 보관하다,•n개까지 모으거나, 필요한 경우 즉시 발송.•서버에서는 받은 후, 낱개로 풀어서 저장.
29. 장애 대응•HTTP / HTTPS 로 전송•200 OK 응답을 받지 못한 경우 장치에 보관•IDC 이전시 효과적으로 활용
30. Speaker’s note• 기존에 하던 방식과 비슷하지만, 서버의 응답을 확인해 서 200 OK 를 받지 않으면 로컬 큐에서 해당 로그를 제 거하지 않고, 다음에 다시 보낼 수 있도록 합니다.• 이를 이용해, 올해 IDC를 이전하면서 약 5-6시간 정도의 장애가 있었는데 해당 기간의 로그를 잃어버리지 않고, 대부분 회수할 수 있었습니다.• 물론, 네트워크가 활성화되지 않은 상태에서 한 번 켜고, 다시 켜지 않으면 해당 로그는 잃어버리지만, 감당할 수 있는 범위의 loss라고 판단했습니다.
31. 로그 스토리지 검토•자원 = 개발자 + 시간 + 돈•자원이 부족했기에 제한된 선택만 가능•대용량 처리 능력보다 사용 편의성에 중점•Hadoop, Cassandra 등은 개발 역량과다 운용비용 부족
32. 해결•기존 : MySQL은 지속적으로 확장하기 어렵다. •ReplicaSet, Sharding을 지원한다.•기존 : 어쨌든 스키마를 매번 만들어야 한다. •JSON 형식으로 자유롭게 저장 가능.•기존 : 쌓는 중엔 형식 변경 비용이 비싸다. •원한다면 언제든지 내용을 바꿀 수 있다.
33. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php
34. Server Server ServerApache httpd Apache httpd Apache httpd mod_php IL E D mod_php mod_php FA 900+ connections
35. Speaker’s note• 접속자가 늘어나 900 커넥션이 넘어가자 더 이상 동작 할 수 없는 상황에 이르게 됩니다.• 락 작업과 쓰기에 바빠 더 이상의 접속을 허용하는 것이 무의미해집니다.• MongoDB는 시스템 ulimit의 80%가 기본 커넥션 제한 값이고, 최대 2만개의 연결을 허용하지만, 천개쯤만 되어 도 장애 상태가 되었습니다.
36. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php 900+ connections
37. Server Server Server •Apache httpd Apache httpd mpm_prefork 사용 httpd Apache httpd Apache •프로세스마다 커넥션을 요구 mod_php mod_php mod_php •연결 폭주, 서비스 장애 발생 •MongoDB Global write lock 문제 900+ connections 위 상황은 MongoDB 1.6.3 을 가정함
38. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php Predis Predis Predis Redis Redis Redis
39. Speaker’s note• 매 사용자 연결 마다 커넥션을 맺는 것이 불합리하므로, 한 곳에 모아 일괄적으로 넣으면 어떨까 생각이 들어 redis를 도입했습니다.• MySQL 같은 경우에도 여러 트랜잭션으로 insert 하는 것에 비해 한 트랜잭션에 몰아 넣는 것이 효율적이므로, 같은 방식으로 적용해봤습니다.• 이에 php의 Predis 모듈을 활용하게 되었습니다.
40. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php Predis Predis Predis Redis Redis Redis
41. Server Server Server RedisApache httpd mod_php Apache httpd mod_php Apache httpd mod_php• Predis In-memory Key-Value Storage by Predis C Predis ANSI•Replication, Cluster 지원•다양한 데이터 타입 지원 Redis Redis Redis •strings, hashes, lists, sets, sorted sets
42. Link• @charsyam blog (very useful) • http://charsyam.wordpress.com/category/cloud/redis/• Redis를 이용한 MongoDB 기반 로그 수집기 성능 개선 • http://blog.naver.com/ez_/140158788246• Predis, using redis on PHP • http://blog.naver.com/ez_/140158670703
43. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php•Redis를 일종의 버퍼로 사용•Predis bulkInsertPredis 모아서 가능 Predis•로그 수 파악을 위한 캐시 UPDATE 명령 절약•피크시 200 log/sec 에서 ~3MB의 메모리 사용 Redis Redis Redis
44. Speaker’s note• percona에서 제공하는 모니터링 플러그인을 사용해서 모니터링합니다. • http://www.percona.com/software/percona-monitoring-plugins• cacti로 관찰한 것 뿐 아니라, mongostat 이나 mongod 의 웹 페이지를 통해 mongo의 상태를 보는 것도 좋습니 다.• 서비스/이벤트, 즉 로그의 종류에 따라 몇 개나 쌓았는지 를 기록하는데, 이를 로그를 쌓으면서 같이 업데이트 합 니다. 이 쿼리 또한 벌크로 넣으면서 절약할 수 있었습니 다.
45. Server Server Server•MongoDB 버전에 따라 write lock 개선Apache httpd Apache httpd Apache httpd mod_php mod_php mod_php Version Level Description Predis 1.6 Predis Global Predis 2.0 Global locking-with-yield 2.2 Database Redis Future Redis Collection Redis
46. Speaker’s note• 1.6 시절과 달리 MongoDB 는 많은 발전을 이뤄, redis / memcached 등의 레이어를 두고 쓰던 사용자들 중 일부 는 2.0으로 업그레이드 하며 캐시 레이어를 제거했다는 글을 쓰기도 했습니다.• locking-with-yield 기능을 통해 page fault 상황에서 쓰 기 성능이 극적으로 개선된 벤치마크를 살펴볼 수 있습 니다.• 앞으로는 전역 lock, 데이터베이스 단위 lock을 넘어 콜 렉션, 즉 테이블 수준의 락을 지원한다고 합니다. 언젠가 는 RDB 수준의 object 단위 락도 기대할 수 있지 않을 까 보고 있습니다.
47. Link• Removing Memcached because it’s too slow • http://blog.serverdensity.com/removing-memcached-because-its-too-slow/ • 번역 : http://charsyam.wordpress.com/2012/06/08/• Goodbye global lock – MongoDB 2.0 vs 2.2 • http://blog.serverdensity.com/goodbye-global-lock-mongodb-2-0-vs-2-2/ • 번역 : http://charsyam.wordpress.com/2012/05/24
48. Server Server ServerApache httpd Apache httpd Apache httpd mod_php mod_php mod_php Predis Predis Predis Redis
49. Speaker’s note• 여러 대의 Redis 를 써야할 정도로 Redis에 부하를 주지 않아, 1대의 Redis로 옮겼고, 그 배경에는 서로 다른 Redis 에 데이터를 부어 넣음에 따른 로그의 순서 문제 도 있었습니다.• Redis에 들어가 있는 순서대로 MongoDB에 들어가게 되는데, 1분 단위로 서로 다른 타이밍에 MongoDB에 부 어 넣으면서, 순차적이지 않은 문제가 있어 변경하게 되 었습니다.
50. Master Replication DiagramSlave Analytics Active / Standby Map / Reduce ~10,000,000 logs/일
51. Master Replication DiagramSlave IL E D Analytics Active / Standby FA Map / Reduce ~10,000,000 logs/일
52. MongoDB • Master Redis를 버퍼로 사용 Replication Diagram• 서비스는 ReplicaSet UPDATE 명령•실로그 수 파악을 위한 캐시추천 Analytics절약 Slave•150 log/sec 에서 2TB x 6 RAID 10사용 사용• 16GB RAM, SATA ~3MB의 메모리 장비•MongoDB 점검이나 이관시에 매우 유용•현재 약 13억 건, 1TB의 데이터를 축적•도저히 장비 1대로 Map / Reduce 할 수가 없음•Sharding 등을 포기하고 다른 방법을 시도
53. Active / Standby Map / Reduce
54. Active / Standby Map / ReduceMySQL /MyISAM•SQL에 친숙하다•운용 경험이 있다•계속 쌓기만 하면 빠른 편
55. Active / Standby Map / Reduce Master Slave Slave•16GB RAM, SATA 2TB x 4 RAID 10 장비 사용
56. Speaker’s note• MongoDB와 마찬가지로 3대의 MySQL 을 구동하고 있 으며,• 2+1대를 운용하는 것은, 한 대의 장비에 장애가 생겼을 경우, 2대로 구성된 M/S 구조라면 HA가 바로 깨어지는 문제가 있을 뿐 아니라, 성능 개선이나 확장을 위해 Slave 장비를 교체하는 경우에도 마찬가지입니다.• 현재 하나의 Slave는 통계 전용으로 쓰고, 하나는 서비스 에서 읽기 전용 데이터를 읽는데 사용해 낭비를 최소화 하고 있습니다.
57. SQL to MongoDBhttp://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart
58. SQL to MongoDBSQLSELECT * FROM usersMongoDB O O Ldb.users.find() C
59. SQL to MongoDBSQLSELECT DISTINCT last_name FROM usersMongoDB Edb.users.distinct(last_name) FAKSpeaker’s note : distinct 로 10,000개 이상을 처리할 수 없습니다.
60. SQL to MongoDBSQLSELECT team, SUM(score) AS total, COUNT(*) FROM scoreboard GROUP BY team ORDER BY total DESC
61. SQL to MongoDBMongoDBdb.scoreboard.group({ key: { team: true }, initial: { total: 0, count:0 }, reduce: function(obj, prev) { prev.total += obj.score; prev.count += 1; G O D Y }}) M H NO SO O RT
62. SQL to MongoDBSQLSELECT msg FROM feed WHERE user_id IN ( SELECT id_to FROM friend WHERE id_from = x ) ORDER BY written_dt DESC LIMIT 10
63. SQL to MongoDBMongoDBdb.feed.find( { user_id: { $in: db.friend.group( { cond: { id_from: x }, initial: O { friends: [] }, RE RDC reduce: function(obj, prev) { } H A prev.friends.push(obj.id_to); } )[‘friends’] }, { msg:1, _id:0 } ) .sort( { written_dt: -1 } ) .limit( 10 );
64. Active / Standby Map / Reduce PV / UV DAU / MAU PU / ARPU NRU / RR
65. MongoDB to MySQL•1분 단위로 전송 •_id 값을 이용해 중복 피함•String을 Integer로 변환 > GROUP 용이•익숙한 SQL을 통해 원하는 데이터 추출•추출된 데이터를 다시 MySQL에 저장
66. Speaker’s note• 로그를 생성한 시점의 디바이스 시간이 JSON에 포함되 어 있고, Redis가 받은 시간과 MongoDB로 넣은 시간까 지 기록하므로, 여러 로그를 한 번에 수집하고, 1분 단위 로 벌크 인서트를 수행하더라도, 로그들 사이의 상대적 인 시간 관계를 확인할 수 있습니다.• 개인 식별자, 기기 종류, 앱 ID, 이벤트 ID, 시간, 타임존, 언어 설정 등을 수집합니다.• String에서 Integer로 변환하기 위한 Lookup 테이블을 생성하고, 이를 지속적으로 업데이트 합니다.
67. Visualization•쌓여 있는 데이터를 읽어 JSON 생성•JSON을 Google Chart API에 던짐•Twitter Bootstrap 사용
68. ?과연 잘 하고 있는 걸까?
69. 바퀴의 재발명Fluentd Treasure Data Ruby LightweightFlume Apache Java Simple, Cloudera supportChukwa Apache Hadoop Java Hadoop based, Rich metadataScribe Facebook C++ Complex, but fast
70. 바퀴의 재발명Fluentd http://fluentd.org/Flume http://flume.apache.org/Chukwa http://incubator.apache.org/chukwa/Scribe https://github.com/facebook/scribe
71. 바퀴의 재발명
72. 바퀴의 재발명 baas.io http://baas.io/Google Analytics http://google.com/analytics Flurry http://www.flurry.com/
73. Speaker’s note• 이미 다양한 로그 수집 애플리케이션이 존재하므로, 알 아보지 않고 새로운 것을 만드는 것은 낭비입니다.• 수집하고자 하는 내용과 분량에 따라 적합한 솔루션을 선택해 기회 비용을 낭비하지 않을 수 있습니다.• 로그 수집뿐 아니라 분석과 통계까지 제공하는 다양한 솔루션을 활용할 수도 있습니다.
74. Conclusion•달라진 환경에 대응하는 수집 전략•꼭 한가지 기술만 쓸 필요 없음•이미 알고 있던 기술을 최대한 활용•역할에 맞는 일을 맡겨, 장점을 최대화
75. 감사합니다 박현우 (@lqez) / 스마트스터디
'정보공유' 카테고리의 다른 글
[정보] 빅데이터, 창업이야기, 그리고 Data-Driven Startup (0) | 2015.04.20 |
---|---|
[정보] 통신서비스 온라인 채널 UX 디자인 사례 (0) | 2015.04.19 |
[정보] 도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다! (0) | 2015.04.19 |
[정보] 버전관리를 들어본적 없는 사람들을 위한 DVCS - Git (0) | 2015.04.19 |
[정보] 아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013) (0) | 2015.04.19 |
[정보] AWS와 함께 한 쿠키런 서버 Re-architecting 사례 (Gaming on AWS) (0) | 2015.04.19 |
[정보] 혼자서 프로젝트 수행하기 (1) | 2015.04.19 |
[정보] 쿠키런 1년, 서버개발 분투기 (0) | 2015.04.19 |