2016-03-31 97 views
1

在研究nhibernate提供的第二級緩存的可能性時,我測試了一些實現。目前的結果是非常意外的,我質疑我的期望是否錯誤。NHibernate SecondLevel緩存性能

  1. 方案(讀重)

在一個字符串屬性第4個* 20000簡單對象插入到數據庫中,然後四個線程由對象ID(session.Get<SimpleObj>(id))得到他們。每個線程只訪問它創建的ID。訪問模式是隨機的,並獲取1000個對象,然後重新創建會話。

while (true) 
{ 
    using (var session = sf.OpenSession()) 
    using (var tx = session.BeginTransaction()) 
    { 
     for (int i3 = 0; i3 < 1000; i3++) 
     { 
      long id = (long)ids[rnd.Next(19999)]; 
      var t = session.Get<SimpleObject>(id); 

      var no = t.StringProperty; 
     } 

     Interlocked.Add(ref ops, 1000); 

     tx.Commit(); 
    } 
} 

結果

  1. Redis的5000每秒
  2. 分佈式緩存8000讀出每秒讀取(EnyimMemcached)
  3. 沒有緩存15000每秒讀取(同機,TCP-IP)
  4. 無緩存每秒25000次讀取(相同機器,共享內存)
  5. SysCache2每秒200000次讀取
  6. HashtableCacheProvider 380000每使用

版本讀取(http://www.couchbase.com/

這些提供程序與SysCache2實現之間的性能不同嗎?

更新1

正如弗雷德裏克指出,測試場景並沒有什麼太大的意義是兩種不同類型的高速緩存架構有兩種不同的使用情況進行了比較。第一類(5 & 6)不能水平縮放,而1和2可以。目前SQL-Server運行在同一臺機器上,因此使用共享內存作爲IPC-Mechanism,因此我禁用了所有IPC Connection的可能性,並將其配置爲使用TCP/IP連接到數據庫。因此,no-cache-scenario的性能下降了大約10000 op/s,從而將分佈式緩存提供商的速度提高到一個合理的距離。

通過對緩存提供者的比較,我想測試這些提供者是否可以用於按請求會話的設置來緩存參考數據,如國家,貨幣或資產負債表結構。由於性能最好的分佈式緩存仍然只有普通NHibernate版本的一半,所以我不確定這是否可行。

+0

我已經更新我的答案,解決您的更新。請注意,這不是Stack Overflow的首選方式。通常,你應該提出一個新的問題,指出這個問題作爲參考。 –

回答

1

這也難怪有SysCache(2)(或RtMemoryCache如果你試試這個另一種太)進行比RedisMemCached非常好。前者是進程內存緩存,它們的使用不會導致任何網絡IO或任何進程間通信。本文是分佈式緩存,它們意味着至少進程間通信,並且在大多數情況下意味着網絡IO,這會導致較高的使用成本。

比較分佈式緩存性能和非分佈式緩存性能沒有任何意義。只有在需要在多個進程間共享緩存時,才應該使用分佈式緩存。如果你有這個要求,你將無法使用非分佈式緩存。

令人驚訝的是讓「無緩存」場景(比如SQL查詢)的執行性能比分佈式緩存更好。

在我看來,測試描述中缺少一個關鍵點:在您的方案中,什麼會推動SQL查詢的性能成本?如果數據庫服務器託管在與Web服務器相同的物理主機上,則與更常用的設置相比,該數據成本相當低。像SQL服務器這樣的一些數據庫解決方案甚至可能會跳過任何網絡IO,並在與Web服務器相同的主機上託管時,通過命名管道進行內存通信中的進程間進程。

備註:如果您不考慮將SysCache2配置爲通過SQL Server數據更改通知獲取失效,則應該測試SysCache,而不是更輕。 (這可能不會真正改變你的測試場景結果雖然)。

尋址更新1:

的第一個點是要確保你真正需要你的緩存中進行分配。每個進程可以安全地有自己的緩存,如果:

  1. 緩存的數據是隻讀的(或最終,如果有服務於舊的緩存數據的一些過程不會在你的應用情況下會引起麻煩)。
  2. 這不會導致太多的內存消耗。 (緩存數據不重,複製它的許多過程中不會是一個問題。)

當然,數據緩存熱身將是與非分佈式緩存速度較慢,但​​如果分佈式緩存進行太差,這不是重點。

如果您需要將其分發,則應評估您的SQL Server是否是負載下的瓶頸。如果在加載情況下,SQL Server可能成爲應用程序的瓶頸,那麼分佈式緩存將有助於卸載它。否則,最好不要使用它們,如果在你的設置中,分佈式緩存的性能一直比你的數據庫服務器差。注意:如果只滿足條件(2),您也可以嘗試使用SQL Server通知失效的非分佈式緩存,這樣可以避免陳舊的數據。請參閱how to configure SysCache2以獲取SQL Server的通知。

1

弗雷德裏克已經寫道,你測試了兩種完全不同類型的緩存,所以我不打算再重複一遍。但我會加上NH如何存儲工作的一些信息,並回答弗雷德裏克的評論:

令人驚訝的是有「無緩存」的情況(這樣,SQL 查詢)進行比分佈式緩存非常好。

其實,有沒有驚喜:)你需要記住的是:

  1. NHibernate的嘗試播放安全與高速緩存和模擬每個緩存的實體「交易」。根據實現的不同,分佈式(NHibernate)緩存可以向緩存服務器發送兩個附加請求(鎖定和釋放實體),導致嚴重的性能下降。不同的緩存使用不同的串行器。例如,Redis緩存使用內置的.NET XML序列化程序,它不以其速度着稱;)
  2. 取決於配置的過期策略,如果使用分佈式緩存,則可能會有額外的性能下降。 ,Redis)會因爲資源壓力而導致嚴重的性能問題(在這種情況下,NH將訪問緩存服務器,導致緩存未命中,然後嘗試從數據庫中檢索實體=> 2x網絡調用)

另外我必須說,你的測試不是很有代表性。運行這些性能測試之前,您需要

  • 檢查有多少個實體將被保存在緩存中
  • 多少「放」與「變」你必須爲這些實體
  • 多少你有鏈接的集合緩存的實體
  • 多少項目都存儲在鏈接的集合平均
  • 做什麼樣的實體,您有(只讀,主要是不可改變或全部是可更新的?)

,當然,您不是僞數據組數據運行測試;)