天天看點

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

今天分享的這篇文章純屬個人的一些了解和使用的一些心得體會,如果錯誤也請朋友指出。

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

關于Codis的整體架構和功能介紹官方文檔給的在詳細不過了,是以我也不想在畫蛇添足。

由于目前使用的是AWS的ec2主機,是以預設目前使用者是ec2-user,而非root使用者。

1、安裝基礎Go環境,所有節點均安裝.

1

2

3

4

5

<code># sudo yum -y install gcc gcc-c++ make git wget go </code>

<code># sudo vim /etc/profile.d/go.sh</code>

<code>export</code> <code>GOPATH=</code><code>/opt/mygo</code>

<code>export</code> <code>PATH=$GOPATH</code><code>/bin</code><code>:$JAVA_HOME</code><code>/bin</code><code>:$PATH</code>

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

2、安裝Codis,除ZooKeeper節點外其餘節點均正常安裝.

6

<code># sudo mkdir /opt/mygo</code>

<code># sudo chown -R ec2-user.ec2-user /opt/mygo/</code>

<code># go get -u -d github.com/wandoulabs/codis</code>

<code># cd /opt/mygo/src/github.com/wandoulabs/codis/</code>

<code># make</code>

<code># make gotest</code>

3、安裝ZooKeeper,僅需要在此節點安裝.

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

<code># yum -y install java-1.8.0</code>

<code># wget https://www.apache.org/dist/zookeeper/zookeeper-3.4.7/zookeeper-3.4.7.tar.gz</code>

<code># tar -zxf zookeeper-3.4.7.tar.gz -C /opt</code>

<code># cd /opt/zookeeper-3.4.7</code>

<code># cp conf/zoo_sample.cfg conf/zoo.cfg</code>

<code># mkdir /data/{zookeeper,logs} -p</code>

<code># sudo vim conf/zoo.cfg</code>

<code>dataLogDir=</code><code>/data/logs</code>

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

<code>server.1=localhost:2888:3888</code>

<code># vim /data/zookeeper/myid</code>

<code>1</code>

<code># vim /etc/profile.d/zookeeper.sh</code>

<code>PATH=$PATH:</code><code>/opt/zookeeper-3</code><code>.4.7</code><code>/bin</code>

<code># sudo /opt/zookeeper-3.4.7/bin/zkServer.sh start conf/zoo.cfg</code>

<code># netstat -alnut | grep 2181</code>

<code># nc -v localhost 2181</code>

<code># zkServer.sh status  #檢視ZooKeeper的角色(leader|follower|standalone)</code>

<code># zkCli.sh -server 127.0.0.1:2181</code>

<code>    </code><code>ls</code> <code>/</code>

<code>    </code><code>create </code><code>/Test</code> <code>hellozk</code>

<code>    </code><code>get </code><code>/Test</code>

<code>    </code><code>set</code> <code>/Test</code> <code>hellozookeeper</code>

<code>    </code><code>delete </code><code>/Test</code>

<code>    </code><code>quit</code>

4、啟動codis-redis服務.僅需要在redis節點.

<code># sudo mkdir /etc/redis</code>

<code># cd /opt/mygo/src/github.com/wandoulabs/codis</code>

<code># sudo ./bin/codis-server /etc/redis/redis.conf</code>

<code># sudo netstat -tnlp |grep codis-se</code>

5、在dashbaord節點上操作.

<code>1&gt; 配置dashboard服務</code>

<code># mkdir /etc/codis</code>

<code># cp config.ini /etc/codis/codis-config.ini</code>

<code># vim vim /etc/codis/codis-config.ini</code>

<code>zk=172.31.16.33:2181</code>

<code>product=cn_release_codis</code>

<code>dashboard_addr=localhost:18087</code>

<code>proxy_id=proxy_1</code>

<code>proto=tcp4</code>

<code>2&gt; 啟動dashboard服務</code>

<code># ./bin/codis-config -c /etc/codis/codis-config.ini dashboard  </code>

<code>3&gt; 初始化 slots(該指令會在zookeeper上建立slot相關資訊)</code>

<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot init</code>

<code>4&gt; 強制格式化slot</code>

6、添加codis-group-redis

&gt; 添加第一組codis

<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.119:6379 master</code>

<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 1 172.31.51.125:6379 slave</code>

&gt; 添加第二組codis

<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.126:6379 master</code>

<code># ./bin/codis-config -c /etc/codis/codis-config.ini server add 2 172.31.51.124:6379 slave</code>

&gt; 開啟分片

<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 0 511 1 online</code>

<code># ./bin/codis-config -c /etc/codis/codis-config.ini slot range-set 512 1023 2 online</code>

&gt; 擴容,線上添加新分片

<code># ./bin/codis-config -c codis-config.ini server add 3 192.168.10.131:6381 master</code>

<code># ./bin/codis-config -c codis-config.ini server add 3 192.168.10.132:6381 slave</code>

<code># ./bin/codis-config -c codis-config.ini slot migrate 256 511 3</code>

7、啟動codis-proxy服務.

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

<code># cp config.ini /etc/codis/codis-proxy.ini </code>

<code># vim /etc/codis/codis-proxy.ini </code>

<code>zk=172.31.51.123:2181</code>

<code>dashboard_addr=172.31.51.120:18087</code>

<code># ./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</code>

<code>proxy_id=proxy_2</code>

<code># ./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</code>

8、dashboard監控頁面

<a href="http://blog.51cto.com/467754239/1728423">http://&lt;dashboard_ip&gt;:18087/admin/</a>

<a href="http://s5.51cto.com/wyfs02/M00/78/7B/wKiom1Z9WMyCr7pXAABfLaMu-Ec810.png" target="_blank"></a>

9、移除分片流程

<code>---假設将分片3移除---</code>

<code>1. 設定codis-proxy為offline狀态.</code>

<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini proxy offline proxy_1</code>

<code>2. 遷移分片3上的資料到分片1</code>

<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini slot migrate 256 511 1</code>

<code>3. 徹底移除分片3</code>

<code>.</code><code>/bin/codis-config</code> <code>-c codis-config.ini server remove-group 3</code>

10、codis-server的HA

<code># export GOPATH=/opt/mygo</code>

<code># go get github.com/ngaut/codis-ha</code>

<code># cp /opt/mygo/bin/codis-ha /opt/mygo/src/github.com/wandoulabs/codis/bin/</code>

<code># ./bin/codis-ha -codis-config="localhost:18087" -log-level="info" -productName="cn_release_codis"</code>

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

(1)

<code>2015</code><code>/12/11</code> <code>16:49:10 dashboard.go:160: [INFO] dashboard listening on addr: :18087</code>

<code>2015</code><code>/12/11</code> <code>16:49:10 dashboard.go:234: [PANIC] create zk node failed</code>

<code>[error]: dashboard already exists: {</code><code>"addr"</code><code>: </code><code>"172.31.16.30:18087"</code><code>, </code><code>"pid"</code><code>: 7762}</code>

解決辦法:

這種問題是由于使用了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的使用者登入認證,配置如下。

<a href="http://s1.51cto.com/wyfs02/M02/78/7A/wKioL1Z9b_aDHql0AABFfwoiA-g909.png" target="_blank"></a>

<a href="http://s1.51cto.com/wyfs02/M02/78/7A/wKioL1Z9Wt6ibZb6AAAxqvS7_ls831.png" target="_blank"></a>

當時我在做這個登入認證的時候,也花了2~3小時才解決,不是因為多麼複雜,是因為dashboard很多都是基于api來擷取資料的,如果少了配置中rewrite重定向那麼就會隻顯示頁面 而擷取不到資料。切記

下一篇Codis文章補充部分:

Codis叢集中每個角色服務強烈建議成server式的服務啟動腳本,這個我已經完成了,但是還是需要調整。

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

由于dashboard沒有友好的登入認證機制,建議關閉dashboard服務,而另外開發一個可檢視但是沒有權限操作的可視化界面。

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

繼續閱讀