StackExchange.Redis性能调优
編者:.net core redis 驅(qū)動推薦,為什么不使用 StackExchange.Redis?引起了很大的反響,大家反應(yīng)過度,其實StackExchange.Redis 2.0已經(jīng)從重構(gòu)了異步隊列,使用管道方式解決異步慢的問題。這篇文章也可以幫助大家正確認(rèn)識這個性能問題
大家經(jīng)常出現(xiàn)同步調(diào)用Redis超時的問題,但改成異步之后發(fā)現(xiàn)錯誤非常少了,但卻可能通過前后記日志之類的發(fā)現(xiàn)Redis命令非常慢。
PS: 以后代碼都在Windows bash中運行,StackExchange.Redis版本為1.2.6
? ?先快速重現(xiàn)問題和解決問題,大家先運行下面的代碼
?運行發(fā)現(xiàn)拋出StackExchange.Redis.RedisTimeoutException,為什么呢?是因為當(dāng)前工作線程根本不夠用,同步等待時已經(jīng)超時。具體請看源代碼
? ? 如果將上面的ThreadPool.SetMinThreads(8, 8)改成ThreadPool.SetMinThreads(100, 100)呢?是不是不拋異常了呢。
?
? ? 再說異步接口變慢的問題,大家先運行下面的代碼:
?最終輸出結(jié)果發(fā)現(xiàn)Run1和Main2是使用相同的線程吧,而Run2的ElapsedMilliseconds基本上就是在Run1的基礎(chǔ)上加100。
? ? 然后再回到調(diào)用Redis代碼上
?你們發(fā)現(xiàn)輸出是100多還是1000多?為什么?原來是因為sdk中有一個特殊的設(shè)置,要保護異步代碼執(zhí)行的順序,然后我們在GetDatabase行之前加一個代碼connection.PreserveAsyncOrder = false;
? ? 然后再運行一次看看結(jié)果是多少呢?通過上面再做代碼基本上可以確定異步慢是和TaskCompletionSource和關(guān)系的,具體請看sdk的源代碼。
?
? ? 總結(jié)上面兩點,簡單得通過SetMinThreads和connection.PreserveAsyncOrder = false可以解決絕大部分問題,但更多其他深層次的問題怎么發(fā)現(xiàn)呢?
?
? ? 下面就要介紹StackExchange.Redis兩個神器ConnectionCounters和IProfiler?
通過connection.GetCounters().Interactive獲得的對象之后其中有三個屬性非常有用
每個屬性表示當(dāng)前redis連接的待完成的命令當(dāng)前所處的狀態(tài)。通過字面意思就可以知道PendingUnsentItems表示已經(jīng)進行待發(fā)送隊列還未發(fā)送出去的命令;SentItemsAwaitingResponse表示已經(jīng)發(fā)送出去但還沒有收到響應(yīng)結(jié)果的命令;ResponsesAwaitingAsyncCompletion則表示已經(jīng)收到響應(yīng)的命令,但還沒有調(diào)用TaskCompletionSource<T>().TrySetResult()的命令。
其中PendingUnsentItems和SentItemsAwaitingResponse過大的原因基本上是因為網(wǎng)絡(luò)阻塞了,你需要檢查一下網(wǎng)絡(luò)帶寬或者redis的value是否很大。
ResponsesAwaitingAsyncCompletion則是因為await之后的代碼,如上面示例中的代碼,線程占用了很長的同步時間,需要優(yōu)化代碼和將PreserveAsyncOrder設(shè)置為false。
ConnectionCounters分析的是一個線程的瞬時狀態(tài),而IProfiler則可以跟蹤一個請求總共執(zhí)行了多少的redis命令以及他們分別使用了多長時間,具體細節(jié)請大家寫代碼體驗。參考文檔
?
? ? 發(fā)現(xiàn)問題就需要解決問題,也就需要深層次得去學(xué)習(xí)才能解決問題。我不喜歡寫文章,但發(fā)現(xiàn)最近有好幾篇說redis超時的問題,最終我還是想把自己的踩坑的心得分享給大家。
? ? 這在里說一個好消息,那就是StackExchange.Redis 2.0已經(jīng)從重構(gòu)了異步隊列,使用管道方式解決異步慢的問題
原文地址:https://www.cnblogs.com/qhca/p/9347604.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的StackExchange.Redis性能调优的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实体类的动态生成(二)
- 下一篇: 通过 Docker Compose 组合