1. 程式人生 > >使用Docker構建redis叢集--最靠譜的版本

使用Docker構建redis叢集--最靠譜的版本

1     叢集結構說明

叢集中有三個主節點,三個從節點,一共六個結點。因此要構建六個redis的docker容器。在宿主機中將這六個獨立的redis結點關聯成一個redis叢集。需要用到官方提供的ruby指令碼。

2     構建redis基礎映象

本文選擇版本為redis-3.0.7,如果需要其他版本,直接修改wget後面地址中的版本號即可。

程式碼清單2-1 下載&編譯redis原始碼包

# mkdir –p /usr/docker_root/redis_cluster
# cd /usr/docker_root/redis_cluster
# wget http://download.redis.io/releases/redis-3.0.7.tar.gz
# tar zxvf redis-3.0.7.tar.gz
# cd redis-3.0.7
# make
PS: 如果你連 # 也複製了,那你還是別看了……

我們已經在宿主機編譯好了redis原始碼,在src路徑下有我們需要的可執行檔案:redis-cli,redis-server和redis-trib.rb。redis-trib.rb是redis官方提供的ruby指令碼,用來構建redis叢集


圖2-1  src路徑下的可執行檔案

修改redis.conf。在redis-3.0.7的根路徑下有redis的配置檔案redis.conf。將其移動到上一級路徑/usr/docker_root/redis_cluster/ 下。

依據程式碼清單2-2,修改redis.conf檔案中的對應引數值。

daemonize : 是否後臺執行,將其設為no,表示前臺執行。

port : redis服務監聽的埠。

logfile : 指定日誌檔案路徑。

appendonly : 是否開啟appendonlylog,開啟的話每次寫操作會記一條log,這會提高資料抗風險能力,但影響效率。

cluster-node-timeout : 叢集結點超時限制。

程式碼清單2-2 需要修改的配置引數

daemonize no
port 6379
logfile "/var/log/redis/redis-server.log"
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

下面構建redis基礎映象。以Dockerfile方式構建。

程式碼清單2-3 建立redis基礎映象的Dockerfile

# pwd
/usr/docker_root/redis_cluster
# vim Dockerfile

我們來看看Dockerfile的內容,如程式碼清單2-4所示。

程式碼清單2-4 Dockerfile

FROM ubuntu:14.04
 
ADD redis-3.0.7.tar.gz /
RUN mkdir -p /redis
ADD redis.conf /redis/
 
RUN apt-get -yqq  update
RUN apt-get install -y gcc make
 
WORKDIR /redis-3.0.7
RUN make
RUN mv /redis-3.0.7/src/redis-server /redis/
 
WORKDIR /
RUN rm -rf /redis-3.0.7
 
RUN apt-get remove --purge -y gcc make
 
VOLUME ["/var/log/redis/"]
 
EXPOSE 6379

將本地的redis原始碼包複製到映象的根路徑下,ADD命令會在複製過後自動解包。被複制的物件必須處於Dockerfile同一路徑,且ADD後面必須使用相對路徑。

將我們修改後的配置檔案也複製到映象內。

為編譯原始碼包,需要安裝gcc和make,安裝之前先更新apt-get。更新和安裝時間較長。

編譯原始碼包。當然編譯也需要一段時間。

編譯後,容器中只需要可執行檔案redis-server,所以將該檔案移到/redis/路徑下。現在redis-server 和redis.conf都在/redis/下。

將redis-3.0.7路徑整個刪除。

gcc和make也可以解除安裝掉。

指定資料卷,通過這個資料卷可以檢視redis執行的日誌檔案。

公開redis預設埠6379。

因為不會執行這個映象,所有沒有包含ENTRYPOINT和CMD指令。我們基於這個映象構建別的映象。

現在我們構建redis基礎映象

程式碼清單2-5 構建redis基礎映象

# docker build -t zcq/redis_base .

構建過程與網路頻寬有關,十分鐘左右,構建完成。成功構建映象之後,執行docker images,可以看見zcq/redis_base映象,如圖2-2所示,映象size有333.3MB。

圖2-2  zcq/redis_base映象資訊

3     構建redis結點映象

我們繼續構建redis結點映象,這個映象將會用於生成提供redis服務的docker容器。

程式碼清單3-1 建立redis結點映象的Dockerfile

# mkdir redis_node
# cd redis_node
# vim Dockerfile

Dockerfile如程式碼清單3-2所示。

程式碼清單3-2 redis結點映象Dockerfile

FROM zcq/redis
 
ENTRYPOINT ["/redis/redis-server", "/redis/redis.conf"]

構建redis結點映象。

程式碼清單3-3 構建redis結點映象

# docker build -t zcq/redis_cluster_node .

檢視redis結點映象zcq/redis_cluster_node,如下圖。

圖3-1  zcq/ redis_cluster_node映象資訊

4     建立redis結點容器

依次建立六個redis結點容器,如程式碼清單4-1所示。

程式碼清單4-1 建立redis結點

# docker run -d --name redis01 -p 30001:6379 zcq/redis_cluster_node
# docker run -d --name redis02 zcq/redis_cluster_node
# docker run -d --name redis03 zcq/redis_cluster_node
# docker run -d --name redis04 zcq/redis_cluster_node
# docker run -d --name redis05 zcq/redis_cluster_node
# docker run -d --name redis06 zcq/redis_cluster_node

是不是很奇怪第一個容器的開啟方式有點不一樣,第一個容器做了埠對映,是專門留給客戶端訪問的,這樣客戶端就可以通過宿主機的30001埠訪問redis叢集了。

檢視各容器IP地址

程式碼清單4-2 檢視redis結點IP

# docker inspect redis01  redis02 redis03 redis04 redis05 redis06 | grep \"IPAddress\"

結果如圖4-1所示,各個容器IP地址分別為:

172.17.0.66

172.17.0.67

172.17.0.68

172.17.0.69

172.17.0.70

172.17.0.71

圖4-1  所有redis結點的IP

5     搭建redis叢集

前文已經提到,要構建叢集需要使用官方提供的ruby指令碼,也就是redis-3.0.7/src/redis-trib.rb,因此需要先安裝ruby的環境。

程式碼清單5-1 安裝ruby環境

# yum install ruby
# yum install rubygems

執行redis-trib.rb指令碼還需要安裝redis的ruby包。

程式碼清單5-2 安裝redis的ruby包

# gem install redis --version 3.0.7

由於源的原因,可能下載失敗,那就手動下載下來安裝 

download地址:http://rubygems.org/gems/redis/versions/3.0.7 

程式碼清單5-3 手動下載&安裝redis的ruby包

# wget https://rubygems.org/downloads/redis-3.0.7.gem --no-check-certificate
# gem install -l redis-3.0.7.gem

一切準備就緒,開始搭建redis叢集吧!參照程式碼清單5-4,但是你還是要修改一下IP地址,你的容器地址應該不可能和我的一毛一樣吧。

程式碼清單5-4 搭建redis叢集

# cd /usr/docker_root/redis_cluster/redis-3.0.7/src/
# ./redis-trib.rb create --replicas 1 172.17.0.66:6379 \   
172.17.0.67:6379 \
172.17.0.68:6379 \
172.17.0.69:6379 \
172.17.0.70:6379 \
172.17.0.71:6379

執行結果程式碼程式碼清單5-5所示

程式碼清單5-5 搭建redis叢集輸出結果

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.17.0.69:6379
172.17.0.68:6379
172.17.0.67:6379
Adding replica 172.17.0.66:6379 to 172.17.0.69:6379
Adding replica 172.17.0.71:6379 to 172.17.0.68:6379
Adding replica 172.17.0.70:6379 to 172.17.0.67:6379
S: 53d5136dfc65dde54372c9b19a07dde922d68018 172.17.0.66:6379
   replicates e33bf44633a1dcc5a92feec0c2f54846707213b5
M: c16ca51f791743e5623180548abce932f26e03a2 172.17.0.67:6379
   slots:10923-16383 (5461 slots) master
M: e8f5a60690fca6388bedbb88b8d58e15a32d169a 172.17.0.68:6379
   slots:5461-10922 (5462 slots) master
M: e33bf44633a1dcc5a92feec0c2f54846707213b5 172.17.0.69:6379
   slots:0-5460 (5461 slots) master
S: 9ba61b899311622e13871952dc6248366d69dca2 172.17.0.70:6379
   replicates c16ca51f791743e5623180548abce932f26e03a2
S: 0b33044326d5e2ee75d4035ed014349ea6d859b0 172.17.0.71:6379
   replicates e8f5a60690fca6388bedbb88b8d58e15a32d169a
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 172.17.0.66:6379)
M: 53d5136dfc65dde54372c9b19a07dde922d68018 172.17.0.66:6379
   slots: (0 slots) master
   replicates e33bf44633a1dcc5a92feec0c2f54846707213b5
M: c16ca51f791743e5623180548abce932f26e03a2 172.17.0.67:6379
   slots:10923-16383 (5461 slots) master
M: e8f5a60690fca6388bedbb88b8d58e15a32d169a 172.17.0.68:6379
   slots:5461-10922 (5462 slots) master
M: e33bf44633a1dcc5a92feec0c2f54846707213b5 172.17.0.69:6379
   slots:0-5460 (5461 slots) master
M: 9ba61b899311622e13871952dc6248366d69dca2 172.17.0.70:6379
   slots: (0 slots) master
   replicates c16ca51f791743e5623180548abce932f26e03a2
M: 0b33044326d5e2ee75d4035ed014349ea6d859b0 172.17.0.71:6379
   slots: (0 slots) master
   replicates e8f5a60690fca6388bedbb88b8d58e15a32d169a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

使用redis-cli連線redis叢集,注意有–c

程式碼清單5-6 連線redis叢集

# redis-cli -p 30001 –c
127.0.0.1:30001> info
下面顯示叢集的相關資訊
# Server
redis_version:3.0.7
redis_git_sha1:00000000
redis_git_dirty:0
 (省略一部分……)
# CPU
used_cpu_sys:2.21
used_cpu_user:1.63
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
 
# Cluster
cluster_enabled:1
 
# Keyspace
127.0.0.1:30001>

做個set操作試試,見圖5-1.

圖5-1  set操作

看到了嗎?Redirected to slot [15495] located at 172.17.0.67:6379。a的value被儲存到172.17.0.67:6379結點上的槽[15495]裡。下面的地址也變成了172.17.0.67:6379>。再試試get操作。

圖5-2  get操作

大功告成!祝賀!!!