2011-02-04 66 views
0

我正在設計一個數據緩存系統,每次可以保存大量的記錄,而且我需要知道要使用哪個stl容器以及如何使用它。該應用程序是我有一個非常大的數據庫記錄的用戶 - 當他們登錄到我的系統我想拉他們的記錄和緩存一些數據,如用戶名和幾個重要的屬性。當他們與系統交互時,我更新並訪問他們的屬性。有幾個屬性非常不穩定,我這樣做是爲了避免在多數事務處理中對數據庫進行「撞擊」。此外,我很少需要使用數據庫進行排序或任何東西 - 我使用它就像一個榮耀的二進制保存文件(這就是爲什麼我很高興將記錄緩存到內存..);對我來說更重要的目標是能夠擴展到大量的用戶。從MySQL DB緩存數據 - 技術和適當的STL容器?

當用戶註銷時,服務器會以循環方式週期性地關閉或(以防萬一..),我想將它們的數據寫回數據庫。

服務器保留它自己:

vector <UserData *> loggedInUsers; 

用的UserData保管之類的用戶名(字符串)和其他屬性從數據庫,以及像網絡處理其他臨時數據。

我的第一個Q是,如果我需要找到這個載體的特定用戶,有什麼最快辦法做到這一點,是有不同的STL容器,我可以用它來做到這一點更快?我現在所做的是創建一個迭代器,在loggedInUsers.begin()處啓動它並遍歷到.end(),檢查* iter-> username ==「foo」,並在找到它時返回。如果用戶名在矢量的末尾,或者矢量有5000個用戶,這是一個很大的延遲。

我的第二個問題是,我該如何循環調度這些數據才能寫回數據庫?每次我準備向DB寫入幾條記錄時,我都可以調用一個函數。但是我不能持有向量的迭代器,因爲它會變成無效的。我想要做的是有一個旋轉隊列,我可以訪問隊列的頭部,將其保存到數據庫中,然後將其旋轉到隊列的末尾。這似乎是一個很大的開銷..我可以用什麼類型來做得更好?

我的第三個問題是,我正在使用MySQL服務器和libmysqlclient連接器/ C ..是否有任何內置的緩存可以解決這個問題「免費」,或者是否有不同的技術?我打開的建議

回答

1

A1。你最好用一張地圖,這是一棵能爲你查找的樹。用map和(假設你有合適的編譯器)或者hash_map(它做同樣的事情,但查找機制不同)測試。它們對於不同類型的數據存儲工作負載具有不同的性能特徵。

A2。列表可能會更好 - 推到前面,拉下結束。 (也可以使用deque,但如果從中刪除迭代器,則可以使用列表)。 push_back和pop_front(反之亦然)將允許您保持緩存數據的滾動隊列。

A3。您可以嘗試SQLite,它是一個爲簡單的應用程序級數據庫存儲需求而設計的小型數據庫。它也可以工作entirely in-memory

+0

A1:謝謝。 A2:拉/推的性能如何,每個操作都會假設我正在丟棄/添加全新的元素?是否有任何數據結構只是「旋轉」? A3:多個應用可以擊中數據庫。更大的後續問題:A1和A2我想合併成一件事,以便我可以將所有這些數據保存在地圖中,並通過它旋轉以將更新保留回數據庫..我該如何實現這一目標? – Nektarios 2011-02-04 17:31:37

1

你不說你的系統做,或者它如何被訪問的,但這種技術可能不會很好地擴展(因爲最終你會耗盡內存,無論您使用查找信息不會像數據庫那樣高效),並且不一定會正確處理併發用戶,除非您確保數據可以在它們之間正確共享。

這就是說..你可能會更好使用地圖(http://www.cplusplus.com/reference/stl/map/)與用戶名的關鍵。

就寫回到數據庫而言,爲什麼不存儲一個單獨的結構(隊列),每次將其寫入數據庫時​​都可以清除它們?只要你存儲指針,它就不會使用更多的內存。這使我去..而不是使用指針,你應該看看智能指針(例如boost's shared_ptr),讓你通過它們而不必擔心所有權。

+0

謝謝,很好的建議,你說得對,我可以更好地定義我的應用程序。我的數據很小,可以說絕對最大64bytes。這意味着在1GB內存中,我有大約1600萬用戶在內存中,所以這沒有問題(我將首先用完網絡套接字描述符)。我喜歡你的想法,只是拿着指針,看看你的意思與shared_ptr幫助 – Nektarios 2011-02-04 17:34:35