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/
九、移除分片流程
---假設將分片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的用戶登陸認證,配置以下。
當時我在作這個登陸認證的時候,也花了2~3小時才解決,不是由於多麼複雜,是由於dashboard不少都是基於api來獲取數據的,若是少了配置中rewrite重定向那麼就會只顯示頁面 而獲取不到數據。切記
下一篇Codis文章補充部分:
Codis集羣中每一個角色服務強烈建議成server式的服務啓動腳本,這個我已經完成了,可是仍是須要調整。
關於Dashboard服務的監控,我認爲更多的是Redis主從,這個我也會在下篇講解遇到Redis的坑。
因爲dashboard沒有友好的登陸認證機制,建議關閉dashboard服務,而另外開發一個可查看可是沒有權限操做的可視化界面。