用Codis實(shí)現(xiàn)Redis分布式集群

一、Redis集群概述

Redis官方近期推出的Redis Cluster,Redis集群有三種實(shí)現(xiàn)機(jī)制,分別介紹如下,(1)客戶端分片,(2)代理分片,(3)Redis Cluster

1.1 客戶端分片

這種方案將分片工作放在業(yè)務(wù)程序端,程序代碼根據(jù)預(yù)先設(shè)置的路由規(guī)則,直接對(duì)多個(gè)Redis實(shí)例進(jìn)行分布式訪問(wèn)。這樣的好處是,不依賴于第三方分布式中間件,實(shí)現(xiàn)方法和代碼都自己掌控,可隨時(shí)調(diào)整,不用擔(dān)心踩到坑。

這實(shí)際上是一種靜態(tài)分片技術(shù)。Redis實(shí)例的增減,都得手工調(diào)整分片程序。基于此分片機(jī)制的開(kāi)源產(chǎn)品,現(xiàn)在仍不多見(jiàn)。

這種分片機(jī)制的性能比代理式更好(少了一個(gè)中間分發(fā)環(huán)節(jié))。但缺點(diǎn)是升級(jí)麻煩,對(duì)研發(fā)人員的個(gè)人依賴性強(qiáng)——需要有較強(qiáng)的程序開(kāi)發(fā)能力做后盾。如果主力程序員離職,可能新的負(fù)責(zé)人,會(huì)選擇重寫一遍。

所以,這種方式下,可運(yùn)維性較差。出現(xiàn)故障,定位和解決都得研發(fā)和運(yùn)維配合著解決,故障時(shí)間變長(zhǎng)。

1.2 代理分片

這種方案,將分片工作交給專門的代理程序來(lái)做。代理程序接收到來(lái)自業(yè)務(wù)程序的數(shù)據(jù)請(qǐng)求,根據(jù)路由規(guī)則,將這些請(qǐng)求分發(fā)給正確的Redis實(shí)例并返回給業(yè)務(wù)程序。

這種機(jī)制下,一般會(huì)選用第三方代理程序(而不是自己研發(fā)),因?yàn)楹蠖擞卸鄠€(gè)Redis實(shí)例,所以這類程序又稱為分布式中間件。

這樣的好處是,業(yè)務(wù)程序不用關(guān)心后端Redis實(shí)例,運(yùn)維起來(lái)也方便。雖然會(huì)因此帶來(lái)些性能損耗,但對(duì)于Redis這種內(nèi)存讀寫型應(yīng)用,相對(duì)而言是能容忍的。

這是我們推薦的集群實(shí)現(xiàn)方案。像基于該機(jī)制的開(kāi)源產(chǎn)品Twemproxy,便是其中代表之一,應(yīng)用非常廣泛。

1.3 Redis Cluster

在這種機(jī)制下,沒(méi)有中心節(jié)點(diǎn)(和代理模式的重要不同之處)。所以,一切開(kāi)心和不開(kāi)心的事情,都將基于此而展開(kāi)。

Redis

Cluster將所有Key映射到16384個(gè)Slot中,集群中每個(gè)Redis實(shí)例負(fù)責(zé)一部分,業(yè)務(wù)程序通過(guò)集成的Redis

Cluster客戶端進(jìn)行操作??蛻舳丝梢韵蛉我粚?shí)例發(fā)出請(qǐng)求,如果所需數(shù)據(jù)不在該實(shí)例中,則該實(shí)例引導(dǎo)客戶端自動(dòng)去對(duì)應(yīng)實(shí)例讀寫數(shù)據(jù)。

Redis Cluster的成員管理(節(jié)點(diǎn)名稱、IP、端口、狀態(tài)、角色)等,都通過(guò)節(jié)點(diǎn)之間兩兩通訊,定期交換并更新。

由此可見(jiàn),這是一種非?!爸亍钡姆桨浮R呀?jīng)不是Redis單實(shí)例的“簡(jiǎn)單、可依賴”了??赡苓@也是延期多年之后,才近期發(fā)布的原因之一。

這令人想起一段歷史。因?yàn)镸emcache不支持持久化,所以有人寫了一個(gè)Membase,后來(lái)改名叫Couchbase,說(shuō)是支持Auto Rebalance,好幾年了,至今都沒(méi)多少家公司在使用。

這是個(gè)令人憂心忡忡的方案。為解決仲裁等集群管理的問(wèn)題,Oracle RAC還會(huì)使用存儲(chǔ)設(shè)備的一塊空間。而Redis Cluster,是一種完全的去中心化……

二、?Twemproxy代理

Twemproxy是一種代理分片機(jī)制,由Twitter開(kāi)源。Twemproxy作為代理,可接受來(lái)自多個(gè)程序的訪問(wèn),按照路由規(guī)則,轉(zhuǎn)發(fā)給后臺(tái)的各個(gè)Redis服務(wù)器,再原路返回。

這個(gè)方案順理成章地解決了單個(gè)Redis實(shí)例承載能力的問(wèn)題。當(dāng)然,Twemproxy本身也是單點(diǎn),需要用Keepalived做高可用方案。

我想很多人都應(yīng)該感謝Twemproxy,這么些年來(lái),應(yīng)用范圍最廣、穩(wěn)定性最高、最久經(jīng)考驗(yàn)的分布式中間件,應(yīng)該就是它了。只是,他還有諸多不方便之處。

Twemproxy最大的痛點(diǎn)在于,無(wú)法平滑地?cái)U(kuò)容/縮容。

這樣導(dǎo)致運(yùn)維同學(xué)非常痛苦:業(yè)務(wù)量突增,需增加Redis服務(wù)器;業(yè)務(wù)量萎縮,需要減少Redis服務(wù)器。但對(duì)Twemproxy而言,基本上都很難操作(那是一種錐心的、糾結(jié)的痛……)。

或者說(shuō),Twemproxy更加像服務(wù)器端靜態(tài)sharding。有時(shí)為了規(guī)避業(yè)務(wù)量突增導(dǎo)致的擴(kuò)容需求,甚至被迫新開(kāi)一個(gè)基于Twemproxy的Redis集群。

Twemproxy另一個(gè)痛點(diǎn)是,運(yùn)維不友好,甚至沒(méi)有控制面板。

三、Codis

Codis由豌豆莢于2014年11月開(kāi)源,基于Go和C開(kāi)發(fā),是近期涌現(xiàn)的、國(guó)人開(kāi)發(fā)的優(yōu)秀開(kāi)源軟件之一。

https://github.com/CodisLabs/codis

一、概要

Codis 是一個(gè)分布式Redis解決方案, 對(duì)于上層的應(yīng)用來(lái)說(shuō), 連接到 Codis Proxy 和連接原生的 Redis Server 沒(méi)有明顯的區(qū)別 (有一些命令不支持), 上層應(yīng)用可以像使用單機(jī)的 Redis 一樣使用, Codis 底層會(huì)處理請(qǐng)求的轉(zhuǎn)發(fā), 不停機(jī)的數(shù)據(jù)遷移等工作, 所有后邊的一切事情, 對(duì)于前面的客戶端來(lái)說(shuō)是透明的, 可以簡(jiǎn)單的認(rèn)為后邊連接的是一個(gè)內(nèi)存無(wú)限大的 Redis?服務(wù),當(dāng)然,前段時(shí)間redis官方的3.0出了穩(wěn)定版,3.0支持集群功能,codis的實(shí)現(xiàn)原理和3.0的集群功能差不多。

二、架構(gòu)

三、角色分批

zookeeper集群:

10.10.0.47

10.10.0.48

10.10.1.76

codis-config、codis-ha:

10.10.32.10:18087

codis-proxy:

10.10.32.10:19000

10.10.32.49:19000

codis-server:

10.10.32.42:6379、10.10.32.43:6380(主、從)

10.10.32.43:6379、10.10.32.44:6380(主、從)

10.10.32.44:6379、10.10.32.42:6380(主、從)

四、部署

1、安裝zookeeper

1yum?-y?installzookeeper?jdk??##安裝服務(wù)

vim?/etc/hosts##添加host

10.10.0.47?ZooKeeper-node1

10.10.0.48?ZooKeeper-node2

10.10.1.76?ZooKeeper-node3

vim?/etc/zookeeper/conf/zoo.cfg?##撰寫zk的配置文件

maxClientCnxns=50

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/

clientPort=2181

server.1=ZooKeeper-node1:2888:3888

server.2=ZooKeeper-node2:2888:3888

server.3=ZooKeeper-node3:2888:3888

mkdir/data/zookeeper/##創(chuàng)建zk的datadir目錄

echo"2">/data/zookeeper/myid##生成ID,這里需要注意,?myid對(duì)應(yīng)的zoo.cfg的server.ID,比如ZooKeeper-node2對(duì)應(yīng)的myid應(yīng)該是2

/usr/lib/zookeeper/bin/zkServer.sh?start??##?服務(wù)啟動(dòng)

2、go安裝(codis是go語(yǔ)言寫的,所以那些機(jī)器需要安裝你懂得)

wget?https://storage.googleapis.com/golang/go1.4.1.linux-amd64.tar.gz

tar-zxvf?go1.4.1.linux-amd64.tar.gz

mvgo?/usr/local/

cd/usr/local/go/src/

bashall.bash

cat>>?~/.bashrc?<<?_bashrc_export

exportGOROOT=/usr/local/go

exportPATH=\$PATH:\$GOROOT/bin

exportGOARCH=amd64

exportGOOS=linux

_bashrc_export

source~/.bashrc

3、下載并編譯codis(codis-config、codis-proxy、codis-server所在的機(jī)器)

mkdir/data/go

exportGOPATH=/data/go

/usr/local/go/bin/goget?github.com/wandoulabs/codis

cd/data/go/src/github.com/wandoulabs/codis/

./bootstrap.sh

makegotest

五、服務(wù)啟動(dòng)及初始化集群

1、啟動(dòng) dashboard(codis-config上操作)

cat/etc/codis/config_10.ini?##撰寫配置文件

zk=10.10.0.47:2181,10.10.0.48:2181,10.10.1.76:2181

product=zh_news

proxy_id=codis-proxy_10

net_timeout=5000

proto=tcp4

dashboard_addr=10.10.32.10:18087

1cd/data/go/src/github.com/wandoulabs/codis/&&??./bin/codis-config-c?/etc/codis/config_10.ini??dashboard?&

2、初始化 slots?(codis-config上操作)

1cd/data/go/src/github.com/wandoulabs/codis/&&??./bin/codis-config-c?/etc/codis/config_10.ini?slot?init

3、啟動(dòng) Codis Redis , 和官方的Redis Server參數(shù)一樣(codis-server上操作)

1cd/data/go/src/github.com/wandoulabs/codis/&&?./bin/codis-server/etc/redis_6379.conf?&

4、添加 Redis Server Group , 每一個(gè) Server Group 作為一個(gè) Redis 服務(wù)器組存在, 只允許有一個(gè) master, 可以有多個(gè) slave, group id 僅支持大于等于1的整數(shù)(codis-config上操作)

cd/data/go/src/github.com/wandoulabs/codis/

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?1?10.10.32.42:6379?master

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?1?10.10.32.43:6380?slave

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?2?10.10.32.43:6379?master

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?2?10.10.32.44:6380?slave

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?3?10.10.32.44:6379?master

./bin/codis-config-c?/etc/codis/config_10.ini?server?add?3?10.10.32.42:6380?slave

5、設(shè)置

server group 服務(wù)的 slot 范圍 Codis 采用 Pre-sharding 的技術(shù)來(lái)實(shí)現(xiàn)數(shù)據(jù)的分片, 默認(rèn)分成 1024 個(gè)

slots (0-1023), 對(duì)于每個(gè)key來(lái)說(shuō), 通過(guò)以下公式確定所屬的 Slot Id : SlotId = crc32(key) %

1024 每一個(gè) slot 都會(huì)有一個(gè)特定的 server group id 來(lái)表示這個(gè) slot 的數(shù)據(jù)由哪個(gè) server group

來(lái)提供.(codis-config上操作)

cd/data/go/src/github.com/wandoulabs/codis/

./bin/codis-config-c?/etc/codis/config_10.ini?slot?range-set0?300?1?online

./bin/codis-config-c?/etc/codis/config_10.ini?slot?range-set301?700?2?online

./bin/codis-config-c?/etc/codis/config_10.ini?slot?range-set701?1023?3?online

6、啟動(dòng) codis-proxy ?(codis-proxy上操作

cat/etc/codis/config_10.ini?##撰寫配置文件

zk=10.10.0.47:2181,10.10.0.48:2181,10.10.1.76:2181

product=zh_news

proxy_id=codis-proxy_10??##10.10.32.49上改成codis-proxy_49,多個(gè)proxy,proxy_id?需要唯一

net_timeout=5000

proto=tcp4

dashboard_addr=10.10.32.10:18087

cd/data/go/src/github.com/wandoulabs/codis/&&??./bin/codis-proxy-c?/etc/codis/config_10.ini?-L?/data/log/codis-proxy_10.log??--cpu=4?--addr=0.0.0.0:19000?--http-addr=0.0.0.0:11000?&

cd/data/go/src/github.com/wandoulabs/codis/&&??./bin/codis-proxy-c?/etc/codis/config_49.ini?-L?/data/log/codis-proxy_49.log??--cpu=4?--addr=0.0.0.0:19000?--http-addr=0.0.0.0:11000?&

OK,整個(gè)集群已經(jīng)搭建成功了,截圖給你們show show

六、codis-server的HA

codis-ha實(shí)現(xiàn)codis-server的主從切換,codis-server主庫(kù)掛了會(huì)提升一個(gè)從庫(kù)為主庫(kù),從庫(kù)掛了會(huì)設(shè)置這個(gè)從庫(kù)從集群下線

1、安裝

exportGOPATH=/data/go

/usr/local/go/bin/goget?github.com/ngaut/codis-ha

cd/data/go/src/github.com/ngaut/codis-ha

go?build

cpcodis-ha?/data/go/src/github.com/wandoulabs/codis/bin/

使用方法:

codis-ha?--codis-config=dashboard地址:18087?--productName=集群項(xiàng)目名稱

2、使用supervisord管理codis-ha進(jìn)程

1yum?-y?installsupervisord

/etc/supervisord.conf中添加如下內(nèi)容:

[program:codis-ha]

autorestart?=?True

stopwaitsecs?=?10

startsecs?=?1

stopsignal?=?QUIT

command=?/data/go/src/github.com/wandoulabs/codis/bin/codis-ha--codis-config=10.10.32.17:18087?--productName=zh_news

user?=?root

startretries?=?3

autostart?=?True

exitcodes?=?0,2

3、啟動(dòng)supervisord服務(wù)

/etc/init.d/supervisordstart

chkconfig?supervisord??on

此時(shí),ps -ef |grep codis-ha 你回發(fā)現(xiàn)codis-ha進(jìn)程已經(jīng)啟動(dòng),這個(gè)時(shí)候你去停掉一個(gè)codis-server的master,看看slave會(huì)不會(huì)提升為master呢

七、關(guān)于監(jiān)控

關(guān)于整個(gè)codis集群的監(jiān)控,我們這邊用的是zabbix,監(jiān)控的指標(biāo)比較簡(jiǎn)單,所以這塊大家有什么好的建議多給我提提哈

zookeeper:監(jiān)控各個(gè)節(jié)點(diǎn)的端口聯(lián)通性(以后想著把進(jìn)程也監(jiān)控上)

codis-proxy:監(jiān)控了端口的聯(lián)通性,這個(gè)監(jiān)控遠(yuǎn)遠(yuǎn)不夠呀

codis-server:監(jiān)控了內(nèi)存使用率、連接數(shù)、聯(lián)通性

codis-ha:監(jiān)控進(jìn)程

dashboard:監(jiān)控端口聯(lián)通性

八、使用過(guò)程中遇到的問(wèn)題

1、codis-proxy的日志切割,codis-proxy的默認(rèn)日志級(jí)別是info,日志量很大,我們這邊每天產(chǎn)生50多G日志,目前codis-proxy還不支持熱重啟,想修改啟動(dòng)參數(shù)還是比較麻煩的,日志切割推薦用logrotate

2、codis-proxy的監(jiān)聽(tīng)地址默認(rèn)沒(méi)有具體ipv4,也就是codis-proxy啟動(dòng)之后沒(méi)有0.0.0.0:19000這樣的監(jiān)聽(tīng),這樣會(huì)導(dǎo)致的問(wèn)題就是前端lvs沒(méi)有辦法負(fù)載均衡codis-proxy,不能轉(zhuǎn)發(fā)請(qǐng)求過(guò),這個(gè)問(wèn)題已聯(lián)系作者處理了,在codis-proxy啟動(dòng)的配置文件中加上proto=tcp4這個(gè)參數(shù)就支持監(jiān)聽(tīng)ipv4了

3、添加

Redis Server

Group的時(shí)候,非codis-server(原生的redis)竟然也能加入到codis集群里面,在redis和codis-server共存在一個(gè)物理機(jī)上的清楚,很容易加錯(cuò),希望能有個(gè)驗(yàn)證,非codis-server不能加入到codis集群

4、codis集群內(nèi)部通訊是通過(guò)主機(jī)名的,如果主機(jī)名沒(méi)有做域名解析那dashboard是通過(guò)主機(jī)名訪問(wèn)不到proxy的http-addr地址的,這會(huì)導(dǎo)致從web界面上看不到?OP/s的數(shù)據(jù),至于還有沒(méi)有其他問(wèn)題,目前我這邊還沒(méi)有發(fā)現(xiàn),建議內(nèi)部通訊直接用內(nèi)網(wǎng)IP

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、codis介紹codis是一個(gè)分布式redis集群解決方案,對(duì)于上層的應(yīng)用來(lái)說(shuō), 連接到codis-proxy...
    曹振華閱讀 7,324評(píng)論 0 9
  • Codis 3.2 部署配置匯總 概念總結(jié) 集群配置前需要了解架構(gòu),集群分片主要分三種: 客戶端分片:這個(gè)需要自己...
    三杯水Plus閱讀 6,316評(píng)論 0 11
  • Codis 是一個(gè)分布式 Redis 解決方案, 對(duì)于上層的應(yīng)用來(lái)說(shuō), 連接到 Codis Proxy 和連接原生...
    柏樹_Jeff閱讀 843評(píng)論 0 2
  • 一. 應(yīng)用場(chǎng)景 redis 作為數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)引擎,有著很多優(yōu)點(diǎn) 高性能單機(jī)引擎可以達(dá)到5-10W qps 數(shù)據(jù)結(jié)構(gòu)...
    skywalker閱讀 15,933評(píng)論 4 29
  • 一、codis 簡(jiǎn)介 摘自官方:Codis 是一個(gè)分布式 Redis 解決方案, 對(duì)于上層的應(yīng)用來(lái)說(shuō), 連接到 C...
    擼大師閱讀 1,309評(píng)論 0 3

友情鏈接更多精彩內(nèi)容