第二十一週微職位

一、概述redis的應用場景、redis的架構及實現。python

1)Redis最爲經常使用的數據類型主要有如下:linux

  • Stringios

  • Hashredis

  • List算法

  • Setsql

  • Sorted setmongodb

  • pub/sub數據庫

  • Transactionsapi

在具體描述這幾種數據類型以前,咱們先經過一張圖瞭解下Redis內部內存管理中是如何描述這些不一樣數據類型的:數組

wKiom1nYxUGgZBV5AABX0wZRsO8297.jpg

首先Redis內部使用一個redisObject對象來表示全部的key和value,redisObject最主要的信息如上圖所示:

         type表明一個value對象具體是何種數據類型,

         encoding是不一樣數據類型在redis內部的存儲方式,

         好比:type=string表明value存儲的是一個普通字符串,那麼對應的encoding能夠是raw或者是int,若是是int則表明實際redis內部是按數值型類存儲和表示這個字符串的,固然前提是這個字符串自己能夠用數值表示,好比:"123" "456"這樣的字符串。

       這裏須要特殊說明一下vm字段,只有打開了Redis的虛擬內存功能,此字段纔會真正的分配內存,該功能默認是關閉狀態的,該功能會在後面具體描述。經過上圖咱們能夠發現Redis使用redisObject來表示全部的key/value數據是比較浪費內存的,固然這些內存管理成本的付出主要也是爲了給Redis不一樣數據類型提供一個統一的管理接口,實際做者也提供了多種方法幫助咱們儘可能節省內存使用,咱們隨後會具體討論。

2)各類數據類型應用和實現方式

下面咱們先來逐一的分析下這7種數據類型的使用和內部實現方式:


String:


Strings 數據結構是簡單的key-value類型,value其實不只是String,也能夠是數字.

經常使用命令:  set,get,decr,incr,mget 等。

應用場景:String是最經常使用的一種數據類型,普通的key/ value 存儲均可以歸爲此類.便可以徹底實現目前 Memcached 的功能,而且效率更高。還能夠享受Redis的定時持久化,操做日誌及 Replication等功能。除了提供與 Memcached 同樣的get、set、incr、decr 等操做外,Redis還提供了下面一些操做:
獲取字符串長度
往字符串append內容
設置和獲取字符串的某一段內容
設置及獲取字符串的某一位(bit)
批量設置一系列字符串的內容
實現方式:String在redis內部存儲默認就是一個字符串,被redisObject所引用,當遇到incr,decr等操做時會轉成數值型進行計算,此時redisObject的encoding字段爲int。
Hash
經常使用命令:hget,hset,hgetall 等。
應用場景:在Memcached中,咱們常常將一些結構化的信息打包成HashMap,在客戶端序列化後存儲爲一個字符串的值,好比用戶的暱稱、年齡、性別、積分等,這時候在須要修改其中某一項時,一般須要將全部值取出反序列化後,修改某一項的值,再序列化存儲回去。這樣不只增大了開銷,也不適用於一些可能併發操做的場合(好比兩個併發的操做都須要修改積分)。而Redis的Hash結構可使你像在數據庫中Update一個屬性同樣只修改某一項屬性值。
        咱們簡單舉個實例來描述下Hash的應用場景,好比咱們要存儲一個用戶信息對象數據,包含如下信息:
用戶ID爲查找的key,存儲的value用戶對象包含姓名,年齡,生日等信息,若是用普通的key/value結構來存儲,主要有如下2種存儲方式:

wKioL1nYxh7jMoRAAACPM7HN4wk728.png


第一種方式將用戶ID做爲查找key,把其餘信息封裝成一個對象以序列化的方式存儲,這種方式的缺點是,增長了序列化/反序列化的開銷,而且在須要修改其中一項信息時,須要把整個對象取回,而且修改操做須要對併發進行保護,引入CAS等複雜問題。

wKioL1nYxnjCd_ZnAACJi3AOJMw966.png

第二種方法是這個用戶信息對象有多少成員就存成多少個key-value對兒,用用戶ID+對應屬性的名稱做爲惟一標識來取得對應屬性的值,雖然省去了序列化開銷和併發問題,可是用戶ID爲重複存儲,若是存在大量這樣的數據,內存浪費仍是很是可觀的。

那麼Redis提供的Hash很好的解決了這個問題,Redis的Hash實際是內部存儲的Value爲一個HashMap,並提供了直接存取這個Map成員的接口,以下圖:

wKioL1nYxsfCPihSAADCutfvfdU747.png

也就是說,Key仍然是用戶ID, value是一個Map,這個Map的key是成員的屬性名,value是屬性值,這樣對數據的修改和存取均可以直接經過其內部Map的Key(Redis裏稱內部Map的key爲field), 也就是經過 key(用戶ID) + field(屬性標籤) 就能夠操做對應屬性數據了,既不須要重複存儲數據,也不會帶來序列化和併發修改控制的問題。很好的解決了問題。

這裏同時須要注意,Redis提供了接口(hgetall)能夠直接取到所有的屬性數據,可是若是內部Map的成員不少,那麼涉及到遍歷整個內部Map的操做,因爲Redis單線程模型的緣故,這個遍歷操做可能會比較耗時,而另其它客戶端的請求徹底不響應,這點須要格外注意。

實現方式:

上面已經說到Redis Hash對應Value內部實際就是一個HashMap,實際這裏會有2種不一樣實現,這個Hash的成員比較少時Redis爲了節省內存會採用相似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,對應的value redisObject的encoding爲zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding爲ht。


List


經常使用命令:lpush,rpush,lpop,rpop,lrange等。

應用場景:

Redis list的應用場景很是多,也是Redis最重要的數據結構之一,好比twitter的關注列表,粉絲列表等均可以用Redis的list結構來實現。

Lists 就是鏈表,相信略有數據結構知識的人都應該能理解其結構。使用Lists結構,咱們能夠輕鬆地實現最新消息排行等功能。Lists的另外一個應用就是消息隊列,
能夠利用Lists的PUSH操做,將任務存在Lists中,而後工做線程再用POP操做將任務取出進行執行。Redis還提供了操做Lists中某一段的api,你能夠直接查詢,刪除Lists中某一段的元素。

實現方式:

Redis list的實現爲一個雙向鏈表,便可以支持反向查找和遍歷,更方便操做,不過帶來了部分額外的內存開銷,Redis內部的不少實現,包括髮送緩衝隊列等也都是用的這個數據結構。


Set


經常使用命令:

sadd,spop,smembers,sunion 等。

應用場景:

Redis set對外提供的功能與list相似是一個列表的功能,特殊之處在於set是能夠自動排重的,當你須要存儲一個列表數據,又不但願出現重複數據時,set是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的重要接口,這個也是list所不能提供的。

Sets 集合的概念就是一堆不重複值的組合。利用Redis提供的Sets數據結構,能夠存儲一些集合性的數據,好比在微博應用中,能夠將一個用戶全部的關注人存在一個集合中,將其全部粉絲存在一個集合。Redis還爲集合提供了求交集、並集、差集等操做,能夠很是方便的實現如共同關注、共同喜愛、二度好友等功能,對上面的全部集合操做,你還可使用不一樣的命令選擇將結果返回給客戶端仍是存集到一個新的集合中。

實現方式:

set 的內部實現是一個 value永遠爲null的HashMap,實際就是經過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的緣由。


Sorted Set


經常使用命令:

zadd,zrange,zrem,zcard等

使用場景:

Redis sorted set的使用場景與set相似,區別是set不是自動有序的,而sorted set能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,即自動排序。當你須要一個有序的而且不重複的集合列表,那麼能夠選擇sorted set數據結構,好比twitter 的public timeline能夠以發表時間做爲score來存儲,這樣獲取時就是自動按時間排好序的。

另外還能夠用Sorted Sets來作帶權重的隊列,好比普通消息的score爲1,重要消息的score爲2,而後工做線程能夠選擇按score的倒序來獲取工做任務。讓重要的任務優先執行。

實現方式:

Redis sorted set的內部使用HashMap和跳躍表(SkipList)來保證數據的存儲和有序,HashMap裏放的是成員到score的映射,而跳躍表裏存放的是全部的成員,排序依據是HashMap裏存的score,使用跳躍表的結構能夠得到比較高的查找效率,而且在實現上比較簡單。



Pub/Sub

Pub/Sub 從字面上理解就是發佈(Publish)與訂閱(Subscribe),在Redis中,你能夠設定對某一個key值進行消息發佈及消息訂閱,當一個key值上進行了消息發佈後,全部訂閱它的客戶端都會收到相應的消息。這一功能最明顯的用法就是用做實時消息系統,好比普通的即時聊天,羣聊等功能。



Transactions

誰說NoSQL都不支持事務,雖然Redis的Transactions提供的並非嚴格的ACID的事務(好比一串用EXEC提交執行的命令,在執行中服務器宕機,那麼會有一部分命令執行了,剩下的沒執行),可是這個Transactions仍是提供了基本的命令打包執行的功能(在服務器不出問題的狀況下,能夠保證一連串的命令是順序在一塊兒執行的,中間有會有其它客戶端命令插進來執行)。Redis還提供了一個Watch功能,你能夠對一個key進行Watch,而後再執行Transactions,在這過程當中,若是這個Watched的值進行了修改,那麼這個Transactions會發現並拒絕執行。


3)Redis實際應用場景

Redis在不少方面與其餘數據庫解決方案不一樣:它使用內存提供主存儲支持,而僅使用硬盤作持久性的存儲;它的數據模型很是獨特,用的是單線程。另外一個大區別在於,你能夠在開發環境中使用Redis的功能,但卻不須要轉到Redis。

轉向Redis固然也是可取的,許多開發者從一開始就把Redis做爲首選數據庫;但設想若是你的開發環境已經搭建好,應用已經在上面運行了,那麼更換數據庫框架顯然不那麼容易。另外在一些須要大容量數據集的應用,Redis也並不適合,由於它的數據集不會超過系統可用的內存。因此若是你有大數據應用,並且主要是讀取訪問模式,那麼Redis並非正確的選擇。

        然而我喜歡Redis的一點就是你能夠把它融入到你的系統中來,這就可以解決不少問題,好比那些你現有的數據庫處理起來感到緩慢的任務。這些你就能夠經過Redis來進行優化,或者爲應用建立些新的功能。在本文中,我就想探討一些怎樣將Redis加入到現有的環境中,並利用它的原語命令等功能來解決 傳統環境中碰到的一些常見問題。在這些例子中,Redis都不是做爲首選數據庫。

(1)顯示最新的項目列表

下面這個語句經常使用來顯示最新項目,隨着數據多了,查詢毫無疑問會愈來愈慢。

SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10

在Web應用中,「列出最新的回覆」之類的查詢很是廣泛,這一般會帶來可擴展性問題。這使人沮喪,由於項目原本就是按這個順序被建立的,但要輸出這個順序卻不得不進行排序操做。

        相似的問題就能夠用Redis來解決。好比說,咱們的一個Web應用想要列出用戶貼出的最新20條評論。在最新的評論邊上咱們有一個「顯示所有」的連接,點擊後就能夠得到更多的評論。

        咱們假設數據庫中的每條評論都有一個惟一的遞增的ID字段。

        咱們可使用分頁來製做主頁和評論頁,使用Redis的模板,每次新評論發表時,咱們會將它的ID添加到一個Redis列表:

LPUSH latest.comments <ID>

       咱們將列表裁剪爲指定長度,所以Redis只須要保存最新的5000條評論:

       LTRIM latest.comments 0 5000 

      每次咱們須要獲取最新評論的項目範圍時,咱們調用一個函數來完成(使用僞代碼):

FUNCTION get_latest_comments(start, num_items):  
    id_list = redis.lrange("latest.comments",start,start+num_items - 1)  
    IF id_list.length < num_items  
        id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")  
    END  
    RETURN id_list  
END

 這裏咱們作的很簡單。在Redis中咱們的最新ID使用了常駐緩存,這是一直更新的。可是咱們作了限制不能超過5000個ID,所以咱們的獲取ID函數會一直詢問Redis。只有在start/count參數超出了這個範圍的時候,才須要去訪問數據庫。

        咱們的系統不會像傳統方式那樣「刷新」緩存,Redis實例中的信息永遠是一致的。SQL數據庫(或是硬盤上的其餘類型數據庫)只是在用戶須要獲取「很遠」的數據時纔會被觸發,而主頁或第一個評論頁是不會麻煩到硬盤上的數據庫了。

(2)刪除與過濾

      咱們可使用LREM來刪除評論。若是刪除操做很是少,另外一個選擇是直接跳過評論條目的入口,報告說該評論已經不存在。

       有些時候你想要給不一樣的列表附加上不一樣的過濾器。若是過濾器的數量受到限制,你能夠簡單的爲每一個不一樣的過濾器使用不一樣的Redis列表。畢竟每一個列表只有5000條項目,但Redis卻可以使用很是少的內存來處理幾百萬條項目。

(3)排行榜相關

      另外一個很廣泛的需求是各類數據庫的數據並不是存儲在內存中,所以在按得分排序以及實時更新這些幾乎每秒鐘都須要更新的功能上數據庫的性能不夠理想。

      典型的好比那些在線遊戲的排行榜,好比一個Facebook的遊戲,根據得分你一般想要:

         - 列出前100名高分選手

         - 列出某用戶當前的全球排名

      這些操做對於Redis來講小菜一碟,即便你有幾百萬個用戶,每分鐘都會有幾百萬個新的得分。

      模式是這樣的,每次得到新得分時,咱們用這樣的代碼:

      ZADD leaderboard  <score>  <username> 

     你可能用userID來取代username,這取決於你是怎麼設計的。

      獲得前100名高分用戶很簡單:ZREVRANGE leaderboard 0 99。

      用戶的全球排名也類似,只須要:ZRANK leaderboard <username>。

(4)按照用戶投票和時間排序

      排行榜的一種常見變體模式就像Reddit或Hacker News用的那樣,新聞按照相似下面的公式根據得分來排序:

       score = points / time^alpha 

      所以用戶的投票會相應的把新聞挖出來,但時間會按照必定的指數將新聞埋下去。下面是咱們的模式,固然算法由你決定。

      模式是這樣的,開始時先觀察那些多是最新的項目,例如首頁上的1000條新聞都是候選者,所以咱們先忽視掉其餘的,這實現起來很簡單。

      每次新的新聞貼上來後,咱們將ID添加到列表中,使用LPUSH + LTRIM,確保只取出最新的1000條項目。

      有一項後臺任務獲取這個列表,而且持續的計算這1000條新聞中每條新聞的最終得分。計算結果由ZADD命令按照新的順序填充生成列表,老新聞則被清除。這裏的關鍵思路是排序工做是由後臺任務來完成的。

(5)處理過時項目

      另外一種經常使用的項目排序是按照時間排序。咱們使用unix時間做爲得分便可。

      模式以下:

       - 每次有新項目添加到咱們的非Redis數據庫時,咱們把它加入到排序集合中。這時咱們用的是時間屬性,current_time和time_to_live。

       - 另外一項後臺任務使用ZRANGE…SCORES查詢排序集合,取出最新的10個項目。若是發現unix時間已通過期,則在數據庫中刪除條目。

(6)計數

       Redis是一個很好的計數器,這要感謝INCRBY和其餘類似命令。

       我相信你曾許屢次想要給數據庫加上新的計數器,用來獲取統計或顯示新信息,可是最後卻因爲寫入敏感而不得不放棄它們。

       好了,如今使用Redis就不須要再擔憂了。有了原子遞增(atomic increment),你能夠放心的加上各類計數,用GETSET重置,或者是讓它們過時。

       例如這樣操做:

         INCR user:<id> EXPIRE 

         user:<id> 60 

       你能夠計算出最近用戶在頁面間停頓不超過60秒的頁面瀏覽量,當計數達到好比20時,就能夠顯示出某些條幅提示,或是其它你想顯示的東西。

(7)特定時間內的特定項目

        另外一項對於其餘數據庫很難,但Redis作起來卻垂手可得的事就是統計在某段特色時間裏有多少特定用戶訪問了某個特定資源。好比我想要知道某些特定的註冊用戶或IP地址,他們到底有多少訪問了某篇文章。

      每次我得到一次新的頁面瀏覽時我只須要這樣作:

       SADD page:day1:<page_id> <user_id> 

      固然你可能想用unix時間替換day1,好比time()-(time()%3600*24)等等。

      想知道特定用戶的數量嗎?只須要使用SCARD page:day1:<page_id>。

       須要測試某個特定用戶是否訪問了這個頁面?SISMEMBER page:day1:<page_id>。

(8)實時分析正在發生的狀況,用於數據統計與防止垃圾郵件等

        咱們只作了幾個例子,但若是你研究Redis的命令集,而且組合一下,就能得到大量的實時分析方法,有效並且很是省力。使用Redis原語命令,更容易實施垃圾郵件過濾系統或其餘實時跟蹤系統。

(9)Pub/Sub

       Redis的Pub/Sub很是很是簡單,運行穩定而且快速。支持模式匹配,可以實時訂閱與取消頻道。

(10)隊列

        你應該已經注意到像list push和list pop這樣的Redis命令可以很方便的執行隊列操做了,但能作的可不止這些:好比Redis還有list pop的變體命令,可以在列表爲空時阻塞隊列。

       現代的互聯網應用大量地使用了消息隊列(Messaging)。消息隊列不只被用於系統內部組件之間的通訊,同時也被用於系統跟其它服務之間的交互。消息隊列的使用能夠增長系統的可擴展性、靈活性和用戶體驗。非基於消息隊列的系統,其運行速度取決於系統中最慢的組件的速度(注:短板效應)。而基於消息隊列能夠將系統中各組件解除耦合,這樣系統就再也不受最慢組件的束縛,各組件能夠異步運行從而得以更快的速度完成各自的工做。

    此外,當服務器處在高併發操做的時候,好比頻繁地寫入日誌文件。能夠利用消息隊列實現異步處理。從而實現高性能的併發操做。



二、搭建一套mongodb分佈式集羣系統。

目標:
搭建帶有安全認證的mongodb集羣準生產環境。
    一共3個shard,每個shard有3個replica set,replicat set採用primary、secondary、secondary方式。9個mongod實例,另外,3個config server,3個mongod實例,3個mongos實例。
        mongodb版本 3.2.9 社區版本
        Cores 4
        OS Name CentOS release 6.6 (Final)
        OS Version Linux version 2.6.32-504.3.3.el6.x86_64 RAM (MB) 3729
注意:關閉SELINUX注意:服務器時間同步,好比用ntpdate,能夠暫時略過無論。
最後會有核武。MongoDB Ops Manager

服務器準備:
服務器-ip
192.168.3.73    
192.168.3.74    
192.168.3.75    
另外準備一臺192.168.3.81用做MongoDB Ops Manager。
訪問互通
好比在192.168.3.73機器上修改
vi /etc/hosts
192.168.3.73 73.dooioo.org
192.168.3.74 74.dooioo.org
192.168.3.75 75.dooioo.org
192.168.3.76 76.dooioo.org
192.168.3.81 81.dooioo.org
vi /etc/sysconfig/network
HOSTNAME=73.dooioo.org

即刻生效可使用在命令下執行便可,以下命令

hostname 73.dooioo.org

下載安裝

登陸到192.168.3.73

$ cd /root
$ wget https://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.9.tgz
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.74:/root
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.75:/root
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.76:/root
$ tar zxvf mongodb-linux-x86_64-rhel62-3.2.9.tgz

規劃集羣和分片

規劃3個shard * 3個replicat set + 配置服務

shard rs name Primary Secondary Secondary port
fang-s-a a1 a2 a3 28111
fang-s-b b2 b1 b3 28112
fang-s-c c3 c1 c2 28113
fang-cs configserver1 configserver2 configserver3 28200

規劃3個config server的mongod實例configserver一、configserver二、configserver3

hostname 實例
73.dooioo.org a1 b1 c1 configserver1
74.dooioo.org a2 b2 c2 configserver2
75.dooioo.org a3 b3 c3 configserver3

規劃目錄和配置文件

建立必要的目錄和文件

#!/usr/bin/env bash
# 登陸到192.168.3.73
# 建立db目錄 日誌目錄 mongod配置文件
mkdir -p /mongodb/a1
mkdir -p /home/log/mongodb/a1
mkdir -p /mongodb/b1
mkdir -p /home/log/mongodb/b1
mkdir -p /mongodb/c1
mkdir -p /home/log/mongodb/c1
 
mkdir -p /mongodb/configserver1
mkdir -p /home/log/mongodb/configserver1
 
touch /mongodb/mongod-a1-config.yml
touch /mongodb/mongod-b1-config.yml
touch /mongodb/mongod-c1-config.yml
touch /mongodb/mongod-configserver1.yml

# 登陸到192.168.3.74
mkdir -p /mongodb/a2
mkdir -p /home/log/mongodb/a2
mkdir -p /mongodb/b2
mkdir -p /home/log/mongodb/b2
mkdir -p /mongodb/c2
mkdir -p /home/log/mongodb/c2
 
mkdir -p /mongodb/configserver2
mkdir -p /home/log/mongodb/configserver2
 
touch /mongodb/mongod-a2-config.yml
touch /mongodb/mongod-b2-config.yml
touch /mongodb/mongod-c2-config.yml
touch /mongodb/mongod-configserver2.yml

# 登陸到192.168.3.75
mkdir -p /mongodb/a3
mkdir -p /home/log/mongodb/a3
mkdir -p /mongodb/b3
mkdir -p /home/log/mongodb/b3
mkdir -p /mongodb/c3
mkdir -p /home/log/mongodb/c3
 
mkdir -p /mongodb/configserver3
mkdir -p /home/log/mongodb/configserver3
 
touch /mongodb/mongod-a3-config.yml
touch /mongodb/mongod-b3-config.yml
touch /mongodb/mongod-c3-config.yml
touch /mongodb/mongod-configserver3.yml

# 登陸到192.168.3.73
# 生產和copy祕鑰用戶實例內部認證
 
openssl rand -base64 755 > /mongodb/keyfile
chmod 400 /mongodb/keyfile
 
scp /mongodb/keyfile root@192.168.3.74:/mongodb/
scp /mongodb/keyfile root@192.168.3.75:/mongodb/

列舉mongod-a1-config.yml文件。

# yml
# mongod config
# 日誌位置
systemLog:
  destination: file
  logAppend: true
  path: /home/log/mongodb/a1/mongodb.log
# Where and how to store data.
# db存儲位置
storage:
  dbPath: /mongodb/a1
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
# fork : fork and run in background  後臺運行
# pidFilePath:location of pidfile 
processManagement:
  fork: true
  pidFilePath: /var/run/mongod-a1.pid
 
# network interfaces
# Listen to local interface only, comment to listen on all interfaces.
net:
  port: 28111
  bindIp: 0.0.0.0
 
#security:  enabled  disabled
#security:
#  keyFile: /mongodb/keyfile
#  clusterAuthMode: keyFile
 
#operationProfiling:
operationProfiling:
   slowOpThresholdMs: 1000
   mode: slowOp
 
#replication:
 
replication:
  replSetName: fang-s-a
 
#sharding:
 
sharding:
  clusterRole: shardsvr
 
## Enterprise-Only Options
 
#auditLog:
 
#snmp:

剛纔touch的文件按照名稱修改配置,好比mongod-b1-config.yml須要修改的內容:a1所有替換問b1, fang-s-a替換爲fang-s-b,端口按照規劃的28111改成28112

configserver稍微有點不同的是clusterRole,注意修改,一個爲shardsvr,一個爲configsvr,其餘同理,不一樣服務器修改數據和配置。按照前面建立的文件名稱,目錄名稱修改。也給出一個配置服務的例子

# yml
# mongod config
 
systemLog:
  destination: file
  logAppend: true
  path: /home/log/mongodb/configserver1/mongodb.log
 
 
# Where and how to store data.
storage:
  dbPath: /mongodb/configserver1
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
# fork : fork and run in background
# pidFilePath:location of pidfile
processManagement:
  fork: true
  pidFilePath: /var/run/mongod-configserver1.pid
 
# network interfaces
# Listen to local interface only, comment to listen on all interfaces.
net:
  port: 28200
  bindIp: 0.0.0.0
 
 
#security:  enabled  disabled
#security:
#  keyFile: /mongodb/keyfile
#  clusterAuthMode: keyFile
 
#operationProfiling:
operationProfiling:
   slowOpThresholdMs: 1000
   mode: slowOp
 
#replication:
 
replication:
  replSetName: fang-cs
 
#sharding:
 
sharding:
  clusterRole: configsvr
 
## Enterprise-Only Options
 
#auditLog:
 
#snmp:


啓動全部實例:

#  登陸到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a1-config.yml
./mongod -f /mongodb/mongod-b1-config.yml
./mongod -f /mongodb/mongod-c1-config.yml
./mongod -f /mongodb/mongod-configserver1.yml

# 其餘兩臺相似,啓動其餘8個實例
#  登陸到192.168.3.74
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a2-config.yml
./mongod -f /mongodb/mongod-b2-config.yml
./mongod -f /mongodb/mongod-c2-config.yml
./mongod -f /mongodb/mongod-configserver2.yml
 
#  登陸到192.168.3.75
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a3-config.yml
./mongod -f /mongodb/mongod-b3-config.yml
./mongod -f /mongodb/mongod-c3-config.yml
./mongod -f /mongodb/mongod-configserver3.yml

建立replicat set

# 登陸到192.168.3.73
 
./mongo 127.0.0.1:28111/admin
 
> use admin
switched to db admin
 
# 初始化fang-s-a的副本集
> rs.initiate()
{
        "info2" : "no configuration specified. Using a default configuration for the set",
        "me" : "73.dooioo.org:28111",
        "ok" : 1
}
 
# 添加到副本集
fang-s-a:OTHER> rs.add("74.dooioo.org:28111")
{ "ok" : 1 }
fang-s-a:PRIMARY> rs.add("75.dooioo.org:28111")
{ "ok" : 1 }
 
# 看下副本集配置狀況
fang-s-a:PRIMARY> rs.conf()
{
        "_id" : "fang-s-a",
        "version" : 3,
        "protocolVersion" : NumberLong(1),
        "members" : [
                {
                        "_id" : 0,
                        "host" : "73.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "74.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "75.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "getLastErrorModes" : {
 
                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("57c00e2b9f6b9f6453c488c3")
        }
}

能夠自行插入記錄看看同步效果:

# 登陸到192.168.3.74  初始化fang-s-b 添加副本集
./mongo 127.0.0.1:28112/admin
rs.initiate()
rs.add("73.dooioo.org:28112")
rs.add("75.dooioo.org:28112")
# 登陸到192.168.3.75  初始化fang-s-c 添加副本集
./mongo 127.0.0.1:28113/admin
rs.initiate()
rs.add("73.dooioo.org:28113")
rs.add("74.dooioo.org:28113")
 
# 登陸到192.168.3.74  初始化fang-cs添加副本集
./mongo 127.0.0.1:28200/admin
rs.initiate()
rs.add("74.dooioo.org:28200")
rs.add("75.dooioo.org:28200")

添加分片集羣:

# 登陸到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongos --port 28300 --configdb fang-cs/73.dooioo.org:28200,74.dooioo.org:28200,75.dooioo.org:28200 --fork --logpath /home/log/mongodb/mongos.log --bind_ip 0.0.0.0

經過mongos來登陸:

# 登陸到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongo 127.0.0.1:28300/admin

mongos> use admin
switched to db admin
mongos> sh.addShard("fang-s-a/73.dooioo.org:28111,74.dooioo.org:28111,75.dooioo.org:28111")
{ "shardAdded" : "fang-s-a", "ok" : 1 }
mongos> sh.addShard("fang-s-b/73.dooioo.org:28112,74.dooioo.org:28112,75.dooioo.org:28112")
{ "shardAdded" : "fang-s-b", "ok" : 1 }
mongos> sh.addShard("fang-s-c/73.dooioo.org:28113,74.dooioo.org:28113,75.dooioo.org:28113")
{ "shardAdded" : "fang-s-c", "ok" : 1 }
mongos>

沒有安全認證的集羣就搭建好了,下面是關於安全認證的。

創建安全

祕鑰文件keyfile

   生成祕鑰文件

openssl rand -base64 755 > /mongodb/keyfile
chmod 400 /mongodb/keyfile
scp keyfile root@192.168.3.74:/mongodb/
scp keyfile root@192.168.3.75:/mongodb/

建立用戶,登陸到一個mongos實例,爲集羣建立root用戶

db.createUser({ user: "root******",pwd: "**************",roles: [ "root", "userAdminAnyDatabase", "userAdmin", "dbOwner" ]})

全部實例所有中止,使用

./mongod -f /mongodb/mongod-a1-config.yml --shutdown

mongod實例啓動添加參數 --keyFile /mongodb/keyfile --auth

啓動時能夠不使用 --auth參數,由於使用了 --keyFile就必須驗證,也就是隱含了 --auth。可是--auth並不隱含 --keyFile。

測試,iostat,觀察使用狀況

例如,如下命令會每隔一秒展現額外的統計數據和每次展現報表的時間(以MB/s爲流量單位):

iostat -xmt 1

Key fields from iostat:

%util: 這對快速查看來講是最有用的字段,它指明瞭設備/驅動器使用時間的百分比。
avgrq-sz:平均請求大小。該值較小的數字反映了更多的隨機IO操做。

核武MongoDB Ops Manager


下面介紹下核武MongoDB Ops Manager。

安裝:

機器同上(CentOS release 6.6)。官方推薦要求15 GB memory and 50 GB disk space。df -h校驗。測試用,少一些不要緊。這裏測試機器30G硬盤空間,4G內存。須要有root帳號。首先安裝一個mongod實例,做爲ops的db。到官網上下載Ops Manager包,我這裏下載的是mongodb-mms-2.0.5.358-1.x86_64.rpm。

執行

sudo rpm -ivh mongodb-mms-2.0.5.358-1.x86_64.rpm
 
sudo service mongodb-mms start

配置文件位置/opt/mongodb/mms/conf/conf-mms.properties
默認訪問8080端口,https://192.168.3.81:8080/.

帳號配置

略,好比修改時區爲北京時間。

新的部署

登陸,能夠選擇部署新的集羣和,管理手動建立的集羣

wKiom1nY0kSw1srvAAFvQdBvXKU346.png選擇Build New Deployment Where would you like to deploy MongoDB?
選擇 Deployment in other remote. What type of MongoDB deployment would you like to build?
選擇 Sharded Cluster Provide details fZ喎"/kf/ware/vc/" target="_blank" class="keylink">vciB5b3VyIHNoYXJkZWQgY2x1c3RlciC55ruuxOO1xLyvyLrF5NbDPGJyIC8+DQpDbHVzdGVyIE5hbWUgOiBtZGItdGVzdC1jbHVzdGVyIFNoYXJkIENvdW50IDogNCBOb2RlcyBQZXIgU2hhcmQgOiAzIFNoYXJkIE5hbWUgUHJlZml4IDogbWRiLXRlc3QgRGF0YSBEaXJlY3RvcnkgUHJlZml4IDogL2RhdGEgSW5zdGFsbCBhbiBBdXRvbWF0aW9uIEFnZW50IG9uIGVhY2ggc2VydmVyLiDU2sO/uPa3/s7xxvewstew19S2r7T6wO23/s7xoaMgxKzIz9Do0qoxMrj2t/7O8cb3o6zS8s6qIDQqIDOjrNXiwO+3/s7xxvfJ2aOs0aHU8TTMqLf+zvHG96GjPGJyIC8+DQrRodTxz8LU2LCy17DF5NbDtPrA7bf+zvHG96O6ILv5sb7Kx9K7sr3Su7K9ytaw0crWwcujrA0KPHA+z8LU2LT6wO2w/DwvcD4NCjxwcmUgY2xhc3M9"brush:sql;"> curl -OL https://192.168.3.81:8080/download/agent/automation/mongodb-mms-automation-agent-manager-2.5.19.1732-1.x86_64.rpm

安裝代理包

sudo rpm -U mongodb-mms-automation-agent-manager-2.5.19.1732-1.x86_64.rpm

打開配置文件,編輯配置,數據庫指定了目錄的,必須建立目錄。

sudo vi /etc/mongodb-mms/automation-agent.config


mmsGroupId=57be67ffe4b09e1dfa498ee7
mmsApiKey=e5b83213955c886d0ef8ce3324cf8f30
mmsBaseUrl=

sudo mkdir -p /data
sudo chown mongod:mongod /data
 
sudo service mongodb-mms-automation-agent start

驗證經過後,下一步。初始了默認的一些實例:

你也能夠移動。先按默認的下一步。

而後提示: We are deploying your changes. This might take a few minutes…

相關文章
相關標籤/搜索