Twemproxy 緩存代理服務器


Twemproxy 緩存代理服務器

 

Twemproxy 概述

Twemproxy(又稱為nutcracker)是一個輕量級的Redis和Memcached代理,主要用來減少對后端緩存服務器的連接數。Twemproxy是由Twitter開源出來的緩存服務器集群管理工具,主要用來彌補Redis/Memcached 對集群(cluster)管理的不足。

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

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

  • 數據存儲系統本身支持,Redis Cluster就是典型的試圖在數據存儲系統上支持分片;
  • 客戶端支持,Memcached的客戶端對分片的支持就是客戶端層面的;
  • 代理支持,twemproxy就是試圖在服務器端和客戶端中間建代理支持;

 

在三種方案中:

1、客戶端方案我認為欠妥,因為這樣每個客戶端需要維護一定的服務器信息,但是如果動態的增加或減少節點就需要重寫配置各個客戶端。

2、而在服務器端增加集群管理有利於使用者,減少使用者需要了解的東西,整合集群管理使得性能比其他方案都要更高,但是缺點是其會嚴重增加代碼復雜度,導致服務器端代碼爆炸。

3、而采用中間層代理的方式我認為是最優雅和有效的,在不改動服務器端程序的情況下,twemproxy使得集群管理更簡單,去除不支持的操作和合並,同時更可以支持多個后端服務,大大減少連接數等等,但是缺點也是顯而易見的,它不能更有效的利用集群的優勢,如多鍵運算和范圍查找操作等等,這都是需要服務器端程序本身支持。

 

Twemproxy 安裝

從源碼安裝:

git clone git@github.com:twitter/twemproxy.git
cd twemproxy
autoreconf -fvi
./configure --enable-debug=full
make
src/nutcracker -h

 

twemproxy命令行選項:

Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]
[-c conf file] [-s stats port] [-a stats addr]
[-i stats interval] [-p pid file] [-m mbuf size]

-h, –help : 查看幫助文檔,顯示命令選項
-V, –version : 查看nutcracker版本
-t, –test-conf : 測試配置腳本的正確性
-d, –daemonize : 以守護進程運行
-D, –describe-stats : 打印狀態描述
-v, –verbosity=N : 設置日志級別 (default: 5, min: 0, max: 11)
-o, –output=S : 設置日志輸出路徑,默認為標准錯誤輸出 (default: stderr)
-c, –conf-file=S : 指定配置文件路徑 (default: conf/nutcracker.yml)
-s, –stats-port=N : 設置狀態監控端口,默認22222 (default: 22222)
-a, –stats-addr=S : 設置狀態監控IP,默認0.0.0.0 (default: 0.0.0.0)
-i, –stats-interval=N : 設置狀態聚合間隔 (default: 30000 msec)
-p, –pid-file=S : 指定進程pid文件路徑,默認關閉 (default: off)
-m, –mbuf-size=N : 設置mbuf塊大小,默認64K,含義見下面的零拷貝

 

零拷貝(Zero Copy)
在twemproxy中,請求和響應都是分配到一塊叫mbuf的內存中的,接收請求的mbuf同時會用於轉發到backend,類似地,從backend接收響應的mbuf同時也會用於轉發到client,這樣做就避免了內存拷貝。
此外,mbuf使用內存池,一旦分配就不再釋放,當一個請求結束時,它所使用的mbuf會放回內存池。一個mbuf占16K,這個大小需要在I/O性能和連接並發數之間做取舍,mbuf尺寸越大,對socket的讀寫系統調用次數越少,但整個系統可支持的並發數也越小。如果希望支持更高的client並發請求數,可以把mbuf的尺寸設置小一點(通過-m選項)。

 

Twemproxy 配置

Twemproxy 通過YAML文件配置,例如:

alpha:
  listen: 127.0.0.1:22121
  hash: fnv1a_64
  distribution: ketama
  auto_eject_hosts: true
  redis: true
  server_retry_timeout: 2000
  server_failure_limit: 1
  servers:
   - 127.0.0.1:6379:1

beta:
  listen: 127.0.0.1:22122
  hash: fnv1a_64
  hash_tag: "{}"
  distribution: ketama
  auto_eject_hosts: false
  timeout: 400
  redis: true
  servers:
   - 127.0.0.1:6380:1 server1
   - 127.0.0.1:6381:1 server2
   - 127.0.0.1:6382:1 server3
   - 127.0.0.1:6383:1 server4

gamma:
  listen: 127.0.0.1:22123
  hash: fnv1a_64
  distribution: ketama
  timeout: 400
  backlog: 1024
  preconnect: true
  auto_eject_hosts: true
  server_retry_timeout: 2000
  server_failure_limit: 3
  servers:
   - 127.0.0.1:11212:1
   - 127.0.0.1:11213:1

delta:
  listen: 127.0.0.1:22124
  hash: fnv1a_64
  distribution: ketama
  timeout: 100
  auto_eject_hosts: true
  server_retry_timeout: 2000
  server_failure_limit: 1
  servers:
   - 127.0.0.1:11214:1
   - 127.0.0.1:11215:1
   - 127.0.0.1:11216:1
   - 127.0.0.1:11217:1
   - 127.0.0.1:11218:1
   - 127.0.0.1:11219:1
   - 127.0.0.1:11220:1
   - 127.0.0.1:11221:1
   - 127.0.0.1:11222:1
   - 127.0.0.1:11223:1

omega:
  listen: /tmp/gamma
  hash: hsieh
  distribution: ketama
  auto_eject_hosts: false
  servers:
   - 127.0.0.1:11214:100000
   - 127.0.0.1:11215:1

 

說明:

listen
twemproxy監聽地址,支持UNIX域套接字。

hash
可以選擇的key值的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

 

hash_tag
hash_tag允許根據key的一個部分來計算key的hash值。hash_tag由兩個字符組成,一個是hash_tag的開始,另外一個是hash_tag的結束,在hash_tag的開始和結束之間,是將用於計算key的hash值的部分,計算的結果會用於選擇服務器。

例如:如果hash_tag被定義為”{}”,那么key值為"user:{user1}:ids"和"user:{user1}:tweets"的hash值都是基於”user1”,最終會被映射到相同的服務器。而"user:user1:ids"將會使用整個key來計算hash,可能會被映射到不同的服務器。

 

distribution
存在ketama、modula和random3種可選的配置。其含義如下:

  • ketama,一致性hash算法,會根據服務器構造出一個hash ring,並為ring上的節點分配hash范圍。ketama的優勢在於單個節點添加、刪除之后,會最大程度上保持整個群集中緩存的key值可以被重用。
  • modula,根據key值的hash值取模,根據取模的結果選擇對應的服務器;
  • random,無論key值的hash是什么,都隨機的選擇一個服務器作為key值操作的目標;

timeout

單位是毫秒,是連接到server的超時值。默認是永久等待。

 

backlog
監聽TCP 的backlog(連接等待隊列)的長度,默認是512。

 

preconnect
是一個boolean值,指示twemproxy是否應該預連接pool中的server。默認是false。

 

redis
是一個boolean值,用來識別到服務器的通訊協議是redis還是memcached。默認是false。

 

server_connections
每個server可以被打開的連接數。默認,每個服務器開一個連接。

 

auto_eject_hosts
是一個boolean值,用於控制twemproxy是否應該根據server的連接狀態重建群集。這個連接狀態是由server_failure_limit閥值來控制。
默認是false。

 

server_retry_timeout
單位是毫秒,控制服務器連接的時間間隔,在auto_eject_host被設置為true的時候產生作用。默認是30000 毫秒。

 

server_failure_limit
控制連接服務器的次數,在auto_eject_host被設置為true的時候產生作用。默認是2。

 

servers
一個pool中的服務器的地址、端口和權重的列表,包括一個可選的服務器的名字,如果提供服務器的名字,將會使用它決定server的次序,從而提供對應的一致性hash的hash ring。否則,將使用server被定義的次序。

 

 

Twemproxy 監控

Twemproxy 監控端口默認為22222,並每隔30s收集一次信息。

nutcracker --describe-stats

報告的信息如下:

pool stats:
  client_eof          "# eof on client connections"
  client_err          "# errors on client connections"
  client_connections  "# active client connections"
  server_ejects       "# times backend server was ejected"
  forward_error       "# times we encountered a forwarding error"
  fragments           "# fragments created from a multi-vector request"

server stats:
  server_eof          "# eof on server connections"
  server_err          "# errors on server connections"
  server_timedout     "# timeouts on server connections"
  server_connections  "# active server connections"
  requests            "# requests"
  request_bytes       "total request bytes"
  responses           "# responses"
  response_bytes      "total response bytes"
  in_queue            "# requests in incoming queue"
  in_queue_bytes      "current request bytes in incoming queue"
  out_queue           "# requests in outgoing queue"
  out_queue_bytes     "current request bytes in outgoing queue"

 

 

Pipelining

Twemproxy 可以同時接收很多client端的請求,並僅通過一個或幾個連接回源,這種結構很適合使用流水線處理請求和響應,從而節省TCP往返時間。
例如,Twemproxy 正在同時代理3個client端的請求,分別是:'get key\r\n'、'set key 0 0 3\r\nval\r\n'和'delete key\r\n' ',Twemproxy 可以將這3個請求打包成一個消息發送給后端的redis: 'get key\r\nset key 0 0 3\r\nval\r\ndelete key\r\n'。

pipelining也是Twemproxy高性能的原因之一。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM