如何设置一个可扩展的MongoDB数据库?
MongoDB是一款NoSQL数据库,功能强大,诸如复制和内置分片,你可以通过给服务器分布内容,将数据库扩展至任意多的服务器。
安装与MongoDB有关的任何东西之前,我们需要确认选择了正确的硬件,并调试好了软件。
1. 硬盘驱动
如果你可以选择即将用到的硬件驱动,可以将企业级双SSD升级为RAID1。正如我们之前提到的,它性能卓越,节省费用。
在Linux编辑你的/etc/fstab文件,并确保在将要和MongoDB使用的挂载点禁用“访问时间logging”(access time logging)。在第4栏添加noatime:
重新挂接分区:
[root@mongodb1 ~]# mount -o remount /
验证新的设置生效:
[root@mongodb1 ~]# mount
/dev/sda on / type ext4 (rw,noatime)
2. CPU和内存
在一个虚拟机监视器上,将MongoDB作为一个虚拟机进行设置,这样你可以在以后扩展RAM和CPU内核。应该分配的CPU内核和RAM的大小取决于你的基础设施的需求以及预算。
3. 优化
最有用的技巧是优化你的数据库查询:
· 给常用的搜索查询和分类查询添加索引。
· 使用MongoDB的explain()命令。
· 限制搜索结果,限制返回结果的字段。
出于测试目的,我们来看一下这3个droplet:
安装
这一过程在mongodb1,mongodb2,mongodb3上都是一样的。
在CentOS上安装MongoDB非常简单。
编辑下面的命令添加库:
/etc/yum.repos.d/10gen.repo
[10gen] name=10gen baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64 gpgcheck=0 enabled=1
现在安装包
[root@mongodb1 ~]# yum -y install mongo-10gen mongo-10gen-server
让MongoDB在电脑重启之后启动,并启动服务器:
[root@mongodb1 ~]# chkconfig mongod on && service mongod start
Starting mongod: forked process: 1387 all output going to: /var/log/mongo/mongod.log child process started successfully, parent exiting [ OK ]
现在你应该看一下http://SERVER:28017/上的统计
建立一个Master-Slave副本集
我们将把mongodb1作为一个主服务器,添加“master = true”到/etc/mongod.conf 然后执行
service mongod restart
Mongodb2和mongodb3会被设置为副服务器。
添加 “slave=true”, “source = mongodb1” 到 /etc/mongod.conf 然后执行
service mongod restart
现在我们应该让这个数据库更安全,设置一个密码或添加ip信息包过滤系统(iptables)规则到27017端口(MongoDB)和28017端口(网络界面)。
创建一个用户和密码:
> use test
> db.addUser('admin', 'password');
{
"user" : "admin",
"readOnly" : false,
"pwd" : "90f500568434c37b61c8c1ce05fdf3ae",
"_id" : ObjectId("50eaae88790af41ffffdcc58")
}
我们同样应该添加防火墙规则来限制其他的MongoDB服务器,我们的IP,并保存:
[root@mongodb1 ~]# iptables -N MongoDB [root@mongodb1 ~]# iptables -I INPUT -s 0/0 -p tcp --dport 27017 -j MongoDB [root@mongodb1 ~]# iptables -I INPUT -s 0/0 -p tcp --dport 28017 -j MongoDB [root@mongodb1 ~]# iptables -I MongoDB -s 127.0.0.1 -j ACCEPT [root@mongodb1 ~]# iptables -I MongoDB -s 192.34.57.64 -j ACCEPT [root@mongodb1 ~]# iptables -I MongoDB -s 192.34.56.123 -j ACCEPT [root@mongodb1 ~]# iptables -I MongoDB -s 192.34.57.162 -j ACCEPT [root@mongodb1 ~]# iptables -A MongoDB -s 0/0 -j DROP [root@mongodb1 ~]# /etc/init.d/iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
在其他的MongoDB服务器上(mongodb2, mongodb3)重复这一步骤。如果你是在前端使用PHP,需要给PHP安装MongoDB模块:
[root@webserver ~]# pecl install mongo [root@webserver ~]# echo extension=mongo.so >> `php -i | grep /php.ini | awk '{print $5}'` [root@webserver ~]# service httpd restart
用数据填充数据库
现在我们可以开始测试我们的新设置了,你可以在命令编辑器(command shell)输入mongo,进入到数据库:
[root@mongodb1 ~]# mongo
MongoDB shell 版本:2.2.2连接到:测试
我们现在进入纽约时报畅销书排行榜的数据库,来进行测试:
> db.books.save( { title: 'Safe Haven', author: 'Nicholas Sparks' } ) > db.books.save( { title: 'Gone Girl', author: 'Gillian Flynn' } ) > db.books.save( { title: 'The Coincidence Of Callie And Kayden', author: 'Jessica Sorensen' } ) > db.books.save( { title: 'Fifty Shades of Grey', author: 'E.L. James' } ) > db.books.save( { title: 'Hopeless', author: 'Colleen Hoover' } )
显示所有结果:
> db.books.find() { "_id" : ObjectId("50eaaa4b633625147f205994"), "title" : "Safe Haven", "author" : "Nicholas Sparks" } { "_id" : ObjectId("50eaaa62633625147f205995"), "title" : "Gone Girl", "author" : "Gillian Flynn" } { "_id" : ObjectId("50eaaa8d633625147f205996"), "title" : "The Coincidence Of Callie And Kayden", "author" : "Jessica Sorensen" } { "_id" : ObjectId("50eaaaa0633625147f205997"), "title" : "Fifty Shades of Grey", "author" : "E.L. James" } { "_id" : ObjectId("50eaaab3633625147f205998"), "title" : "Hopeless", "author" : "Colleen Hoover" }
你应该能在mongodb2和mongodb3上看到相同的入口(entries),因为他们是一个副本集:
你可以进入这些书的所有数据值,比如发行者名字,ISBN号,平均客户评价,书写语言等等。为了能优化你的查询,最好限制一下结果数量和返回的字段数量。
例如,只返回两个结果我们会在最后用到limit():
> db.books.find( {}, { title : 1 , author: 1 } ).sort( { timestamp : -1 } ).limit(2) { "_id" : ObjectId("50eaaa4b633625147f205994"), "title" : "Safe Haven", "author" : "Nicholas Sparks" } { "_id" : ObjectId("50eaaa62633625147f205995"), "title" : "Gone Girl", "author" : "Gillian Flynn" }
一旦达到了当前设置的最大容量,你可以将数据库分片,这方面我们会在以后的文章中详解。