2017-08-07 137 views
1

快速背景:當我回去重新設計應用程序的某些關鍵部分時,我一直在考慮鎖定及其對性能的影響。該應用程序有一個大型的Tree風格的數據結構,可以緩存數據庫中的數據/ DTO。對大樹的更新可以通過兩種主要方式實現:1.用戶觸發的命令,2.自動更新來自在後臺運行的作業。鎖定性能:鎖定更長時間與鎖定更經常

當任何操作類型發生(用戶/自動)時,我鎖定(顯式鎖定)數據結構。我遇到了一致性問題,因此鎖定一切似乎最能保護緩存中數據的完整性。

問:由於許多自動更新可以發生在一次我想實現某種隊列(JMS或許)來處理的數據結構,其中的任何用戶驅動的更新推送到頂部和處理的第一個指令。當談到處理批量/未知大小的自動「任務」集時,我試圖弄清楚我是否應該讓它們單獨運行和鎖定,或者嘗試按時間將它們集中在一起,並與鎖定進行一次交互。問題的真正癥結在於任何更新的任務都可能影響整個樹。

就整體性能而言(通常,沒有特定的),是否有更多的事務鎖定潛在的大型更新,或嘗試並結合到一個大規模批量更新,只鎖定一次,但更長的時間?我知道很多這可能取決於數據,更新類型,頻率等。我不知道是否存在「更小更頻繁的鎖」或「更大的可能更長的鎖」的一般經驗法則。

+0

是的。嗯。也許沒有。也許也許吧。好,嚴重:我認爲你的問題太廣泛了。 – GhostCat

+0

@GhostCat我有一個暗示它可能有點太寬泛。你能想出一些我可能縮小一點的方法嗎?如果它是def,我就沒有問題了。太寬泛。 – Walls

+0

什麼是緩存策略?物體是否比所需要的時間更長,增加了樹的大小並影響了性能? –

回答

1

我認爲答案取決於您的程序是否在解鎖數據結構上花費了大量時間。如果沒有,我建議爲所有未決更新鎖定一次。

原因是,當更新線程再次快速鎖定資源時,可能正在等待鎖定的其他線程可能會被喚醒,然後無用地發送回睡眠狀態。或者更新被另一個可能不利於緩存利用率的線程中斷。此外,與更新相比,鎖定成本可能很小:管道可能需要刷新,內存訪問可能不會自由重新排序等。

如果線程在更新之間花費了一些時間而無需鎖定數據結構,如果預計其他線程可以完成它們之間的事務並因此減少爭用,我會考慮重新鎖定每個更新。

請注意,當針對不同的更新有不同的優先級時,例如我認爲用戶更新與後臺更新不同時,如果可以在較低優先級的更新中鎖定數據結構很長時間任何方式阻止運行更高優先級的任務。

1

如果你最終實現某種類型的隊列,那麼你將失去所有的併發性。如果您一次收到1000個請求,請考慮一下效率如何。

試着看看這段併發樹的代碼。 https://github.com/npgall/concurrent-trees

+0

允許更少的併發活動連接將在大多數情況下提高整體性能。當然,它總是取決於。 https://stackoverflow.com/questions/1208077/optimal-number-of-connections-in-connection-pool – daniu

+0

問題是數據本身將會在除緩存樹之外的全局事務中觸及數據庫。一個簡單的併發數據結構不會增加事務性的好處。 – Walls