Codis 是一個分佈式 Redis 解決方案


Codis源碼地址:https://github.com/wandoulabs/codis java

關於Codis組件能夠參考:https://github.com/wandoulabs/codis/blob/master/doc/tutorial_zh.md node


今天分享的這篇文章純屬我的的一些理解和使用的一些心得體會,若是錯誤也請朋友指出。python

更重要的是爲了認識一些正在使用或將要使用Codis的朋友有或多或少的幫助。nginx


關於Codis的總體架構和功能介紹官方文檔給的在詳細不過了,因此我也不想在多此一舉。
c++


因爲當前使用的是AWS的ec2主機,因此默認當前用戶是ec2-user,而非root用戶。git


一、安裝基礎Go環境,全部節點均安裝.
github

# sudo yum -y install gcc gcc-c++ make git wget go 
# sudo vim /etc/profile.d/go.sh
export GOPATH=/opt/mygo
export PATH=$GOPATH/bin:$JAVA_HOME/bin:$PATH
# source /etc/profile


二、安裝Codis,除ZooKeeper節點外其他節點均正常安裝.
redis

# sudo mkdir /opt/mygo
# sudo chown -R ec2-user.ec2-user /opt/mygo/
# go get -u -d github.com/wandoulabs/codis
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# make
# make gotest


三、安裝ZooKeeper,僅須要在此節點安裝.apache

# yum -y install java-1.8.0

# wget https://www.apache.org/dist/zookeeper/zookeeper-3.4.7/zookeeper-3.4.7.tar.gz
# tar -zxf zookeeper-3.4.7.tar.gz -C /opt
# cd /opt/zookeeper-3.4.7
# cp conf/zoo_sample.cfg conf/zoo.cfg
# mkdir /data/{zookeeper,logs} -p

# sudo vim conf/zoo.cfg
dataLogDir=/data/logs
dataDir=/data/zookeeper
server.1=localhost:2888:3888

# vim /data/zookeeper/myid
1

# vim /etc/profile.d/zookeeper.sh
PATH=$PATH:/opt/zookeeper-3.4.7/bin

# source /etc/profile
# sudo /opt/zookeeper-3.4.7/bin/zkServer.sh start conf/zoo.cfg

# netstat -alnut | grep 2181
# nc -v localhost 2181
# zkServer.sh status	#查看ZooKeeper的角色(leader|follower|standalone)

# zkCli.sh -server 127.0.0.1:2181
	ls /
	create /Test hellozk
	get /Test
	set /Test hellozookeeper
	get /Test
	delete /Test
	get /Test
	quit


四、啓動codis-redis服務.僅須要在redis節點.vim

# sudo mkdir /etc/redis
# cd /opt/mygo/src/github.com/wandoulabs/codis
# sudo ./bin/codis-server /etc/redis/redis.conf
# sudo netstat -tnlp |grep codis-se


五、在dashbaord節點上操做.

1> 配置dashboard服務
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-config.ini
# vim vim /etc/codis/codis-config.ini
zk=172.31.16.33:2181
product=cn_release_codis
dashboard_addr=localhost:18087
proxy_id=proxy_1
proto=tcp4

2> 啓動dashboard服務
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-config -c /etc/codis/codis-config.ini dashboard	

3> 初始化 slots(該命令會在zookeeper上建立slot相關信息)
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-config -c /etc/codis/codis-config.ini slot init

4> 強制格式化slot
# ./bin/codis-config -c /etc/codis/codis-config.ini slot init


六、添加codis-group-redis

> 添加第一組codis

# ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.119:6379 master
# ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.125:6379 slave

> 添加第二組codis

# ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.126:6379 master
# ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.124:6379 slave

> 開啓分片

# ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 0 511 1 online
# ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 512 1023 2 online

> 擴容,在線添加新分片

# ./bin/codis-config -c codis-config.ini server add 3 192.168.10.131:6381 master
# ./bin/codis-config -c codis-config.ini server add 3 192.168.10.132:6381 slave
# ./bin/codis-config -c codis-config.ini slot migrate 256 511 3


七、啓動codis-proxy服務.

好比線上有兩個Codis-proxy服務.

# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-proxy.ini 
# vim /etc/codis/codis-proxy.ini 
zk=172.31.51.123:2181
product=cn_release_codis
dashboard_addr=172.31.51.120:18087
proxy_id=proxy_1
proto=tcp4
# ./bin/codis-proxy -c /etc/codis/codis-proxy.ini -L /var/log/codis_proxy.log --cpu=1 --addr=172.31.51.122:19000 --http-addr=172.31.51.122:11000

# cd /opt/mygo/src/github.com/wandoulabs/codis/
# mkdir /etc/codis
# cp config.ini /etc/codis/codis-proxy.ini 
# vim /etc/codis/codis-proxy.ini 
zk=172.31.51.123:2181
product=cn_release_codis
dashboard_addr=172.31.51.120:18087
proxy_id=proxy_2
proto=tcp4
# ./bin/codis-proxy -c /etc/codis/codis-proxy.ini -L /var/log/codis_proxy.log --cpu=1 --addr=172.31.51.121:19000 --http-addr=172.31.51.121:11000


八、dashboard監控頁面

http://<dashboard_ip>:18087/admin/

wKiom1Z9WMyCr7pXAABfLaMu-Ec810.png


九、移除分片流程

---假設將分片3移除---
1. 設置codis-proxy爲offline狀態.
./bin/codis-config -c codis-config.ini proxy offline proxy_1

2. 遷移分片3上的數據到分片1
./bin/codis-config -c codis-config.ini slot migrate 256 511 1

3. 完全移除分片3
./bin/codis-config -c codis-config.ini server remove-group 3


十、codis-server的HA

# export GOPATH=/opt/mygo
# go get github.com/ngaut/codis-ha
# cp /opt/mygo/bin/codis-ha /opt/mygo/src/github.com/wandoulabs/codis/bin/
# cd /opt/mygo/src/github.com/wandoulabs/codis/
# ./bin/codis-ha -codis-config="localhost:18087" -log-level="info" -productName="cn_release_codis"



遇到的問題以及解決辦法,也但願這部分對朋友有用。

(1)

2015/12/11 16:49:10 dashboard.go:160: [INFO] dashboard listening on addr: :18087
2015/12/11 16:49:10 dashboard.go:234: [PANIC] create zk node failed
[error]: dashboard already exists: {"addr": "172.31.16.30:18087", "pid": 7762}

解決辦法:

這種問題是因爲使用了kill -9致使了dashboard服務異常終止,而退出服務的時候沒有在zk上清除自已的信息,因此就出現了這種問題。

因此咱們在中止codis集羣的任何服務的時候都不要輕易使用kill -9,可使用kill.

若是使用kill,那麼服務在終止的時候也會自動的到zk上清除自已的信息,下次再啓動的時候會馬上註冊。


臨時性的解決辦法就是:

# rmr /zk/codis/db_codis_proxy_test/dashboard


(2)

dashboard提供的api接口

http://debugAddr/setloglevel?level=debug

http://debugAddr/debug/vars #主要是獲取ops信息的還能夠設置日誌級別

瀏覽器訪問proxy的debug_addr對應地址/debug/vars路徑,能夠看到每一個proxy的qps信息。


(3)

codis-proxy的服務日誌中產生的信息解釋。

quit : client主動發的quit指令

EOF  : 鏈接直接斷開了,就是proxy從client的tcp讀的時候遇到EOF了


codis每次主動關閉client的鏈接都會打log的,通常來講主要可能有:

非法操做、該請求連的底層redis掛了、這個session好久沒請求觸發了proxy這邊的清理邏輯。

第三個可能更大些,看時間是6點多,是否是大家的訪問量不大?


session_max_timeout=1800

若是30分鐘內沒有任何ops 那麼codis就主動關閉這個鏈接。

嗯,主要是有人反饋說他們的環境下有時候client主動關了鏈接可是proxy這邊沒收到close的消息,致使proxy這邊最後積累了一大堆鏈接把資源吃滿了


(4)

NaN GB

由於redis配置文件中沒有設置內存maxmemory參數



(5)

codis中全部的讀寫操做都是在redis-master上執行的,redis-slave只負責數據的冗餘,當master出現down以後 能夠進行master和slave的切換。


(6)******

在codis集羣中product是用來區分是否爲同一個集羣的。因此若是是同一個集羣,那麼dashboard和codis-proxy中的product要設置的同樣。不然就面臨的下面這個問題

zk: node does not exist

codis-proxy配置文件中的proxy_id 是用來區分同一個集羣下的不一樣成員,因此這個參數要惟一。


(7)

codis-ha只負責在master掛掉的時候自動選擇一個slave提高爲master,但沒有把剩餘的slave從新掛在新的master上,並且也沒有確保選擇的slave是最優的


(8)

Too many open files

在用python多線程對redis進行壓力測試的時候,壓力超過4000的時候就出現這種問題。

2臺codis-proxy支持併發2-3w沒有太大的問題。


(9)

dashboard服務即便中止也不會影響app經過codis-proxy正常的訪問redis服務。

可是會影響codis-ha服務,則主備不會自動切換啦.


意思也就是dashboard服務若是中止,那麼app仍是能夠正常訪問redis的,可是codis-ha會終止運行期。


(10)

同一個group中能夠實現redis數據的主從複製,可是不一樣的group中沒法實現。

若是同一個group中全部的master和slave都掛掉了,那麼數據就丟失了,可是你若是還查詢掛掉的group中的key就會提示錯誤。而且那個key也就會佔用啦。

全部的寫操做codis-proxy就不會發送到掛掉的group上去了。


(11)

同一個Group中的codis-server 實例下,多個slave 是否會分擔master的讀請求?

codis的設計理念是更注重一致性,redis的主從同步不是強一致的,所以codis不支持讀寫分離


(12)

一個集羣中只能有一個dashboard服務出於運行狀態,能夠有多個 可是同時只能有一個服務出於running狀態。




若是正在使用Codis的朋友,那麼確定也會遇到這樣一個問題,就是關於dashboard的登陸認證問題。在這裏我作了一個基於nginx的用戶登陸認證,配置以下。

wKioL1Z9b_aDHql0AABFfwoiA-g909.png

wKioL1Z9Wt6ibZb6AAAxqvS7_ls831.png

當時我在作這個登陸認證的時候,也花了2~3小時才解決,不是由於多麼複雜,是由於dashboard不少都是基於api來獲取數據的,若是少了配置中rewrite重定向那麼就會只顯示頁面 而獲取不到數據。切記


下一篇Codis文章補充部分:

  1. Codis集羣中每一個角色服務強烈建議成server式的服務啓動腳本,這個我已經完成了,可是仍是須要調整。

  2. 關於Dashboard服務的監控,我認爲更多的是Redis主從,這個我也會在下篇講解遇到Redis的坑。

  3. 因爲dashboard沒有友好的登陸認證機制,建議關閉dashboard服務,而另外開發一個可查看可是沒有權限操做的可視化界面。

相關文章
相關標籤/搜索