天天看點

codis3.2.1叢集搭建與測試

Codis是一套用go語言編寫的,為了應對高并環境下的redis叢集軟體,原理是對一個redis key操作前,先把這個key通過crc32算法,配置設定到不同redis的某一個slot上,實作并發讀寫功能.而且能通過zookeeper調用redis-sentinel來實作故障切換功能.現在最新版本是3.2.1,依托于redis3.2.9開發出來.

優點:實作高并發讀寫,資料一緻性高.

缺點:性能有較大損耗,故障切換無法保證不丢key,無法進行讀寫分離.

架構介紹

1.需要用到的軟體有:

codis3.2.1

描述:codis叢集套件,裡面含有redis相關程式,和叢集專用程式,主要功能程式解析:

codis-server:屬于redis-server優化版,基于 redis-3.2.9 分支開發。增加了額外的資料結構,以支援 slot 有關的操作以及資料遷移指令。

codis-proxy:用戶端連接配接的 Redis 代理服務, 實作了 Redis 協定。 除部分指令不支援以外(例如:keys *,flush ),表現的和原生的 Redis 沒有差別(就像 Twemproxy)。

redis-sentinel:可以實作對Redis的監控、通知、自動故障轉移。如果Master不能工作,則會自動啟動故障轉移程序,将其中的一個Slave提升為Master,其他的Slave重新設定新的Master服務。Sentinel的配置由 codis-dashboard和zookeeper一起控制,不需要手工填寫.

codis-dashboard:叢集管理工具,支援 codis-proxy、codis-server 的添加、删除,以及據遷移等操作。在叢集狀态發生改變時,codis-dashboard 維護叢集下所有 codis-proxy 的狀态的一緻性。

codis-fe:叢集web管理界面。

go1.9.1

描述:codis依賴語言包

jdk1.8

描述:zookeeper依賴語言包

zookeeper-3.4.11

描述:用于存放資料配置路由表。zookeeper簡稱zk。在生産環境中,zk部署越多,其可靠性越高。由于zk叢集是以當機個數過半才會讓整個叢集當機,是以,奇數個zk更佳。

2. 邏輯架構如下:

通路層:通路方式可以是vip或者是通過java代碼調用jodis,然後連接配接調用不同的codis-proxy位址來實作高可用的LVS和HA功能.

代理層:然後中間層由codis-proxy和zookeeper處理資料走向和配置設定,通過crc32算法,把key平均配置設定在不同redis的某一個slot中.實作類似raid0的條帶化,在舊版本的codis中,slot需要手工配置設定,在codis3.2之後,slot會自動配置設定,相當友善.

資料層:最後codis-proxy把資料存進真實的redis-server主伺服器上,由于codis的作者黃東旭相當注重資料一緻性,不允許有資料延時造成的資料不一緻,是以架構從一開始就沒考慮主從讀寫分離.從伺服器僅僅是作為故障切換的備援架構,由zookeeper調用redis-sentinel實作故障切換功能.

3.因為機器有限,部署的架構如下:

zookeeper叢集:

10.0.2.5:2181

10.0.2.6:2181

10.0.2.7:2181

codis-config和codis-dashboard:

10.0.2.6:18087

10.0.2.6:8090

codis-proxy:

10.0.2.5:19000

10.0.2.7:19000

codis-server:

10.0.2.5:6379(主),10.0.2.5:6380(從)

10.0.2.6:6379(主),10.0.2.6:6380(從)

10.0.2.7:6379(主),10.0.2.7:6380(從)

安裝部署

1. 下載下傳程式代碼

1)下載下傳golang語言程式包,

按正常途徑是要×××的,不過國内位址也有人放出來了,因為codis3.2要求至少是1.7或1.8以上版本的,那幹脆下最新版吧.

https://studygolang.com/dl/golang/go1.9.1.linux-amd64.tar.gz

2)下載下傳java語言程式包,

Java的下載下傳位址一直在變,是以最好自己上去看着來下載下傳

http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz?AuthParam=1513326216_bcf60226458d67751e1d8d1bbe6689b4

3)下載下傳zookeeper程式

直接就是程式包,不用編譯了,好友善

http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz

4)下載下傳codis3.2.1

https://github.com/CodisLabs/codis/releases/download/3.2.1/codis3.2.1-go1.7.6-linux.tar.gz

2. 安裝程式

1) 安裝java

<code>#解壓程式包</code>

<code>tar</code> <code>xf jdk-8u144-linux-x64.</code><code>tar</code><code>.gz</code>

<code>#移動到指定目錄</code>

<code>mv</code> <code>jdk1.8.0_144/ </code><code>/usr/local/</code>

<code>#進入指定目錄,并建立程式軟連接配接</code>

<code>cd</code> <code>/usr/local/</code>

<code>ln</code> <code>-sf jdk1.8.0_144/ jdk</code>

<code>#建立環境變量檔案</code>

<code>echo</code> <code>“</code><code>export</code> <code>JAVA_HOME=</code><code>/usr/local/jdk</code>  

<code>export</code> <code>JRE_HOME=</code><code>/usr/local/jdk/jre</code>  

<code>export</code> <code>CLASSPATH=.:$JAVA_HOME</code><code>/lib/dt</code><code>.jar:$JAVA_HOME</code><code>/lib/tools</code><code>.jar:$JRE_HOME</code><code>/lib</code>  

<code>export</code> <code>PATH=$PATH:$JAVA_HOME</code><code>/bin</code> <code>”&gt; </code><code>/etc/profile</code><code>.d</code><code>/java</code><code>.sh</code>

<code>#重載環境變量</code>

<code>source</code> <code>/etc/profile</code>

<code>#測試檢查是否安裝完成</code>

<code>java -version</code>

<code>java version </code><code>"1.8.0_144"</code>

<code>Java(TM) SE Runtime Environment (build 1.8.0_144-b01)</code>

<code>Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)</code>

安裝完畢

2) 安裝golang

<code>tar</code> <code>xf go1.9.1.linux-amd64.</code><code>tar</code><code>.gz</code>

<code>mv</code> <code>go </code><code>/usr/local/</code>

<code>#把程式包裡的指令軟連接配接到系統預設指令目錄</code>

<code>ln</code> <code>-sf </code><code>/usr/local/go/bin/</code><code>* </code><code>/usr/bin/</code>

<code>go version</code>

<code>go version go1.9.1 linux</code><code>/amd64</code>

安裝完成

3) 安裝zookeeper

<code>tar</code> <code>xf zookeeper-3.4.11.</code><code>tar</code><code>.gz</code>

<code>mv</code> <code>zookeeper-3.4.11 </code><code>/usr/local/</code>

<code>ln</code> <code>-sf zookeeper-3.4.11/ zookeeper</code>

安裝完成,等候配置.

4) 安裝codis

<code>tar</code> <code>xf codis3.2.1-go1.7.6-linux.</code><code>tar</code><code>.gz</code>

<code>mv</code> <code>codis3.2.1-go1.7.6-linux </code><code>/usr/local/</code>

<code>ln</code> <code>-sf codis3.2.1-go1.7.6-linux/ codis</code>

安裝完成,等候配置,因為我們用的都是二進制程式包,隻要依賴包有正常安裝,就不會報錯,直接就能用,是以安裝就很簡單.

3. 配置程式

1) 配置zookeeper,3台一起都是這麼配置

<code>#設定hosts跳轉規則,好像不這麼設定的話,不能順利啟動</code>

<code>echo</code> <code>“10.0.2.5        zookeeper-node1</code>

<code>10.0.2.6        zookeeper-node2</code>

<code>10.0.2.7        zookeeper-node3” &gt;&gt; </code><code>/etc/hosts</code>

<code>#建立程式目錄</code>

<code>mkdir</code> <code>-p </code><code>/data/zookeeper</code>

<code>#建立配置檔案,檔案夾裡有一個模闆,有興趣可以看看</code>

<code>vim </code><code>/usr/local/zookeeper/conf/zoo</code><code>.cfg</code>

<code>#最大連接配接數設定. 注:可不配置. </code>

<code>maxClientCnxns=50</code>

<code>#一個周期(tick)的時長(機關:毫秒). 注:可用預設值</code>

<code>tickTime=2000</code>

<code>#初始化同步階段最多耗費tick個數. 注:可用預設值</code>

<code>initLimit=10</code>

<code>#等待應答的最大間隔tick個數. 注:可用預設值</code>

<code>syncLimit=5</code>

<code>#資料存儲目錄,剛才建立那個. 注:勿放在/tmp目錄</code>

<code>dataDir=</code><code>/data/zookeeper/</code>

<code>#通信端口. 注:可用預設值</code>

<code>clientPort=2181</code>

<code>server.1=zookeeper-node1:2888:3888</code>

<code>server.2=zookeeper-node2:2888:3888</code>

<code>server.3=zookeeper-node3:2888:3888</code>

生成ID,這裡需要注意, myid對應的zoo.cfg的server.ID.比如zookeeper-node2對應的myid應該是2,不按規定設定,zookeeper叢集将無法啟動. 

<code>echo</code> <code>"1"</code><code>&gt; </code><code>/data/zookeeper/myid</code>

==============================================

例如:在zookeeper-node3那台10.0.2.7的伺服器,就應該是

<code>echo</code> <code>"3"</code><code>&gt; </code><code>/data/zookeeper/myid</code>

====================================================

#zoo.cfg最後三行特别說明

說明:server.A=B:C:D:其中 A 是一個數字,表示這個是第幾号伺服器;B 是這個伺服器的 ip 位址;C 表示的是這個伺服器與叢集中的 Leader 伺服器交換資訊的端口;D 表示的是萬一叢集中的 Leader 伺服器挂了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時伺服器互相通信的端口。

<code>#最後啟動,因為zookeeper的server是有順序的,最好是按順序啟動,先啟動server.1再啟動server2,最後啟動server.3這樣</code>

<code>/usr/local/zookeeper/bin/zkServer</code><code>.sh start</code>

<code>#檢視狀态,會有follower和leader的差別,他們自己會選誰是leader</code>

<code>/usr/local/zookeeper/bin/zkServer</code><code>.sh status</code>

<code>ZooKeeper JMX enabled by default</code>

<code>Using config: </code><code>/usr/local/zookeeper/bin/</code><code>..</code><code>/conf/zoo</code><code>.cfg</code>

<code>Mode: follower</code>

配置并啟動完畢.

2) 配置codis-server,3台一起都是這麼配置

注意:codis-server就是redis-server程式,屬于codis優化版本,配合codis叢集使用.

是以就是配置個redis的主從結構,實際生産環境不要搭在一起

<code>#建立redis資料目錄,配置檔案目錄,日志目錄</code>

<code>mkdir</code> <code>-p </code><code>/data/redis/data/config/</code>

<code>mkdir</code> <code>-p </code><code>/data/redis/data/logs/</code>

<code>#建立主庫的配置檔案,暫時隻配置這些,其他先預設</code>

<code>vim </code><code>/data/redis/data/config/redis_6379</code><code>.conf</code>

<code>#允許背景運作</code>

<code>daemonize </code><code>yes</code>

<code>#設定端口,最好是非預設端口</code>

<code>port 6379</code>

<code>#綁定登入IP,安全考慮,最好是内網</code>

<code>bind *</code>

<code>#命名并指定目前redis的PID路徑,用以區分多個redis</code>

<code>pidfile </code><code>"/data/redis/data/config/redis_6379.pid"</code>

<code>#命名并指定目前redis日志檔案路徑</code>

<code>logfile </code><code>"/data/redis/data/logs/redis_6379.log"</code>

<code>#指定RDB檔案名,用以備份資料到硬碟并區分不同redis,當使用記憶體超過可用記憶體的45%時觸發快照功能</code>

<code>dbfilename </code><code>"dump_6379.rdb"</code>

<code>#指定目前redis的根目錄,用來存放RDB/AOF檔案</code>

<code>dir</code> <code>"/data/redis/data"</code>

<code>#目前redis的認證密鑰,redis運作速度非常快,這個密碼要足夠強大,</code>

<code>#所有codis-proxy叢集相關的redis-server認證密碼必須全部一緻</code>

<code>requirepass </code><code>"123"</code>

<code>#目前redis的最大容量限制,建議設定為可用記憶體的45%内,最高能設定為系統可用記憶體的95%,</code>

<code>#可用config set maxmemory 去線上修改,但重新開機失效,需要使用config rewrite指令去重新整理配置檔案</code>

<code>#注意,使用codis叢集,必須配置容量大小限制,不然無法啟動</code>

<code>maxmemory 100000kb</code>

<code>#LRU的政策,有四種,看情況選擇</code>

<code>maxmemory-policy allkeys-lru</code>

<code>#如果做故障切換,不論主從節點都要填寫密碼且要保持一緻</code>

<code>masterauth </code><code>"123"</code>

<code> </code> 

<code>#建立從庫的配置檔案,暫時隻配置這些,其他先預設</code>

<code>vim </code><code>/data/redis/data/config/redis_6380</code><code>.conf</code>

<code>port 6380</code>

<code>pidfile </code><code>"/data/redis/data/config/redis_6380.pid"</code>

<code>logfile </code><code>"/data/redis/data/logs/redis_6380.log"</code>

<code>dbfilename </code><code>"dump_6380.rdb"</code>

<code>#目前redis的認證密鑰,redis運作速度非常快,這個密碼要足夠強大</code>

<code>#配置主節點資訊</code>

<code>slaveof 10.0.2.5 6379</code>

除了端口号不同帶來的檔案名不同.實際上從庫配置隻是多了最後一行,指定了主庫位址

<code>#然後就可以啟動了,我一開始就說過codis-server就是redis-server</code>

<code>/usr/local/codis/codis-server</code> <code>/data/redis/data/config/redis_6379</code><code>.conf</code>

<code>/usr/local/codis/codis-server</code> <code>/data/redis/data/config/redis_6380</code><code>.conf</code>

<code>#驗證一下</code>

<code>ss -ntplu |</code><code>grep</code> <code>codis-server</code>

<code>tcp    LISTEN     0      128       *:6379                  *:*                   </code><code>users</code><code>:((</code><code>"codis-server"</code><code>,pid=2192,fd=4))</code>

<code>tcp    LISTEN     0      128       *:6380                  *:*                   </code><code>users</code><code>:((</code><code>"codis-server"</code><code>,pid=2197,fd=4))</code>

啟動方式和redis-server一樣,指定配置檔案就可以啟動.這就配置并啟動成功了.

3) 配置redis-sentinel,3台一起都是這麼配置

正确來說,redis-sentinel是要配置主從架構才能生效,但是在codis叢集中并不一樣,因為他的配置由zookeeper來維護,是以,這裡codis使用的redis-sentinel隻需要配置一些基本配置就可以了.

<code>#我們把配置放到redis資料目錄的配置檔案目錄</code>

<code>vim </code><code>/data/redis/data/config/sentinel</code><code>.conf</code>

<code>bind 0.0.0.0</code>

<code>protected-mode no</code>

<code>port 26379</code>

<code>pidfile </code><code>"/data/redis/data/config/sentinel_26379.pid"</code>

<code>logfile </code><code>"/data/redis/data/logs/sentinel_26379.log"</code>

<code>#然後就可以啟動了</code>

<code>/usr/local/codis/redis-sentinel</code> <code>/data/redis/data/config/sentinel</code><code>.conf</code>

<code>/usr/local/codis/redis-cli</code> <code>-p 26379 -c info Sentinel</code>

<code># Sentinel</code>

<code>sentinel_masters:3</code>

<code>sentinel_tilt:0</code>

<code>sentinel_running_scripts:0</code>

<code>sentinel_scripts_queue_length:0</code>

<code>sentinel_simulate_failure_flags:0</code>

<code>master0:name=codis-test1-3,status=ok,address=10.0.2.7:6380,slaves=1,sentinels=3</code>

<code>master1:name=codis-test1-1,status=ok,address=10.0.2.5:6379,slaves=1,sentinels=3</code>

<code>master2:name=codis-test1-2,status=ok,address=10.0.2.6:6379,slaves=1,sentinels=3</code>

配置并啟動成功.

注意:沒有配置好codis-dashboard會沒最後那幾行,因為還不受zookeeper控制,是以是正常的,配置好之後才會自動加載進來.

4) 配置codis-proxy,這次隻有兩台要配置,當然你也可以配三台

這個是codis叢集的核心,實際上他也沒配主從架構,配置也是從zookeeper拿來用的,是以,直接來看配置吧

<code>#配置很多,我們先生成一下預設的配置檔案</code>

<code>/usr/local/codis/codis-proxy</code> <code>--default-config | </code><code>tee</code> <code>.</code><code>/proxy</code><code>.conf</code>

<code>#然後我們把配置放到redis資料目錄的配置檔案目錄,再更改關鍵位置,其他預設即可</code>

<code>vim </code><code>/data/redis/data/config/proxy</code><code>.conf</code>

<code>#項目名稱,會登記在zookeeper裡,如果你想一套zookeeper管理多套codis,就必須區分好</code>

<code>product_name = </code><code>"codis-test1"</code>

<code># 設定登入dashboard的密碼(與真實redis中requirepass一緻)</code>

<code>product_auth = </code><code>"123"</code>

<code>#用戶端(redis-cli)的登入密碼(與真實redis中requirepass不一緻),是登入codis的密碼</code>

<code>session_auth = </code><code>"123456"</code>

<code>#管理的端口,0.0.0.0即對所有ip開放,基于安全考慮,可以限制内網</code>

<code>admin_addr = </code><code>"0.0.0.0:11080"</code>

<code>#用那種方式通信,假如你的網絡支援tcp6的話就可以設别的</code>

<code>proto_type = </code><code>"tcp4"</code>

<code>#用戶端(redis-cli)通路代理的端口,0.0.0.0即對所有ip開放</code>

<code>proxy_addr = </code><code>"0.0.0.0:19000"</code>

<code>#外部配置存儲類型,我們用的就是zookeeper,當然也是還有其他可以支援,這裡不展開說</code>

<code>jodis_name = </code><code>"zookeeper"</code>

<code>#配置zookeeper的連接配接位址,這裡是三台就填三台</code>

<code>jodis_addr = </code><code>"10.0.2.5:2181,10.0.2.6:2181,10.0.2.7:2181"</code>

<code>#zookeeper的密碼,假如有的話</code>

<code>jodis_auth = </code><code>""</code>

<code>#codis代理的最大連接配接數,預設是1000</code>

<code>proxy_max_clients = 1000</code>

<code>#假如并發太大,你可能需要調這個pipeline參數,大多數情況預設就夠了</code>

<code>session_max_pipeline = 10000</code>

<code>#然後就可以啟動了,</code>

<code>/usr/local/codis/codis-proxy</code> <code>--ncpu=1 --config=</code><code>/data/redis/data/config/proxy</code><code>.conf --log=</code><code>/data/redis/data/logs/proxy</code><code>.log &amp;</code>

<code>ss -ntplu |</code><code>grep</code> <code>codis-proxy</code>

<code>tcp    LISTEN     0      128       *:19000                 *:*                   </code><code>users</code><code>:((</code><code>"codis-proxy"</code><code>,pid=2075,fd=4))</code>

<code>tcp    LISTEN     0      128      :::11080                :::*                   </code><code>users</code><code>:((</code><code>"codis-proxy"</code><code>,pid=2075,fd=6))</code>

--ncpu    指定使用多少個cpu,我的是虛拟機,是以就1了,如果你是多核,那就填多個

--config    指定配置檔案,就是剛才的配置檔案

--log    指定輸出日志檔案

配置并啟動成功,但是暫時還用不了,因為還需要配置codis-dashboard才能最終完成.

5) 配置codis-dashboard,隻需要配置一台機上

這個屬于管理配置codis叢集資訊的工具,配置完之後的配置資訊會自動加載到zookeeper叢集,即使這個服務挂了,配置都還在zookeeper上,是以不用考慮高可用,單點就足夠了,大不了重新啟動一下也不是特别麻煩,配置界面由codis-fe來實作,是以通常也是一套配置.

<code>#我們也可以用程式來生成一下預設配置檔案</code>

<code>/usr/local/codis/codis-dashboard</code> <code>--default-config | </code><code>tee</code> <code>.</code><code>/dashboard</code><code>.conf</code>

<code>vim </code><code>/data/redis/data/config/dashboard</code><code>.conf</code>

<code>coordinator_name = </code><code>"zookeeper"</code>

<code>coordinator_addr = </code><code>"10.0.2.5:2181,10.0.2.6:2181,10.0.2.7:2181"</code>

<code>#所有redis的登入密碼(與真實redis中requirepass一緻),因為要登入進去修改資料</code>

<code>#codis-dashboard的通信端口,0.0.0.0表示對所有開放,最好使用内網位址</code>

<code>admin_addr = </code><code>"0.0.0.0:18080"</code>

<code>#如果想要在codis叢集在故障切換功能上執行一些腳本,可以配置以下兩個配置</code>

<code>sentinel_notification_script = </code><code>""</code>

<code>sentinel_client_reconfig_script = </code><code>""</code>

<code>/usr/local/codis/codis-dashboard</code> <code>--ncpu=1 --config=</code><code>/data/redis/data/config/dashboard</code><code>.conf --log=</code><code>/data/redis/data/logs/codis_dashboard</code><code>.log --log-level=WARN &amp;</code>

<code>ss -ntplu |</code><code>grep</code> <code>codis-dashboard</code>

<code>tcp    LISTEN     0      128      :::18080                :::*                   </code><code>users</code><code>:((</code><code>"codis-dashboard"</code><code>,pid=2021,fd=5))</code>

--ncpu    指定使用多少個cpu

--config    指定配置檔案

--log-level    指定日志等級,有INFO,WARN,DEBUG,ERROR

安裝完成,就差最後一步就可以開始配置.

由于codis-dashboard本身是不需要密碼登入的,是以這将會非常危險,強烈建議使用内網位址,而作者表示将會在下個版本考慮增加codis-dashboard的認證密碼.

6) 配置codis-fe,隻需要配置一台機上

這個是屬于web界面操作codis-dashboard配置的工具,web代碼檔案在codis安裝檔案夾的目錄下,具體是:/usr/local/codis/assets/這個目錄.

這個工具本身不需要配置檔案就能啟動,隻需要指定codis-dashboard的ip和端口就可以了,但是我為了友善管理,還是生成一個配置檔案的好.

<code>#生成一下配置檔案,其實也就是codis-dashboard的ip和端口</code>

<code>/usr/local/codis/codis-admin</code> <code>--dashboard-list --zookeeper=10.0.2.6:2181 &gt;codis.json</code>

<code>#然後我們把配置放到redis資料目錄的配置檔案目錄,看一下</code>

<code>cat</code> <code>/data/redis/data/config/codis</code><code>.json </code>

<code>[</code>

<code>    </code><code>{</code>

<code>        </code><code>"name"</code><code>: </code><code>"codis-test1"</code><code>,</code>

<code>        </code><code>"dashboard"</code><code>: </code><code>"10.0.2.6:18080"</code>

<code>    </code><code>}</code>

<code>]</code>

<code>/usr/local/codis/codis-fe</code> <code>--ncpu=1 --log=</code><code>/data/redis/data/logs/fe</code><code>.log --log-level=WARN --dashboard-list=</code><code>/data/redis/data/config/codis</code><code>.json --listen=0.0.0.0:8090 &amp;</code>

--dashboard-list    指定dashboard的位址和項目名稱,這裡因為生成了檔案,是以就指定成檔案了

--listen    指定codis-fe的web登入端口,也就是我們通過8090來通路這個管理端了,0.0.0.0即對來訪IP無限制,其實最好是限制内網

驗證一下

全套安裝完成,成功啟動.開始下一步.

使用舉例

因為有了web界面,基本上就都是界面操作了,非常友善,配置會直接加載到zookeeper裡面去.

首先,我們先添加codis-proxy位址和端口

按順序:

第一步,先添加codis-proxy的位址和管理端口,上面設定的是11080.

第二步,點選左方的橙色按鈕,然後就添加完畢.

第三步,看到下方出現該有的codis-proxy位址就算完成了,然後看到右方的SYNC字樣的顔色是綠色,則代表配置正常.

如果要删除記錄,點選最右方的紅色按鈕即可.

然後,我們添加真實redis-server(也是codis-server)位址和端口

第一步,先建立一個組,準備把相關的一組主從放進去

第二步,點選按鈕生成這個分組

第三步,添加真實redis-server位址,并標明一個分組,例如剛才建立的分組1

第四步,點選按鈕生成配置

第五步,可以看到配置已經登記好,注意sync狀态.

第六步,點選重新平衡所有slots資料塊(任何添加和删除新舊節點都需要點選這個)

在舊版本中slots需要手動配置,但是3.2版本之後就改成自動配置設定了,是以已經不需要配置,點選一下就可以了.當然你也可以手動去配置設定.

最後配置sentinel的位址和端口

第一步,添加真實的sentinel位址和端口

第二步,點選按鈕添加

第三步,檢視狀态,這裡有點不一樣,他會自動添加目前主從組架構由多少台,控制切換

也正如我之前說的,他們自動去改配置檔案,可以去看看sentinel的配置檔案證明一下,這裡不展開來說了

都配置好了,就可以使用了,連接配接其中一個codis-proxy測一下,注意區分好登入的位址和端口,還有密碼

<code>/usr/local/codis/redis-cli</code> <code>-h 10.0.2.5 -p 19000 -a 123456</code>

<code>10.0.2.5:19000&gt; info</code>

<code># Server</code>

<code>redis_version:3.2.9</code>

<code>redis_git_sha1:f8bc4e32</code>

<code>redis_git_dirty:0</code>

<code>redis_build_id:2bdb8aa56be3fbc2</code>

<code>redis_mode:standalone</code>

<code>os:Linux 4.10.0-19-generic x86_64</code>

<code>arch_bits:64</code>

<code>multiplexing_api:epoll</code>

<code>gcc_version:4.8.4</code>

<code>process_id:2032</code>

<code>run_id:98e2364d837990dfb47be050901ef9e36ea113fa</code>

<code>tcp_port:6379</code>

<code>uptime_in_seconds:16312</code>

<code>uptime_in_days:0</code>

<code>hz:10</code>

<code>lru_clock:3634855</code>

<code>executable:</code><code>/usr/local/codis/codis-server</code>

<code>config_file:</code><code>/data/redis/data/config/redis_6379</code><code>.conf</code>

<code># Clients</code>

<code>connected_clients:71</code>

<code>client_longest_output_list:0</code>

<code>client_biggest_input_buf:0</code>

<code>blocked_clients:0</code>

<code># Memory</code>

<code>used_memory:61878808</code>

<code>used_memory_human:59.01M</code>

<code>used_memory_rss:76623872</code>

<code>used_memory_rss_human:73.07M</code>

<code>used_memory_peak:63148384</code>

<code>used_memory_peak_human:60.22M</code>

<code>total_system_memory:1529741312</code>

<code>total_system_memory_human:1.42G</code>

<code>used_memory_lua:37888</code>

<code>used_memory_lua_human:37.00K</code>

<code>maxmemory:102400000</code>

<code>maxmemory_human:97.66M</code>

<code>maxmemory_policy:allkeys-lru</code>

<code>mem_fragmentation_ratio:1.24</code>

<code>mem_allocator:jemalloc-4.0.3</code>

<code>.</code>

可以使用了.

壓力測試

1.性能測試

先用自帶的redis-benchmark來壓測性能,模拟500個并發和100萬個請求.注意區分好登入的位址和端口,還有密碼

先壓測codis-proxy的性能

<code>/usr/local/codis/redis-benchmark</code> <code>-h 10.0.2.5 -p 19000 -a 123456 -c 500 -n 1000000 -q</code>

再壓測單節點的性能

<code>/usr/local/codis/redis-benchmark</code> <code>-h 10.0.2.5 -p 6379 -a 123 -c 500 -n 1000000 -q</code>

redis-benchmark參數解析:

-h    ip位址

-p    redis端口

-a    認證密碼

-c    設定多少個并發連接配接

-n    總共多少個請求

-q    顯示模式:簡要模式

然後看圖

可以看到,有些操作相差不大,有些相差甚遠,性能損耗明顯,不過作為叢集應用,主要應對的是高并發環境,性能損耗是可以接受的,何況對于redis這種記憶體型高速應用來說,性能損耗基本沒什麼太大感覺.

2.資料分布測試

然後是讀寫分布測試:

我寫了個腳本來測試:

<code>cat</code> <code>t-redis.sh</code>

<code>#!/bin/bash</code>

<code>hos=</code><code>"10.0.2.7"</code>

<code>pot=</code><code>"19000"</code>

<code>pawd=</code><code>"123456"</code>

<code>cli=</code><code>"/usr/local/codis/redis-cli"</code>

<code>keyset=</code><code>"keytest2"</code>

<code>valueset=</code><code>"jlasdnfnsdfsdf;sdfhlkjahsdjlkfadfjkasdbbcjhdgasfyuefkbadjkhflk"</code>

<code>dbname=2</code>

<code>a=0</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>seq</code> <code>1 300000`</code>

<code>do</code>

<code>        </code><code>$cli -h $hos -p $pot -a $pawd -n $dbname </code><code>'set'</code> <code>${keyset}${a} </code><code>"${valueset}${a}"</code> <code>&gt;</code><code>/dev/null</code>

<code>        </code><code>#echo $a</code>

<code>        </code><code>let</code> <code>a++</code>

<code>done</code>

腳本很簡單,就是不斷向codis叢集寫垃圾資料而已,執行腳本.

<code>bash</code> <code>t-redis.sh</code>

然後結果可以看web界面,因為你連接配接codis-proxy用info來看,其實是不準确的,那個顯示的隻是單台的資料.

可以看到,每一個組都分布得比較均勻,把壓力都分到三台redis-server主伺服器去了.

3.故障切換測試

然後來看故障切換,繼續執行那個腳本

進入其中一台codis-server,例如10.0.2.5,此時狀态是正常的.

開始模拟操作

<code>#查找主庫程序</code>

<code>ss -ntplu |</code><code>grep</code> <code>codis-server </code>

<code>tcp    LISTEN     0      128       *:6379                  *:*                   </code><code>users</code><code>:((</code><code>"codis-server"</code><code>,pid=2032,fd=4))</code>

<code>tcp    LISTEN     0      128       *:6380                  *:*                   </code><code>users</code><code>:((</code><code>"codis-server"</code><code>,pid=2037,fd=4))</code>

<code>#殺掉主庫程序</code>

<code>kill</code> <code>2032</code>

此時從庫接管了主庫的程序,sentinels有提示資訊.

可能有人發現組1的sync按鈕變成了紅色,也就是說主從失效,點一下就變回正常.

現在等待資料寫完,我先把舊的主程序6379端口從新起來

然後看看:

看狀态是恢複正常了,但是有計算機的同學可以算一下,我的腳本執行的總共是30萬個key,但是現在少了幾千個.

坑---1:

上面丢key的問題是由于redis-sentinel故障切換期間,整個codis叢集并不會關閉對此故障redis-server的連接配接,是以codis-proxy依然會發送資料給目前故障的redis-server,而顯然此時的redis-server是無法存儲資料的,這就造成了丢key現象了.如果整個主從挂了,就會丢掉所有發送到此redis-server的key了,除非手工剔除故障節點.

雖然codis還自帶有一種故障切換程式codis-ha,他屬于一個守護程序,會連接配接codis-dashboard檢視各節點狀态,

<code>#執行一下指令啟動codis-ha,端口是codis-dashboard的端口</code>

<code>/usr/local/codis/codis-ha</code> <code>--dashboard=10.0.2.6:18080 --log=</code><code>/data/redis/data/logs/ha</code><code>.log --log-level=WARN &amp;</code>

--dashboard    指定dashboard的位址和端口

--log    指定日志檔案

但是這個軟體也是有缺陷,他會自動連接配接上dashboard檢測各主從結構的健康資訊,檢測間隔很快(預設3秒,可修改參數--interval),檢測到故障後,會将故障主庫或者從庫強制下線并删除在dashboard登記的資訊.

雖然切換速度非常快,隻會有很少的丢key現象(3秒還是會丢一些),但是後面會把故障舊主庫強制下線,需要手動修改配置并重新啟動redis-server(codis-server),還要再在codis-fe界面添加配置才行.

顯然這是做不到全自動管理,有點麻煩了,而且也會讓redis-sentinel變得沒有意義了,是以隻能兩個方式選其一.

雖然看上去丢key現象是少了,但是依然還是有丢key的情況,隻能說是50步笑100步,而且該組内其他 slave 執行個體是不會自動改變狀态的,這些 slave 仍将試圖從舊的 master 上同步資料,因而會導緻組内新的 master 和其他 slave 之間的資料不一緻。是以當出現主從切換時,需要管理者手動建立新的 sync action 來完成新 master 與 slave 之間的資料同步,這樣反而增加了手動操作的工作量,各位對于codis-ha和redis-sentinel的叢集的選擇還是需要多考慮一些實際情況.

是以,說到底就是codis的故障切換沒有做好,如果對丢key可以容忍的,就開redis-sentinel就足夠了,對于資料一緻性要求高的,就開codis-ha加腳本來實作比較好,各取所需.

實時添加删除節點

codis的另一個賣點就是可以線上添加/删除redis-server(codis-server)節點,做到實時擴容和更換問題節點,對于單點redis而言優勢明顯,不用重新開機服務就能有更大的空間,也可以線上切換掉有問題的節點.不過要注意,可以實時擴容和故障切換,并不代表沒有性能損耗,真的要做也是要注意線上壓力,避免性能壓力導緻的服務不可用.

實作的原理是因為codis叢集把各個redis-server節點都用規則分成了多個slots資料塊(總共1024個).需要擴容隻要把新的節點添加完成後,在把這些slots資訊從新配置設定就可以達到擴容效果,需要故障切換則把問題redis-server節點的slots遷移走,然後就可以把這個節點下架了,對于線上環境可以說是幾乎沒感覺,試驗過程中也沒發現有丢key現象,就是性能有所下降,但是我測試的環境下性能下降還能接受,大概隻有10%-30%的性能損耗.

開始試驗,首先我們假設添加兩個新的redis-server節點,都直接是主庫,沒有從庫環境(因為這次不需要測故障切換):

10.0.2.5:16379

10.0.2.6:16379

1.添加一個節點,等于是擴容,這還是比較簡單

第一步,和之前差不多,先建立一個新組,點選按鈕确認添加

第二步,把新位址添加到新的組,點選按鈕确認添加

第三步,确認新的位址已成功添加進去

第四步,點選按鈕,從新配置設定所有slots資料塊

這裡唯一問題就是最後一步,重新配置設定會耗費一定資源,codis會自動平衡資料塊的分布,是以會有資料遷移過程,但是據我測試的結果來看,并不很嚴重,大概在20%左右.

根據它自帶的監控來看的話,

可以看到之前正常情況的qps接近1500,剛點重新平衡下降比較嚴重一些,後面就大概有20%的性能損耗那樣子,最後遷移完畢就恢複正常了.當然這是資料量少的情況,如果資料量多,這個遷移時間就恐怕不是那麼簡單了.

2.切換一個節點,并下架

正常下架隻需要點選這個按鈕

但是因為裡面還有資料,是不允許直接下架的

是以我們要先遷移資料,如下所示:

第一步,确認一個需要遷移的組的資料塊的編号,例如這裡499-512的塊是資料組4的,我現在要遷移組4,就標明這個

第二步,把剛才擷取到的資訊填進去,就是把500這個編号的資料塊從組4遷移到組5,點選按鈕執行

然後你就會看到,

顯然組4的資訊消失了,codis把組4的資料塊都遷移到了組5去了,

這個時候,這個redis-server節點就可以删除了

至于還需不需要重新填補,這個問題則需要自身考慮.如果不需要填補,最好再點一下重新平衡slots比較好.

可以看到,又重新平衡了.

故障處理

1.codis-dashboard無法啟動,并提示:

[ERROR] store: acquire lock of codis-test1 failed

[error]: zk: node already exists

由于是測試環境,我經常強制關機,導緻codis-dashboard沒有正常關閉.直接造成zookeeper裡面的狀态沒有更新,最終新啟動的codis-dashboard不能注冊進zookeeper,一直提示已存在而被強制關閉.

修複方法也不難,就是删除這個lock的狀态鍵值就可以了

<code>#輸入項目名和zookeeper位址</code>

<code>/usr/local/codis/codis-admin</code> <code>--remove-lock --product=codis-test1 --zookeeper=10.0.2.6:2181</code>

然後,codis-dashboard又可以正常啟動了.

codis-admin是可以全權控制codis叢集的工具,所有添加/删除/修改的工作都可以用他來實作,參數很多,這裡隻是舉例了一個方法,詳細可以參照codis-admin --help

     本文轉自arthur376 51CTO部落格,原文連結:http://blog.51cto.com/arthur376/2051993,如需轉載請自行聯系原作者