Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

FIFA 온라인 3의 MongoDB 사용기

13,824 views

Published on

NDC 2015 발표자료

Published in: Software

FIFA 온라인 3의 MongoDB 사용기

  1. 1. FIFA 온라인 3의 MongoDB 사용기 1 스피어헤드 스튜디오 FIFA실 운영팀 김종원
  2. 2. FIFA Online 3, Need For Speed Online 구 EA Seoul Studio
  3. 3. 누구? 넥슨에서 10년 2003: 세강 빌딩에서 사회 생활을 시작함 2005~2007: 잠깐 도쿄에서 외국인 노동자 생활을 경험함 2007~2013: 다시 선릉역으로 출퇴근 Spearhead Studio 2년 2013.5~: FIFA실 Software Engineer 서버 운영, DB, 툴 유지보수, 모니터링 등등… 잡캐 이런저런 것 다 좋아하고, 먹고 살려면 다 하게 됩디다 3
  4. 4. Timeline 4 2012년 8월 MongoDB 2.2 2013년 3월 MongoDB 2.4 2014년 4월 MongoDB 2.6 2015년 3월 MongoDB 3.0 2012년 12월 FO3 런칭 입사시점
  5. 5. 일러두기 여기서 다루는 MongoDB 2.2, 2.4는 오래된 버전입니다 최신 버전에서는 해결된 문제가 좀 있습니다 생각보다 기본적인 내용일 수 있습니다 마치 Best Practices 백서의 요약본 같은… 자세한 수치는 등장하지 않습니다 그런 거 넣으면 혼납니다 슬라이드 공개 예정입니다 너무 열심히 적지 않으셔도 됩니다 5 단종되기도 했고…
  6. 6. 이 슬라이드에는 발표자의 개인 의견이 들어 있습니다 소속된 회사나 팀의 공식 의견과 다를 수 있습니다 6 같이 고생하면서 해결책을 고민하는 넥슨 IT본부 여러분 항상 감사합니다 
  7. 7. 이것이 mongodb다 (희망편) 메모리에서 고속으로 처리되는 I/O MMAP이니까… 인스턴스를 샤드에 추가하면 알아서 도는 Balancer 신속하게 끝나는 단위 moveChunk 작업 서비스가 살짝 멈칫거리다가 말 거야 게임 서비스는 밤에도 멈추지 않지만, 유저가 적으니 영향은 덜하겠지 7
  8. 8. 8
  9. 9. 이것이 mongodb다 (절망편) 생각보다 잘 나오지 않는 단위 샤드의 성능 (Operations / sec) 끝나지 않는 moveChunk 작업 풀리지 않는 Cluster Lock 초기 mongodb 드라이버의 각종 버그는 심각했다… Replica Set 지정해서 Failover 시험하면 잘 안 넘어가고… 떨어져 나가는 유저들 Timeout과 클라이언트 에러의 폭풍 ‘베타’ 가 원래 그런 것 아닌가요 하하하… 9
  10. 10. 7년 같은 7일 왜 일어났나? 글쎄 왜 일어났을까.. 입사하기 전이라 사내 위키와 담당자들의 의견을 종합하였습니다 서비스 오픈 부하 (부족했지만) 샤딩을 안 한 것도 아니고… mongoDB가 버텨줄 줄 알았다 Auto Sharding에 의존 그때만 해도 다들 mongo님이 다 해주실 줄 알았다고 한다 클러스터 전체에 잠금이… Chunk migration 작업 시에 그렇다는 것은 나중에 알았다 10
  11. 11. 사용자 폭증 DB 데이터 & 부하 급증 밸런서 동작 청크 이전 DB Block Timeout → 끊김 재접속 시도 악순환 11
  12. 12. 12 처리량을 어떻게 늘릴까?
  13. 13. FIFA Online 3 Shard Cluster 13 Shard (game) Game Server Mongos (game) Mongos (game) Mongos (player) Mongos (etc) Mongos (player) Mongos (etc) mongod rs sk:0, 16, 32, 48 mongod rs sk:1, 17, 33, 49 …. Shard (player) …. …. config DB config DB config DB
  14. 14. Mongos의 역할 Query Router DB Query를 각 샤드로 분배하고 결과를 받는다 샤드 클러스터 관리 임무 Chunk Splitting Balancing 흔히 간과하는 부분…
  15. 15. Mongos의 역할 Chunk Splitting 데이터를 일정한 크기의 논리 단위(chunk)로 쪼갠다 Config.chunks 컬렉션에 기록함 백그라운드 스캔 작업이 항상 돌고 있다 꺼버릴 수 있다 Balancing 쪼갠 청크를 고르게 분배 moveChunk 동작 시간을 지정할 수 있고, 꺼버릴 수 있다
  16. 16. preSplit Balancing 때문에 망했으면, 사용하지 않으면 된다 미리 쪼개면 되지 Shard key를 지정하여 chunk를 미리 쪼갠다 청크는 mongos에서 관리하는 ‘논리적‘ 단위 키 어디서 어디까지는 어느 샤드에서 처리하라는 ‘매핑’ Mongos에 접속, config.chunks 컬렉션을 조회하여 확인 쪼갠 chunk를 특정 샤드로 지정한다 moveChunk 명령
  17. 17. preSplit 샤드를 쓰는 모든 컬렉션은 다음 과정을 거쳐서 만든다 sh.enableSharding (“somedb“) sh.shardCollection (“somedb.coll”, { sk:1, _id:1 }) for … 1~64 … sh.splitAt ( … ) sh.moveChunk ( … ) Shell로 리턴해도 바로 잠금이 풀리지 않아서 retry가 필요할 수 있음.. 쿼리에 explain() 을 써서 실제로 처리하는 샤드를 확인 가능
  18. 18. Shard Key 분포도(Selectivity)가 좋은 키 만만한 것이 ObjectId 퍼블리셔 별 User Id 딱 찝어서 데이터를 가져올 수 있는 키 (Point query 가능) …를 해싱해서 사용한다 연속적으로 들어오는 데이터라도 강제로 쪼갤 수 있다 예제 { sk: 1, _id: 1 } { sk: 1, userid: 1 } sk: 해시값 (0..63)
  19. 19. ‘sk’ 필드 계산하기 쿼리를 날릴 때 sk 필드를 계산해서 붙여줘야 함 Mongoose 등을 사용한다면 ORM 로직에서 처리하게 할 수 있다 64개 정도면 적절하다고 예상했고, 실제로 적절했음 64 = 26, 데이터를 반씩 쪼개서 샤드를 2배 늘리기 좋음 왜 안썼을까?
  20. 20. ‘sk’ 필드 계산하기 Timestamp ‘초’ 단위의 정밀성 1초에도 수백건 이상의 요청이 들어올 수 있음 특히 insert가 빈번한 경우 문제가 된다 Counter 같은 시각에 들어왔더라도 counter 값은 다름 카운터 값을 64로 나눈 나머지를 쓴다
  21. 21. Hashed Sharding 간편하다 번거로운 presplit 과정이 필요가 없다 미리 나눠놓고 데이터를 입력하면 된다 _id로 쪼갰을 때도 잘 나뉜다 Point Query에 적합하다 SQL) SELECT … FROM Users WHERE UserId = ? js) db.users.find({ userid: ObjectId(“xxxxxx”) }) db.adminCommand({ shardCollection: "db.col", key: { keycol: "hashed" }, numInitialChunks: 64 }) mongoDB 2.4~
  22. 22. Hashed Sharding 직접 관리하기 어렵다 청크를 직접 분할하고 옮기는 것은 가능 Sk 필드처럼 직관적인 범위가 없다 Sk 0~7은 1번, 8~15는 2번 샤드와 같은 배치가 불가능 mongos의 청크 분할과 balancer를 사용하는게 좋다 7년같은 7일을 당하지 않으려면 밸런서는 점검 시간에만 동작시킨다
  23. 23. Hashed Sharding FO3에서는 아직 사용하지 않음 2.2로 서비스를 시작해서 앞에서 설명한 자체 샤딩을 구현했고, 이미 안정적으로 잘 굴러가고 있으므로 큰 필요성을 느끼지 못함 앞으로 적용할 곳이 있는지 보고 있음 간편하므로 로그 데이터라든가
  24. 24. 정리하자면 24 Presplitted Key Hashed Shard Key 필요함 불가 불가
  25. 25. 항상 주의하세요 샤드 키를 빼먹으면 쿼리가 전체 샤드로 갔다가 돌아온다 그러려고 쪼갠게 아닐텐데! Map/reduce 보다는 aggregation framework M/R은 Global Write Lock을 건다 2.6부터는 out 옵션도 추가됨 (write 시에 잠금이 생기겠지만) 집계 시 readPref를 설정해서 Secondary로 보내주는 것도 좋다 findAndModify 주의 _id로 찾는 게 아니면 쓰지 말자 어떤 종류의 쿼리가 어떻게 / 얼마나 들어올지 깊게 생각하고 나눠야 한다
  26. 26. 26 서비스 운영하다가 발생한 일
  27. 27. Monitoring: MMS 해외 서비스에는 MongoDB Monitoring Service를 적용함 무료”였”다 꽤나 자세한 지표를 보여줬음 뭔가 조금씩 불편하긴 했지만 무료니까… 일부 국가에서 통신문제가 있음 베트남이 가끔… 중국이 꽤 자주 -_-… 아무래도 AWS라서 별도 계약 시 MMS Ops Manager를 사용할 수 있음 하지만 유료 서비스 쓰지 않을 것 다 압니다…
  28. 28. 28
  29. 29. Monitoring: MMS 강력한 Alert 기능: Mail, HipChat, SMS …
  30. 30. Monitoring: Tools mongosniff Profile 걸지 않고 쿼리 분석용 (wireShark도 사용 가능) mongotop 어느 DB에 부하가 걸리고 있나 = db.adminCommand({top:1}) mongostat 대부분의 지표 = db.serverStatus() mongod.log Slow query 분석용 (default: 100ms)
  31. 31. Monitoring: metrics Lock % 60 넘어가면 서버가 많이 힘들어하고 있는 것으로 판단 (잠금이 걸린 시간) / (모니터링 간격) Page faults / sec X0 ~ X00 넘어가기 시작하면 메모리가 부족한 것 단 점검 후 초반에 메모리가 예열(!)이 덜 되었을 땐 높을 수 있다 메모리에 데이터가 충분히 올라가지 않았다면 디스크에서 읽음 touch 명령, find() 등으로 full scan
  32. 32. Monitoring: metrics Replication Lag Secondary의 oplog time – Primary의 oplog time 몇 분 이상 밀리기 시작하면 복제에 문제가 있는 것 Replication Oplog Window 복제가 끊겼을 때 full sync 대신 얼마나 버틸 수 있는가 var c = db.getSisterDB("local").oplog.rs; print(c.find().sort({$natural:-1}).limit(1)[0].ts.t - c.find().sort({$natural:1}).limit(1)[0].ts.t, "sec") ← 이렇게 계산합니다
  33. 33. Configurations: CMOS Configuration Maximum Performance Disable C1E, C-States, Monitor/mwait … OS에서도 가능 Dell, HP 서버 등
  34. 34. Configurations: CMOS Configuration 설정 몇 개 바꿨을 뿐인데!
  35. 35. Configurations: CMOS Configuration 클라우드 쓰는 분들은 해당사항 없습니다 그냥 인스턴스를 잘 고르세요… 서버 과열에 주의하세요! IDC 냉방 못 믿겠네
  36. 36. SSD 쓰세요 SSD 쓰세요, 두 번 쓰세요 36 NVMe (PCIe x4) 15k 2.5" 300G x 6 800G 900G $2,150 $430 $4,300 $2,580 Software RAID Hardware RAID 200,000 900 20 µs 3.4 ms 14.6 PBW - Dell.com 가격 RAID 1 / RAID 10 R70% / W30% 800G x 18,250
  37. 37. SSD 쓰세요 SSD 수명이 걱정된다고요?! 서비스 접을 때까지 써도 될 듯.. 37 # fio-status -a ... Reserve space status: Healthy; Reserves: 100.00%, warn at 10.00% Active media: 100.00% Rated PBW: 4.00 PB, 95.63% remaining Lifetime data volumes: Physical bytes written: 174,868,745,102,696 Physical bytes read : 142,721,083,007,568 RAM usage: Current: 179,791,680 bytes Peak : 179,999,680 bytes ...
  38. 38. Configurations: Storage 디스크 볼륨 구성 OS + Journal에 RAID 1로 하나 나머지는 RAID 10으로 몰빵 플래시 장비는 플래시 볼륨에 데이터를 모두 넣음 OS Readahead Configuration 사실 큰 차이를 보지 못했음 너무 낮추면 백업시 불리함
  39. 39. Configurations: Journal RDBMS의 트랜잭션 로그 같은 것 더 설명이 必要韓紙? 성능 저하 있음 변경점을 로그에 미리 쓰고 나서 기록하는데 없으면 이상함 직접 구성한 서버에서는 반드시 사용함 mmap 엔진에서는 안쓰면 데이터를 깨먹을 위험이 있음 메모리 사용량이 두배로 나옴 Don’t Panic: 실제로 그만큼 쓰지는 않는다
  40. 40. Configurations: Oplog 복제 로그 (필수 요소) 세컨더리 잠깐 내렸다 올려도 oplog가 남아있다면 빠르게 따라잡음 …그러나 그만큼 메모리를 먹는다 Oplog를 계속 기록하므로 메모리에 항상 올라와 있다
  41. 41. Configurations: Oplog 얼마나 만들어지는지를 아는 것이 좋습니다 적당한 크기 최저 2-3시간, 최대 하루 정도까지 DB를 더 많이 괴롭히면(?) 더 많은 로그가 생성됨 메모리를 128GB 장착한 서버라면 10G쯤 써도 됨…
  42. 42. 했더니 도움이 된 것 Game DB와 Log DB 클러스터 분리 Game DB (Insert, Delete, Update, Select) Log DB (Insert, Select) 로그 데이터가 메모리에 올라와 있을 필요가 없으니까 한 클러스터에 다른 부하를 섞지 말자
  43. 43. 했더니 도움이 된 것 선수 DB 변천사 Game DB에서 컬렉션을 떼어내 DB 분리 db 수준 잠금이니까 (부작용) DB 연결이 늘어남 게임 DB 클러스터에서 분리 게임 DB 장비를 반으로 줄이고 선수 DB 장비를 따로 구성함 떼어내야 산다 (2.6까지는…) 3.0의 mmap은 Collection Level Lock으로 개선
  44. 44. 했더니 도움이 된 것 Document 크기를 고정시킴 필요한 필드는 만들 때 채워둔다 업데이트는 in-place로 처리한다 db.serverStatus().metrics.operation.fastmod usePowerOf2Sizes 옵션 (2.6 부터는 기본) Update시 문서 이동을 줄여줌 임시 문서를 만들었다가 삭제하는 일이 잦다면 특히 유용하다 FO3 Transaction 구현에서 효과를 크게 봄 로그성 데이터에는 적합하지 않다 – 꺼야 함 (in-place 업데이트만 집계되는 건 아님)
  45. 45. 대규모 작업 데이터 이전 시에는 원격 서버에서! 작업자 PC에서 mongo 셸 띄우지 말 것 데이터가 원격 서버에서 작업자 컴퓨터 왔다가 감 서버끼리 직접 데이터를 주고받는 경우는 많지 않다 copydb, clone, cloneCollection 정도
  46. 46. 대규모 작업 셸은 싱글스레드 Thread 개체가 있지만 내부 테스트 용 보통 타 언어로 스크립트를 짜는게 더 빠르게 작업이 가능 병렬처리 꼭 하세요! 읽기는 각 샤드 mongod에서, 쓰기는 mongos로 단순 작업에는 dump / restore 또는 export / import 사용 느리다고 생각하면 3.0의 mongodb tools를 사용
  47. 47. mongos 중요한 컴포넌트이긴 한데… 샤딩의 핵심이기도 한데… 너무 적게 띄우지 말고 부하가 몰리면 메모리가 샌다 너무 많이 띄우지 말 것 100개 넘게 띄우지는 말라는 개발사의 충고 서버간 동기화는 공짜가 아니다 (config db 부하) 애플리케이션 서버와 연동해서 올리고 내리면 좋음
  48. 48. mongos 대폭발 Resident Set Size 13.58GB
  49. 49. TokuMX mongodb 2.4에서 파생된 엔진 MySQL TokuDB 엔진을 만든 그 Tokutek에서 만듦 장점도 많고… 높은 압축률 + 적당한 cpu 사용 높은 insert 성능, 낮은 I/O량 로그 저장에는 확실히 좋다 단점도 있고… 섞어서 못씀 → 클러스터를 따로 구축해야 함 불안함 (가끔 이유없이 사망) 우리 게임 DB로는 안 맞았음
  50. 50. TokuMX IO 대기 MongoDB: 4 shards in cluster TokuMX: 2 shards in cluster
  51. 51. 51 MongoDB 3.0에 거는 기대
  52. 52. mongoDB 3.0 원래는 2.8 어른의 사정으로 뻥튀기를 하지 않았을까 Storage Engine 도입 엔진간 데이터 포맷이 다르다! DB나 컬렉션 단위로 섞어 쓸 수 없다 Replica set 안에서 섞을 수 있다 3rd party 엔진도 개발중 TokuMXse 아까 말한 TokuMX에서 엔진만 똑 RocksDB, In-Memory Engine, …
  53. 53. 엔진 섞어쓰기 티어를 둔 구성이 가능 쓸 일은 많지 않을 것 같지만… 백업에 특화된 엔진 등이 있다면? 점진적인 마이그레이션 rs3 엔진 변경, 재시작 복제 완료 rs2 엔진 변경, 재시작 복제 완료 rs1 엔진 변경, 재시작 … mmap WT Rocks DB rs1 (Primary) rs2 (Secondary) rs3 (Secondary)
  54. 54. 성능 향상 Document Level Locking journal 안써도 데이터가 깨지지 않음 안 쓰면 최대 60초까지 데이터를 잃을 수 있음 Replica set 구성으로 극복 NO IN-PLACE UPDATE 업데이트가 데이터를 바로 교체하지 않는다 먼저 쓰고, 구 버전은 나중에 지워짐 문서 크기를 가급적 키우지 않는 것이 좋을 듯 wiredTiger
  55. 55. 간단한 벤치마크 Sysbench-mongodb https://github.com/tmcallaghan/sysbench-mongodb Benchmark 설정 Insert Batch size: 10,000 2,500,000 docs * 16 collection 8 insert threads 64 writer threads / 15분 Avg. document size: 217 bytes Load 40M docs -> Execute (15min) 55 장비 & MongoDB 설정 Xeon X5660 2.83 GHz (6 cores) 12GB RAM 200 GB SATA SSD Ubuntu 14.04 WT Cache 8GB Compression: snappy Replica Set, oplogSize 1GB MMAP / WT (저널 On/Off)
  56. 56. Number of Rows Inserted 56 0 500 1000 1500 2000 2500 3000 3500 4000 10 70 130 190 250 310 370 430 490 550 610 670 730 790 850 910 970 1030 1090 1150 1210 1270 1330 1390 1450 1510 1570 1630 1690 1750 1810 1870 1930 1990 2050 2110 2170 2230 X10000 mmap wt_journal wt_nojournal
  57. 57. Rows per sec (Load Phase) 57 0 2 4 6 8 10 12 10 70 130 190 250 310 370 430 490 550 610 670 730 790 850 910 970 1030 1090 1150 1210 1270 1330 1390 1450 1510 1570 1630 1690 1750 1810 1870 1930 1990 2050 2110 2170 2230 X10000 mmap wt_journal wt_nojournal
  58. 58. CPU Usage (Load Phase) 58 0% 10% 20% 30% 40% 50% 60% 10 60 110 160 210 260 310 360 410 460 510 560 610 660 710 760 810 860 910 960 1010 1060 1110 1160 1210 1260 1310 1360 1410 1460 1510 1560 1610 1660 1710 1760 1810 1860 1910 1960 2010 2060 2110 2160 2210 mmap wt_journal wt_nojournal
  59. 59. MiB/sec (Load Phase) 59 0 20 40 60 80 100 120 140 160 180 10 60 110 160 210 260 310 360 410 460 510 560 610 660 710 760 810 860 910 960 1010 1060 1110 1160 1210 1260 1310 1360 1410 1460 1510 1560 1610 1660 1710 1760 1810 1860 1910 1960 2010 2060 2110 2160 2210 mmap wt_journal wt_nojournal
  60. 60. Disk IOPS (Load Phase) 60 0 200 400 600 800 1000 1200 1400 1600 10 60 110 160 210 260 310 360 410 460 510 560 610 660 710 760 810 860 910 960 1010 1060 1110 1160 1210 1260 1310 1360 1410 1460 1510 1560 1610 1660 1710 1760 1810 1860 1910 1960 2010 2060 2110 2160 2210 mmap wt_journal wt_nojournal
  61. 61. Cumulative TPS (Execute Phase) 61 0 50 100 150 200 250 300 350 400 450 500 10 30 50 70 90 110 130 150 170 190 210 230 250 270 290 310 330 350 370 390 410 430 450 470 490 510 530 550 570 590 610 630 650 670 690 710 730 750 770 790 810 830 850 870 890 mmap ssd_wt_journal ssd_wt_nojournal
  62. 62. 10sec Interval TPS (Execute Phase) 62 0 100 200 300 400 500 600 10 30 50 70 90 110 130 150 170 190 210 230 250 270 290 310 330 350 370 390 410 430 450 470 490 510 530 550 570 590 610 630 650 670 690 710 730 750 770 790 810 830 850 870 890 mmap ssd_wt_journal ssd_wt_nojournal
  63. 63. CPU Usage (Execute Phase) 63 0% 5% 10% 15% 20% 25% 30% 35% 40% 45% 50% 10 30 50 70 90 110 130 150 170 190 210 230 250 270 290 310 330 350 370 390 410 430 450 470 490 510 530 550 570 590 610 630 650 670 690 710 730 750 770 790 810 830 850 870 890 mmap ssd_wt_journal ssd_wt_nojournal
  64. 64. 300317 274006 297663 40300319 40274008 40297665 63065603 57540636 62508349 300319 274008 297665 18360 10559 10900 file storage+idx Number of Rows 64 wt에 저널을 끄면 좀 나아지기는 하지만.. 서비스용 장비에서 테스트를 다시 해볼 예정
  65. 65. mongoDB 3.0: 그 밖의 변경점 MMAPv1 엔진 collection level lock으로 개선됨 explain 변경 이제 쿼리를 실제로 실행하지 않고 질의 계획을 볼 수 있다 mongoimport / export / dump / restore Go로 재작성: 이제 --dbpath 사용 못함 Batch 처리 및 멀티스레드 작업 지원 Client Driver 업데이트 필요 구버전 드라이버 접속 시 호환성 문제가 발생함: 인증, 시스템 컬렉션..
  66. 66. 올해의 목표와 연구과제 mongoDB upgrade 2.4 → 3.0 영향이 적은 쪽부터 부분적으로 microsharding 한 서버에 여러 다른 샤드의 인스턴스를 띄움 샤드 수가 늘어나면 클러스터 전체 성능이 늘어나는 효과 3.0 WT 엔진은 사용하는 캐시 메모리 크기를 정할 수 있게 됨 MMAP은 불가능하여 cgroups 등을 사용해야 했음
  67. 67. microsharding 같은 수의 장비에 더 많은 샤드를 배치할 수 있다 예제에서 장비 1대당 부하는 3배까지 늘어남
  68. 68. 참고 Hash based sharding http://www.slideshare.net/mongodb/hash-based-sharding Introduction to wiredTiger http://www.slideshare.net/vkarpov15/mongodb-miami-meetup-12615-introduction-to-wiredtiger Acme Benchmarking http://www.acmebenchmarking.com/ MongoDB 완벽 가이드 2판 (한국어판) http://www.hanbit.co.kr/book/look.html?isbn=978-89-6848-095-9 mongoDB Operations Best Practices http://s3.amazonaws.com/info-mongodb-com/10gen-MongoDB_Operations_Best_Practices.pdf mongoDB Performance Best Practices http://s3.amazonaws.com/info-mongodb-com/MongoDB-Performance-Best-Practices.pdf Shaping the Future of Travel with MongoDB http://www.slideshare.net/mongodb/shaping-the-future-of-travel-with-mongodb/21
  69. 69. Q & A 자동 sharding을 믿지 말자 해시할 키를 잘 잡아서 미리 쪼개놓자 모니터링을 잘 하자 CPU 전원 설정은 의외의 튜닝 포인트 데이터 종류 별로 클러스터를 분리하자 새 버전이 나왔으니 잘 살펴보고 업그레이드를 해보자
  70. 70. Q & A (추가) 타 DB에 비해서 MongoDB를 쓰게 된 이유는? 추천할 만한 이유가 있다면? 서비스를 개발하고 오픈하던 시기에는 비정형 데이터를 넣을 쓸만한 DBMS가 없었던 것이 사실이나, 지금은 그렇지 않습니다. Ex) PostgreSQL, MySQL DocStore, SQL Server 차기 버전 등… 굳이 처음부터 MongoDB를 고려하기 보다 익숙한 RDBMS로 빠르게 개발할 수 있다면 그것도 한 방법입니다. 단 샤딩만큼은 기존 RDBMS에 비해 MongoDB가 제공하는 강력한 장점입니다. 70 저는 MongoDB 쓰지 마세요 라고 하지 않았습니다! 
  71. 71. Q & A (추가) 아까 SSD 쓰라고 할 때 Software RAID를 쓰라고 했는데 왜죠? SAS / SATA SSD를 쓰면 RAID 컨트롤러를 사용할 수 있지만 카드형은 그게 안되니까요. 속도는 이미 빠르니 내결함성을 보장하면 되죠. C***hbase 써봤나요? 안 써봤어요. 71
  72. 72. WE’RE HIRING! 72

×