31. •항상 로그 전송이 가능한 상태는 아님.
•JSON 형태로 로컬 저장소에 보관하다,
•n개까지 모으거나, 필요한 경우 즉시 발송.
•서버에서는 받은 후, 낱개로 풀어서 저장.
모바일 환경
32. •HTTP / HTTPS 로 전송
•200 OK 응답을 받지 못한 경우 장치에 보관
•IDC 이전시 효과적으로 활용
장애 대응
33. • 기존에 하던 방식과 비슷하지만, 서버의 응답을 확인해
서 200 OK 를 받지 않으면 로컬 큐에서 해당 로그를 제
거하지 않고, 다음에 다시 보낼 수 있도록 합니다.
• 이를 이용해, 올해 IDC를 이전하면서 약 5-6시간 정도의
장애가 있었는데 해당 기간의 로그를 잃어버리지 않고,
대부분 회수할 수 있었습니다.
• 물론, 네트워크가 활성화되지 않은 상태에서 한 번 켜고,
다시 켜지 않으면 해당 로그는 잃어버리지만, 감당할 수
있는 범위의 loss라고 판단했습니다.
Speaker’s note
34. •자원 = 개발자 + 시간 + 돈
•자원이 부족했기에 제한된 선택만 가능
•대용량 처리 능력보다 사용 편의성에 중점
•Hadoop, Cassandra 등은 운용비용 과다
로그 스토리지 검토
개발 역량 부족
36. •기존 : MySQL은 지속적으로 확장하기 어렵다.
•ReplicaSet, Sharding을 지원한다.
•기존 : 어쨌든 스키마를 매번 만들어야 한다.
•JSON 형식으로 자유롭게 저장 가능.
•기존 : 쌓는 중엔 형식 변경 비용이 비싸다.
•원한다면 언제든지 내용을 바꿀 수 있다.
해결
41. • 접속자가 늘어나 900 커넥션이 넘어가자 더 이상 동작
할 수 없는 상황에 이르게 됩니다.
• 락 작업과 쓰기에 바빠 더 이상의 접속을 허용하는 것이
무의미해집니다.
• MongoDB는 시스템 ulimit의 80%가 기본 커넥션 제한
값이고, 최대 2만개의 연결을 허용하지만, 천개쯤만 되어
도 장애 상태가 되었습니다.
Speaker’s note
45. • 매 사용자 연결 마다 커넥션을 맺는 것이 불합리하므로,
한 곳에 모아 일괄적으로 넣으면 어떨까 생각이 들어
redis를 도입했습니다.
• MySQL 같은 경우에도 여러 트랜잭션으로 insert 하는
것에 비해 한 트랜잭션에 몰아 넣는 것이 효율적이므로,
같은 방식으로 적용해봤습니다.
• 이에 php의 Predis 모듈을 활용하게 되었습니다.
Speaker’s note
48. 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
50. • percona에서 제공하는 모니터링 플러그인을 사용해서
모니터링합니다.
• http://www.percona.com/software/percona-monitoring-plugins
• cacti로 관찰한 것 뿐 아니라, mongostat 이나 mongod
의 웹 페이지를 통해 mongo의 상태를 보는 것도 좋습니
다.
• 서비스/이벤트, 즉 로그의 종류에 따라 몇 개나 쌓았는지
를 기록하는데, 이를 로그를 쌓으면서 같이 업데이트 합
니다. 이 쿼리 또한 벌크로 넣으면서 절약할 수 있었습니
다.
Speaker’s note
52. • 1.6 시절과 달리 MongoDB 는 많은 발전을 이뤄, redis /
memcached 등의 레이어를 두고 쓰던 사용자들 중 일부
는 2.0으로 업그레이드 하며 캐시 레이어를 제거했다는
글을 쓰기도 했습니다.
• locking-with-yield 기능을 통해 page fault 상황에서 쓰
기 성능이 극적으로 개선된 벤치마크를 살펴볼 수 있습
니다.
• 앞으로는 전역 lock, 데이터베이스 단위 lock을 넘어 콜
렉션, 즉 테이블 수준의 락을 지원한다고 합니다. 언젠가
는 RDB 수준의 object 단위 락도 기대할 수 있지 않을
까 보고 있습니다.
Speaker’s note
53. 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
55. • 여러 대의 Redis 를 써야할 정도로 Redis에 부하를 주지
않아, 1대의 Redis로 옮겼고, 그 배경에는 서로 다른
Redis 에 데이터를 부어 넣음에 따른 로그의 순서 문제
도 있었습니다.
• Redis에 들어가 있는 순서대로 MongoDB에 들어가게
되는데, 1분 단위로 서로 다른 타이밍에 MongoDB에 부
어 넣으면서, 순차적이지 않은 문제가 있어 변경하게 되
었습니다.
Speaker’s note
58. Slave Analytics
Master Replication Diagram
•Redis를 버퍼로 사용
•로그 수 파악을 위한 캐시 UPDATE 명령 절약
•150 log/sec 에서 ~3MB의 메모리 사용
•MongoDB 점검이나 이관시에 매우 유용
•실 서비스는 ReplicaSet 추천
•16GB RAM, SATA 2TB x 6 RAID 10 장비 사용
•현재 약 13억 건, 1TB의 데이터를 축적
•도저히 장비 1대로 Map / Reduce 할 수가 없음
•Sharding 등을 포기하고 다른 방법을 시도
MongoDB
60. Map / ReduceActive / Standby
•SQL에 친숙하다
•운용 경험이 있다
•계속 쌓기만 하면 빠른 편
MySQL /MyISAM
61. Map / ReduceActive / Standby
Slave Slave
Master
•16GB RAM, SATA 2TB x 4 RAID 10 장비 사용
62. • MongoDB와 마찬가지로 3대의 MySQL 을 구동하고 있
으며,
• 2+1대를 운용하는 것은, 한 대의 장비에 장애가 생겼을
경우, 2대로 구성된 M/S 구조라면 HA가 바로 깨어지는
문제가 있을 뿐 아니라, 성능 개선이나 확장을 위해 Slave
장비를 교체하는 경우에도 마찬가지입니다.
• 현재 하나의 Slave는 통계 전용으로 쓰고, 하나는 서비스
에서 읽기 전용 데이터를 읽는데 사용해 낭비를 최소화
하고 있습니다.
Speaker’s note
65. SELECT DISTINCT last_name FROM users
db.users.distinct('last_name')
SQL
MongoDB
FAKE
SQL to MongoDB
Speaker’s note : distinct 로 10,000개 이상을 처리할 수 없습니다.
66. SQL
SELECT team, SUM(score) AS total, COUNT(*)
FROM scoreboard
GROUP BY team
ORDER BY total DESC
SQL to MongoDB
67. db.scoreboard.group({
key: { team: true },
initial: { total: 0, count:0 },
reduce: function(obj, prev) {
prev.total += obj.score;
prev.count += 1;
}
})
OH MY GOD
MongoDB
NO SORT
SQL to MongoDB
68. SELECT msg FROM feed
WHERE user_id IN
( SELECT id_to FROM friend
WHERE id_from = x )
ORDER BY written_dt
DESC LIMIT 10
SQL
SQL to MongoDB
70. PV / UV
DAU / MAU
PU / ARPU
NRU / RR
Map / ReduceActive / Standby
71. MongoDB to MySQL
•1분 단위로 전송
•_id 값을 이용해 중복 피함
•String을 Integer로 변환 > GROUP 용이
•익숙한 SQL을 통해 원하는 데이터 추출
•추출된 데이터를 다시 MySQL에 저장
72. • 로그를 생성한 시점의 디바이스 시간이 JSON에 포함되
어 있고, Redis가 받은 시간과 MongoDB로 넣은 시간까
지 기록하므로, 여러 로그를 한 번에 수집하고, 1분 단위
로 벌크 인서트를 수행하더라도, 로그들 사이의 상대적
인 시간 관계를 확인할 수 있습니다.
• 개인 식별자, 기기 종류, 앱 ID, 이벤트 ID, 시간, 타임존,
언어 설정 등을 수집합니다.
• String에서 Integer로 변환하기 위한 Lookup 테이블을
생성하고, 이를 지속적으로 업데이트 합니다.
Speaker’s note
88. • 이미 다양한 로그 수집 애플리케이션이 존재하므로, 알
아보지 않고 새로운 것을 만드는 것은 낭비입니다.
• 수집하고자 하는 내용과 분량에 따라 적합한 솔루션을
선택해 기회 비용을 낭비하지 않을 수 있습니다.
• 로그 수집뿐 아니라 분석과 통계까지 제공하는 다양한
솔루션을 활용할 수도 있습니다.
Speaker’s note