Monday, August 15, 2011

ReplicaSet MongoDb

A. Giới thiệu :
Replication được dùng để "hot backup" dữ liệu khi có sự cố xảy ra . MongoDb có 1 collection gọi là oplog (viết tắt của operation log) , master sẽ dùng collection này cho việc ghi và các slave sẽ truy vấn từ collection này . Mỗi lần ghi (insert,update, delete) sẽ tạo ra một document trong oplog collection (nếu sử dụng replication, không dùng thì mongoDb sẽ không dùng tới collection oplog này) .
Để sử dụng replication , start mongod với option replSet.
Truy vấn từ oplog xem ở đây
(Mình xin dịch lại)

rs.initiate()

use local

db.oplog.rs.find()

{      "ts" : { "t" : 1286821527000, "i" : 1 },      "h" : NumberLong(0),      "op" : "n",      "ns" : "",      "o" : { "msg" : "initiating set" }  }

  • ts: thời gian thao tác thực hiện .
  • h: một ID duy nhất cho thao tác này . Mỗi thao tác sẽ có một giá trị khác nhau trong trường này .
  • op: thao tác ghi sẽ được thực hiện cho slave. n chỉ ra rằng no-op , ý nghĩa chỉ là một thông điệp bình thường.
  • ns: database và collection mà thao tác này tác động . Vì đây là một no-op , trường này đê trống.
  • o: document mà thao tác này thực hiện trên nó . Vì là một no-op trường này không có ý nghĩa .
> use test
 switched to db test
 > db.foo.insert({x:1})
 > db.foo.update({x:1}, {$set : {y:1}})
 > db.foo.update({x:2}, {$set : {y:1}}, true)
 > db.foo.remove({x:1}

Kết quả trong oplog:
> use local 
switched to db local
 > db.oplog.rs.find() 
{ "ts" : { "t" : 1286821527000, "i" : 1 }, "h" : NumberLong(0), "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } } 
{ "ts" : { "t" : 1286821977000, "i" : 1 }, "h" : NumberLong("1722870850266333201"), "op" : "i", "ns" : "test.foo", "o" : { "_id" : ObjectId("4cb35859007cc1f4f9f7f85d"), "x" : 1 } } 
{ "ts" : { "t" : 1286821984000, "i" : 1 }, "h" : NumberLong("1633487572904743924"), "op" : "u", "ns" : "test.foo", "o2" : { "_id" : ObjectId("4cb35859007cc1f4f9f7f85d") }, "o" : { "$set" : { "y" : 1 } } } 
{ "ts" : { "t" : 1286821993000, "i" : 1 }, "h" : NumberLong("5491114356580488109"), "op" : "i", "ns" : "test.foo", "o" : { "_id" : ObjectId("4cb3586928ce78a2245fbd57"), "x" : 2, "y" : 1 } } 
{ "ts" : { "t" : 1286821996000, "i" : 1 }, "h" : NumberLong("243223472855067144"), "op" : "d", "ns" : "test.foo", "b" : true, "o" : { "_id" : ObjectId("4cb35859007cc1f4f9f7f85d") } }

Trong trường op, i : insert , u : update , d : delete

Trường o chứa document dùng insert hoặc là tiêu chuẩn (criteria) để update và remove . Chú ý , đối với update , có 2 trường 0 và 02 . o2 là update criteria và o là modifications (các chỉnh sửa , tường ứng với đối số thứ hai trong câu lệnh update)

B. Cách cài đặt :

Trong file config của cả 2 instance MongoDb (master + slave) đều có replSet =
Start 2 instance này .
Trên instance master , initiate replicaSet bằng cách dùng command trong mongoshell rs.initiate()
Thêm member (các slave ):
> rs.add(“sf2”)
{ “ok” : 1 } 
> rs.addArb(“sf3”) 
{ “ok” : 1 }

Khi master bị down , slave sẽ thay thế và trở thành master . Tuy nhiên nếu có nhiều slave , tùy theo độ ưu tiên của các slave mà cái nào sẽ được chọn làm master . Có thể dùng thêm 1 instance arbiter để quyết định lựa chọn vị trí master khi master cũ bị down. Arbiter không chứa dữ liệu và nó cũng không bao giờ trở thành master hoặc slave . Nó đóng vai trò như một trọng tài bình chọn khi master bị down.
Cấu hình arbiter , có thêm tùy chọn arbiter . Xem ở đây.
C.Tài liệu tham khảo :
1. http://www.snailinaturtleneck.com/blog/2010/04/23/there-must-be-50-ways-to-start-your-mongo/