使用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集群

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

依據代碼清單2-2,修改redis.conf文件中的對應參數值。

代碼清單2-2 需要修改的配置參數

1 daemonize no
2 port 6379
3 logfile "/var/log/redis/redis-server.log"
4 appendonly yes
5 cluster-enabled yes
6 cluster-config-file nodes.conf
7 cluster-node-timeout 5000
8 bind 0.0.0.0

 

  

daemonize : 是否后台運行,將其設為no,表示前台運行。

port :redis服務監聽的端口。

logfile : 指定日志文件路徑。

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

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

 

由於需要在內網其他服務器上連接redis服務器(192.168.1.110),本想直接在redis配置文件中加上目標的IP地址:
bind 192.168.1.166
就可以了,實際上不正確。
redis bind表示的是指定本機可以接受連接的網卡地址,比如redis服務器上有一個公網IP(114.114.114.114),一個內網IP(192.168.1.110),如果該redis服務器需要被本機以外的服務器訪問(比如說內網的服務器),
此時需要在redis 配置文件中配置:
bind 192.168.1.110
意思是該redis使用該IP來接受外部的連接(注意:bind的意思不是綁定外部服務器的IP,而是綁定本機可以接受訪問的IP)。
然而我這要配置后使用116依然連接不上,經多次排查發現我是使用
./redis-server &
來啟動redis的,啟動時沒有指定配置文件。(即使修改了redis安裝目錄下的配置文件也不生效)
所以指定配置文件路徑的方式來啟動:
./redis-server /usr/local/redis/redis.conf &
如果到這步還不能生效,可以在配置文件中將redis保護模式關閉,但記得使用密碼來保證安全性(使用復雜密碼)。
protected-mode no
requirepass a1s2W3l4%G
redis bind連不上的坑

 

下面構建redis基礎鏡像。以Dockerfile方式構建。

代碼清單2-3 創建redis基礎鏡像的Dockerfile

# pwd
/usr/docker_root/redis_cluster
# vim Dockerfile

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

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

 

 1 將本地的redis源碼包復制到鏡像的根路徑下,ADD命令會在復制過后自動解包。被復制的對象必須處於Dockerfile同一路徑,且ADD后面必須使用相對路徑。
 2 將我們修改后的配置文件也復制到鏡像內。
 3 為編譯源碼包,需要安裝gcc和make,安裝之前先更新apt-get。更新和安裝時間較長。
 4 編譯源碼包。當然編譯也需要一段時間。
 5 編譯后,容器中只需要可執行文件redis-server,所以將該文件移到/redis/路徑下。現在redis-server 和redis.conf都在/redis/下。
 6 將redis-3.0.7路徑整個刪除。
 7 gcc和make也可以卸載掉。
 8 指定數據卷,通過這個數據卷可以查看redis運行的日志文件。
 9 公開redis默認端口6379。
10 因為不會執行這個鏡像,所有沒有包含ENTRYPOINT和CMD指令。我們基於這個鏡像構建別的鏡像。
做了哪些事

 

現在我們構建redis基礎鏡像

代碼清單2-5 構建redis基礎鏡像

# docker build -t redis:3.0.7 .

構建過程與網絡帶寬有關,十分鍾左右,構建完成。成功構建鏡像之后,運行docker images,可以看到構建后的鏡像

 

3構建redis結點鏡像

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

代碼清單3-1 創建redis結點鏡像的Dockerfile

 

# mkdir redis_node
# cd redis_node

 # pwd
  /usr/docker_root/redis_cluster/redis_node

# vim Dockerfile

Dockerfile如代碼清單3-2所示。

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

構建redis結點鏡像。

代碼清單3-3 構建redis結點鏡像

# docker build -t redis-cluster:3.0.7 .

查看redis結點鏡像redis-cluster:3.0.7

4創建redis結點容器

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

代碼清單4-1 創建redis結點

# docker run -d --name redis01 -p 30001:6379 redis-cluster:3.0.7
# docker run -d --name redis02 redis-cluster:3.0.7
# docker run -d --name redis03 redis-cluster:3.0.7
# docker run -d --name redis04 redis-cluster:3.0.7
# docker run -d --name redis05 redis-cluster:3.0.7
# docker run -d --name redis06 redis-cluster:3.0.7

第一個容器做了端口映射,是專門留給客戶端訪問的,這樣客戶端就可以通過宿主機的30001端口訪問redis集群了。

查看各容器IP地址

代碼清單4-2 查看redis結點IP

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

5搭建redis集群

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

一般需要安裝ruby1.9的版本,可以自己下載安裝。

代碼清單5-1 安裝ruby環境

# yum install ruby

# yum install rubygems

以下為源碼包安裝方式,如已經yum安裝過,可直接略過

手動安裝步驟:

tar -xzf ruby-1.9.3-p194.tar.gz解壓安裝包

./configure --prefix=/usr/local/ruby

 

由於redhat新版本(redhat5.4不報錯,開發環境會報錯)默認openssl的配置變更取消了對EC_xx的支持,make 會出錯,

此時需要修改ext/openssl/ossl_pkey_ec.c代碼,修改的內容如下

修改762行開始處:

if (id == s_GFp_simple) {

method = EC_GFp_simple_method();

            } else if (id == s_GFp_mont) {

method = EC_GFp_mont_method();

            } else if (id == s_GFp_nist) {

method = EC_GFp_nist_method();

#if !defined (OPENSSL_NO_EC2M)

            } else if (id == s_GF2m_simple) {

method = EC_GF2m_simple_method();

#endif

修改817行開始處:

if (id == s_GFp) {

new_curve = EC_GROUP_new_curve_GFp;

#if !defined (OPENSSL_NO_EC2M)

            } else if (id == s_GF2m) {

new_curve = EC_GROUP_new_curve_GF2m;

#endif

            } else {

ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");

            }

修改完成后執行如下命令

make

make install

安裝完成后設置PATH路徑,把安裝的ruby放在系統PATH前面,

避免調用操作系統自帶的ruby  (開發環境REDHAT自帶為1.8版本,而1.8版本不能用於redis集群的部署,至少用1.9以上)   ,

修改~/.bash_profile

#PATH=$PATH:$HOME/bin—原來的配置

PATH=/usr/local/ruby/bin:$PATH:$HOME/bin—修改后的配置

修改后保存,並執行 source ~/.bash_profile生效

執行ruby -v 查看ruby版本

運行redis-trib.rb腳本還需要安裝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/
[root@localhost src]# ./redis-trib.rb create --replicas 1 172.17.0.2:6379 \
172.17.0.3:6379 \
172.17.0.4:6379 \
172.17.0.5:6379 \
172.17.0.6:6379 \
172.17.0.7:6379

執行結果代碼代碼清單5-5所示

代碼清單5-5 搭建redis集群輸出結果

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.17.0.2:6379
172.17.0.3:6379
172.17.0.4:6379
Adding replica 172.17.0.5:6379 to 172.17.0.2:6379
Adding replica 172.17.0.6:6379 to 172.17.0.3:6379
Adding replica 172.17.0.7:6379 to 172.17.0.4:6379
M: 88f67ae03cd9f9856895ae432b17b5bae9e278f4 172.17.0.2:6379
   slots:0-5460 (5461 slots) master
M: fd25d673a7dd9044c269c56a3967b12fcd228225 172.17.0.3:6379
   slots:5461-10922 (5462 slots) master
M: f1b54c64af4bfa39271540928e513372f76d0b5f 172.17.0.4:6379
   slots:10923-16383 (5461 slots) master
S: 1b17ff2b22d033bd013e902a436e4694ca73d1e1 172.17.0.5:6379
   replicates 88f67ae03cd9f9856895ae432b17b5bae9e278f4
S: 779725a1ae038c214c09ad532a250431e7e69793 172.17.0.6:6379
   replicates fd25d673a7dd9044c269c56a3967b12fcd228225
S: 2a60bef969f9191701d4de2a109d14170fd76b37 172.17.0.7:6379
   replicates f1b54c64af4bfa39271540928e513372f76d0b5f
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.2:6379)
M: 88f67ae03cd9f9856895ae432b17b5bae9e278f4 172.17.0.2:6379
   slots:0-5460 (5461 slots) master
M: fd25d673a7dd9044c269c56a3967b12fcd228225 172.17.0.3:6379
   slots:5461-10922 (5462 slots) master
M: f1b54c64af4bfa39271540928e513372f76d0b5f 172.17.0.4:6379
   slots:10923-16383 (5461 slots) master
M: 1b17ff2b22d033bd013e902a436e4694ca73d1e1 172.17.0.5:6379
   slots: (0 slots) master
   replicates 88f67ae03cd9f9856895ae432b17b5bae9e278f4
M: 779725a1ae038c214c09ad532a250431e7e69793 172.17.0.6:6379
   slots: (0 slots) master
   replicates fd25d673a7dd9044c269c56a3967b12fcd228225
M: 2a60bef969f9191701d4de2a109d14170fd76b37 172.17.0.7:6379
   slots: (0 slots) master
   replicates f1b54c64af4bfa39271540928e513372f76d0b5f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
View Code

使用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<br>
# Keyspace
127.0.0.1:30001>
View Code

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

再試試get操作。

 

大功告成!祝賀!!!

 

個人公眾號:度一聊,不定期推送干貨,及有用資源。

 

 

 


免責聲明!

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



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