2013-05-30 152 views
15

我們正在運行一個web應用程序,並從memcached切換到redis(2.4)進行緩存。現在我們對redis性能有些失望。 Redis在同一臺服務器上運行,我們只使用非常簡單的GET和SET操作。在一些大量使用緩存值的請求中,我們最多有300個GET請求用於重新發送,但這些請求最多需要150ms。我們有大約200,000個活動密鑰,每秒約有1000個redis請求。磁盤io,ram或cpu沒有問題。由於我們現有的代碼,我們不能簡單地將redis請求分組在一起。 Memcached的速度快了4倍。 我們喜歡redis的是,我們不需要任何緩存升溫,並且將來可以使用更高級的數據存儲功能。我們預計redis的表現類似於memcached。所以也許我們錯過了我們的配置,這基本上是默認配置。Redis性能調優

你知道redis性能調優的最佳做法嗎?

+0

Redis正在運行在與服務器相同的服務器上?客戶端,還是運行memcached的客戶端?對於Redis請求,150毫秒聽起來像是在觸及交換/磁盤,而不是內存,或者對於所有300個請求,你的意思是150毫秒? –

+0

這是一個每秒約有100個Apache請求的Web應用程序。 Redis與Web應用程序本身和mysql數據庫服務器運行在同一主機上,但我們計劃很快將apache移動到3個負載均衡服務器。目前的服務器有大約64GB的RAM,Redis大約需要100MB。有足夠的免費ram和cpu或io沒有問題。服務器不交換到磁盤。是的,我的意思是150ms的300個請求,但memcached在相同的條件下只用了40ms。 – ak2

+1

我唯一能想到的是,如果您針對所有請求使用與Redis的共享連接,而不是每個Web請求使用一個共享連接,那麼Redis可能存在延遲問題,但在每秒1000次請求時,您不應該看到那麼嚴重的延遲。對不起,今天我的方向沒有任何真正的幫助:) –

回答

21

首先,您可能需要閱讀the Redis benchmark page。它提供了檢查Redis的要點的一個很好的總結。

即使假設您不使用流水線,150 ms中的300個GET也沒有那麼高效。這意味着平均等待時間是500 us。但是,它實際上取決於您的對象的大小。更大的對象,更多的延遲。在我非常老的2 GHz AMD盒子上,我可以測量150個小物體(幾個字節)的延遲。

要快速檢查Redis的實例的平均等待時間,你可以使用:

$ redis-cli --latency 

一定要使用最近Redis的版本(不是2.4),以獲得該選項。 注意:2.4現在已經很老了,使用Redis 2.6 - 如果需要編譯你自己的Redis版本,它非常簡單。

要快速運行的基準,研究延遲,你可以啓動:

$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes 

它運行了一個獨特的連接並沒有流水線,所以延遲可以從吞吐量推斷。嘗試將這些基準的結果與您的應用程序測得的數據進行比較。

有一些點你可能要檢查:

  • 哪個Redis的客戶端庫您使用?用哪種開發語言?對於某些腳本語言,您需要安裝hiredis模塊以獲得高效的客戶端。
  • 您的機器是VM嗎?在哪個操作系統?
  • 與Redis的連接是否持久? (即,您不應該在您的應用服務器的每個HTTP請求上連接/斷開連接)。

爲什麼使用memcached更好?那麼,單個memcached實例當然更具可擴展性,並且可能比單個Redis實例更具響應能力,因爲它可以在多個線程上運行。 Redis速度很快,但是單線程 - 所有命令的執行都是序列化的。因此,當命令正在進行連接時,所有其他客戶端都必須等待 - 給定命令上的延遲時間也會影響所有未決命令。一般來說,在低吞吐量下,性能是可比的。在1000 q/s(Redis或memcached標準的低吞吐量)下,我認爲你的問題更可能發生在客戶端(即,客戶端庫的選擇,連接/斷開連接等),而不是Redis服務器本身。

最後我應該提到,如果您爲每個HTTP請求生成多個Redis查詢,請儘可能考慮您發送給Redis的命令pipelining。這是開發高效Redis應用程序的關鍵。

如果您的應用程序服務器與Redis位於同一個框中,則還可以使用unix域套接字而不是TCP環回來連接到Redis。它稍微提高了性能(不使用流水線時,吞吐量提高了50%)。

+0

「所有命令的執行都是序列化的」:你會在這個聲明中提供更多細節嗎?對我來說,聽起來好像你在說一個命令不運行其他命令,即使在其他連接上也可以運行。是redis如何實現命令原子性? – akonsu

+0

是的。請參閱http://stackoverflow.com/questions/10489298/redis-is-single-threaded-then-how-does-it-do-concurrent-io/10495458#10495458 –

+0

另請參閱http://redis.io/topics /潛伏 –

0

檢查redis是否使用OS交換內存。如果那樣會增加延遲。 爲了找到答案,搜索「延遲通過交換誘導」在這裏:http://redis.io/topics/latency

如果您的服務器硬件NUMA能力,更好地啓動Redis的服務器與numactl的。 如果您使用帶有NUMA的redis服務器啓動,請不要忘記在sysctl中關閉區域回收模式(vm.zone_reclaim_mode = 0)。

0

嘗試在Lua腳本中腳本執行300 GET請求。它應該工作得更快,因爲即使您的客戶端代碼在本地運行到Redis,您也可以節省TCP/IP協議棧的時間。