1. 程式人生 > >測試TwemProxy的應知應會

測試TwemProxy的應知應會

一、背景

最近中介軟體開發組對twemproxy的發現註冊機制做了改造,之前沒有接觸過twemproxy,借這次測試的機會,初步學習了一下twemproxy相關的知識;下面用“測試語言“來做一次梳理(站在測試的角度,掌握哪些技能可以順利開展測試)。

二、TwemProxy是什麼

twemproxy是一種代理分片機制,由Twitter開源。twemproxy作為代理,可接受來自多個程式的訪問,按照路由規則,轉發給後臺的各個Redis伺服器,再原路返回。該方案很好的解決了單個Redis例項承載能力的問題。通過Twemproxy可以使用多臺伺服器來水平擴張redis服務,可以有效的避免單點故障問題。雖然使用twemproxy需要更多的硬體資源和在redis效能有一定的損失(twitter測試約20%),但是能夠提高整個系統的HA也是相當划算的。當然,twemproxy本身也是單點,需要用Keepalived做高可用方案。

其實twemproxy不光實現了redis協議,還實現了memcached協議,換句話說,twemproxy不光可以代理redis,還可以代理memcached(同樣作為快取伺服器,memcached越來越被更少的應用,redis越來越成為更普遍的選擇)。

Twemproxy單點架構:

通常會結合keepalived來實現twemproxy的高可用。架構圖如下:

上面的架構通常只有一臺twemproxy在工作,另外一臺處於備機,當一臺掛掉以後,vip自動漂移,備機接替工作。

即便我們通過keepalived實現了twemproxy的高可用,也不難發現在整個的redis叢集裡面,如果使用者要想訪問redis叢集必須通過twemproxy,於是這個時候就有可能造成一種問題:

  1,後面的redis叢集一定速度暴快,因為一堆的資料庫服務

  2,所有的效能都卡在了代理上

為了解決上面兩個問題,很自然的想到在設計架構時,在twemproxy前面需要一個負載均衡的機制,由此haproxy作為一個千萬級高併發負載均衡軟體被引入到架構中。

Haproxy的特點:

  1,一個開源的

  2,高效能的(千萬級)

  3,基於TCP第四層和http第七層

Haproxy優點:

  1,最高可以同時維護40000-50000個併發連線。單位時間內處理最大的請求數為20000.最大資料處理能力可達10GBPS

  2,支援多餘8種負載均衡演算法,同時也支援session保持

  3,支援虛擬主機功能

  4,擁有伺服器效能監控工具

三、TwemProxy能做什麼

Antirez(redis作者)寫過一篇對twemproxy的介紹,他認為twemproxy是目前Redis 分片管理的最好方案,雖然Antirez的Redis cluster正在實現並且對其給予厚望,但從現有的cluster實現上還是認為cluster除了增加redis複雜度,對於叢集的管理沒有twemproxy來的輕量和有效。

談到叢集管理不得不又說到資料的分片管理(shard),為了滿足資料的日益增長和擴充套件性,資料儲存系統一般都需要進行一定的分片,如傳統的MySQL進行橫向分表和縱向分表,然後應用程式訪問正確的位置就需要找的正確的表。這時候,這個資料定向工作一般有三個位置可以放:

  1,資料儲存系統本身支援,Redis cluster就是典型的試圖在資料儲存系統上支援分片

  2,客戶端支援,memcached的客戶端對分片的支援就是客戶端層面的

  3,代理支援,twemproxy就是試圖在伺服器端和客戶端中間建代理支援

Twemproxy的特性:

    • 支援失敗節點自動刪除 
      • 可以設定重新連線該節點的時間
      • 可以設定連線多少次之後刪除該節點
    • 支援設定HashTag 
      • 通過HashTag可以自己設定將兩個key雜湊到同一個例項上去
    • 減少與redis的直接連線數 
      • 保持與redis的長連線
      • 減少了客戶端直接與伺服器連線的連結數量
    • 自動分片到後端多個redis例項上 
      • 多種hash演算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
      • 多種分片演算法:ketama(一致性hash演算法的一種實現)、modular、random
      • 可以設定後端例項的權重
    • 避免單節點問題 
      • 可以平行部署多個代理層,通過HAProxy做負載均衡,將redis的讀寫分散到多個twemproxy上
    • 支援狀態監控 
      • 可設定狀態監控IP和埠,訪問IP和埠可以得到一個json格式的狀態資訊串
      • 可設定監控資訊重新整理間隔時間
    • 使用pipelining處理請求和響應 
      • 連線複用,記憶體服用
      • 將多個連線請求,組成redis pipelining統一redis請求
    • 並不是支援所有redis命令 
      • 不支援redis的事務操作
      • 使用SIDFF,SDIFFSTORE,SINTER,SINTERSTORE,SMOVE,SUNION and SUNIONSTORE 命令需要保證key都在同一個分片上

最主要功能:使用者不再直接操作真正的Redis,而且支援高效能的資料訪問,而且支援分片處理,可以操作Redis叢集。

四、TwemProxy怎麼用

Twemproxy通過配置檔案nutcracker.yml來實現對redis叢集實現管理。

nutcracker.yml的結構如下:

eshop-detail-test:  
  listen: 127.0.0.1:1111  
  hash: fnv1a_64  
  distribution: ketama  
  timeout:1000  
  redis: true  
  servers:  
   - 127.0.0.1:6379:1 test-redis-01 
   - 127.0.0.1:6380:1 test-redis-02
 auto_eject_hosts: true
 server_retry_timeout: 30000
 server_failure_limit: 2

註解:

eshop-detail-test: redis叢集的邏輯名稱

listen:twemproxy監聽的埠號

hash:hash雜湊演算法

distribution:分片演算法,一致性hash,取模,等等

timeout:跟redis連線的超時時長

redis:是否是redis,false的話是memcached

servers:redis例項列表,一定要加別名,否則預設使用ip:port:weight來計算分片,如果宕機後更換機器,那麼分片就不一樣了,因此加了別名後,可以確保分片一定是準確的

auto_eject_hosts: true,自動摘除故障節點

server_retry_timeout: 30000,每隔30秒判斷故障節點是否正常,如果正常則放回一致性hash環

server_failure_limit: 2,多少次無響應,就從一致性hash環中摘除

業務方程式(如java/php)連線twemproxy寫資料的時候,twemproxy負責將資料分片,寫入不同的redis例項。

如果某個redis機器宕機,需要自動從一致性hash環上摘掉,等恢復後自動上線。

五、TwemProxy配合redis的主從模式和哨兵機制

主從模式

只要是進行高可用的架構部署,那麼就必須保證多節點,前面提到的redis叢集,對於每一個redis節點實際上都採用來主從模式。雖然redis提供了資料持久化的機制,AOF和RDB,但是兩種模式解決的是資料容災,即當redis伺服器掛掉時,可以對歷史資料進行恢復。AOF模式實際上是生成一個日誌檔案,當redis伺服器重啟時,通過讀配置檔案來恢復歷史資料;RDB模式是從redis上實時同步資料到資料庫如Myslq,顯然兩種模式都不能實時的提供歷史資料的讀,主從模式解決了這一問題。傳統的主從模式是一個redis伺服器作為master,只負責寫入資料,其它幾個redis伺服器作為slave,只負責讀資料,這樣就做到了資料的讀寫分離,也起到了對資料備份的目的。

為什麼用主從模式?

最大好處在於:可以自動對資料做備份

有缺點嗎?

最大缺點在於:只能夠做備份,而出現災難之後無法立即恢復(還是要使用redis的持久化的機制,使用兩者的目的不同,並不矛盾,需要配合使用)

哨兵機制

Redis裡面使用了主從模式可以實現多節點配置,但是傳統的主從模式的設計有一個缺陷:一旦Master主機出現了問題之後,兩臺Slave主機將無法提供正常的工作支援,例如:slave主機為只讀主機,而且如果要想繼續提供支援,那麼至少應該通過剩餘的幾臺slave裡面去推選出一個新的master,並且最為重要的是,這個新的master還必須能夠被使用者的程式找到,由此催生了哨兵機制。

哨兵機制(Sentinel) 原理圖:

不難看出哨兵機制帶來的好處是提升了redis叢集的HA(高可用),哨兵機制也是redis官方推薦的高可用解決方案之一。

哨兵機制(Sentinel) 的功能: 

  • 監控(Monitoring),sentinel時刻監控著redis master-slave 是否正常執行; 
  • 通知(Notification),sentinel 可以通過api來通知管理員,被監控的 redis master-slave 出現了問題; 
  • 自動故障轉移(Automatic failover),當redis master出現故障不可用狀態,sentinel 會開始一次故障轉移,將其中一個slave 提升為新的 master ,將其他的 slave 將重新配置使用新的 master 同步,並使用redis 的伺服器應用程式在連線時受到使用新的地址連線; 
  • 配置提供者(Configuration provider),sentinel 作為在叢集中的權威來源,客戶端連線到 sentinel 來獲取某個服務的當前 redis 主伺服器的地址和其他資訊。當前故障轉移發生時,sentinel 會報告新地址。

六、本次測試的需求改動點和測試方法

先了解一下中介軟體開發組twemproxy的實現原理。

php語言實現架構圖:

註解:

1,confd是一個客戶端,安裝在業務方的機器上,作用是從etcd叢集中獲取twemproxy機器的ip和埠號

2,etcd是一個分散式、可靠的 key-value 儲存的分散式系統,當然,它不僅僅用於儲存,還提供共享配置及服務發現(可以簡單理解成提供服務發現功能的redis)

業務方獲取 tw ip 流程:

  • Twemproxy 啟動時向 etcd 叢集註冊一個(K,V) 對,key是特定的業務名稱+twproxy ip , value 是 twproxy 的 ip:port ,並且每隔 2 秒向 etcd 叢集續活
  • 業務方 API 機器啟動 confd 去 etcd 叢集拉取對應業務下所有key的value,並生成配置檔案
  • 增加或者刪除一個 twproxy 節點時,confd watch 到 etcd 叢集相應的 key 發生變化,重新生成配置檔案

高可用:

  • 每個業務最少提供兩個 twemproxy 供業務方連線
  • redis 發生主從切換, twemproxy 會實時生成新的配置檔案,並重啟

提測的改動點:

安裝在業務方機器上的confd軟體實時與etcd通訊,當twproxy與etcd之間網路中斷,就會導致twproxy在etcd中的key過期被刪除,進而etcd會及時通知confd來刪除資料,直至twproxy整個叢集的host全部被刪除。因此對confd進行二次開發,當confd要求刪除所有資料時,遮蔽此要求,並釘釘告警。綜上,此次改造的目的是保證業務方至少可以使用1臺twproxy伺服器。

測試方法:

上面提到了業務方獲取 twproxy ip 的流程,即業務方 API 機器啟動 confd 去 etcd 叢集拉取對應業務下所有key的value,並生成配置檔案,然後業務方通過指令碼讀取配置檔案來獲取twproxy ip。那麼測試思路就是對etcd執行刪除的操作,當刪除到最後一個(K,V) 對時,檢視confd的日誌,是否有重新生成配置檔案的動作。

測試分解:

etcd執行刪除操作:

檢視confd的日誌: