鍍金池/ 教程/ Linux/ Redis/SSDB+Twemproxy 安裝與使用
Web 開(kāi)發(fā)實(shí)戰(zhàn)2——商品詳情頁(yè)
流量復(fù)制 /AB 測(cè)試/協(xié)程
常用 Lua 開(kāi)發(fā)庫(kù) 1-redis、mysql、http 客戶端
Lua 模塊開(kāi)發(fā)
常用 Lua 開(kāi)發(fā)庫(kù) 3-模板渲染
HTTP 服務(wù)
Nginx+Lua 開(kāi)發(fā)入門
安裝 Nginx+Lua 開(kāi)發(fā)環(huán)境
Redis/SSDB+Twemproxy 安裝與使用
JSON 庫(kù)、編碼轉(zhuǎn)換、字符串處理

Redis/SSDB+Twemproxy 安裝與使用

目前對(duì)于互聯(lián)網(wǎng)公司不使用 Redis 的很少,Redis 不僅僅可以作為 key-value 緩存,而且提供了豐富的數(shù)據(jù)結(jié)果如 set、list、map 等,可以實(shí)現(xiàn)很多復(fù)雜的功能;但是 Redis 本身主要用作內(nèi)存緩存,不適合做持久化存儲(chǔ),因此目前有如 SSDB、ARDB 等,還有如京東的 JIMDB,它們都支持 Redis 協(xié)議,可以支持 Redis 客戶端直接訪問(wèn);而這些持久化存儲(chǔ)大多數(shù)使用了如LevelDB、RocksDB、LMDB 持久化引擎來(lái)實(shí)現(xiàn)數(shù)據(jù)的持久化存儲(chǔ);京東的 JIMDB 主要分為兩個(gè)版本:LevelDB 和 LMDB,而我們看到的京東商品詳情頁(yè)就是使用 LMDB 引擎作為存儲(chǔ)的,可以實(shí)現(xiàn)海量KV存儲(chǔ);當(dāng)然 SSDB 在京東內(nèi)部也有些部門在使用;另外調(diào)研過(guò)得如豆瓣的 beansDB 也是很不錯(cuò)的。具體這些持久化引擎之間的區(qū)別可以自行查找資料學(xué)習(xí)。

Twemproxy 是一個(gè) Redis/Memcached 代理中間件,可以實(shí)現(xiàn)諸如分片邏輯、HashTag、減少連接數(shù)等功能;尤其在有大量應(yīng)用服務(wù)器的場(chǎng)景下 Twemproxy 的角色就凸顯了,能有效減少連接數(shù)。

Redis 安裝與使用

下載 redis 并安裝

Java 代碼

cd /usr/servers/  
wget https://github.com/antirez/redis/archive/2.8.19.tar.gz  
tar -xvf 2.8.19.tar.gz  
cd redis-2.8.19/  
make     

通過(guò)如上步驟構(gòu)建完畢。

后臺(tái)啟動(dòng) Redis 服務(wù)器

Java 代碼

nohup /usr/servers/redis-2.8.19/src/redis-server  /usr/servers/redis-2.8.19/redis.conf &  

查看是否啟動(dòng)成功

Java 代碼

ps -aux | grep redis  

進(jìn)入客戶端

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 6379  

執(zhí)行如下命令

Java 代碼

127.0.0.1:6379> set i 1  
OK  
127.0.0.1:6379> get i  
"1"     

通過(guò)如上命令可以看到我們的 Redis 安裝成功。更多細(xì)節(jié)請(qǐng)參考 http://redis.io/

SSDB 安裝與使用

下載 SSDB 并安裝

Java 代碼

\#首先確保安裝了g++,如果沒(méi)有安裝,如ubuntu可以使用如下命令安裝  
apt-get install g++  
cd /usr/servers  
wget https://github.com/ideawu/ssdb/archive/1.8.0.tar.gz  
tar -xvf 1.8.0.tar.gz  
make   

后臺(tái)啟動(dòng) SSDB 服務(wù)器

Java 代碼

nohup /usr/servers/ssdb-1.8.0/ssdb-server  /usr/servers/ssdb-1.8.0/ssdb.conf &  

查看是否啟動(dòng)成功

Java 代碼

ps -aux | grep ssdb  

進(jìn)入客戶端

Java 代碼

/usr/servers/ssdb-1.8.0/tools/ssdb-cli -p 8888  
/usr/servers/redis-2.8.19/src/redis-cli  -p 888  

因?yàn)?SSDB 支持 Redis 協(xié)議,所以用 Redis 客戶端也可以訪問(wèn)

執(zhí)行如下命令

Java 代碼

127.0.0.1:8888> set i 1  
OK  
127.0.0.1:8888> get i  
"1"    

安裝過(guò)程中遇到錯(cuò)誤請(qǐng)參考 http://ssdb.io/docs/zh_cn/install.html;對(duì)于 SSDB 的配置請(qǐng)參考官方文檔 https://github.com/ideawu/ssdb[http://ssdb.io/docs/zh_cn/install.html](http://ssdb.io/docs/zh_cn/install.html)。

Twemproxy 安裝與使用

首先需要安裝 autoconf、automake、libtool 工具,比如 ubuntu 可以使用如下命令安裝

Java 代碼

apt-get install autoconf automake  
apt-get install libtool  

下載 Twemproxy 并安裝

Java 代碼

cd /usr/servers  
wget https://github.com/twitter/twemproxy/archive/v0.4.0.tar.gz  
tar -xvf v0.4.0.tar.gz    
cd twemproxy-0.4.0/  
autoreconf -fvi  
./configure && make    

此處根據(jù)要注意,如上安裝方式在有些服務(wù)器上可能在大量如mset時(shí)可能導(dǎo)致 Twemproxy 崩潰,需要使用如 CFLAGS="-O1" ./configure && make 或 CFLAGS="-O3 -fno-strict-aliasing" ./configure && make 安裝。

配置

Java 代碼

vim /usr/servers/twemproxy-0.4.0/conf/nutcracker.yml  

Java 代碼

server1:  
  listen: 127.0.0.1:1111  
  hash: fnv1a_64  
  distribution: ketama  
  redis: true  
  servers:  
   - 127.0.0.1:6379:1  

啟動(dòng) Twemproxy 代理

Java 代碼

/usr/servers/twemproxy-0.4.0/src/nutcracker  -d -c /usr/servers/twemproxy-0.4.0/conf/nutcracker.yml    

-d 指定后臺(tái)啟動(dòng) -c 指定配置文件;此處我們指定了代理端口為 1111,其他配置的含義后續(xù)介紹。

查看是否啟動(dòng)成功

Java 代碼

ps -aux | grep nutcracker  

進(jìn)入客戶端

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 1111  

執(zhí)行如下命令

Java 代碼

127.0.0.1:1111> set i 1  
OK  
127.0.0.1:1111> get i  
"1"     

Twemproxy 文檔請(qǐng)參考 https://github.com/twitter/twemproxy。

到此基本的安裝就完成了。接下來(lái)做一些介紹。

Redis 設(shè)置

基本設(shè)置

Java 代碼

\#端口設(shè)置,默認(rèn)6379    
port 6379    
\#日志文件,默認(rèn)/dev/null    
logfile ""     

Redis 內(nèi)存

Java 代碼

內(nèi)存大小對(duì)應(yīng)關(guān)系   
\# 1k => 1000 bytes  
\# 1kb => 1024 bytes  
\# 1m => 1000000 bytes  
\# 1mb => 1024*1024 bytes  
\# 1g => 1000000000 bytes  
\# 1gb => 1024*1024*1024 bytes  

\#設(shè)置Redis占用100mb的大小  
maxmemory  100mb  

\#如果內(nèi)存滿了就需要按照如相應(yīng)算法進(jìn)行刪除過(guò)期的/最老的  
\#volatile-lru 根據(jù)LRU算法移除設(shè)置了過(guò)期的key  
\#allkeys-lru  根據(jù)LRU算法移除任何key(包含那些未設(shè)置過(guò)期時(shí)間的key)  
\#volatile-random/allkeys->random 使用隨機(jī)算法而不是LRU進(jìn)行刪除  
\#volatile-ttl 根據(jù)Time-To-Live移除即將過(guò)期的key   
\#noeviction   永不過(guò)期,而是報(bào)錯(cuò)  
maxmemory-policy volatile-lru  

\#Redis并不是真正的LRU/TTL,而是基于采樣進(jìn)行移除的,即如采樣10個(gè)數(shù)據(jù)移除其中最老的/即將過(guò)期的  
maxmemory-samples 10   

而如 Memcached 是真正的 LRU,此處要根據(jù)實(shí)際情況設(shè)置緩存策略,如緩存用戶數(shù)據(jù)時(shí)可能帶上了過(guò)期時(shí)間,此時(shí)采用 volatile-lru 即可;而假設(shè)我們的數(shù)據(jù)未設(shè)置過(guò)期時(shí)間,此時(shí)可以考慮使用 allkeys-lru/allkeys->random;假設(shè)我們的數(shù)據(jù)不允許從內(nèi)存刪除那就使用noeviction。

內(nèi)存大小盡量在系統(tǒng)內(nèi)存的 60%~80% 之間,因?yàn)槿缈蛻舳恕⒅鲝臅r(shí)復(fù)制時(shí)都需要緩存區(qū)的,這些也是耗費(fèi)系統(tǒng)內(nèi)存的。

Redis 本身是單線程的,因此我們可以設(shè)置每個(gè)實(shí)例在 6-8GB 之間,通過(guò)啟動(dòng)更多的實(shí)例提高吞吐量。如 128GB 的我們可以開(kāi)啟 8GB * 10 個(gè)實(shí)例,充分利用多核 CPU。

Redis 主從

實(shí)際項(xiàng)目時(shí),為了提高吞吐量,我們使用主從策略,即數(shù)據(jù)寫到主 Redis,讀的時(shí)候從從 Redis上讀,這樣可以通過(guò)掛載更多的從來(lái)提高吞吐量。而且可以通過(guò)主從機(jī)制,在葉子節(jié)點(diǎn)開(kāi)啟持久化方式防止數(shù)據(jù)丟失。

Java 代碼

\#在配置文件中掛載主從,不推薦這種方式,我們實(shí)際應(yīng)用時(shí)Redis可能是會(huì)宕機(jī)的  
slaveof masterIP masterPort  
\#從是否只讀,默認(rèn)yes  
slave-read-only yes  
\#當(dāng)從失去與主的連接或者復(fù)制正在進(jìn)行時(shí),從是響應(yīng)客戶端(可能返回過(guò)期的數(shù)據(jù))還是返回“SYNC with master in progress”錯(cuò)誤,默認(rèn)yes響應(yīng)客戶端  
slave-serve-stale-data yes  
\#從庫(kù)按照默認(rèn)10s的周期向主庫(kù)發(fā)送PING測(cè)試連通性  
repl-ping-slave-period 10  
\#設(shè)置復(fù)制超時(shí)時(shí)間(SYNC期間批量I/O傳輸、PING的超時(shí)時(shí)間),確保此值大于repl-ping-slave-period  
\#repl-timeout 60  
\#當(dāng)從斷開(kāi)與主的連接時(shí)的復(fù)制緩存區(qū),僅當(dāng)?shù)谝粋€(gè)從斷開(kāi)時(shí)創(chuàng)建一個(gè),緩存區(qū)越大從斷開(kāi)的時(shí)間可以持續(xù)越長(zhǎng)  
\# repl-backlog-size 1mb  
\#當(dāng)從與主斷開(kāi)持續(xù)多久時(shí)清空復(fù)制緩存區(qū),此時(shí)從就需要全量復(fù)制了,如果設(shè)置為0將永不清空    
\# repl-backlog-ttl 3600  
\#slave客戶端緩存區(qū),如果緩存區(qū)超過(guò)256mb將直接斷開(kāi)與從的連接,如果持續(xù)60秒超過(guò)64mb也會(huì)斷開(kāi)與從的連接  
client-output-buffer-limit slave 256mb 64mb 60   
此處需要根據(jù)實(shí)際情況設(shè)置client-output-buffer-limit slave和 repl-backlog-size;比如如果網(wǎng)絡(luò)環(huán)境不好,從與主經(jīng)常斷開(kāi),而每次設(shè)置的數(shù)據(jù)都特別大而且速度特別快(大量設(shè)置html片段)那么就需要加大repl-backlog-size。 

主從示例

Java 代碼

cd /usr/servers/redis-2.8.19  
cp redis.conf redis_6660.conf  
cp redis.conf redis_6661.conf  
vim redis_6660.conf  
vim redis_6661.conf   

將端口分別改為 port 6660 和 port 6661,然后啟動(dòng)

Java 代碼

nohup /usr/servers/redis-2.8.19/src/redis-server  /usr/servers/redis-2.8.19/redis_6660.conf &  
nohup /usr/servers/redis-2.8.19/src/redis-server  /usr/servers/redis-2.8.19/redis_6661.conf &    

查看是否啟動(dòng)

Java 代碼

ps -aux | grep redis  

進(jìn)入從客戶端,掛主

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 6661    

Java 代碼

127.0.0.1:6661> slaveof 127.0.0.1 6660  
OK  
127.0.0.1:6661> info replication  
\# Replication  
role:slave  
master_host:127.0.0.1  
master_port:6660  
master_link_status:up  
master_last_io_seconds_ago:3  
master_sync_in_progress:0  
slave_repl_offset:57  
slave_priority:100  
slave_read_only:1  
connected_slaves:0  
master_repl_offset:0  
repl_backlog_active:0  
repl_backlog_size:1048576  
repl_backlog_first_byte_offset:0  
repl_backlog_histlen:0   

進(jìn)入主

Java 代碼

/usr/servers/redis-2.8.19# /usr/servers/redis-2.8.19/src/redis-cli  -p 6660  

Java 代碼

127.0.0.1:6660> info replication  
\# Replication  
role:master  
connected_slaves:1  
slave0:ip=127.0.0.1,port=6661,state=online,offset=85,lag=1  
master_repl_offset:85  
repl_backlog_active:1  
repl_backlog_size:1048576  
repl_backlog_first_byte_offset:2  
repl_backlog_histlen:84  
127.0.0.1:6660> set i 1  
OK   

進(jìn)入從

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 6661    

Java 代碼

127.0.0.1:6661> get i  
"1"     

此時(shí)可以看到主從掛載成功,可以進(jìn)行主從復(fù)制了。使用 slaveof no one 斷開(kāi)主從。

Redis 持久化

Redis 雖然不適合做持久化存儲(chǔ),但是為了防止數(shù)據(jù)丟失有時(shí)需要進(jìn)行持久化存儲(chǔ),此時(shí)可以掛載一個(gè)從(葉子節(jié)點(diǎn))只進(jìn)行持久化存儲(chǔ)工作,這樣假設(shè)其他服務(wù)器掛了,我們可以通過(guò)這個(gè)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)恢復(fù)。

Redis 持久化有 RDB 快照模式和 AOF 追加模式,根據(jù)自己需求進(jìn)行選擇。

RDB 持久化

Java 代碼

\#格式save seconds changes 即N秒變更N次則保存,從如下默認(rèn)配置可以看到丟失數(shù)據(jù)的周期很長(zhǎng),通過(guò)save “” 配置可以完全禁用此持久化  
save 900 1    
save 300 10    
save 60 10000   
\#RDB是否進(jìn)行壓縮,壓縮耗CPU但是可以減少存儲(chǔ)大小  
rdbcompression yes  
\#RDB保存的位置,默認(rèn)當(dāng)前位置    
dir ./  
\#RDB保存的數(shù)據(jù)庫(kù)名稱  
dbfilename dump.rdb    
\#不使用AOF模式,即RDB模式  
appendonly no     

可以通過(guò) set 一個(gè)數(shù)據(jù),然后很快的 kill 掉 redis 進(jìn)程然后再啟動(dòng)會(huì)發(fā)現(xiàn)數(shù)據(jù)丟失了。

AOF 持久化

AOF(append only file)即文件追加模式,即把每一個(gè)用戶操作的命令保存下來(lái),這樣就會(huì)存在好多重復(fù)的命令導(dǎo)致恢復(fù)時(shí)間過(guò)長(zhǎng),那么可以通過(guò)相應(yīng)的配置定期進(jìn)行 AOF 重寫來(lái)減少重復(fù)。

Java 代碼

\#開(kāi)啟AOF  
appendonly yes  
\#AOF保存的位置,默認(rèn)當(dāng)前位置    
dir ./  
\#AOF保存的數(shù)據(jù)庫(kù)名稱  
appendfilename appendonly.aof  
\#持久化策略,默認(rèn)每秒fsync一次,也可以選擇always即每次操作都進(jìn)行持久化,或者no表示不進(jìn)行持久化而是借助操作系統(tǒng)的同步將緩存區(qū)數(shù)據(jù)寫到磁盤  
appendfsync everysec  

\#AOF重寫策略(同時(shí)滿足如下兩個(gè)策略進(jìn)行重寫)  
\#當(dāng)AOF文件大小占到初始文件大小的多少百分比時(shí)進(jìn)行重寫  
auto-aof-rewrite-percentage 100  
\#觸發(fā)重寫的最小文件大小  
auto-aof-rewrite-min-size 64mb  

\#為減少磁盤操作,暫緩重寫階段的磁盤同步  
no-appendfsync-on-rewrite no     

此處的 appendfsync everysec 可以認(rèn)為是 RDB 和 AOF 的一個(gè)折中方案。

#當(dāng) bgsave 出錯(cuò)時(shí)停止寫(MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.),遇到該錯(cuò)誤可以暫時(shí)改為 no,當(dāng)寫成功后再改回 yes stop-writes-on-bgsave-error yes

更多 Redis 持久化請(qǐng)參考 http://redis.readthedocs.org/en/latest/topic/persistence.html。

Redis 動(dòng)態(tài)調(diào)整配置

獲取 maxmemory(10mb)

Java 代碼

127.0.0.1:6660> config get maxmemory  
1) "maxmemory"  
2) "10485760"   

設(shè)置新的 maxmemory(20mb)

Java 代碼

127.0.0.1:6660> config set maxmemory 20971520  
OK  

但是此時(shí)重啟 redis 后該配置會(huì)丟失,可以執(zhí)行如下命令重寫配置文件

Java 代碼

127.0.0.1:6660> config rewrite  
OK   

注意:此時(shí)所以配置包括主從配置都會(huì)重寫。

Redis 執(zhí)行 Lua 腳本

Redis 客戶端支持解析和處理 lua 腳本,因?yàn)?Redis 的單線程機(jī)制,我們可以借助 Lua 腳本實(shí)現(xiàn)一些原子操作,如扣減庫(kù)存/紅包之類的。此處不建議使用 EVAL 直接發(fā)送 lua 腳本到客戶端,因?yàn)槠涿看味紩?huì)進(jìn)行 Lua 腳本的解析,而是使用 SCRIPT LOAD+ EVALSHA 進(jìn)行操作。未來(lái)不知道是否會(huì)用 luajit 來(lái)代替 lua,讓redis lua 腳本性能更強(qiáng)。

到此基本的 Redis 知識(shí)就講完了。

Twemproxy 設(shè)置

一旦涉及到一臺(tái)物理機(jī)無(wú)法存儲(chǔ)的情況就需要考慮使用分片機(jī)制將數(shù)據(jù)存儲(chǔ)到多臺(tái)服務(wù)器,可以說(shuō)是 Redis 集群;如果客戶端都是如 Java 沒(méi)什么問(wèn)題,但是如果有多種類型客戶端(如 PHP、C)等也要使用那么需要保證它們的分片邏輯是一樣的;另外隨著客戶端的增加,連接數(shù)也會(huì)隨之增多,發(fā)展到一定地步肯定會(huì)出現(xiàn)連接數(shù)不夠用的;此時(shí) Twemproxy 就可以上場(chǎng)了。主要作用:分片、減少連接數(shù)。另外還提供了 Hash Tag 機(jī)制來(lái)幫助我們將相似的數(shù)據(jù)存儲(chǔ)到同一個(gè)分片。另外也可以參考豌豆莢的 https://github.com/wandoulabs/codis。

基本配置

其使用 YML 語(yǔ)法,如

Java 代碼

server1:  
  listen: 127.0.0.1:1111  
  hash: fnv1a_64  
  distribution: ketama  
  timeout:1000  
  redis: true  
  servers:  
   - 127.0.0.1:6660:1  
   - 127.0.0.1:6661:1    
  • server1:是給當(dāng)前分片配置起的名字,一個(gè)配置文件可以有多個(gè)分片配置;
  • listen : 監(jiān)聽(tīng)的 ip 和端口;
  • hash:散列算法;
  • distribution:分片算法,比如一致性 Hash/ 取模;
  • timeout:連接后端 Redis 或接收響應(yīng)的超時(shí)時(shí)間;
  • redis:是否是 redis 代理,如果是 false 則是 memcached 代理;
  • servers:代理的服務(wù)器列表,該列表會(huì)使用 distribution 配置的分片算法進(jìn)行分片;

分片算法

hash 算法:

one_at_a_time
md5
crc16
crc32 (crc32 implementation compatible with libmemcached)
crc32a (correct crc32 implementation as per the spec)
fnv1_64
fnv1a_64
fnv1_32
fnv1a_32
hsieh
murmur
jenkins  

分片算法:

ketama(一致性 Hash 算法)
modula(取模)
random(隨機(jī)算法)

服務(wù)器列表

servers:

  • ip:port:weight alias

    servers:
  • 127.0.0.1:6660:1
  • 127.0.0.1:6661:1
    或者
    servers:
  • 127.0.0.1:6660:1 server1
  • 127.0.0.1:6661:1 server2

推薦使用后一種方式,默認(rèn)情況下使用 ip:port:weight 進(jìn)行散列并分片,這樣假設(shè)服務(wù)器宕機(jī)換上新的服務(wù)器,那么此時(shí)得到的散列值就不一樣了,因此建議給每個(gè)配置起一個(gè)別名來(lái)保證映射到自己想要的服務(wù)器。即如果不使用一致性 Hash 算法來(lái)作緩存服務(wù)器,而是作持久化存儲(chǔ)服務(wù)器時(shí)就更有必要了(即不存在服務(wù)器下線的情況,即使服務(wù)器 ip:port 不一樣但仍然要得到一樣的分片結(jié)果)。

HashTag

比如一個(gè)商品有:商品基本信息(p:id:)、商品介紹(d:id:)、顏色尺碼(c:id:)等,假設(shè)我們存儲(chǔ)時(shí)不采用 HashTag 將會(huì)導(dǎo)致這些數(shù)據(jù)不會(huì)存儲(chǔ)到一個(gè)分片,而是分散到多個(gè)分片,這樣獲取時(shí)將需要從多個(gè)分片獲取數(shù)據(jù)進(jìn)行合并,無(wú)法進(jìn)行 mget;那么如果有了 HashTag,那么可以使用“::”中間的數(shù)據(jù)做分片邏輯,這樣 id 一樣的將會(huì)分到一個(gè)分片。

nutcracker.yml配置如下

Java 代碼

server1:  
  listen: 127.0.0.1:1111  
  hash: fnv1a_64  
  distribution: ketama  
  redis: true  
  hash_tag: "::"  
  servers:  
   - 127.0.0.1:6660:1 server1  
   - 127.0.0.1:6661:1 server2  

連接 Twemproxy

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 1111  

Java 代碼

127.0.0.1:1111> set p:12: 1  
OK  
127.0.0.1:1111> set d:12: 1  
OK  
127.0.0.1:1111> set c:12: 1  
OK  

在我的服務(wù)器上可以連接 6660 端口

Java 代碼

/usr/servers/redis-2.8.19/src/redis-cli  -p 6660  
127.0.0.1:6660> get p:12:   
"1"  
127.0.0.1:6660> get d:12:   
"1"  
127.0.0.1:6660> get c:12:   
"1"  

一致性 Hash 與服務(wù)器宕機(jī)

如果我們把 Redis 服務(wù)器作為緩存服務(wù)器并使用一致性 Hash 進(jìn)行分片,當(dāng)有服務(wù)器宕機(jī)時(shí)需要自動(dòng)從一致性 Hash 環(huán)上摘掉,或者其上線后自動(dòng)加上,此時(shí)就需要如下配置:

#是否在節(jié)點(diǎn)故障無(wú)法響應(yīng)時(shí)自動(dòng)摘除該節(jié)點(diǎn),如果作為存儲(chǔ)需要設(shè)置為為false auto_eject_hosts: true #重試時(shí)間(毫秒),重新連接一個(gè)臨時(shí)摘掉的故障節(jié)點(diǎn)的間隔,如果判斷節(jié)點(diǎn)正常會(huì)自動(dòng)加到一致性Hash環(huán)上 server_retry_timeout: 30000 #節(jié)點(diǎn)故障無(wú)法響應(yīng)多少次從一致性Hash環(huán)臨時(shí)摘掉它,默認(rèn)是2 server_failure_limit: 2

支持的 Redis 命令

不是所有 Redis 命令都支持,請(qǐng)參考 https://github.com/twitter/twemproxy/blob/master/notes/redis.md

因?yàn)槲覀兯械?Twemproxy 配置文件規(guī)則都是一樣的,因此我們應(yīng)該將其移到我們項(xiàng)目中。

Java 代碼

cp /usr/servers/twemproxy-0.4.0/conf/nutcracker.yml  /usr/example/   

另外 Twemproxy 提供了啟動(dòng)/重啟/停止腳本方便操作,但是需要修改配置文件位置為 /usr/example/nutcracker.yml。

Java 代碼

chmod +x /usr/servers/twemproxy-0.4.0/scripts/nutcracker.init   
vim /usr/servers/twemproxy-0.4.0/scripts/nutcracker.init    

將 OPTIONS 改為

OPTIONS="-d -c /usr/example/nutcracker.yml"

另外注釋掉. /etc/rc.d/init.d/functions;將 daemon --user ${USER} ${prog} $OPTIONS 改為 ${prog} $OPTIONS;將 killproc 改為 killall。

這樣就可以使用如下腳本進(jìn)行啟動(dòng)、重啟、停止了。
/usr/servers/twemproxy-0.4.0/scripts/nutcracker.init {start|stop|status|restart|reload|condrestart}

對(duì)于擴(kuò)容最簡(jiǎn)單的辦法是:

  1. 創(chuàng)建新的集群;
  2. 雙寫兩個(gè)集群;
  3. 把數(shù)據(jù)從老集群遷移到新集群(不存在才設(shè)置值,防止覆蓋新的值);
  4. 復(fù)制速度要根據(jù)實(shí)際情況調(diào)整,不能影響老集群的性能;
  5. 切換到新集群即可,如果使用Twemproxy代理層的話,可以做到遷移對(duì)讀的應(yīng)用透明。