一次Redis client组件性能分析
??????? BeetleX也擴展了RedisClient驅動,寫這些高并發應用的驅動性能測試分析是必不可少的。在最近一次測試中發現測試采樣度不足,引起的一些問題;通過這一次的問題也警醒一下自己在以后設計上要考慮更多細節的特性需求。
發現問題
????????在寫組件的時候往往會拿同樣的組件產品做一些簡單的測試性能對象,最近也拿BeetleX.Redis組件和其他組件做了一下性能測試,經過兩次測試環境的采樣發現的結果差異還是很大的,如下是兩個環境的測試結果:
4核環境
20核環境
從兩個測試環境的結果來看StackExchange.Redis由原來并發數量最差,到后面領先了50%。
問題所在
????????這問題分析很久,包括用Redis-cli來測發現該實例的Redis極限只能達到10RPS,但測試結果來看StackExchange.Redis已遠超過Redis自身的交互吞吐量了。經過查看代碼和相關文檔才發現StackExchange.Redis的async默認即支持Redis的pipeline特性,并完美支持多線程環境操作。
????????以代碼上來看StackExchange.Redis為了讓組件默認支持這特性讓Redis吞吐量最大化,所以在設計上也變得非常復雜和更多異步切換處理;這樣引起了代碼處理量比較多性能有些損耗。所以在StackExchange.Redis在配置低的情況達不到Redis滿負載時浪費比較多的CPU資源性能相對就變得差了。
????????當StackExchange.Redis運行在資源比較多的服務器上時,高壓下輕易壓爆了Redis的交互IO量時那pipeline特性就可以在IO量不變的情況下更一步提高吞吐量。這是沒有默認實現pipeline的組件所能比的。
總結
????????在這里不得不佩服StackExchange.Redis設計者的思路,在Client資源充足的情況把Redis的吞吐最大化發揮到極致。當然這種設計也是針對性的,他是利用Redis的特性和大量的CPU來提高Redis的吞量能力。對于沒有默認支持pipeline只能跑到Redis交互的上限,受Redis的限制對應Client所使用的CPU自然也就無法上去來提高吞吐。
??????? StackExchange.Redis在20線程下可以跑到30%的CPU,其他則只能跑到15%. StackExchange.Redis的這種設計缺點就是Client資源比較低的情況下性能就相對來說差一些。
????????所以性能好壞還真的很難通過一些簡單的采樣就能得出個合理的結果,關注性能更多應該關注代碼是否能更好地發揮相關資源的作用。很多時候測試方式都受制定者的主觀因素影響。如果沒有這次測試我還真自認為BeetleX.Redis設計很不錯。
StackExchange.Redis超時問題
????????用過StackExchange.Redis的朋友相信一定碰到Timeout的問題...,其實這個和StackExchange.Redis設計有些關系,最直接的辦法是加大線程池和超時時間配置。對于CPU硬件資源少的還是加大超時時間比較好。主要原因是pipeline方式下意味著同時多個指令處理,但當前會話awaiter receive線程就一個最后會觸發多個響應,如果響應的消息后面有邏輯處理那自然會影響后面消息處理。
void IResultBox.ActivateContinuations() {if ((Task.CreationOptions & TaskCreationOptions.RunContinuationsAsynchronously) == 0)ThreadPool.UnsafeQueueUserWorkItem(s_ActivateContinuations, this);elseActivateContinuationsImpl(); }從最終代碼來看,ActivateContinuationsImpl則由當前awaiter receive線程觸發,串行得太多后面的消息處理不及時就會引起超時。
ConnectionMultiplexer會每秒探測還在隊列中等待響應的命令,如果有超時直接就觸發對應命令的timeout(由于全局性的pipeline處理非常復雜也有可能 是處理過程存在一些問題,可以嘗試用同步指令,從測試結果來看同步指令沒用pipeline).
總結
以上是生活随笔為你收集整理的一次Redis client组件性能分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Async和Await异步编程的原理
- 下一篇: 联机分析的列式数据库 clickHous