您好,登錄后才能下訂單哦!
Codis是一套用go語(yǔ)言編寫的,為了應(yīng)對(duì)高并環(huán)境下的redis集群軟件,原理是對(duì)一個(gè)redis key操作前,先把這個(gè)key通過crc32算法,分配到不同redis的某一個(gè)slot上,實(shí)現(xiàn)并發(fā)讀寫功能.而且能通過zookeeper調(diào)用redis-sentinel來(lái)實(shí)現(xiàn)故障切換功能.現(xiàn)在最新版本是3.2.1,依托于redis3.2.9開發(fā)出來(lái).
優(yōu)點(diǎn):實(shí)現(xiàn)高并發(fā)讀寫,數(shù)據(jù)一致性高.
缺點(diǎn):性能有較大損耗,故障切換無(wú)法保證不丟key,無(wú)法進(jìn)行讀寫分離.
架構(gòu)介紹
1.需要用到的軟件有:
codis3.2.1
描述:codis集群套件,里面含有redis相關(guān)程序,和集群專用程序,主要功能程序解析:
codis-server:屬于redis-server優(yōu)化版,基于 redis-3.2.9 分支開發(fā)。增加了額外的數(shù)據(jù)結(jié)構(gòu),以支持 slot 有關(guān)的操作以及數(shù)據(jù)遷移指令。
codis-proxy:客戶端連接的 Redis 代理服務(wù), 實(shí)現(xiàn)了 Redis 協(xié)議。 除部分命令不支持以外(例如:keys *,flush ),表現(xiàn)的和原生的 Redis 沒有區(qū)別(就像 Twemproxy)。
redis-sentinel:可以實(shí)現(xiàn)對(duì)Redis的監(jiān)控、通知、自動(dòng)故障轉(zhuǎn)移。如果Master不能工作,則會(huì)自動(dòng)啟動(dòng)故障轉(zhuǎn)移進(jìn)程,將其中的一個(gè)Slave提升為Master,其他的Slave重新設(shè)置新的Master服務(wù)。Sentinel的配置由 codis-dashboard和zookeeper一起控制,不需要手工填寫.
codis-dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、刪除,以及據(jù)遷移等操作。在集群狀態(tài)發(fā)生改變時(shí),codis-dashboard 維護(hù)集群下所有 codis-proxy 的狀態(tài)的一致性。
codis-fe:集群web管理界面。
go1.9.1
描述:codis依賴語(yǔ)言包
jdk1.8
描述:zookeeper依賴語(yǔ)言包
zookeeper-3.4.11
描述:用于存放數(shù)據(jù)配置路由表。zookeeper簡(jiǎn)稱zk。在生產(chǎn)環(huán)境中,zk部署越多,其可靠性越高。由于zk集群是以宕機(jī)個(gè)數(shù)過半才會(huì)讓整個(gè)集群宕機(jī),因此,奇數(shù)個(gè)zk更佳。
2. 邏輯架構(gòu)如下:
訪問層:訪問方式可以是類似keepalived集群的vip方式,或者是通過java代碼調(diào)用jodis控件再連接上zookeeper集群,然后查找到可用的proxy端,進(jìn)而連接調(diào)用不同的codis-proxy地址來(lái)實(shí)現(xiàn)高可用的LVS和HA功能.
代理層:中間層由codis-proxy和zookeeper處理數(shù)據(jù)走向和分配,通過crc32算法,把key平均分配在不同redis的某一個(gè)slot中.實(shí)現(xiàn)類似raid0的條帶化,在舊版本的codis中,slot需要手工分配,在codis3.2之后,只要點(diǎn)一個(gè)按鈕slot會(huì)自動(dòng)分配,相當(dāng)方便,但是也可以手動(dòng)分配,需要另外調(diào)用codis-admin命令.
數(shù)據(jù)層:最后codis-proxy把數(shù)據(jù)存進(jìn)真實(shí)的redis-server主服務(wù)器上,由于codis的作者黃東旭相當(dāng)注重?cái)?shù)據(jù)一致性,不允許有數(shù)據(jù)延時(shí)造成的數(shù)據(jù)不一致,所以架構(gòu)從一開始就沒考慮主從讀寫分離.從服務(wù)器僅僅是作為故障切換的冗余架構(gòu),由codis-dashboard監(jiān)控各服務(wù)的狀態(tài),然后通過改寫zookeeper數(shù)據(jù)和調(diào)用redis-sentinel實(shí)現(xiàn)故障切換功能.
3.因?yàn)闄C(jī)器有限,部署的架構(gòu)如下:
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語(yǔ)言程序包,
按正常途徑是要×××的,不過國(guó)內(nèi)地址也有人放出來(lái)了,因?yàn)?/span>codis3.2要求至少是1.7或1.8以上版本的,那干脆下最新版吧.
https://studygolang.com/dl/golang/go1.9.1.linux-amd64.tar.gz
2)下載java語(yǔ)言程序包,
Java的下載地址一直在變,所以最好自己上去看著來(lái)下載
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
#解壓程序包 tar xf jdk-8u144-linux-x64.tar.gz #移動(dòng)到指定目錄 mv jdk1.8.0_144/ /usr/local/ #進(jìn)入指定目錄,并創(chuàng)建程序軟連接 cd /usr/local/ ln -sf jdk1.8.0_144/ jdk #創(chuàng)建環(huán)境變量文件 echo "export JAVA_HOME=/usr/local/jdk export JRE_HOME=/usr/local/jdk/jre export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib export PATH=$PATH:$JAVA_HOME/bin"> /etc/profile.d/java.sh #重載環(huán)境變量 source /etc/profile #測(cè)試檢查是否安裝完成 java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
安裝完畢
2) 安裝golang
#解壓程序包 tar xf go1.9.1.linux-amd64.tar.gz #移動(dòng)到指定目錄 mv go /usr/local/ #把程序包里的命令軟連接到系統(tǒng)默認(rèn)命令目錄 ln -sf /usr/local/go/bin/* /usr/bin/ #測(cè)試檢查是否安裝完成 go version go version go1.9.1 linux/amd64
安裝完成
3) 安裝zookeeper
#解壓程序包 tar xf zookeeper-3.4.11.tar.gz #移動(dòng)到指定目錄 mv zookeeper-3.4.11 /usr/local/ #進(jìn)入指定目錄,并創(chuàng)建程序軟連接 cd /usr/local/ ln -sf zookeeper-3.4.11/ zookeeper
安裝完成,等候配置.
4) 安裝codis
#解壓程序包 tar xf codis3.2.1-go1.7.6-linux.tar.gz #移動(dòng)到指定目錄 mv codis3.2.1-go1.7.6-linux /usr/local/ #進(jìn)入指定目錄,并創(chuàng)建程序軟連接 cd /usr/local/ ln -sf codis3.2.1-go1.7.6-linux/ codis
安裝完成,等候配置,因?yàn)槲覀冇玫亩际嵌M(jìn)制程序包,只要依賴包有正常安裝,就不會(huì)報(bào)錯(cuò),直接就能用,所以安裝就很簡(jiǎn)單.
3. 配置程序
1) 配置zookeeper,3臺(tái)一起都是這么配置
#設(shè)置hosts跳轉(zhuǎn)規(guī)則,好像不這么設(shè)置的話,不能順利啟動(dòng) echo “10.0.2.5 zookeeper-node1 10.0.2.6 zookeeper-node2 10.0.2.7 zookeeper-node3” >> /etc/hosts #創(chuàng)建程序目錄 mkdir -p /data/zookeeper #創(chuàng)建配置文件,文件夾里有一個(gè)模板,有興趣可以看看 vim /usr/local/zookeeper/conf/zoo.cfg #最大連接數(shù)設(shè)置(單ip限制). 注:默認(rèn)60,設(shè)成0即無(wú)限制. maxClientCnxns=500 #一個(gè)周期(tick)的時(shí)長(zhǎng)(單位:毫秒). tickTime=28800 #初始化同步階段最多耗費(fèi)tick個(gè)數(shù). 注:可用默認(rèn)值 initLimit=10 #等待應(yīng)答的最大間隔tick個(gè)數(shù). 注:可用默認(rèn)值 syncLimit=5 #數(shù)據(jù)存儲(chǔ)目錄,剛才創(chuàng)建那個(gè). 注:勿放在/tmp目錄 dataDir=/data/zookeeper/ #通信端口. 注:可用默認(rèn)值 clientPort=2181 server.1=zookeeper-node1:2888:3888 server.2=zookeeper-node2:2888:3888 server.3=zookeeper-node3:2888:3888
生成ID,這里需要注意, myid對(duì)應(yīng)的zoo.cfg的server.ID.比如zookeeper-node2對(duì)應(yīng)的myid應(yīng)該是2,不按規(guī)定設(shè)置,zookeeper集群將無(wú)法啟動(dòng).
echo "1"> /data/zookeeper/myid
==============================================
例如:在zookeeper-node3那臺(tái)10.0.2.7的服務(wù)器,就應(yīng)該是
echo "3"> /data/zookeeper/myid
====================================================
#zoo.cfg最后三行特別說明
說明:server.A=B:C:D:其中 A 是一個(gè)數(shù)字,表示這個(gè)是第幾號(hào)服務(wù)器;B 是這個(gè)服務(wù)器的 ip 地址;C 表示的是這個(gè)服務(wù)器與集群中的 Leader 服務(wù)器交換信息的端口;D 表示的是萬(wàn)一集群中的 Leader 服務(wù)器掛了,需要一個(gè)端口來(lái)重新進(jìn)行選舉,選出一個(gè)新的 Leader,而這個(gè)端口就是用來(lái)執(zhí)行選舉時(shí)服務(wù)器相互通信的端口。
#最后啟動(dòng),因?yàn)閦ookeeper的server是有順序的,最好是按順序啟動(dòng),先啟動(dòng)server.1再啟動(dòng)server2,最后啟動(dòng)server.3這樣 /usr/local/zookeeper/bin/zkServer.sh start #查看狀態(tài),會(huì)有follower和leader的區(qū)別,他們自己會(huì)選誰(shuí)是leader /usr/local/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg Mode: follower
配置并啟動(dòng)完畢.
2) 配置codis-server,3臺(tái)一起都是這么配置
注意:codis-server就是redis-server程序,屬于codis優(yōu)化版本,配合codis集群使用.
所以就是配置個(gè)redis的主從結(jié)構(gòu),實(shí)際生產(chǎn)環(huán)境不要搭在一起
#創(chuàng)建redis數(shù)據(jù)目錄,配置文件目錄,日志目錄 mkdir -p /data/redis/data/config/ mkdir -p /data/redis/data/logs/ #創(chuàng)建主庫(kù)的配置文件,暫時(shí)只配置這些,其他先默認(rèn) vim /data/redis/data/config/redis_6379.conf #允許后臺(tái)運(yùn)行 daemonize yes #設(shè)置端口,最好是非默認(rèn)端口 port 6379 #綁定登錄IP,安全考慮,最好是內(nèi)網(wǎng) bind * #命名并指定當(dāng)前redis的PID路徑,用以區(qū)分多個(gè)redis pidfile "/data/redis/data/config/redis_6379.pid" #命名并指定當(dāng)前redis日志文件路徑 logfile "/data/redis/data/logs/redis_6379.log" #指定RDB文件名,用以備份數(shù)據(jù)到硬盤并區(qū)分不同redis,當(dāng)使用內(nèi)存超過可用內(nèi)存的45%時(shí)觸發(fā)快照功能 dbfilename "dump_6379.rdb" #指定當(dāng)前redis的根目錄,用來(lái)存放RDB/AOF文件 dir "/data/redis/data" #當(dāng)前redis的認(rèn)證密鑰,redis運(yùn)行速度非???這個(gè)密碼要足夠強(qiáng)大, #所有codis-proxy集群相關(guān)的redis-server認(rèn)證密碼必須全部一致 requirepass "123" #當(dāng)前redis的最大容量限制,建議設(shè)置為可用內(nèi)存的45%內(nèi),最高能設(shè)置為系統(tǒng)可用內(nèi)存的95%, #可用config set maxmemory 去在線修改,但重啟失效,需要使用config rewrite命令去刷新配置文件 #注意,使用codis集群,必須配置容量大小限制,不然無(wú)法啟動(dòng) maxmemory 100000kb #LRU的策略,有四種,看情況選擇 maxmemory-policy allkeys-lru #如果做故障切換,不論主從節(jié)點(diǎn)都要填寫密碼且要保持一致 masterauth "123" #創(chuàng)建從庫(kù)的配置文件,暫時(shí)只配置這些,其他先默認(rèn) vim /data/redis/data/config/redis_6380.conf #允許后臺(tái)運(yùn)行 daemonize yes #設(shè)置端口,最好是非默認(rèn)端口 port 6380 #綁定登錄IP,安全考慮,最好是內(nèi)網(wǎng) bind * #命名并指定當(dāng)前redis的PID路徑,用以區(qū)分多個(gè)redis pidfile "/data/redis/data/config/redis_6380.pid" #命名并指定當(dāng)前redis日志文件路徑 logfile "/data/redis/data/logs/redis_6380.log" #指定RDB文件名,用以備份數(shù)據(jù)到硬盤并區(qū)分不同redis,當(dāng)使用內(nèi)存超過可用內(nèi)存的45%時(shí)觸發(fā)快照功能 dbfilename "dump_6380.rdb" #指定當(dāng)前redis的根目錄,用來(lái)存放RDB/AOF文件 dir "/data/redis/data" #當(dāng)前redis的認(rèn)證密鑰,redis運(yùn)行速度非???這個(gè)密碼要足夠強(qiáng)大 #所有codis-proxy集群相關(guān)的redis-server認(rèn)證密碼必須全部一致 requirepass "123" #當(dāng)前redis的最大容量限制,建議設(shè)置為可用內(nèi)存的45%內(nèi),最高能設(shè)置為系統(tǒng)可用內(nèi)存的95%, #可用config set maxmemory 去在線修改,但重啟失效,需要使用config rewrite命令去刷新配置文件 #注意,使用codis集群,必須配置容量大小限制,不然無(wú)法啟動(dòng) maxmemory 100000kb #LRU的策略,有四種,看情況選擇 maxmemory-policy allkeys-lru #如果做故障切換,不論主從節(jié)點(diǎn)都要填寫密碼且要保持一致 masterauth "123" #配置主節(jié)點(diǎn)信息 slaveof 10.0.2.5 6379
除了端口號(hào)不同帶來(lái)的文件名不同.實(shí)際上從庫(kù)配置只是多了最后一行,指定了主庫(kù)地址
#然后就可以啟動(dòng)了,我一開始就說過codis-server就是redis-server /usr/local/codis/codis-server /data/redis/data/config/redis_6379.conf /usr/local/codis/codis-server /data/redis/data/config/redis_6380.conf #驗(yàn)證一下 ss -ntplu |grep codis-server tcp LISTEN 0 128 *:6379 *:* users:(("codis-server",pid=2192,fd=4)) tcp LISTEN 0 128 *:6380 *:* users:(("codis-server",pid=2197,fd=4))
啟動(dòng)方式和redis-server一樣,指定配置文件就可以啟動(dòng).這就配置并啟動(dòng)成功了.
3) 配置redis-sentinel,3臺(tái)一起都是這么配置
正確來(lái)說,redis-sentinel是要配置主從架構(gòu)才能生效,但是在codis集群中并不一樣,因?yàn)?/span>他的配置由zookeeper來(lái)維護(hù),所以,這里codis使用的redis-sentinel只需要配置一些基本配置就可以了.
#我們把配置放到redis數(shù)據(jù)目錄的配置文件目錄 vim /data/redis/data/config/sentinel.conf bind 0.0.0.0 protected-mode no port 26379 dir "/data/redis/data" pidfile "/data/redis/data/config/sentinel_26379.pid" logfile "/data/redis/data/logs/sentinel_26379.log" daemonize yes #然后就可以啟動(dòng)了 /usr/local/codis/redis-sentinel /data/redis/data/config/sentinel.conf #驗(yàn)證一下 /usr/local/codis/redis-cli -p 26379 -c info Sentinel # Sentinel sentinel_masters:3 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=codis-test1-3,status=ok,address=10.0.2.7:6380,slaves=1,sentinels=3 master1:name=codis-test1-1,status=ok,address=10.0.2.5:6379,slaves=1,sentinels=3 master2:name=codis-test1-2,status=ok,address=10.0.2.6:6379,slaves=1,sentinels=3
配置并啟動(dòng)成功.
注意:沒有配置好codis-dashboard會(huì)沒最后那幾行,因?yàn)檫€不受zookeeper控制,所以是正常的,配置好之后才會(huì)自動(dòng)加載進(jìn)來(lái).
4) 配置codis-proxy,這次只有兩臺(tái)要配置,當(dāng)然你也可以配三臺(tái)
這個(gè)是codis集群的核心,實(shí)際上他也沒配主從架構(gòu),配置也是從zookeeper拿來(lái)用的,所以,直接來(lái)看配置吧
#配置很多,我們先生成一下默認(rèn)的配置文件 /usr/local/codis/codis-proxy --default-config | tee ./proxy.conf #然后我們把配置放到redis數(shù)據(jù)目錄的配置文件目錄,再更改關(guān)鍵位置,其他默認(rèn)即可 vim /data/redis/data/config/proxy.conf #項(xiàng)目名稱,會(huì)登記在zookeeper里,如果你想一套zookeeper管理多套codis,就必須區(qū)分好 product_name = "codis-test1" # 設(shè)置登錄dashboard的密碼(與真實(shí)redis中requirepass一致) product_auth = "123" #客戶端(redis-cli)的登錄密碼(與真實(shí)redis中requirepass不一致),是登錄codis的密碼 session_auth = "123456" #管理的端口,0.0.0.0即對(duì)所有ip開放,基于安全考慮,可以限制內(nèi)網(wǎng) admin_addr = "0.0.0.0:11080" #用那種方式通信,假如你的網(wǎng)絡(luò)支持tcp6的話就可以設(shè)別的 proto_type = "tcp4" #客戶端(redis-cli)訪問代理的端口,0.0.0.0即對(duì)所有ip開放 proxy_addr = "0.0.0.0:19000" #外部配置存儲(chǔ)類型,我們用的就是zookeeper,當(dāng)然也是還有其他可以支持,這里不展開說 jodis_name = "zookeeper" #配置zookeeper的連接地址,這里是三臺(tái)就填三臺(tái) jodis_addr = "10.0.2.5:2181,10.0.2.6:2181,10.0.2.7:2181" #zookeeper的密碼,假如有的話 jodis_auth = "" #codis代理的最大連接數(shù),默認(rèn)是1000,并發(fā)大要調(diào)大 proxy_max_clients = 100000 #假如并發(fā)太大,你可能需要調(diào)這個(gè)pipeline參數(shù),大多數(shù)情況默認(rèn)10000就夠了 session_max_pipeline = 100000 #并發(fā)大也可以改以下參數(shù) backend_max_pipeline = 204800 session_recv_bufsize = "256kb" session_recv_timeout = "0s" #然后就可以啟動(dòng)了, /usr/local/codis/codis-proxy --ncpu=1 --config=/data/redis/data/config/proxy.conf --log=/data/redis/data/logs/proxy.log & #驗(yàn)證一下 ss -ntplu |grep codis-proxy tcp LISTEN 0 128 *:19000 *:* users:(("codis-proxy",pid=2075,fd=4)) tcp LISTEN 0 128 :::11080 :::* users:(("codis-proxy",pid=2075,fd=6))
--ncpu 指定使用多少個(gè)cpu,我的是虛擬機(jī),所以就1了,如果你是多核,那就填多個(gè)
--config 指定配置文件,就是剛才的配置文件
--log 指定輸出日志文件
配置并啟動(dòng)成功,但是暫時(shí)還用不了,因?yàn)檫€需要配置codis-dashboard才能最終完成.
5) 配置codis-dashboard,只需要配置一臺(tái)機(jī)上
這個(gè)屬于管理配置codis集群信息的工具,配置完之后的配置信息會(huì)自動(dòng)加載到zookeeper集群,即使這個(gè)服務(wù)掛了,配置都還在zookeeper上,所以不用考慮高可用,單點(diǎn)就足夠了,大不了重新啟動(dòng)一下也不是特別麻煩,配置界面由codis-fe來(lái)實(shí)現(xiàn).因?yàn)?/span>限制于zookeeper的命名空間,通常是和proxy一套配置.
#我們也可以用程序來(lái)生成一下默認(rèn)配置文件 /usr/local/codis/codis-dashboard --default-config | tee ./dashboard.conf #然后我們把配置放到redis數(shù)據(jù)目錄的配置文件目錄,再更改關(guān)鍵位置,其他默認(rèn)即可 vim /data/redis/data/config/dashboard.conf #外部配置存儲(chǔ)類型,我們用的就是zookeeper,當(dāng)然也是還有其他可以支持,這里不展開說 coordinator_name = "zookeeper" #配置zookeeper的連接地址,這里是三臺(tái)就填三臺(tái) coordinator_addr = "10.0.2.5:2181,10.0.2.6:2181,10.0.2.7:2181" #項(xiàng)目名稱,會(huì)登記在zookeeper里,如果你想一套zookeeper管理多套codis,就必須區(qū)分好 product_name = "codis-test1" #所有redis的登錄密碼(與真實(shí)redis中requirepass一致),因?yàn)橐卿涍M(jìn)去修改數(shù)據(jù) product_auth = "123" #codis-dashboard的通信端口,0.0.0.0表示對(duì)所有開放,最好使用內(nèi)網(wǎng)地址 admin_addr = "0.0.0.0:18080" #如果想要在codis集群在故障切換功能上執(zhí)行一些腳本,可以配置以下兩個(gè)配置 sentinel_notification_script = "" sentinel_client_reconfig_script = "" #然后就可以啟動(dòng)了, /usr/local/codis/codis-dashboard --ncpu=1 --config=/data/redis/data/config/dashboard.conf --log=/data/redis/data/logs/codis_dashboard.log --log-level=WARN & #驗(yàn)證一下 ss -ntplu |grep codis-dashboard tcp LISTEN 0 128 :::18080 :::* users:(("codis-dashboard",pid=2021,fd=5))
--ncpu 指定使用多少個(gè)cpu
--config 指定配置文件
--log 指定輸出日志文件
--log-level 指定日志等級(jí),有INFO,WARN,DEBUG,ERROR
安裝完成,就差最后一步就可以開始配置.
由于codis-dashboard本身是不需要密碼登錄的,所以這將會(huì)非常危險(xiǎn),強(qiáng)烈建議使用內(nèi)網(wǎng)地址,而作者表示將會(huì)在下個(gè)版本考慮增加codis-dashboard的認(rèn)證密碼.
6) 配置codis-fe,只需要配置一臺(tái)機(jī)上
這個(gè)是屬于web界面操作codis-dashboard配置的工具,web代碼文件在codis安裝文件夾的目錄下,具體是:/usr/local/codis/assets/這個(gè)目錄.可多臺(tái)dashboard共用.
這個(gè)工具本身不需要配置文件就能啟動(dòng),只需要指定codis-dashboard的ip和端口就可以了,但是我為了方便管理,還是生成一個(gè)配置文件的好.
#生成一下配置文件,其實(shí)也就是codis-dashboard的ip和端口 /usr/local/codis/codis-admin --dashboard-list --zookeeper=10.0.2.6:2181 >codis.json #然后我們把配置放到redis數(shù)據(jù)目錄的配置文件目錄,看一下 cat /data/redis/data/config/codis.json [ { "name": "codis-test1", "dashboard": "10.0.2.6:18080" } ] #然后就可以啟動(dòng)了, /usr/local/codis/codis-fe --ncpu=1 --log=/data/redis/data/logs/fe.log --log-level=WARN --dashboard-list=/data/redis/data/config/codis.json --listen=0.0.0.0:8090 &
--ncpu 指定使用多少個(gè)cpu
--log 指定輸出日志文件
--log-level 指定日志等級(jí),有INFO,WARN,DEBUG,ERROR
--dashboard-list 指定dashboard的地址和項(xiàng)目名稱,這里因?yàn)樯闪宋募?所以就指定成文件了
--listen 指定codis-fe的web登錄端口,也就是我們通過8090來(lái)訪問這個(gè)管理端了,0.0.0.0即對(duì)來(lái)訪IP無(wú)限制,其實(shí)最好是限制內(nèi)網(wǎng)
驗(yàn)證一下
全套安裝完成,成功啟動(dòng).開始下一步.
使用舉例
因?yàn)橛辛?/span>web界面,基本上就都是界面操作了,非常方便,配置會(huì)直接加載到zookeeper里面去.
首先,我們先添加codis-proxy地址和端口
按順序:
第一步,先添加codis-proxy的地址和管理端口,上面設(shè)置的是11080.
第二步,點(diǎn)擊左方的橙色按鈕,然后就添加完畢.
第三步,看到下方出現(xiàn)該有的codis-proxy地址就算完成了,然后看到右方的SYNC字樣的顏色是綠色,則代表配置正常.
如果要?jiǎng)h除記錄,點(diǎn)擊最右方的紅色按鈕即可.
然后,我們添加真實(shí)redis-server(也是codis-server)地址和端口
按順序:
第一步,先創(chuàng)建一個(gè)組,準(zhǔn)備把相關(guān)的一組主從放進(jìn)去
第二步,點(diǎn)擊按鈕生成這個(gè)分組
第三步,添加真實(shí)redis-server地址,并選定一個(gè)分組,例如剛才創(chuàng)建的分組1
第四步,點(diǎn)擊按鈕生成配置
第五步,可以看到配置已經(jīng)登記好,注意sync狀態(tài).
第六步,點(diǎn)擊重新平衡所有slots數(shù)據(jù)塊(任何添加和刪除新舊節(jié)點(diǎn)都需要點(diǎn)擊這個(gè))
在舊版本中slots需要手動(dòng)配置,但是3.2版本之后就改成自動(dòng)分配了,所以已經(jīng)不需要配置,點(diǎn)擊一下就可以了.當(dāng)然你也可以手動(dòng)去分配.
最后配置sentinel的地址和端口
按順序:
第一步,添加真實(shí)的sentinel地址和端口
第二步,點(diǎn)擊按鈕添加
第三步,查看狀態(tài),這里有點(diǎn)不一樣,他會(huì)自動(dòng)添加當(dāng)前主從組架構(gòu)由多少臺(tái),控制切換
也正如我之前說的,他們自動(dòng)去改配置文件,可以去看看sentinel的配置文件證實(shí)一下,這里不展開來(lái)說了
都配置好了,就可以使用了,連接其中一個(gè)codis-proxy測(cè)一下,注意區(qū)分好登錄的地址和端口,還有密碼
/usr/local/codis/redis-cli -h 10.0.2.5 -p 19000 -a 123456 10.0.2.5:19000> info # Server redis_version:3.2.9 redis_git_sha1:f8bc4e32 redis_git_dirty:0 redis_build_id:2bdb8aa56be3fbc2 redis_mode:standalone os:Linux 4.10.0-19-generic x86_64 arch_bits:64 multiplexing_api:epoll gcc_version:4.8.4 process_id:2032 run_id:98e2364d837990dfb47be050901ef9e36ea113fa tcp_port:6379 uptime_in_seconds:16312 uptime_in_days:0 hz:10 lru_clock:3634855 executable:/usr/local/codis/codis-server config_file:/data/redis/data/config/redis_6379.conf # Clients connected_clients:71 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:61878808 used_memory_human:59.01M used_memory_rss:76623872 used_memory_rss_human:73.07M used_memory_peak:63148384 used_memory_peak_human:60.22M total_system_memory:1529741312 total_system_memory_human:1.42G used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:102400000 maxmemory_human:97.66M maxmemory_policy:allkeys-lru mem_fragmentation_ratio:1.24 mem_allocator:jemalloc-4.0.3 . . .
可以使用了.
壓力測(cè)試
1.性能測(cè)試
先用自帶的redis-benchmark來(lái)壓測(cè)性能,模擬500個(gè)并發(fā)和100萬(wàn)個(gè)請(qǐng)求.注意區(qū)分好登錄的地址和端口,還有密碼
先壓測(cè)codis-proxy的性能
/usr/local/codis/redis-benchmark -h 10.0.2.5 -p 19000 -a 123456 -c 500 -n 1000000 -q
再壓測(cè)單節(jié)點(diǎn)的性能
/usr/local/codis/redis-benchmark -h 10.0.2.5 -p 6379 -a 123 -c 500 -n 1000000 -q
redis-benchmark參數(shù)解析:
-h ip地址
-p redis端口
-a 認(rèn)證密碼
-c 設(shè)定多少個(gè)并發(fā)連接
-n 總共多少個(gè)請(qǐng)求
-q 顯示模式:簡(jiǎn)要模式
然后看圖
可以看到,有些操作相差不大,有些相差甚遠(yuǎn),性能損耗明顯,不過作為集群應(yīng)用,主要應(yīng)對(duì)的是高并發(fā)環(huán)境,性能損耗是可以接受的,何況對(duì)于redis這種內(nèi)存型高速應(yīng)用來(lái)說,性能損耗基本沒什么太大感知.
2.數(shù)據(jù)分布測(cè)試
然后是讀寫分布測(cè)試:
我寫了個(gè)腳本來(lái)測(cè)試:
cat t-redis.sh #!/bin/bash hos="10.0.2.7" pot="19000" pawd="123456" cli="/usr/local/codis/redis-cli" keyset="keytest2" valueset="jlasdnfnsdfsdf;sdfhlkjahsdjlkfadfjkasdbbcjhdgasfyuefkbadjkhflk" dbname=2 a=0 for i in `seq 1 300000` do $cli -h $hos -p $pot -a $pawd -n $dbname 'set' ${keyset}${a} "${valueset}${a}" >/dev/null #echo $a let a++ done
腳本很簡(jiǎn)單,就是不斷向codis集群寫垃圾數(shù)據(jù)而已,執(zhí)行腳本.
bash t-redis.sh
然后結(jié)果可以看web界面,因?yàn)槟氵B接codis-proxy用info來(lái)看,其實(shí)是不準(zhǔn)確的,那個(gè)顯示的只是單臺(tái)的數(shù)據(jù).
可以看到,每一個(gè)組都分布得比較均勻,把壓力都分到三臺(tái)redis-server主服務(wù)器去了.
3.故障切換測(cè)試
然后來(lái)看故障切換,繼續(xù)執(zhí)行那個(gè)腳本
bash t-redis.sh
進(jìn)入其中一臺(tái)codis-server,例如10.0.2.5,此時(shí)狀態(tài)是正常的.
開始模擬操作
#查找主庫(kù)進(jìn)程 ss -ntplu |grep codis-server tcp LISTEN 0 128 *:6379 *:* users:(("codis-server",pid=2032,fd=4)) tcp LISTEN 0 128 *:6380 *:* users:(("codis-server",pid=2037,fd=4)) #殺掉主庫(kù)進(jìn)程 kill 2032
此時(shí)從庫(kù)接管了主庫(kù)的進(jìn)程,sentinels有提示信息.
可能有人發(fā)現(xiàn)組1的sync按鈕變成了紅色,也就是說主從失效,點(diǎn)一下就變回正常.
現(xiàn)在等待數(shù)據(jù)寫完,我先把舊的主進(jìn)程6379端口從新起來(lái)
/usr/local/codis/codis-server /data/redis/data/config/redis_6379.conf
然后看看:
看狀態(tài)是恢復(fù)正常了,但是有計(jì)算機(jī)的同學(xué)可以算一下,我的腳本執(zhí)行的總共是30萬(wàn)個(gè)key,但是現(xiàn)在少了幾千個(gè).
坑---1:
上面丟key的問題是由于redis-sentinel故障切換期間,整個(gè)codis集群并不會(huì)關(guān)閉對(duì)此故障redis-server的連接,所以codis-proxy依然會(huì)發(fā)送數(shù)據(jù)給當(dāng)前故障的redis-server,而顯然此時(shí)的redis-server是無(wú)法存儲(chǔ)數(shù)據(jù)的,這就造成了丟key現(xiàn)象了.如果整個(gè)主從掛了,就會(huì)丟掉所有發(fā)送到此redis-server的key了,除非手工剔除故障節(jié)點(diǎn).
雖然codis還自帶有一種故障切換程序codis-ha,他屬于一個(gè)守護(hù)進(jìn)程,會(huì)連接codis-dashboard查看各節(jié)點(diǎn)狀態(tài),
#執(zhí)行一下命令啟動(dòng)codis-ha,端口是codis-dashboard的端口 /usr/local/codis/codis-ha --dashboard=10.0.2.6:18080 --log=/data/redis/data/logs/ha.log --log-level=WARN &
--dashboard 指定dashboard的地址和端口
--log 指定日志文件
--log-level 指定日志等級(jí),有INFO,WARN,DEBUG,ERROR
但是這個(gè)軟件也是有缺陷,他會(huì)自動(dòng)連接上dashboard檢測(cè)各主從結(jié)構(gòu)的健康信息,檢測(cè)間隔很快(默認(rèn)3秒,可修改參數(shù)--interval),檢測(cè)到故障后,會(huì)將故障主庫(kù)或者從庫(kù)強(qiáng)制下線并刪除在dashboard登記的信息.
雖然切換速度非???/span>,只會(huì)有很少的丟key現(xiàn)象(3秒還是會(huì)丟一些),但是后面會(huì)把故障舊主庫(kù)強(qiáng)制下線,需要手動(dòng)修改配置并重新啟動(dòng)redis-server(codis-server),還要再在codis-fe界面添加配置才行.
顯然這是做不到全自動(dòng)管理,有點(diǎn)麻煩了,而且也會(huì)讓redis-sentinel變得沒有意義了,所以只能兩個(gè)方式選其一.
雖然看上去丟key現(xiàn)象是少了,但是依然還是有丟key的情況,只能說是50步笑100步,而且該組內(nèi)其他 slave 實(shí)例是不會(huì)自動(dòng)改變狀態(tài)的,這些 slave 仍將試圖從舊的 master 上同步數(shù)據(jù),因而會(huì)導(dǎo)致組內(nèi)新的 master 和其他 slave 之間的數(shù)據(jù)不一致。因此當(dāng)出現(xiàn)主從切換時(shí),需要管理員手動(dòng)創(chuàng)建新的 sync action 來(lái)完成新 master 與 slave 之間的數(shù)據(jù)同步,這樣反而增加了手動(dòng)操作的工作量,各位對(duì)于codis-ha和redis-sentinel的集群的選擇還是需要多考慮一些實(shí)際情況.
所以,說到底就是codis的故障切換沒有做好,如果對(duì)丟key可以容忍的,就開redis-sentinel就足夠了,對(duì)于數(shù)據(jù)一致性要求高的,就開codis-ha加腳本來(lái)實(shí)現(xiàn)比較好,各取所需.
實(shí)時(shí)添加刪除節(jié)點(diǎn)
codis的另一個(gè)賣點(diǎn)就是可以在線添加/刪除redis-server(codis-server)節(jié)點(diǎn),做到實(shí)時(shí)擴(kuò)容和更換問題節(jié)點(diǎn),對(duì)于單點(diǎn)redis而言優(yōu)勢(shì)明顯,不用重啟服務(wù)就能有更大的空間,也可以在線切換掉有問題的節(jié)點(diǎn).不過要注意,可以實(shí)時(shí)擴(kuò)容和故障切換,并不代表沒有性能損耗,真的要做也是要注意線上壓力,避免性能壓力導(dǎo)致的服務(wù)不可用.
實(shí)現(xiàn)的原理是因?yàn)閏odis集群把各個(gè)redis-server節(jié)點(diǎn)都用規(guī)則分成了多個(gè)slots數(shù)據(jù)塊(總共1024個(gè)).需要擴(kuò)容只要把新的節(jié)點(diǎn)添加完成后,在把這些slots信息從新分配就可以達(dá)到擴(kuò)容效果,需要故障切換則把問題redis-server節(jié)點(diǎn)的slots遷移走,然后就可以把這個(gè)節(jié)點(diǎn)下架了,對(duì)于線上環(huán)境可以說是幾乎沒感知,試驗(yàn)過程中也沒發(fā)現(xiàn)有丟key現(xiàn)象,就是性能有所下降,但是我測(cè)試的環(huán)境下性能下降還能接受,大概只有10%-30%的性能損耗.
開始試驗(yàn),首先我們假設(shè)添加兩個(gè)新的redis-server節(jié)點(diǎn),都直接是主庫(kù),沒有從庫(kù)環(huán)境(因?yàn)檫@次不需要測(cè)故障切換):
10.0.2.5:16379
10.0.2.6:16379
1.添加一個(gè)節(jié)點(diǎn),等于是擴(kuò)容,這還是比較簡(jiǎn)單
第一步,和之前差不多,先創(chuàng)建一個(gè)新組,點(diǎn)擊按鈕確認(rèn)添加
第二步,把新地址添加到新的組,點(diǎn)擊按鈕確認(rèn)添加
第三步,確認(rèn)新的地址已成功添加進(jìn)去
第四步,點(diǎn)擊按鈕,從新分配所有slots數(shù)據(jù)塊
這里唯一問題就是最后一步,重新分配會(huì)耗費(fèi)一定資源,codis會(huì)自動(dòng)平衡數(shù)據(jù)塊的分布,所以會(huì)有數(shù)據(jù)遷移過程,但是據(jù)我測(cè)試的結(jié)果來(lái)看,并不很嚴(yán)重,大概在20%左右.
根據(jù)它自帶的監(jiān)控來(lái)看的話,
可以看到之前正常情況的qps接近1500,剛點(diǎn)重新平衡下降比較嚴(yán)重一些,后面就大概有20%的性能損耗那樣子,最后遷移完畢就恢復(fù)正常了.當(dāng)然這是數(shù)據(jù)量少的情況,如果數(shù)據(jù)量多,這個(gè)遷移時(shí)間就恐怕不是那么簡(jiǎn)單了.
2.切換一個(gè)節(jié)點(diǎn),并下架
正常下架只需要點(diǎn)擊這個(gè)按鈕
但是因?yàn)槔锩孢€有數(shù)據(jù),是不允許直接下架的
所以我們要先遷移數(shù)據(jù),如下所示:
第一步,確認(rèn)一個(gè)需要遷移的組的數(shù)據(jù)塊的編號(hào),例如這里499-512的塊是數(shù)據(jù)組4的,我現(xiàn)在要遷移組4,就選定這個(gè)
第二步,把剛才獲取到的信息填進(jìn)去,就是把500這個(gè)編號(hào)的數(shù)據(jù)塊從組4遷移到組5,點(diǎn)擊按鈕執(zhí)行
然后你就會(huì)看到,
顯然組4的信息消失了,codis把組4的數(shù)據(jù)塊都遷移到了組5去了,
這個(gè)時(shí)候,這個(gè)redis-server節(jié)點(diǎn)就可以刪除了
至于還需不需要重新填補(bǔ),這個(gè)問題則需要自身考慮.如果不需要填補(bǔ),最好再點(diǎn)一下重新平衡slots比較好.
可以看到,又重新平衡了.
故障處理
1.codis-dashboard無(wú)法啟動(dòng),并提示:
[ERROR] store: acquire lock of codis-test1 failed
[error]: zk: node already exists
由于是測(cè)試環(huán)境,我經(jīng)常強(qiáng)制關(guān)機(jī),導(dǎo)致codis-dashboard沒有正常關(guān)閉.直接造成zookeeper里面的狀態(tài)沒有更新,最終新啟動(dòng)的codis-dashboard不能注冊(cè)進(jìn)zookeeper,一直提示已存在而被強(qiáng)制關(guān)閉.
修復(fù)方法也不難,就是刪除這個(gè)lock的狀態(tài)鍵值就可以了
#輸入項(xiàng)目名和zookeeper地址 /usr/local/codis/codis-admin --remove-lock --product=codis-test1 --zookeeper=10.0.2.6:2181
然后,codis-dashboard又可以正常啟動(dòng)了.
codis-admin是可以全權(quán)控制codis集群的工具,所有添加/刪除/修改的工作都可以用他來(lái)實(shí)現(xiàn),參數(shù)很多,這里只是舉例了一個(gè)方法,詳細(xì)可以參照codis-admin --help
2.codis-proxy異常退出導(dǎo)致無(wú)法刪除
通常codis-proxy都是通過codis-dashboard進(jìn)行移除,移除過程中codis-dashboard為了安全會(huì)向codis-proxy發(fā)送offline指令,成功后才會(huì)將proxy信息從外部存儲(chǔ)(zookeeper)中移除。如果codis-proxy異常退出,該操作會(huì)失敗。此時(shí)需要手動(dòng)刪除zookeeper信息。
#先登入zookeeper進(jìn)行操作 /usr/local/zookeeper/bin/zkCli.sh -server #確認(rèn)有問題的codis-proxy地址對(duì)應(yīng)在zookeeper上的信息 [zk: localhost:2181(CONNECTED) 6] get /codis3/codis-zyyhj1/proxy/proxy-80722e128c6e8fc3d0da44983343a843 { "id": 1, "token": "80722e128c6e8fc3d0da44983343a843", "start_time": "2018-06-16 23:30:57.44436209 +0800 CST", "admin_addr": "10.21.1.140:11080", "proto_type": "tcp4", "proxy_addr": "10.21.1.140:19000", "jodis_path": "/jodis/codis-zyyhj1/proxy-80722e128c6e8fc3d0da44983343a843", "product_name": "codis-zyyhj1", "pid": 26493, "pwd": "/root", "sys": "Linux localhost.localdomain 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux", "hostname": "localhost.localdomain", "datacenter": "" } cZxid = 0x100001c7b ctime = Fri Jun 15 21:02:22 CST 2018 mZxid = 0x1000038ae mtime = Sat Jun 16 23:30:57 CST 2018 pZxid = 0x100001c7b cversion = 0 dataVersion = 2 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 576 numChildren = 0 #確認(rèn)完畢,刪除 [zk: localhost:2181(CONNECTED) 7] rmr /codis3/codis-zyyhj1/proxy/proxy-80722e128c6e8fc3d0da44983343a843 #刪除完畢,還需要重載一下dashboard,不然信息也是不會(huì)更新的 /usr/local/codis/codis-admin --dashboard=10.21.1.124:18081 --reload
然后,刪不掉的proxy端就不見了,完成.
備注:
codis不支持命令列表:
Command Type | Command Name |
---|---|
Keys | KEYS |
MIGRATE | |
MOVE | |
OBJECT | |
RANDOMKEY | |
RENAME | |
RENAMENX | |
SCAN | |
Strings | BITOP |
MSETNX | |
Lists | BLPOP |
BRPOP | |
BRPOPLPUSH | |
Pub/Sub | PSUBSCRIBE |
PUBLISH | |
PUNSUBSCRIBE | |
SUBSCRIBE | |
UNSUBSCRIBE | |
Transactions | DISCARD |
EXEC | |
MULTI | |
UNWATCH | |
WATCH | |
Scripting | SCRIPT |
Server | BGREWRITEAOF |
BGSAVE | |
CLIENT | |
CONFIG | |
DBSIZE | |
DEBUG | |
FLUSHALL | |
FLUSHDB | |
LASTSAVE | |
MONITOR | |
RESTORE | |
SAVE | |
SHUTDOWN | |
SLAVEOF | |
SLOWLOG | |
SYNC | |
TIME | |
Codis Slot | SLOTSCHECK |
SLOTSDEL | |
SLOTSINFO | |
SLOTSMGRTONE | |
SLOTSMGRTSLOT | |
SLOTSMGRTTAGONE | |
SLOTSMGRTTAGSLOT |
以下屬于半支持命令, Codis不支持跨節(jié)點(diǎn)操作,因此您必須使用散列標(biāo)簽將可能顯示在一個(gè)請(qǐng)求中的所有密鑰放入同一個(gè)插槽中,然后您可以使用這些命令。 Codis不檢查密鑰是否有相同的標(biāo)簽,所以如果你不使用標(biāo)簽,你的程序會(huì)得到錯(cuò)誤的回應(yīng)。
Command Type | Command Name |
---|---|
Lists | RPOPLPUSH |
Sets | SDIFF |
SINTER | |
SINTERSTORE | |
SMOVE | |
SUNION | |
SUNIONSTORE | |
Sorted Sets | ZINTERSTORE |
ZUNIONSTORE | |
HyperLogLog | PFMERGE |
Scripting | EVAL |
EVALSHA |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。