Giới thiệu MongoDB
mongodb
11
Male avatar

manhdung viết ngày 17/06/2015

Giới thiệu

MongoDB là một giải pháp nosql database. Data được lưu ở dạng các bson document. Hỗ trợ vertical scaling và horizontal scaling, dynamic schemas. Phù hợp với agile development.

Bson document là các document có cấu trúc json nhưng không ở dạng text mà là dạng binary.

Vertical scaling là hành động nâng cao năng lực xử lý bằng cách bổ sung thêm memory, thêm disk, thêm CPU. Scaling kiểu này rất giới hạn

Horizontal scaling là hành động nâng cao năng lực xử lý bằng cách partition tập data lên nhiều node khác nhau. Mỗi node sẽ chỉ mang một phần của tập data và hợp tác với nhau để cung cấp dịch vụ. Mongodb thực hiện horizontal scaling bằng cách sharding.

Dynamic schema: MongoDB là database không cần định nghĩa một cấu trúc trước khi lưu data (schemaless). Bản thân data sẽ tự nói lên cấu trúc của nó. Ví dụ một collection (tương đương với một table trong RDBMS) có lưu các document như sau:

{ name : “Joe”, age : 30, interests : ‘football’ }

{ name : “Kate”, age : 25 }

Nhìn vào tập data, bạn có thể biết được cấu trúc (schema) của collection này. Nhưng do không có một cấu trúc ràng buộc định nghĩa sẵn từ trước nên document trong collection có thể rất tùy ý và nếu chẳng may application lưu thêm một document không có liên quan về thông tin như:

{ name : “Joe”, age : 30, interests : ‘football’ }

{ name : “Kate”, age : 25 }

{ phone : “iphone”, ios : 6 }

thì mongodb cũng chấp nhận. Tuy vậy, nhìn ở khía cạnh bớt khắt khe hơn thì không có ràng buộc lại đem đến cho mongodb khả năng linh động uyển chuyển trong cấu trúc của nó.

Agile develoment đang là xu hướng hiện nay. Với các lợi thế linh động uyển chuyển, mongodb rất thích hợp với các nhu cầu thay đổi requirement thường xuyên.

Cài đặt

vi /etc/yum.repos.d/mongodb.repo
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1
yum clean all
yum install mongodb-org

Check lại:

rpm -qa | grep -i mongo
mongodb-org-mongos-2.6.10-1.x86_64
mongodb-org-2.6.10-1.x86_64
mongodb-org-server-2.6.10-1.x86_64
mongodb-org-tools-2.6.10-1.x86_64
mongodb-org-shell-2.6.10-1.x86_64

Các thành phần cần thiết đã đủ.

Nếu bạn muốn cài đặt mongodb version 3.x thì cần bổ sung phiên bản vào file repo
Xem link sau:
http://docs.mongodb.org/master/tutorial/install-mongodb-on-red-hat/?_ga=1.190445609.385799739.1434424448

Một số chú ý:

  • Mongodb từ 3.0 hỗ trợ hai loại storage engine: NMAPV1 và WiredTiger. Mặc định, Mongo vẫn dùng NMAPV1. MongoDB sẽ không start được nếu files trong db được tạo ra bởi storage engine khác với tham số --storageEngine. Nếu bạn có ý định move data từ database này sang database khác thì cần chú ý điều này. Công sức move data sẽ đổ sông đổ bể nếu data đang có trên database mới sử dụng storage engine khác với data được move sang.
  • Sử dụng phiên bản 64 bits của mongodb vì nó ổn định hơn. Bản 32 bits không hỗ trợ WiredTiger và bị giới hạn dung lượng lưu trữ chỉ có 2GB.
  • Chạy mongo trong trust network. Mặc định mongodb không enable authorization và authentication.
  • Sử dụng ổ SSD. MongoDB sử dụng NMAPV1 rất thích hợp với SSD
  • Disable NUMA. Về nguyên nhân NUMA ảnh hưởng đến mongodb tôi cũng chưa rõ nhưng mongodb khuyến cáo NUMA cần được disable. Bạn có thể disable NUMA trong BIOS hoặc thực hiện hai thao tác sau:

    echo 0 > /proc/sys/vm/zone_reclaim_mode
    

    và khởi chạy mongod dùng numactl

    numactl --interleave=all /usr/bin/mongod
    

    Thay vì khởi chạy mongod với câu lệnh dài dòng như trên, bạn có thể dùng service script. Trong service script của mongod đã hỗ trợ chạy bằng numactl rồi.

  • Sử dụng RAID10. Tránh dùng RAID0.

Cấu hình single mongodb

Tôi sử dụng YAML format cho file cấu hình
/etc/mongod.conf

systemLog:
     destination: file
     path: /var/log/mongodb/mongod.log
     logAppend: true
     verbosity: 1
     quiet: false
     traceAllExceptions: true
     timeStampFormat: ctime
processManagement:
     fork: true
     pidFilePath: /var/run/mongodb/mongod.pid
net:
     port: 27017
     unixDomainSocket:
         enabled: false
     ipv6: false
storage:
     dbPath: /var/lib/mongo
     directoryPerDB: true
     journal:
         enabled: true

Chú ý: Đừng dùng dấu ngoặc kép khi khai báo đường dẫn. Ban đầu tôi khai báo pidFilePath: “/var/run/mongodb/mongod.pid” Sau đó tôi không thể stop service dùng service script. YAML cũng yêu cầu có cặp dấu hai chấm và một khoảng trắng để phân cách giữa key và value. Cấu trúc được hình thành bởi việc căn lề nên bạn cần chú ý căn lề chính xác

ln -s /data/db /var/lib/mongo
chown -R mongod:mongod /data/db
chown -R mongod:mongod /var/log/mongodb

Start/stop service

Start service mongod

service mongod start

Lần đâu, bạn sẽ chờ khá lâu do mongodb phải thực hiện tạo journaling file

[initandlisten] flushing directory /data/db
[initandlisten] journal dir=/data/db/journal
[initandlisten] recover : no journal files present, no recovery needed
[initandlisten] flushing directory /data/db/journal
[initandlisten] flushing directory /data/db/journal
[initandlisten] preallocateIsFaster=true 306.02
[initandlisten] flushing directory /data/db/journal
[initandlisten] flushing directory /data/db/journal
[initandlisten] preallocateIsFaster=true 177
[initandlisten] flushing directory /data/db/journal
[DataFileSync] flushing mmaps took 0ms  for 0 files
[initandlisten] flushing directory /data/db/journal
[initandlisten] preallocateIsFaster=true 173.02
[initandlisten] preallocateIsFaster check took 66.047 secs
[initandlisten] preallocating a journal file /data/db/journal/prealloc.0

Journal files được sử dụng để recover database. Vai trò của nó giống redo log trong mysql

Stop service mongod
Truy cập vào mongod qua mongo shell
[root@mongo1 mongodb]# mongo
MongoDB shell version: 2.6.10
connecting to: test

Để tắt mongod service

> use admin
switched to db admin
> db.shutdownServer()

hoặc

mongo --eval "db.getSiblingDB('admin').shutdownServer()"

hoặc

service mongod stop

Thao tác với user

Mặc định, authentication bị disable nên bạn có thể truy cập đến mongodb từ localhost lẫn remote host và có toàn bộ mọi quyền thao tác mà không có cản trở nào cả. Khi authentication được enable thì vẫn còn cơ chế localhost exception: mongodb cho phép connection đến từ localhost và có toàn bộ quyền thao tác mà không cần authentication gì cả. Ngoại lệ này áp dụng với các truy cập từ locahost và khi không có user nào được định nghĩa trong mongodb. Có thể loại bỏ ngoại lệ này bằng cách set enabledLocalhostAuthBypass về giá trị 0. Mặc định tham số này có giá trị 1

Để enable authentication bạn thêm dòng config sau:

security:
     authorization: enabled

Lúc này những truy cập từ remote host vẫn hoạt động được nhưng lại không có quyền thực hiện bất cứ hành động gì trên db:

> show dbs
listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
    "code" : 13
} at src/mongo/shell/mongo.js:47

Dựa vào localhost exception, bạn có thể truy cập mongodb từ localhost với toàn quyền để tạo user

Đầu tiên, bạn cần tạo một system user admin

> use admin
switched to db admin
> db.createUser(
   {
     user: "siteUserAdmin",
     pwd: "password",
     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
   }
 )

Login thử vào user siteUserAdmin:

mongo -u siteUserAdmin -p password admin
MongoDB shell version: 2.6.10
connecting to: admin
> 

Sử dụng siteUserAdmin, bạn có thể tạo thêm các user khác nữa:

use development

db.createUser(
    {
      user: "developer",
      pwd: "12345678",
      roles: [
         { role: "readWrite", db: "test" },
         { role: "read", db: "product" },
         { role: "readWrite", db: "development" }         
      ]
    }
)

Login thử vào user deveoper đó:

mongo -u developer -p 12345678 development
MongoDB shell version: 2.6.10
connecting to: development
>

Sau khi tạo user xong, bạn cần loại bỏ localhost exception bằng cách thêm dòng config sau:

setParameter:
     enableLocalhostAuthBypass: 0

Bạn có thể kiểm tra thông tin xác thực của user qua db.auth()
Ví dụ

use development;
db.auth("developer", "12345678");

Hoặc có thể lấy ra thông tin về user hiện tại

 db.runCommand({connectionStatus : 1})
{
    "authInfo" : {
        "authenticatedUsers" : [
            {
                "user" : "developer",
                "db" : "development"
            }
        ]
    },
    "ok" : 1
}

Các thao tác khác với user:
http://docs.mongodb.org/manual/reference/method/#user-management

Các thao tác với role:
http://docs.mongodb.org/manual/reference/method/#role-management

Thao tác với database và collections

Các thao tác với database:
http://docs.mongodb.org/manual/reference/method/#database

Dữ liệu trên disk của mongodb được lưu ở dạng các bson document. Một collection là tập hợp các document. Collection tương đương với table trong RDBMS nhưng collection không có schema. Document trong collection có thể có các field không đồng nhất nhưng về mặt logic thì thường có liên quan và chung mục đích sử dụng.

Ví dụ:

> use harryPotter
switched to db harryPotter
> db.characters.save({name:"harry"});
WriteResult({ "nInserted" : 1 })
> db.characters.save({name:"hermione", age: 18});
WriteResult({ "nInserted" : 1 })
>  db.characters.save({name:"ron"})
WriteResult({ "nInserted" : 1 })
> show collections;
characters
system.indexes
> db.characters.find()
{ "_id" : ObjectId("55803b84d5f52ae97ad0029e"), "name" : "harry" }
{ "_id" : ObjectId("558044198a5cd30efbc9578b"), "name" : "hermione", "age" : 18 }
{ "_id" : ObjectId("558044918a5cd30efbc9578c"), "name" : "ron" }

Các document trong collection harryPotter không hề có field đồng nhất.

Các thao tác với collections:
http://docs.mongodb.org/manual/reference/method/#collection

Backup và restore

Có ba cách để backup data trong mongodb:

  • Cách 1: Copying data files. Có hai hướng tiếp cận cụ thể: Hoặc là dùng filesystem snapshot nếu storage hỗ trợ hoặc là copy trực tiếp các file dùng rsync, scp. Trên linux, LVM có thể được sử dụng để tạo snapshot.
  • Cách 2: Dùng mongodump
  • Cách 3: Dùng dịch vụ MongoDB Management Service

Bài viết này tạm thời chỉ là đề cập đến copy file vật lý và dùng mongo backup/restore tool.

Mongo mà tôi thực hiện backup gọi là src-mongo 192.168.3.228
Mongo mà tôi thực hiện restore gọi là dest-mongo 192.168.3.229

Backup và restore bằng cách copy file vật lý

Files vật lý của mongodb có dạng:

admin  harryPotter  journal  local  mongod.lock

admin và local database là hai database đặc biệt. Admin là database mà bạn sẽ sử dụng để thực hiện các command quản trị. Nó cũng giữ tất cả các user của mongodb. Còn local database thì lưu data dùng cho quá trình replication. Nó lưu các internal data cho mỗi member trong replica set. Collection trong local database sẽ không được replicate. Mongodb sẽ tự động tạo lại local database nếu nó bị xóa.

Đầu tiên, bạn cần stop service mongod trên src-mongo trước khi copy. Vì cách làm này gây downtime dịch vụ nên chỉ thường dùng khi move data thôi.

Do đã stop service an toàn nên bạn không cần journal file nữa nhưng nếu không có journal file thì quá trình start service khi restore lại lâu. Bạn cũng không cần local database vì nó chỉ chứa các dữ liệu cho replication. Thực tế khi dùng mongodump, bạn sẽ không thấy có local database và journal trong output dump.

Sau đó, bạn rsync dbpath của src-mongo đến dest-mongo

rsync -avzP /data/db root@192.168.3.229:/root/

Trên dest-mongo, chúng ta sẽ phục hồi database như sau: Stop service mongod. Sau đó bạn chỉ cần đưa toàn bộ admin và các user-defiend database như harryPotter đem vào dbPath của dest-mongo rồi start service.

Sử dụng mongodump và mongorestore

Bạn sẽ có thể backup online được vì mongodump là một non-blocking backup tool.

Để backup và restore, bạn cần một account có role backup trên cả src-mongo và dest-mongo

> db.createUser(
   {
     user: "maintainUser",
     pwd: "maintainUser",
     roles: [ { role: "backup", db: "admin" },
              { role: "restore", db: "admin" } ]
   }
 )

Hoặc nếu bạn không muốn bận tâm đến role thì có thể disable security.authorization rồi restart mongod service.

Backup. Ở đây, tôi đứng trên dest-mongo để thực hiện backup src-mongo về /data/backup trên dest-mongo.

mongodump --host 192.168.3.228 --port 27017 --out /data/backup/ --username maintainUser --password maintainUser

Restore:

mongorestore --username maintainUser --password maintainUser --port 27017 /data/backup/ 

Một điểm chú ý:
Khi test thử, tôi thấy các data có trên dest-mongo không bị overwrite bởi bởi dữ liệu restore về từ src-mongo. Trên dest-mongo có account maintainUser nhưng password của user này không bị ghi đè bởi user có tên tương tự từ src-mongo. Một trường hợp khác, các document của collection cũng không bị ghi đè bởi tập document của collection có tên tương tự từ src-mongo

Bài viết chỉ mang tính chất giới thiệu. Hi vọng giúp ích cho các bạn mới bắt đầu.

Nguồn tham khảo:

http://blog.mongodb.org/post/119945109/why-schemaless
https://stackoverflow.com/questions/11707879/difference-between-scaling-horizontally-and-vertically-for-databases
http://docs.mongodb.org/manual/

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

manhdung

44 bài viết.
240 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
67 11
Giới thiệu RabbitMQ là một message broker ( messageoriented middleware) sử dụng giao thức AMQP Advanced Message Queue Protocol (Đây là giao thức ph...
manhdung viết gần 3 năm trước
67 11
Male avatar
45 4
Giả định bạn tiếp nhận một server mới toanh, bạn cần tìm một số thông tin về nó như loại CPU, loại main, loại memory, memory dùng của hãng nào... c...
manhdung viết hơn 1 năm trước
45 4
Male avatar
35 11
Trong phần 1, tôi đã giới thiệu về sơ lược rabbitmq, vai trò của rabbitmq trong hệ thống phân tán và hướng dẫn cài đặt. Trong phần này, tôi sẽ trìn...
manhdung viết hơn 2 năm trước
35 11
Bài viết liên quan
White
3 0
Khoảng 5, 7 năm nay NOSQL là đề tài rất nóng bỏng. SQL phổ biến thì chỉ có khoảng vài ba cái như PostgreSQL, MySQL, MS SQL, Oracle nói chung na na ...
Ngoc Dao viết gần 2 năm trước
3 0
White
3 1
Chatbotlà khái niệm không mới nhưng gần đây trở thành hot trend khi kết hợp cùng machine learning và AI. Mình sẽ có một bài viết cụ thể hơn về kỹ t...
Mầu Hà Quang viết 30 ngày trước
3 1
White
0 0
1, Cài đặt MongoDB. Đầu tiên các bạn truy cập vào địa chỉ website https://www.mongodb.com//downloadcenter?jmp=nav Và làm theo hình ảnh dưới đây (l...
Thanh Tài viết 7 tháng trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
44 bài viết.
240 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!