OpenStack Ceilometer -- 后台數據存儲優化之MongoDB的分片存儲設置


https://xiaofandh12.github.io/Mongo-Shard

MongoDB中的概念與關系型數據庫之間的對應:

  • Database --> Database
  • Collection --> Table
  • Document --> Row

MongoDB相較於關系型數據庫的優勢:

  • 簡化關系型數據庫復雜的關聯問題
  • 擺脫關系模型里面的強一致性限制
  • MongoDB可以做到水平擴展和高可用

學習MongoDB有幾個比較重要的方面:

  • CRUD操作
  • 聚合(Aggregation)操作
  • 索引(Indexs)
  • 存儲引擎(Storage)
  • 復制集(Replication)
  • 分片(Sharding)
  • 各種命令
  • yum info mongo-10gen查看yum源中是否包含MongoDB的相關資源。

  • vi /etc/yum.repos.d/10gen.repo添加yum源,若已有則不添加。

    1. [10gen]
    2. name=10gen Repository
    3. baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
    4. gpgcheck=0
  • yum info mongo-10gen-server,配置好yum源之后,查看yum源中是否包含MongoDB的服務器包的信息。

  • 安裝MongoDB的服務器端和客戶端工具:

    1. yum install mongo-10gen-server
    2. yum install mongo-10gen
  • 根據需要修改/etc/mongod.conf,啟動MongoDB: service mongod start

  • 相關操作如下:

    1. [root@node-51 ~]# mongo --host hostIP/hostName --port portNum
    2. mongos> show dbs
    3. admin *GB
    4. ceilometer *GB
    5. config *GB
    6. mongos> use ceilometer
    7. mongos> show collections
    8. meter
    9. project
    10. resource
    11. system.indexes
    12. system.users
    13. user
  • 相關操作如下:

    1. mongos> db.meter.find()
    2. mongos> db.meter.find().count()
  • 相關操作如下:

    1. mongos> db.meter.distinct("counter_name")
  • 相關操作如下:

    1. mongos> db.meter.aggregate([
    2. {
    3. $group: {
    4. _id: "$counter_name",
    5. count: {$sum:1}
    6. }
    7. },
    8. { $match: { count: { $gt: 1 } } }
    9. ])

我們一般對SQL型的數據庫比較熟,因此對一些復雜的查詢我們可以用SQL的思維來思考,再到頁面SQL to Aggregation Mapping Chart中去尋找對應的MongoDB的查詢方式

  • 相關操作如下:

    1. mongos> db.meter.aggregate([
    2. {
    3. $match: {
    4. counter_name: "hardware.memory.total"
    5. }
    6. },
    7. {
    8. $group: {
    9. _id: {
    10. counter_name: "$counter_name",
    11. resource_id: "$resource_id"
    12. }
    13. }
    14. }
    15. ])

一個完整的數據庫可以備份為多份,原始的數據庫和備份的數據庫就組成了一個復制集,由此可以提高容錯性。

一個完整的數據庫的數據可以進行分片,通過分片可以把數據庫中的完整數據分為多份分別存儲在多台機器中,由此可以提高吞吐量。

分片和復制集是分開的兩個功能,可以只做分片,也可以只做復制集。

如果既有分片又有復制集的話,那么同一個分片組成的集合就是一個復制集,如一個數據庫分為兩片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 Sharding

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)即可對數據庫進行讀寫。

  1. 新建數據目錄和日志目錄

    1. [root@node-51 ~]# mkdir -p /data/shard/s0
    2. [root@node-51 ~]# mkdir -p /data/shard/s1
    3. [root@node-51 ~]# mkdir -p /data/shard/log
  2. 配置shard server

    1. [root@node-51 ~]# /usr/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath /data/shard/log/s0.log --directoryperdb
    2. [root@node-51 ~]# /usr/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
  3. 配置config server和route server

    1. [root@node-51 ~]# mkdir -p /data/shard/config
    2. [root@node-51 ~]# /usr/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
    3. [root@node-51 ~]# /usr/bin/mongos --port 27017 --configdb 172.31.2.51:30000 --fork --logpath /data/shard/log/route.log --chunkSize 1
  4. admin數據庫和ceilometer數據庫配置

    1. [root@node-51 ~]# mongo admin --host 172.31.2.51 --port 27017
    2. mongos> use admin
    3. mongos> db.runCommand({addshard:'172.31.2.51:20000'})
    4. mongos> db.runCommand({addshard:'172.31.2.51:20001'})
    5. mongos> db.runCommand({enablesharding:'ceilometer'})
    6. mongos> db.runCommand({shardcollecton:'ceilometer.meter',key:{counter_name:1}})
    7. mongos> use ceilometer
    8. mongos> db.addUser("ceilometer","ceilometer")
    9. mongos> db.meter.stats()

    在這里ceilometer是一個新建的數據庫,OpenStack模塊的openstack-ceilometer需要連接MongoDB中的ceilometer數據庫,而openstack-ceilomter在連接MongoDB中的ceilometer數據庫時,使用的是用戶名:ceilometer,密碼:ceilometer來連接的(再安裝openstack-ceilometer時設置的),所以有了db.addUser("ceilometer","ceilomter")。

  5. 修改ceilometer.conf,並重啟ceilometer服務

    將ceilometer.conf中的connection改為如下:

    1. connection=mongodb://ceilometer:ceilometer@172.31.2.51:27017/ceilometer

    重啟ceilometer服務:

    1. [root@node-51 ~]# service openstack-ceilometer-alarm-evalutor restart
    2. [root@node-51 ~]# service openstack-ceilometer-alarm-notifier restart
    3. [root@node-51 ~]# service openstack-ceilometer-api restart
    4. [root@node-51 ~]# service openstack-ceilometer-central restart
    5. [root@node-51 ~]# service openstack-ceilometer-collector restart

現在有一個問題是,設置好分片重啟機器后,又得重新執行分片的命令。目前解決的辦法是在/etc/rc.d/rc.local/中新增命令。

  • 關閉mongod開機啟動:

    1. [root@node-51 ~]# chkconfig --list | grep mongod --> 可以查出mongod在哪幾個運行級別上運行了
    2. [root@node-51 ~]# chkconfig --levels 2345 mongod off
  • 在文件/etc/rc.d/rc.local中,增加下述內容:

    1. /usr/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath /data/shard/log/s0.log --directoryperdb
    2. /usr/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
    3. /usr/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
    4. /usr/bin/mongos --port 27017 --configdb 172.31.2.51:30000 --fork --logpath /data/shard/log/route.log --chunkSize 1
    5. service openstack-ceilometer-alarm-evalutor restart
    6. service openstack-ceilometer-alarm-notifier restart
    7. service openstack-ceilometer-api restart
    8. service openstack-ceilometer-central restart
    9. service openstack-ceilometer-collector restart

這個問題沒算完全解決,有空再看看《鳥哥的linux私房菜》第18章 認識系統服務(daemons)和第20章 啟動流程、模塊管理與Loader。

這小節我會介紹一下把MongoDB中的數據庫分為三片,並且把三個分片存儲在不同物理機上的方法。

Mongo-Shard

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)即可對數據庫進行讀寫。

下面詳細介紹一下整個過程:

  1. 安裝好操作系統,安裝好MongoDB,重要提醒:關閉iptables,seLinux(因為這個我中午都沒睡成午覺...)

    1. service iptables stop
    2. setenforce 0
  2. 在mongos1, mongos2, mongos3中新建目錄

    1. [root@mongos1 ~]# mkdir -p /data/shard/s1
    2. [root@mongos1 ~]# mkdir -p /data/shard/log
    3. [root@mongos1 ~]# mkdir -p /data/shard/config
    4. [root@mongos2 ~]# mkdir -p /data/shard/s2
    5. [root@mongos2 ~]# mkdir -p /data/shard/log
    6. [root@mongos3 ~]# mkdir -p /data/shard/s3
    7. [root@mongos3 ~]# mkdir -p /data/shard/log
  3. 在mongos1, mongos2, mongos3中配置shard server

    1. [root@mongos1 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb
    2. [root@mongos2 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s2 --fork --logpath /data/shard/log/s2.log --directoryperdb
    3. [root@mongos3 ~]# mongod --shardsvr --port 27018 --dbpath /data/shard/s3 --fork --logpath /data/shard/log/s3.log --directoryperdb
  4. 在mongos1中配置config server

    1. [root@mongos1 ~]# mongod --configsvr --port 27019 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb
  5. 在mongos1中配置route server

    1. [root@mongos1 ~]# mongos --port 27017 --configdb 172.31.2.135:27019 --fork --logpath /data/shard/log/route.log --chunkSize 1
  6. 在mongos1中配置admin數據庫和ceilometer數據庫

    1. [root@mongos1 ~]# mongo admin --host 172.31.2.135 --port 27017
    2. mongos> db.runCommand({addshard:'172.31.2.135:27018'})
    3. mongos> db.runCommand({addshard:'172.31.2.136:27018'})
    4. mongos> db.runCommand({addshard:'172.31.2.137:27018'})
    5. mongos> db.runCommand({enablesharding:'ceilometer'})
    6. mongos> db.runCommand({shardCollection:'ceilometer.meter',key:{counter_name:1}})
    7. mongos> use ceilometer
    8. mongos> db.addUser("ceilometer", "ceilometer")
    9. mongos> db.meter.stats()
    10. mongos> sh.status()
  7. 修改ceilometer.conf,並重啟ceilometer服務

    將ceilometer.conf中的connection改為如下:

    1. connection=mongodb://ceilometer:ceilometer@172.31.2.135:27017/ceilometer

    重啟ceilometer服務:

    1. [root@node-51 ~]# service openstack-ceilometer-alarm-evalutor restart
    2. [root@node-51 ~]# service openstack-ceilometer-alarm-notifier restart
    3. [root@node-51 ~]# service openstack-ceilometer-api restart
    4. [root@node-51 ~]# service openstack-ceilometer-central restart
    5. [root@node-51 ~]# service openstack-ceilometer-collector restart

    可以再到mongos1中去查看數據量db.meter.find().count(),每隔一段時間執行一次,數字是不是越來越大。

當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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM