2013년 8월 27일 화요일

몽고 db 교육 4일차

4일차 교육

1. 샤딩 시스템의 문제점
  - 청크 사이즈 - 사이즈가 작으면 청크 마이그레이션 횟수가 증가
  - 샤드 키 - 분포도가 좋은 필드로 지정하는 것이 가장 적합하다.
  - hashed sharding -> 일반필드를 지정하면 해시값으로 키를 생성. db.컬렉션.ensureIndex({ a : "hashed "})
2. Replica & ReplicaSets
1) Master & slave
  - 마스터가 메인, 마스터의 데이터를 슬래이브(s)로 복제. 슬레이브는 최대 32개 가능.
  - 마스터에 문제가 발생할 경우 슬래이브를 마스터로 수정해줘야함. 슬레이브가 메인이 될 경우 Read-only.
 (실습)
  - 폴더 3개 생성. master, slave1, slave2
  - mongod --dbpath c:\mongodb\master\ --port 10000 --master
  - mongod --dbpath c:\mongodb\slave1\ --port 10001 --slave --source localhost:10000
  - mongod --dbpath c:\mongodb\slave2\ --port 10002 --slave --source localhost:10000
  - 세군데 모두 접속
  - mongo localhost:10000, mongo localhost:10001, mongo localhost:10002
  - 마스터에서 insert명령
  - db.things.insert({ a : 1}) // 마스터에 insert, 슬레이브에 자동으로 복제
  - 세군데에서 find 명령
  - db.things.find()
  - 슬레이브2 서버 셧다운, 해당 폴더 비우기
  - use admin
  - db.shutdownServer()
  - slave2 폴더 내용 삭제
  - 셧다운된 도스창을 확인후 다시실행
  - slave2 폴더 내용 확인 // 자동 복구됨. 마스터의 경우에는 직접 복구해야함.
  - db.things.insert({ b : 3})
  - 이번엔 마스터를 셧다운 후 해당 폴더 삭제
  - 슬레이브 모두 셧다운
  - 슬레이브 파일을 마스터쪽으로 복사
  - --autoresync 옵션을 주어 싱크가 되도록 다시 구동
  - mongod --dbpath c:\mongodb\master\ --port 10000 --master --autoresync
 - mongod --dbpath c:\mongodb\slave1\ --port 10001 --slave --source localhost:10000 --autoresync
  - mongod --dbpath c:\mongodb\slave2\ --port 10002 --slave --source localhost:10000 --autoresync
  - find 명령으로 모두 확인.
  2) ReplicaSets
   - Primary server와 Secondary(s)서버. Primary에 문제가 발생할 경우 secondary가 자동으로 메인이 된다.
   - Primary에 쌓인 데이터는 opLog에 우선 백업 후 Secondary 서버로 복제된다. 이는 복제가 실패할 경우를 위함이다.
   - Heartbeat : 매 2초마다 상대 서버의 상태를 체크
  - Primary server 선출방법
   a) Priority에 의한 선출. 사용자가 우선순위를 주어 다음 Primary를 지정.
   b) Arbiter 서버에 의한 선출. 아비터 서버는 사양이 좋을 필요는 없다.
  - 멤버의 종류
   a) Secondary only member - 복제후 read only 셀렉트만 하는 역할.
   b) hidden member - 아비터가 Primary 서버로 선택하지 못하게 하는 옵션
   c) Arbiter member - 장애발생시 Primary 서버 선출역할만 진행.
   d) Delayed member - Secondary 옵션으로 데이터복제가 실시간이 아니라 딜레이 시간이 지난뒤 복제되도록 설정
   e) non voting member - Secondary only member 와 같은 개념. Primary 서버로 선택받지 않는 옵션.
 (실습)
  - 폴더 4개 생성. disk1, disk2, disk3, arbiter
  - mongod --dbpath c:\mongodb\disk1\ --port 10001 --replSet rptmongo --oplogSize 10 --rest    //replSet의 이름을 rptmongo라고 지정.
  - mongod --dbpath c:\mongodb\disk2\ --port 10002 --replSet rptmongo --oplogSize 10 --rest    //oplogSize 사이즈는 10MB로 지정
  - mongod --dbpath c:\mongodb\disk3\ --port 10003 --replSet rptmongo --oplogSize 10 --rest
  - mongod --dbpath c:\mongodb\arbiter\ --port 10004 --replSet rptmongo --oplogSize 10 --rest   //아비터 서버
  - admin으로 접속
  - mongo localhost:10001/admin
  - 리플리카셋 init
  - db.runCommand({"replSetInitiate" : {"_id" : "rptmongo", "members" :
    [{"_id" : 1, "host" : "localhost:10001"},
   {"_id" : 2, "host" : "localhost:10003"},
   {"_id" : 3, "host" : "localhost:10002"},
   {"_id" : 4, "host" : "localhost:10004", arbiterOnly:true}]
   }})
  - 상태 확인
  - db.printReplicationInfo()
  - 프롬프트 변경
  - use test
  - db.things.insert({a:1})  //Secondary에도 복제
  - mongo localhost:10002/admin   //Secondary 서버 접속
  - use test
  - db.getMongo().setSlaveOk()     //이 명령을 실행해야 Secondary에서도 find를 할 수 있음.
  - db.things.find()  // 확인
  - db.things.insert({b:3})   //불가능함.

  -> Primary 서버 셧다운(장애발생)
  - use admin, db.shutdownServer()
  - Secondary 서버 둘 중 하나가 Primary로 자동 변환. 프롬프트로 확인.
  - 셧다운된 서버를 재구동
  - 프롬프트를 확인해보면 Secondary가 되어있음.
  - Secondary 둘 다 셧다운 할 경우 Primary는 Secondary로 변경됨. 운영 불가하다는 의미.

  -> 아비터는 find 명령을 해봐도 데이터 없음
  - 아비터를 셧다운 한 뒤 Primary에 장애가 발생하면 나머지 두 서버는 그대로 Secondary

  -> 서버 한대 더 생성
  - mongod --dbpath c:\mongodb\disk4\ --port 10005 --replSet rptmongo --oplogSize 10 --rest
  - Primary에서 새로 생성된 서버를 add
  - rs.add("localhost:10005")
  - 상태확인 => db.printSlaveReplicationInfo() 또는 rs.status()
  - db.getMongo().setSlaveOk() 및 find()
  - 서버를 제거
  - rs.remove("localhost:10005")   => 내 경우 Primary가 변경됨.

  -> oplog 용량 변경
  - mongodump --db local --collection 'oplog.rs' --port 10001
  - mongo --port 10001
  - use local
  - db.temp.save(db.oplog.rs.find().sort({$natural : -1}).limit(1).next())    //oplog 내용을 temp에 save. 이 코딩이 맞는지는 확인해봐야겠다.
  - db.temp.find()  // 확인
  - db.oplog.rs.drop()   //oplog 영역 제거
  - db.runCommand( {create:"oplog.rs", capped:true, size:20000000} )   //20MB로 다시 생성
  - db.oplog.rs.save(db.temp.findOnd())    //temp 컬렉션에 있는 복사본을 복제


(복합실습)
mongod --dbpath c:\mongodb\DATA\SHARD_B\ --port 40002 --replSet blue --oplogSize 10 --rest
mongod --configsvr --dbpath c:\mongodb\DATA\CONFIG_A4  --port 30004
mongod --dbpath c:\mongodb\DATA\S_B1\ --port 50002 --replSet blue --oplogSize 10 --rest
mongod --dbpath c:\mongodb\DATA\S_A2\ --port 60001 --replSet red --oplogSize 10 --rest

(initiate 실습)
-- 4개 띄우기
mongod --dbpath c:\mongodb\TE\Primary\ --port 15001 --replSet rptmongo --oplogSize 10 --rest
mongod --dbpath c:\mongodb\TE\Secondary1\ --port 15002 --replSet rptmongo --oplogSize 10 --rest
mongod --dbpath c:\mongodb\TE\Secondary2\ --port 15003 --replSet rptmongo --oplogSize 10 --rest
mongod --dbpath c:\mongodb\TE\hidden\ --port 15004 --replSet rptmongo --oplogSize 10 --rest
-- 15001 서버로 접근. -> mongo localhost:15001
conf = {
_id:"rptmongo",
members:[
{_id:0, host:"localhost:15001", priority:3},
{_id:1, host:"localhost:15002", priority:1},
{_id:2, host:"localhost:15003", priority:2},
{_id:3, host:"localhost:15004", priority:0, hidden:true, slaveDelay:1800}
]
}
rs.initiate(conf)   ==> 리플리카셋 완료. 
 => 우선순위에 따라서 프라이머리가 정해진다.

3. 성능튜닝
 1) 프로파일러 설정
 2) Index와 find의 성능
  - find 명령실행시 검색 우선순위는 제한된 검색조건 -> and -> or조건 순으로 우선순위를 결정한다.
  - 컴파운드 인덱스의 경우 좌측부터 우측순으로 우선순위를 결정한다.
  - 인덱스의 우선순위가 or조건절을 이용할 경우 인덱스를 사용하지 않는다. -> basicCursor. 이는 인덱스 사용이 더 많은 비용이 발생한다고 판단되기 때문이다.
  - index가 없는 상태에서 hint를 이용할 경우 더 느려진 성능이 보여진다. index + find로 보인다.
  - 인덱스가 여러개일 경우, 갯수가 적은 필드조건의 값으로 인덱스가 선정된다.

댓글 없음:

댓글 쓰기