ServiceStack.Redis的問題與修正
Redis是開源、高性能的Key-value存儲引擎。
最近我們在一個日訪問量約1kw的網(wǎng)站上使用redis替換以前的memcache,成功將CPU從30%下降到15%,效果相當(dāng)顯著。

ServiceStackRedis是***的C#驅(qū)動之一。關(guān)于如何使用ServiceStackRedis請參見這里——使用ServiceStackRedis鏈接Redis簡介
不過我們在使用ServiceStackRedis的線程池(PooledRedisClientManager)還是碰到了不少問題。
1 鏈接數(shù)異常。
一個webserver會占用80個鏈接。當(dāng)15臺webserver就過千了,這時會出現(xiàn)有些客戶端鏈接不上的情況。
解決方案:
GetInActiveWriteClient方法中
- //找下一個目標(biāo)
- //從當(dāng)前讀寫指針的后面開始查找,而不是從0開始
- var nextIndex = (WritePoolIndex + i) % writeClients.Length;
- 更改為
- var nextIndex = i;
同時修改DisposeClient方法中將readClient.Active == false將DisposeConnection一下。線程就能很好的回收了。
效果:
在我們這樣一個網(wǎng)站下,單臺webserver大約會占用10個~15個鏈接,比之前的80個少了不少。
分析:
從代碼上來看,作者的初衷是為了更快的找到空閑的線程,但是卻認(rèn)所有線程都不間斷的使用,沒有一個線程可能空閑。如果站點較小,webserver不太多,不改問題也不大。不過我認(rèn)為用長鏈接并不劃算,因為與redis建立一個鏈接還是相對比較“便宜”的。
2 多臺redis存儲相同的內(nèi)容。
相同的內(nèi)容會冗余在所有redis中
解決方案
在GetInActiveWriteClient中加入int型參數(shù)來標(biāo)識出使用那臺redis
- var start = 0;
- var step = 1;
- if (index > -1 && index < ReadWriteHosts.Count)
- {
- start = index;
- step = ReadWriteHosts.Count;
- }
- //遍歷讀寫池
- //這個時候池是鎖定的
- for (var i = start; i < writeClients.Length; i += step)
- {
- 省略
這樣線程池中就會按ReadWriteHosts的個數(shù)來順序分配。
效果:
在進(jìn)行讀寫時只需要使用key.GetHashCode方法獲得一個hash值就能準(zhǔn)確分配到其中一臺redis上。保證所有的redis的數(shù)據(jù)不重復(fù)。
原文鏈接:http://www.cnblogs.com/goodspeed/archive/2011/07/26/servicestack_redis_optimize.html
【編輯推薦】































