天天看點

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

目前公司的業務是php語言開發,使用的是laravel開源架構。laravel架構使用predis連接配接redis,但是目前predis不支援主從式redis叢集,這點很坑。

看了看目前網上的解決方案,國内豌豆莢開源的codis很不錯。這篇文章,我們主要介紹codis叢集的安裝。

codis是一個分布式redis叢集解決方案,對于上層的應用來說, 連接配接到codis-proxy和連接配接原生的redis-server沒有明顯的差別。

上層應用可以像使用單機的redis一樣使用,codis底層會處理請求的轉發,不停機的資料遷移等工作。所有後邊的一切事情,對于前面的用戶端來說是透明的,可以簡單的認為後邊連接配接的是一個記憶體無限大的redis服務。

codis由四部分組成:

codis proxy(codis-proxy)

codis dashboard(codis-config)

codis redis(codis-server)

zookeeper/etcd

codis-proxy是用戶端連接配接的redis代理服務,codis-proxy本身實作了redis協定,表現得和一個原生的redis沒什麼差別(就像twemproxy),對于一個業務來說,可以部署多個codis-proxy,codis-proxy本身是無狀态的。

codis-config是codis的管理工具,支援包括:添加/删除redis節點,添加/删除proxy節點,發起資料遷移等操作。

codis-config本身還自帶了一個http-server,會啟動一個dashboard,使用者可以直接在浏覽器上觀察codis叢集的運作狀态。

codis-server是codis項目維護的一個redis分支,基于redis2.8.21開發,加入了slot的支援和原子的資料遷移指令。codis上層的codis-proxy和codis-config隻能和這個版本的redis互動才能正常運作。

codis依賴zookeeper來存放資料路由表和codis-proxy節點的元資訊,codis-config發起的指令都會通過zookeeper同步到各個存活的codis-proxy。

codis支援按照namespace區分不同的産品,擁有不同的product name的産品,各項配置都不會沖突。

codis架構圖如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

<b>二、環境準備</b>

除了zookeeper叢集之外,我們還需要安裝go語言環境,因為codis是基于go語言開發的。

安裝基礎依賴,使用如下指令:

yum install -y git gcc make g++ gcc-c++ automake openssl-devel zlib-*

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

基礎依賴安裝往後,我們現在開始配置go語言環境。

codis是基于go語言開發的,是以我們要在所有伺服器上都配置go語言環境。

下載下傳go語言包,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

下載下傳完畢後,解壓到/usr/local,如下:

tar -c /usr/local -xf go1.4.2.linux-amd64.tar.gz

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

把go加入到系統的環境變量,如下:

vim /etc/profile

export path=$path:/usr/local/go/bin

export gopath=/usr/local/

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

讓剛剛加入的環境變量生效,并檢視go是否配置成功,如下:

source /etc/profile

env

go version

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以很明顯的看出go語言環境配置成功。

codis的安裝,我們可以通過三種不同的方式進行:通過go下載下傳安裝、通過git方式和通過源碼方式,下面分别介紹下。

按照官方github介紹,codis首選方式是通過go下載下傳安裝的。指令如下:

go get -u -d github.com/codislabs/codis

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

注意:由于衆所周知的原因,這一步比較慢,需要耐心等待。

上一步執行完畢後,我們切換到/usr/local/src/github.com/codislabs/codis目錄下,進行編譯,如下:

cd /usr/local/src/github.com/codislabs/codis

make

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

注意:這一步也比較慢,需要耐心等待。

make編譯執行完畢後後,會在bin目錄下生成codis-config、codis-proxy、codis-server三個可執行檔案以及assets目錄。

其中assets是codis-config的dashboard http 服務需要的前端資源,需要和codis-config放置在同一目錄下。如下:

ll bin/

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

編譯完畢後,我們現在來測試編譯的結果,使用如下指令:

make gotest

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以看到codis已經安裝成功。

上一章節,我們介紹了codis通過go下載下傳安裝的方法,這一章節,我們通過git方式進行安裝。

首先下載下傳codis最新的git倉庫,使用如下指令:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

git倉庫下載下傳完畢後,我們接下來進行如下的操作。如下:

mkdir -p /usr/local/src/github.com/codislabs/

cp -r codis /usr/local/src/github.com/codislabs/

cd /usr/local/src/github.com/codislabs/codis/

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

以上操作完畢後,就和通過go下載下傳安裝方式一樣了。執行make指令進行編譯,然後執行make gotest指令進行測試。

下面我們來介紹下,通過源碼方式的安裝。下載下傳codis源碼檔案,如下:

wget https://github.com/codislabs/codis/archive/3.0.3.tar.gz

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

解壓源碼包,如下:

tar -xf 3.0.3.tar.gz

cd codis-3.0.3/

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

然後進行編譯,使用make指令,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這一步很慢,需要下載下傳各種依賴,然後是make gotest。

基本和go下載下傳安裝方式一樣,不過需要說明下,我通過源碼方式一直沒有安裝成功。報如下錯誤:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

是以以上三種安裝的方法,建議使用第一、二種,盡管有點慢。

codis安裝完畢後,我們現在來配置codis叢集。在正式配置叢集之前,先建立相關的目錄,然後複制相關檔案到新的目錄下。使用如下指令:

mkdir -p /usr/local/codis/{log,redis_conf}

cp -rf bin/ /usr/local/codis/

cp config.ini /usr/local/codis/

cp extern/redis-test/conf/6379.conf /usr/local/codis/redis_conf/20189.conf

cp extern/redis-test/conf/6380.conf /usr/local/codis/redis_conf/20190.conf

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

上述操作完畢後,我們來修改codis的配置檔案config.ini,在此我們隻需要修改相關的選項即可。如下:

vim /usr/local/codis/config.ini

coordinator=zookeeper

<b>zk=192.168.1.9:2181,192.168.1.124:2181,192.168.1.231:2181</b>

product=test

<b>dashboard_addr=192.168.1.9:18087</b>

password=

backend_ping_period=5

session_max_timeout=1800

session_max_bufsize=131072

session_max_pipeline=1024

zk_session_timeout=30000

<b>proxy_id=proxy_9</b>

該配置檔案中,我們需要注意三個參數:zk、dashboard_addr、proxy_id。

其中zk是表示zookeeper叢集的伺服器ip位址,dashboard_addr表示codis web管理的ip位址及端口,proxy_id表示codis的id,注意每台codis伺服器該值要<b>唯一</b>。

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

另外兩台伺服器的codis配置檔案,内容如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

到此codis配置檔案修改完畢。

codis配置檔案修改完畢後,我們現在來修改redis配置檔案。

每台codis伺服器上,我們要啟動兩個redis執行個體(也可以啟動多個redis執行個體),是以我們要配置兩個redis。如下:

vim /usr/local/codis/redis_conf/20189.conf

daemonize no

pidfile /var/run/redis20189.pid

port 20189

tcp-backlog 511

timeout 0

tcp-keepalive 0

loglevel notice

logfile /var/log/redis/20189.log

databases 16

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename dump20189.rdb

dir /usr/local/codis/

slave-serve-stale-data yes

slave-read-only yes

repl-disable-tcp-nodelay no

slave-priority 100

appendonly no

appendfilename “appendonly.aof”

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

lua-time-limit 5000

slowlog-log-slower-than 10000

slowlog-max-len 128

latency-monitor-threshold 0

notify-keyspace-events “”

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

hll-sparse-max-bytes 3000

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

配置第二個redis執行個體,如下:

yes|cp /usr/local/codis/redis_conf/20189.conf /usr/local/codis/redis_conf/20190.conf

sed -i ‘s/20189/20190/g’ /usr/local/codis/redis_conf/20190.conf

mkdir -p /var/log/redis/

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

每台codis伺服器上redis配置完畢後,我們來啟動redis執行個體,如下:

/usr/local/codis/bin/codis-server /usr/local/codis/redis_conf/20189.conf &amp;

/usr/local/codis/bin/codis-server /usr/local/codis/redis_conf/20190.conf &amp;

ps -ef |grep codis-server

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

注意:我們每台codis伺服器上的redis執行個體都需要啟動。

redis執行個體全部啟動後,我們現在來啟動codis的dashboard。

<b>注意,我們一定要在192.168.1.9這台codis伺服器上啟動該指令,這是因為我們在4.1章節codis配置檔案中配置的dashboard位址就是192.168.1.9。</b>

使用如下指令啟動dashboard:

nohup /usr/local/codis/bin/codis-config -c config.ini dashboard &amp;

netstat -tunlp

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

codis dashboard通路端口是18087,如下:

<a href="http://codis.ilanni.com:18087/admin/">http://codis.ilanni.com:18087/admin/</a>

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以很明顯的看出codis dashboard已經正常啟動。

codis dashboard已經正常啟動後,我們現在來創添加redis server分組。如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這樣我們第一個redis server分組就建立完畢了,可以使用同樣的方法建立第二、三個分組。如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這樣三組redis server分組就建立完畢了。

當然我們也可以通過指令進行建立,如下:

/usr/local/codis/bin/codis-config server add-group 1

/usr/local/codis/bin/codis-config server add-group 2

/usr/local/codis/bin/codis-config server add-group 3

/usr/local/codis/bin/codis-config server list

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

<b>注意:上述指令在三台codis伺服器上任意一台上執行。</b>

到此codis的redis server分組添加完畢。

redis server分組添加完畢後,我們現在來為每一個分組添加redis執行個體。先為group_1添加redis執行個體,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這個裡面可以填寫任何一個codis伺服器上的redis執行個體(哪怕不是codis伺服器的redis執行個體),在此我們填寫的是192.168.1.9這台伺服器上的redis執行個體。

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

可以看到group_1組的第一個redis執行個體,被自動配置為master類型。

現在我們來添加第二個redis執行個體,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以很明顯的看到第二個添加的redis執行個體被預設配置為slave類型。

<b>注意:redis官方的支援的叢集也是master-slave主從式的叢集。</b>

group_2組和group_3組的redis執行個體添加和上面的操作一樣,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這樣三組redis執行個體就全部添加完畢。

當然我們也可以通過指令進行添加,如下:

/usr/local/codis/bin/codis-config server add <b>1</b> 192.168.1.9:20189 <b>master</b>

/usr/local/codis/bin/codis-config server add 1 192.168.1.9:20190 slave

/usr/local/codis/bin/codis-config server add <b>2</b> 192.168.1.124:20189 <b>master</b>

/usr/local/codis/bin/codis-config server add 2 192.168.1.124:20190 slave

/usr/local/codis/bin/codis-config server add <b>3</b> 192.168.1.231:20189 <b>master</b>

/usr/local/codis/bin/codis-config server add 3 192.168.1.231:20190 slave

<b>注意:上述指令中的數字,表示的是哪一個分組,master/slave表示的是所屬類型。</b>

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

我們也可以通過指令檢視,各個redis server組的資訊,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

注意:每組添加的第一個redis執行個體不能被删除,因為codis預設把該redis執行個體設定為master。

到此redis server分組的redis執行個體添加完畢。

codis采用pre-sharding的技術來實作資料的分片,預設分成1024個slot(0-1023)。對于每個key來說,可以通過以下公式确定所屬的slot id:slotid=crc32(key)%1024。

每一個slot都會有一個且必須有一個特定的server group id來表示這個slot的資料由哪個server group來提供。

在配置設定slot之前,我們需要初始化slot。

在codis伺服器<b>任意一台</b>上執行bin/codis-config slot init指令,該指令會在zookeeper上建立slot相關資訊。如下:

cd /usr/local/codis

/usr/local/codis/bin/codis-config -c config.ini slot init

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

slot初始化完畢後,我們現在來配置設定slot範圍。如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

上圖中的new group id是自定義的。

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以看到第一組slot配置設定成功。

現在來檢視slot配置設定資訊,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以很明顯的看出組1配置設定的slot是0-334,335以後還沒有配置設定。現在來配置設定剩下的slot,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這樣slot已經全部配置設定完畢。

當然我們也可以通過指令進行配置設定,如下:

/usr/local/codis/bin/codis-config slot range-set 0 334 1 online

/usr/local/codis/bin/codis-config slot range-set 335 669 2 online

/usr/local/codis/bin/codis-config slot range-set 670 1023 3 online

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

檢視slot資訊,如下:

/usr/local/codis/bin/codis-config slot info 1

/usr/local/codis/bin/codis-config slot info 2

/usr/local/codis/bin/codis-config slot info 3

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

以上全部配置完畢後,我們來啟動codis-proxy,使用如下指令:

nohup /usr/local/codis/bin/codis-proxy -c /usr/local/codis/config.ini –log-level=error -l/usr/local/codis/log/proxy.log –cpu=8 –addr=0.0.0.0:19000 –http-addr=0.0.0.0:11000 &amp;

下面對以上指令中的參數進行解釋:

-c 配置檔案位址。

-l 日志輸出檔案位址。

–log-level=&lt;loglevel&gt; 輸出日志級别(debug&lt;info (default)&lt;warn&lt;error&lt;fatal)。

–cpu=&lt;cpu_num&gt; proxy占用的cpu核數,預設1,最好設定為機器的實體cpu數的一半到2/3左右。

–addr=&lt;proxy_listen_addr&gt; proxy的redis server監聽的位址, 格式&lt;ip or hostname&gt;:&lt;port&gt;, 如: localhost:9000, :9001。

–http-addr=&lt;debug_http_server_addr&gt; proxy的調試資訊啟動的http server,可以通路 http://debug_http_server_addr/debug/vars。

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

codis-proxy啟動後,我們可以在dashboard上進行檢視,如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

到此codis叢集就搭建完畢。

codis叢集搭建完畢後,現在我們來連接配接codis叢集。要連接配接codis叢集,我們隻需要連接配接codis-proxy即可。即連接配接4.7章節中的codis-proxy伺服器位址,然後加19000端口。使用redis-cli指令連接配接,如下:

redis-cli -h 192.168.1.9 -p 19000

info

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,我們可以很明顯的看到連接配接codis叢集是ok的。

我們現在對codis叢集做一些壓力測試,同時在dashboard上觀察鍵值對的情況。如下:

redis-benchmark -h 192.168.1.9 -p 19000 -c 10000 -d 100 -t set -n 100000 -r 100000

上述指令的意思是,使用redis-benchmark壓力測試指令連接配接codis叢集,同時并發10000個(-c),測試set操作(-t),每個測試資料集是100位元組(-d),請求數是100000(-n),使用使用随機數插入數值(-r)。

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

通過上圖,可以很明顯的看到codis叢集的性能還是很不錯的呢。

而我們laravel架構中redis的配置直接填寫codis-proxy的連接配接位址即可。如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

在codis搭建和使用過程中,我們還是會碰到一些其他問題的,下面就稍微提下。

如果要kill的dashboard的話,強烈建議通過kill -15 pid來關閉。

如果是直接使用kill -9進行kill的話,可能會報zk節點不存在錯誤的話。

這樣的話,我們需要通過連接配接zookeeper叢集,删除相關節點,然後再進行操作。删除節點操作,操作如下:

cd /usr/local/zookeeper/

./bin/zkcli.sh -server 127.0.0.1:2181

ls /zk/codis/db_test

rmr /zk/codis/db_test

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

在這裡我們大緻介紹下,codis在與阿裡雲的slb(負載均衡)進行內建的線上生産環境的案例。

目前我們連接配接codis叢集是通過單個codis-proxy來進行的,如果這個節點挂了,就會出現了單點故障的危險。

是以我們這邊在codis叢集每台伺服器上,都啟動一個codis-proxy。然後前端使用slb進行統一接入,slb後端就有三台codis-proxy伺服器。

codis叢集的搭建和前面是一樣的,隻是在此我們的codis所在ecs(伺服器)隻有内網ip(省錢),而且slb我們是要的也是内網(省錢)。如下:

codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他
codis叢集搭建一、codis介紹三、安裝codis四、配置codis叢集五、連接配接codis叢集六、其他

這樣的話,用戶端連接配接slb的位址就是連接配接codis整個叢集了,同時也避免了單點故障的問題。

<b>注意:阿裡雲slb後端的ecs,不能telnet通其前端的slb。</b>

繼續閱讀