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>”> </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” >> </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>> </code><code>/data/zookeeper/myid</code>
==============================================
例如:在zookeeper-node3那台10.0.2.7的伺服器,就應該是
<code>echo</code> <code>"3"</code><code>> </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 &</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 &</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 >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 &</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> 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>></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 &</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,如需轉載請自行聯系原作者