介 紹node
Redis(REmote DIctionary Server的意思)是一個開源的內存數據存儲,一般用做數據庫、緩存以及消息代理。它能夠存儲和操做高級的數據結構類型,好比lists、maps、sets以及排序sets。Redis接受多種格式的鍵,所以能夠在服務器上執行操做,減小客戶端的工做負載。它將數據庫徹底地保存在內存中,只使用磁盤進行持久化存儲。Redis是一種流行的數據存儲解決方案,受到了Github、Pinterest、Snapchat、Twitter、StackOverflow、Flickr等科技巨頭的青睞。python
爲何要用Redis?redis
它很是快,它由ANSI C編寫,能夠在Linux、Mac OS X和Solaris等POSIX系統上運行。數據庫
Reis常常被評爲最流行的鍵值數據庫以及在容器上使用最流行的NoSQL數據庫。編程
它的緩存解決方案減小了對雲數據庫後端的調用。json
應用程序能夠經過客戶端API庫訪問它。後端
全部流行的編程語言都支持Redis。瀏覽器
它開源且很是穩定的。緩存
Redis的應用案例服務器
Facebook的一些在線遊戲中,遊戲分數更新頻率很是高。當使用Redis排序set時,即便每分鐘有數百萬用戶和數百萬個新分數,執行這些操做都很是簡單。
Twitter在Redis集羣中存儲了全部用戶的時間線。
Pinterest將用戶關注者圖存儲在Redis集羣中,其中的數據分佈在數百個實例中。
Github使用Redis做爲隊列
什麼是Redis集羣?
Redis集羣是一個多Redis實例的集合,用於經過對數據庫分區來擴展數據庫,使其更具備彈性。集羣中的每一個成員,不管是主副本仍是次級副本,都管理哈希槽的一個子集。若是一個主服務器出現不能訪問的故障,那麼它的從屬服務器會提高爲主服務器。在由三個主節點組成的最小的Redis集羣中,每一個主節點都有一個從屬節點(爲了至少能保證最低程度的故障轉移),每一個主節點分配一個範圍在0至16383之間的哈希槽。節點A包含哈希槽範圍爲從0到5000,節點B爲5001到10000,節點C從10001到18383。集羣內部的通訊則經過內部總線進行,使用gossip協議來傳播關於集羣的信息或者發現新節點。
在Kubernetes上部署Redis集羣
在Kubernetes中部署Redis集羣頗有挑戰,由於每一個Redis實例都依賴於一個配置文件,該文件跟蹤其餘集羣實例及其角色。爲此,咱們須要結合使用Kubernetes狀態集(StatefulSets)和持久卷(PersistentVolumes)。
前期準備
要完成這次的demo,咱們須要有下列準備:
Rancher
Google雲平臺或者其餘雲提供商帳號。下面的展現中使用了GKE,不過使用任何雲提供商都是能夠的,且操做方法大體相同。
啓動Rancher實例
若是你沒有Rancher的實例,能夠參考這裏的Quick Start文檔簡單快速地啓動一個:
https://rancher.com/quick-start/
用Rancher部署GKE集羣
用Rancher啓動並配置你的Kubernetes集羣,具體步驟能夠參考文檔:
https://rancher.com/docs/rancher/v2.x/en/cluster-provisioning/hosted-kubernetes-clusters/gke/
當集羣準備就緒,咱們能夠經過kubectl指令檢查當前狀態
部署Redis
接着部署Redis集羣,咱們既能夠經過kubectl來應用YAML文件,也能夠將它們導入到Rancher UI中。下面列出了咱們全部須要的YAML文件。
YAML內容以下:
redis-sts.yaml
redis-svc.yaml
驗證部署
檢查Redis節點是否啓動並運行:
下面的6個卷是咱們建立的
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-ae61ad5c-f0a5-11e8-a6e0-42010aa40039 1Gi RWO Delete Bound default/data-redis-cluster-0 standard 7m
pvc-b74b6ef1-f0a5-11e8-a6e0-42010aa40039 1Gi RWO Delete Bound default/data-redis-cluster-1 standard 7m
pvc-c4f9b982-f0a5-11e8-a6e0-42010aa40039 1Gi RWO Delete Bound default/data-redis-cluster-2 standard 6m
pvc-cd7af12d-f0a5-11e8-a6e0-42010aa40039 1Gi RWO Delete Bound default/data-redis-cluster-3 standard 6m
pvc-d5bd0ad3-f0a5-11e8-a6e0-42010aa40039 1Gi RWO Delete Bound default/data-redis-cluster-4 standard 6m
咱們能夠檢查任何一個pod,看看它添加的卷:
$ kubectl describe pods redis-cluster-0 | grep pvc
Normal SuccessfulAttachVolume 29m attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-ae61ad5c-f0a5-11e8-a6e0-42010aa40039"
一樣的數據還能夠在Rancher UI上看到
部署Redis集羣
下一步就是建立Redis集羣了。爲此,咱們須要運行如下命令,輸入yes接受配置。前三個節點成爲主節點,最後三個節點設置爲從屬節點。
$ kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ')
如下是完整的輸出命令:
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.60.1.13:6379 to 10.60.2.12:6379
Adding replica 10.60.2.14:6379 to 10.60.1.12:6379
Adding replica 10.60.1.14:6379 to 10.60.2.13:6379
M: 2847de6f6e7c8aaa8b0d2f204cf3ff6e8562a75b 10.60.2.12:6379
slots:[0-5460] (5461 slots) master
M: 3f119dcdd4a33aab0107409524a633e0d22bac1a 10.60.1.12:6379
slots:[5461-10922] (5462 slots) master
M: 754823247cf28af9a2a82f61a8caaa63702275a0 10.60.2.13:6379
slots:[10923-16383] (5461 slots) master
S: 47efe749c97073822cbef9a212a7971a0df8aecd 10.60.1.13:6379
replicates 2847de6f6e7c8aaa8b0d2f204cf3ff6e8562a75b
S: e40ae789995dc6b0dbb5bb18bd243722451d2e95 10.60.2.14:6379
replicates 3f119dcdd4a33aab0107409524a633e0d22bac1a
S: 8d627e43d8a7a2142f9f16c2d66b1010fb472079 10.60.1.14:6379
replicates 754823247cf28af9a2a82f61a8caaa63702275a0
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 10.60.2.12:6379)
M: 2847de6f6e7c8aaa8b0d2f204cf3ff6e8562a75b 10.60.2.12:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 47efe749c97073822cbef9a212a7971a0df8aecd 10.60.1.13:6379
slots: (0 slots) slave
replicates 2847de6f6e7c8aaa8b0d2f204cf3ff6e8562a75b
M: 754823247cf28af9a2a82f61a8caaa63702275a0 10.60.2.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 3f119dcdd4a33aab0107409524a633e0d22bac1a 10.60.1.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: e40ae789995dc6b0dbb5bb18bd243722451d2e95 10.60.2.14:6379
slots: (0 slots) slave
replicates 3f119dcdd4a33aab0107409524a633e0d22bac1a
S: 8d627e43d8a7a2142f9f16c2d66b1010fb472079 10.60.1.14:6379
slots: (0 slots) slave
replicates 754823247cf28af9a2a82f61a8caaa63702275a0
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
驗證集羣部署
檢查集羣細節以及每一個成員的角色
測試Redis集羣
咱們但願使用集羣而且模擬節點故障。對於前一個任務,咱們將部署一個簡單的python應用程序,然後一個任務,咱們將刪除一個節點來觀察集羣行爲。
部署Hit Counter應用
咱們將在集羣中部署一個簡單的應用程序,並在其以前放置一個負載均衡器。該應用程序的目的是在將計數器的值做爲HTTP響應返回值返回以前,增長計數器的值,並將值存到Redis集羣上。
使用kubectl或者Rancher UI部署:
YAML內容以下:
app-deployment-service.yaml
Rancher展現了咱們建立的資源:一個包含python應用的pod,以及LoadBalancer類型的服務。該服務的詳細信息內,將顯示其公共IP地址:
到了這一步,咱們能夠用瀏覽器訪問IP,生成hit counter的值:
模擬節點故障
咱們能夠經過刪除pod(使用kubectl或Rancher UI)來模擬集羣成員的故障。當咱們刪除原先是master的redis-cluster-0時,咱們看到Kubernetes將redis-cluster-3提高爲master,而當redis-cluster-0從新回來時,redis-cluster-3會從新恢復從屬身份。
之 前
之 後
咱們能夠看到redis-cluster-0的IP發生了變化,那麼集羣是如何恢復的呢?
在建立集羣時,咱們建立了ConfigMap,該ConfigMap又在/conf/update-node.sh處建立了一個腳本,容器在啓動時調用該腳本。該腳本使用本地節點的新IP地址更新Redis配置。有了confic中的新IP,集羣就能夠在新的pod中以不一樣的IP地址啓動並恢復。
在這個過程當中,若是咱們繼續加載頁面,計數器仍會繼續增長,在集羣收斂以後,咱們會看到沒有丟失任何數據。
結 論
Redis是一個強大的數據存儲和緩存工具。由於Redis存儲數據的方式,Redis集羣更是能經過提供分片、相關性能優點、線性擴展和高可用性,來進一步擴展其功能。數據在多個節點之間自動分割,即便節點的子集出現故障或者不能和集羣其餘部分通訊,操做仍然可以繼續。
有關Redis集羣的更多信息,請訪問教程(https://redis.io/topics/cluster-tutorial)或者文檔(https://redis.io/topics/cluster-spec)。
有關Rancher的更多信息,請訪問咱們的主頁(https://www.cnrancher.com)或者部署文檔(https://www.cnrancher.com/docs/rancher/v2.x/cn/overview/)。