https://xiaofandh12.github.io/Mongo-Shard
關於MongoDB
MongoDB中的概念與關系型數據庫之間的對應:
- Database --> Database
- Collection --> Table
- Document --> Row
MongoDB相較於關系型數據庫的優勢:
- 簡化關系型數據庫復雜的關聯問題
- 擺脫關系模型里面的強一致性限制
- MongoDB可以做到水平擴展和高可用
學習MongoDB有幾個比較重要的方面:
- CRUD操作
- 聚合(Aggregation)操作
- 索引(Indexs)
- 存儲引擎(Storage)
- 復制集(Replication)
- 分片(Sharding)
- 各種命令
MongoDB的部署
-
yum info mongo-10gen
查看yum源中是否包含MongoDB的相關資源。 -
vi /etc/yum.repos.d/10gen.repo
添加yum源,若已有則不添加。[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
-
yum info mongo-10gen-server
,配置好yum源之后,查看yum源中是否包含MongoDB的服務器包的信息。 -
安裝MongoDB的服務器端和客戶端工具:
yum install mongo-10gen-server
yum install mongo-10gen
-
根據需要修改
/etc/mongod.conf
,啟動MongoDB:service mongod start
。
MongoDB的簡單操作
連接MongoDB
-
相關操作如下:
[root@node-51 ~]# mongo --host hostIP/hostName --port portNum
mongos> show dbs
admin *GB
ceilometer *GB
config *GB
mongos> use ceilometer
mongos> show collections
meter
project
resource
system.indexes
system.users
user
查詢meter中所有的數據
-
相關操作如下:
mongos> db.meter.find()
mongos> db.meter.find().count()
查詢meter中所有的counter_name
-
相關操作如下:
mongos> db.meter.distinct("counter_name")
查詢meter中各counter_name有多少條記錄
-
相關操作如下:
mongos> db.meter.aggregate([
{
$group: {
_id: "$counter_name",
count: {$sum:1}
}
},
{ $match: { count: { $gt: 1 } } }
])
我們一般對SQL型的數據庫比較熟,因此對一些復雜的查詢我們可以用SQL的思維來思考,再到頁面SQL to Aggregation Mapping Chart中去尋找對應的MongoDB的查詢方式
查詢counter_name為hardware.memory.total時,resource_id分別為什么
-
相關操作如下:
mongos> db.meter.aggregate([
{
$match: {
counter_name: "hardware.memory.total"
}
},
{
$group: {
_id: {
counter_name: "$counter_name",
resource_id: "$resource_id"
}
}
}
])
分片與復制集(Sharding與Replication)
一個完整的數據庫可以備份為多份,原始的數據庫和備份的數據庫就組成了一個復制集,由此可以提高容錯性。
一個完整的數據庫的數據可以進行分片,通過分片可以把數據庫中的完整數據分為多份分別存儲在多台機器中,由此可以提高吞吐量。
分片和復制集是分開的兩個功能,可以只做分片,也可以只做復制集。
如果既有分片又有復制集的話,那么同一個分片組成的集合就是一個復制集,如一個數據庫分為兩片shard1、shard2,可以再分別對shard1、shard2做兩個復制shard1_1、shard1_2、shard2_1、shard2_2,那么shard1、shar1_1、shard1_2組成一個復制集,shard2、shard2_1、shard2_2組成另一個復制集。
MongoDB的每一個分片或復制集中的分片都可以不存儲在同一個機器上,只要指定好IP地址和端口號即可。
本文並不討論復制集的問題。
MongoDB的分片,分為兩片,兩個分片在同一台物理機上
node-51為一台物理機,它的IP地址為172.31.2.51。
圖中各服務所在IP和端口號,對應過來如下:
- shard1 --> 172.31.2.51:20000
- shard2 --> 172.31.2.51:20001
- config --> 172.31.2.51:30000
- mongos --> 172.31.2.51:27017
client通過mongos(172.31.2.51:27017)即可對數據庫進行讀寫。
-
新建數據目錄和日志目錄
[root@node-51 ~]# mkdir -p /data/shard/s0
[root@node-51 ~]# mkdir -p /data/shard/s1
[root@node-51 ~]# mkdir -p /data/shard/log
-
配置shard server
[root@node-51 ~]# /usr/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath /data/shard/log/s0.log --directoryperdb
[root@node-51 ~]# /usr/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
-
配置config server和route server
[root@node-51 ~]# mkdir -p /data/shard/config
[root@node-51 ~]# /usr/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
[root@node-51 ~]# /usr/bin/mongos --port 27017 --configdb 172.31.2.51:30000 --fork --logpath /data/shard/log/route.log --chunkSize 1
-
admin數據庫和ceilometer數據庫配置
[root@node-51 ~]# mongo admin --host 172.31.2.51 --port 27017
mongos> use admin
mongos> db.runCommand({addshard:'172.31.2.51:20000'})
mongos> db.runCommand({addshard:'172.31.2.51:20001'})
mongos> db.runCommand({enablesharding:'ceilometer'})
mongos> db.runCommand({shardcollecton:'ceilometer.meter',key:{counter_name:1}})
mongos> use ceilometer
mongos> db.addUser("ceilometer","ceilometer")
mongos> db.meter.stats()
在這里ceilometer是一個新建的數據庫,OpenStack模塊的openstack-ceilometer需要連接MongoDB中的ceilometer數據庫,而openstack-ceilomter在連接MongoDB中的ceilometer數據庫時,使用的是用戶名:ceilometer,密碼:ceilometer來連接的(再安裝openstack-ceilometer時設置的),所以有了db.addUser("ceilometer","ceilomter")。
-
修改ceilometer.conf,並重啟ceilometer服務
將ceilometer.conf中的connection改為如下:
connection=mongodb://ceilometer:ceilometer@172.31.2.51:27017/ceilometer
重啟ceilometer服務:
[root@node-51 ~]# service openstack-ceilometer-alarm-evalutor restart
[root@node-51 ~]# service openstack-ceilometer-alarm-notifier restart
[root@node-51 ~]# service openstack-ceilometer-api restart
[root@node-51 ~]# service openstack-ceilometer-central restart
[root@node-51 ~]# service openstack-ceilometer-collector restart
Mongodb分片后的開機啟動設置
現在有一個問題是,設置好分片重啟機器后,又得重新執行分片的命令。目前解決的辦法是在/etc/rc.d/rc.local/中新增命令。
-
關閉mongod開機啟動:
[root@node-51 ~]# chkconfig --list | grep mongod --> 可以查出mongod在哪幾個運行級別上運行了
[root@node-51 ~]# chkconfig --levels 2345 mongod off
-
在文件/etc/rc.d/rc.local中,增加下述內容:
/usr/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath /data/shard/log/s0.log --directoryperdb
/usr/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
/usr/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
/usr/bin/mongos --port 27017 --configdb 172.31.2.51:30000 --fork --logpath /data/shard/log/route.log --chunkSize 1
service openstack-ceilometer-alarm-evalutor restart
service openstack-ceilometer-alarm-notifier restart
service openstack-ceilometer-api restart
service openstack-ceilometer-central restart
service openstack-ceilometer-collector restart
這個問題沒算完全解決,有空再看看《鳥哥的linux私房菜》第18章 認識系統服務(daemons)和第20章 啟動流程、模塊管理與Loader。
MongoDB的分片,分為三片,三個分片在不同的物理機上
這小節我會介紹一下把MongoDB中的數據庫分為三片,並且把三個分片存儲在不同物理機上的方法。
mongos1,mongos2,mongos3代表三台物理機,它們的IP地址為:
- mongos1 --> 172.31.2.135
- mongos2 --> 172.31.2.136
- mongos3 --> 172.31.2.137
圖中各服務所在IP和端口號,對應過來如下:
- shard1 --> 172.31.2.135:27018
- shard2 --> 172.31.2.136:27018
- shard3 --> 172.31.2.137:27018
- config1 --> 172.31.2.135:27019
- mongos1 --> 172.31.2.135:27017
client通過連接mongos1(172.31.2.135:27017)即可對數據庫進行讀寫。
下面詳細介紹一下整個過程:
-
安裝好操作系統,安裝好MongoDB,重要提醒:關閉iptables,seLinux(因為這個我中午都沒睡成午覺...)
service iptables stop
setenforce 0
-
在mongos1, mongos2, mongos3中新建目錄
[root@mongos1 ~]# mkdir -p /data/shard/s1
[root@mongos1 ~]# mkdir -p /data/shard/log
[root@mongos1 ~]# mkdir -p /data/shard/config
[root@mongos2 ~]# mkdir -p /data/shard/s2
[root@mongos2 ~]# mkdir -p /data/shard/log
[root@mongos3 ~]# mkdir -p /data/shard/s3
[root@mongos3 ~]# mkdir -p /data/shard/log
-
在mongos1, mongos2, mongos3中配置shard server
[root@mongos1 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
[root@mongos2 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s2 --fork --logpath /data/shard/log/s2.log --directoryperdb
[root@mongos3 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s3 --fork --logpath /data/shard/log/s3.log --directoryperdb
-
在mongos1中配置config server
[root@mongos1 ~]# mongod --configsvr --port 27019 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
-
在mongos1中配置route server
[root@mongos1 ~]# mongos --port 27017 --configdb 172.31.2.135:27019 --fork --logpath /data/shard/log/route.log --chunkSize 1
-
在mongos1中配置admin數據庫和ceilometer數據庫
[root@mongos1 ~]# mongo admin --host 172.31.2.135 --port 27017
mongos> db.runCommand({addshard:'172.31.2.135:27018'})
mongos> db.runCommand({addshard:'172.31.2.136:27018'})
mongos> db.runCommand({addshard:'172.31.2.137:27018'})
mongos> db.runCommand({enablesharding:'ceilometer'})
mongos> db.runCommand({shardCollection:'ceilometer.meter',key:{counter_name:1}})
mongos> use ceilometer
mongos> db.addUser("ceilometer", "ceilometer")
mongos> db.meter.stats()
mongos> sh.status()
-
修改ceilometer.conf,並重啟ceilometer服務
將ceilometer.conf中的connection改為如下:
connection=mongodb://ceilometer:ceilometer@172.31.2.135:27017/ceilometer
重啟ceilometer服務:
[root@node-51 ~]# service openstack-ceilometer-alarm-evalutor restart
[root@node-51 ~]# service openstack-ceilometer-alarm-notifier restart
[root@node-51 ~]# service openstack-ceilometer-api restart
[root@node-51 ~]# service openstack-ceilometer-central restart
[root@node-51 ~]# service openstack-ceilometer-collector restart
可以再到mongos1中去查看數據量db.meter.find().count(),每隔一段時間執行一次,數字是不是越來越大。
MongoDB:Expire Data from Collections by Setting TTL
當MongoDB數據庫中的數據量變得很大時,查詢的速度也會隨之下降,定期的刪除或轉存數據庫中的數據就成為了一個很重要的需求了。
在MongoDB 2.2中就引進了一個功能,即Expire Data from Collections by Setting TTL,有了這個功能我們只要做一個簡單的設置就可以定期的刪除歷史數據了。
在Ceilometer的配置文件中,設置了ttl的相關參數后,Ceiloemter的后台數據庫就會去自動清理數據庫中的歷史數據,而后台數據庫不論是MongoDB還是關系型數據庫都可以,當后台是MongoDB時就正是利用了MongoDB 2.2中引入的Expire Data from Collections by Setting TTL這項功能。
Ceilometer中新增自動清理數據庫中的歷史數據的blueprint頁面為:Database data TTL,review頁面為:Database data TTL Review