同事說網上有篇《PostgreSQL的NoSQL特性表現搶眼,多個方面優於MongoDB》,見
http://www.infoq.com/cn/news/2014/09/postgres-outperforms-mongodb?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global&utm_reader=feedly
先不說pg的NoSQL特性的事。
到網上找了個《mongodb分佈式集羣架構》,放到這兒備查
該文轉自http://freeze.blog.51cto.com/1846439/884925
一、關於mongodb
MongoDB是一個基於分佈式文件存儲的數據庫。由C++語言編寫。旨在爲WEB應用提供可擴展的高性能數據存儲解決方案。 MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。他支持的數據結構非常鬆散,是類似json的bjson格式,因此可以存儲比較複雜的數據類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。 |
二、mongodb分佈式應用原理
MongoDB集羣包括一定數量的mongod(分片存儲數據)、mongos(路由處理)、config server(配置節點)、clients(客戶端)、arbiter(仲裁節點:爲了選舉某個分片存儲數據節點那臺爲主節點)。 |
1、shards:一個shard爲一組mongod,通常一組爲兩臺,主從或互爲主從,這一組mongod中的數據時相同的,具體可見《mongodb分佈式之數據複製》。數據分割按有序分割方式,每個分片上的數據爲某一範圍的數據塊,故可支持指定分片的範圍查詢,這同google的BigTable 類似。數據塊有指定的最大容量,一旦某個數據塊的容量增長到最大容量時,這個數據塊會切分成爲兩塊;當分片的數據過多時,數據塊將被遷移到系統的其他分片中。另外,新的分片加入時,數據塊也會遷移。2、mongos:可以有多個,相當於一個控制中心,負責路由和協調操作,使得集羣像一個整體的系統。mongos可以運行在任何一臺服務器上,有些選擇放在shards服務器上,也有放在client 服務器上的。mongos啓動時需要從config servers上獲取基本信息,然後接受client端的請求,路由到shards服務器上,然後整理返回的結果發回給client服務器。3、config server:存儲集羣的信息,包括分片和塊數據信息。主要存儲塊數據信息,每個config server上都有一份所有塊數據信息的拷貝,以保證每臺config server上的數據的一致性。4、shard key:爲了分割數據集,需要制定分片key的格式,類似於用於索引的key格式,通常由一個或多個字段組成以分發數據,比如:{ name : 1 }{ _id : 1 }{ lastname : 1, firstname : 1 }{ tag : 1, timestamp : -1 }mongoDB的分片爲有序存儲(1爲升序,-1爲降序),shard key相鄰的數據通常會存在同一臺服務(數據塊)上。
三、mongodb分佈式部署方式
當然也有其他的方案,比如把mongos部署在所有的mongod(server1-6)上,又或者在每個運用服務器(server7)上部署mongos。這樣部署有個好處在於,appserver和mongos之間的通信建立在localhost interface上,減少了通信成本。當然,此乃官方說法,但本人有想法,儘管減少了appserver和mongos之間的通信成本,但mongos與mongod之間的通信成本卻增加了,而且把mongos部署在appserver上並不是很利於sa管理,mongoDB應該是一個相對獨立的系統,與應用的耦合度應該儘量降到最低,萬一應用想要換數據庫,也能多少減少些工作量。 |
wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.4.tgz
tar zxvf mongodb-linux-2.0.4.tgzcp -fr mongodb-linux-*2.0.4/* /data/mongodb/mkdir -p /data/mongodb/data/ #創建數據存儲目錄mkdir -p /data/mongodb/log/ #創建日誌存儲目錄mkdir -p /data/mongodb/config/ #創建配置存儲目錄mkdir -p /data/mongodb/arbiter/ #創建仲裁節點存儲目錄
mongod --fork --bind_ip 127.0.0.1 --port 11811 --dbpath /data0/mongodb/data --directoryperdb --logpath /data0/mongodb/log/db1.log --logappend --nohttpinterfacenetstat -ntlp|grep mongod
簡單的參數說明:–logpath 日誌文件路徑–master 指定爲主機器–slave 指定爲從機器–source 指定主機器的IP地址–pologSize 指定日誌文件大小不超過64M.因爲resync是非常操作量大且耗時,最好通過設置一個足夠大的oplogSize來避免resync(默認的 oplog大小是空閒磁盤大小的5%)。–logappend 日誌文件末尾添加–port 啓用端口號–fork 在後臺運行–only 指定只複製哪一個數據庫–slavedelay 指從複製檢測的時間間隔–auth 是否需要驗證權限登錄(用戶名和密碼)–noauth 不需要驗證權限登錄(用戶名和密碼)
1.Shard分片--第一組分片 192.168.200.226: /data/mongodb/bin/mongod --replSet rep1 --fork --port 11813 --maxConns 65535 --dbpath /data/mongodb/data --directoryperdb --logpath /data/mongodb/log/db.log --logappend --nohttpinterface#啓動rep1分片的一個數據節點/data/mongodb/bin/mongos --configdb 192.168.201.226:11812 --port 11811 --fork --chunkSize 256 --logpath /data/mongodb/log/ms.log #啓動路由節點,讀取201.226上的配置節點的配置文件,(在配置節點啓動後啓動)/data/mongodb/bin/mongod --replSet rep1 --fork --port 11814 --dbpath /data/mongodb/arbiter --directoryperdb --logpath /data/mongodb/log/arbiter.log --logappend --nohttpinterface#啓動分片的仲裁節點192.168.201.226: /data/mongodb/bin/mongod --replSet rep1 --fork --port 11813 --maxConns 65535 --dbpath /data/mongodb/data --directoryperdb --logpath /data/mongodb/log/db.log --logappend --nohttpinterface#啓動rep1分片的第二個數據節點/data/mongodb/bin/mongos --configdb 192.168.201.226:11812 --port 11811 --fork --chunkSize 256 --logpath /data/mongodb/log/ms.log #啓動第二個路由節點 (在配置節點啓動後啓動)2.ConfigServer--- #啓動config server 192.168.201.226: /data/mongodb/bin/mongod --configsvr --dbpath /data/mongodb/config --port 11812 --fork --logpath /data/mongodb/log/mc.log#啓動配置節點,注意配置節點應該優先啓動,不然路由節點讀取不到配置節點信息則會啓動失敗。3.Mongos路由--- #啓動mongos,指定config server, chunkSize 256M 192.168.201.226: /data/mongodb/bin/mongos --configdb 192.168.201.226:11812 --port 11811 --fork --chunkSize 256 --logpath /data/mongodb/log/ms.log#啓動路由節點
4.配置replSet: 連接任一mongod membersmongo 192.168.201.226:11813config = {_id: 'rep1', members: [{_id: 0, host: '192.168.200.226:11813', priority: 2}, #priority 爲定義優先級,默認爲1,高優先級會被認爲是主節點優先啓用。{_id: 1, host: '192.168.201.226:11813'},{_id: 2, host: '192.168.200.226:11814', arbiterOnly: true}]} rs.initiate(config); rs.status()
5.連接mongos增加shard 80G mongo 192.168.201.226:11811/admin show dbs use admin db.runCommand({addshard:'rep1/192.168.201.226:11813,192.168.200.226:11813',maxsize:81920}) db.runCommand({listshards:1})
-
6.連接mongos增加創建test庫和c1集合,並測試
-
mongo 192.168.201.226:11811/admin
-
db.runCommand({enablesharding:'test'})
-
printShardingStatus()
-
db.runCommand({shardcollection:'test.auto_increment_id', key:{_id:1}, unique : true})
-
db.runCommand({shardcollection:'test.c1', key:{_id:1}, unique : true})
-
for (var i = 1; i <= 100; i++)db.c1.save({id:i,value1:"1234567890",value2:"1234567890",value3:"1234567890",value4:"1234567890"})
-
db.c1.stats()
-
db.createCollection("cap_coll", {capped:true, size:100000, max:100});
-
db.mycoll.validate();
-
-
7.檢查: db.printCollectionStats()
-
-
8.管理: mongo 127.0.0.1:11811
-
show dbs
-
use admin
-
show collections
-
db.serverStatus()
-
db.shutdownServer()
-
exit
9.索引:db.product_data.ensureIndex({data_id: 1}, {unique: true,dropDups: true}); #創建索引db.product_data.dropIndexes(); #刪除索引
至此,mongodb的分佈式架構就架起來了,並且通過測試和log的分析,可看服務是否正常,下面就需要php客戶端的支持,和程序的運行,之後加到監控裏,就可以在線上部署使用了。 |
# wget http://pecl.php.net/get/mongo-1.2.6.tgz # tar zxvf mongo-1.2.6.tgz # cd mongo-1.2.6 # /usr/local/php5/bin/phpize # ./configure --enable-mongo=share--with-php-config=/usr/local/php5/bin/php-config # make && make installl
將生成的拓展mongo.so文件添加到php.ini中,重啓php-fpm,或者apache,然後查看下phpinfo()請編輯php.ini文件。添加如下一行:extension=mongo.so然後用php輸出:phpinfo,就可以看到mongo的信息了。。這樣就說明你安裝成功的了!
ssh-keygen ##如果是root用戶,生成的默認目錄爲/root/.ssh下2個文件id_rsa(公鑰) id_rsa.pub(私鑰)cd /root/.ssh/ && chmod 600 id_rsa* 把這2個文件修改權限,爲600 ssh-copy-id -i /root/.ssh/id_rsa [email protected] #加被監控節點公私鑰認證
mongodb或redis的監控所需到的是你下載目錄中的better-cacti-templates-1.1.8\scripts下的ss_get_by_ssh.php 這個腳本 這個腳本需要放在cacti的服務端。如果你cacti是裝到/var/www/html/cacti/目錄下。把該文件放在其下面的scripts目錄下。別忘了看下權限。要有執行權限。
# ============================================================================$ssh_user = 'root'; # SSH username$ssh_port = 22; # SSH port$ssh_iden = '-i /root/.ssh/id_rsa'; # SSH identity##修改根據你的配置,你的ssh連接用戶,還有認證私鑰的位置。
$memcache_port = 11211; # Which port memcached listens on$redis_port = 6379; # Which port redis listens on
function mongodb_cmdline ( $options ) {return “echo \”db._adminCommand({serverStatus:1, repl:1})\” | /usr/local/mongo/mongodb/bin/mongo –port 10000″;}
php /var/www/html/scripts/ss_get_by_ssh.php --type mongodb --host 192.168.200.1 --items c,de,df,dg,dh,di,dj,dk,dl,dm,dn,do,dp,dq,dr,ds,dt,du