基于緩沖區的異步更新的方法
【專利摘要】本發明公開了一種基于緩沖區的異步更新的方法,包括:提交更新請求;判斷隊列是否為空;如果所述隊列不為空,則取出隊列元素,以準備處理所述更新請求;計算出最新的更新閾值;將所述更新請求更新到本地;檢查所述更新是否觸發了更新策略;以及如果觸發了所述更新策略,則更新分布式緩存或者數據庫。
【專利說明】基于緩沖區的異步更新的方法
【技術領域】
[0001]本發明涉及數據的更新,更具體地,本發明涉及基于緩沖區的異步更新的方法。
【背景技術】
[0002]如果想將某個值更新到分布式緩存服務器或者數據庫中,只能直接更新數據庫或者分布式緩存。然而,因為代碼通常被部署在多臺服務器上,每臺服務器上又有多個程序實例運行,所以同一時間很有可能會有兩個或者兩個以上的更新請求到達分布式緩存或者數據庫。
[0003]特別對于更新某個數值的情況。圖1示出了現有技術中更新某個數值的示意圖。如圖1所示,例如:分布式緩存中有數據A,值為1,有兩個(或者兩個以上)程序實例希望將A的值+1 (每個實例更新一次,理想的更新結果應該為3),程序實例同一時刻從分布式緩存中獲取A的值為1,并且在程序實例本地更新為2,同一時刻將請求發送到分布式緩存中,執行更新操作(將1更新為2)。這時,雖然有兩個程序實例發出了更新請求,但更新的結果卻是2,而不是3,從而很容易產生臟寫。其根本原因是兩個程序實例都以為只有自己在更新這個值,因為都是在1的基礎上+1,等到期待更新結果為2,并在同一時刻更新。
[0004]可以看出,更新越頻繁的場景,產生臟寫的頻率越高(因為同一時刻發出更新請求的幾率越高)。而且,整個獲取、更新操作是同步執行的,這意味著每次更新都要至少和分布式緩存交互三次才能更新值。另外,在交互過程中,執行的線程只能等待,降低了線程的處理效率。
[0005]因此,需要一種能夠克服以上問題的基于緩沖區的異步更新的方法。
【發明內容】
[0006]針對現有處理方法的以下問題:每次更新都要等待更新結果,線程才能繼續執行;針對更新頻繁的場景,不僅對分布式緩存或者數據庫產生很大的壓力,并且產生臟寫的幾率越高,本發明提出了一種異步的、對使用者透明的更新分布式緩存或數據庫的方法,以便提高發出更新請求線程的執行效率以及在高并發場景下對數據庫可用性的提升。
[0007]根據本發明的一個實施例,提供了一種基于緩沖區的異步更新的方法,包括:提交更新請求;判斷隊列是否為空;如果所述隊列不為空,則取出隊列元素,以準備處理所述更新請求;計算出最新的更新閾值;將所述更新請求更新到本地;檢查所述更新是否觸發了更新策略;以及如果觸發了所述更新策略,則更新分布式緩存或者數據庫。
[0008]優選地,所述提交更新請求的步驟進一步包括:通過所述更新請求中的密鑰計算出散列碼的值;通過用所述散列碼與處理線程的個數取模,計算出偏移量,以找到相應的處理線程;以及將所述更新請求封裝后放入所述相應的處理線程的處理隊列中,以供線程獲取。
[0009]優選地,將所述更新請求封裝后放入所述相應的處理線程的處理隊列中的步驟進一步包括:將同一類型的所述更新請求指向同一個處理線程,并放入同一個處理隊列。
[0010]優選地,如果所述隊列為空,則當前線程沉睡,等待提交更新請求的線程放入更新請求后恢復執行。
[0011]優選地,所述計算出最新的更新閾值的步驟進一步包括:每次更新請求計算前設定保護閥值,獲取當前線程處理隊列的大小,a)如果當前線程處理隊列的大小小于保護閥值,則將當前更新請求的更新閥值設置為所述保護閥值山)如果當前線程處理隊列的大小大于保護閥值,則直接采用當前隊列的大小作為當前的更新閥值。
[0012]優選地,觸發更新策略包括更新次數達到所述最新的更新閥值、或者本次更新在更新周期內。
[0013]本發明判斷請求由哪個線程計算的方式,實現了每個更新請求被固定線程處理,從而線程處理更新時,不需要任何加鎖,有很好的執行效率。而且本發明對更新請求提出了一種異步更新的方式,提高更新效率的同時,起到了緩沖區的作用,在突然大量請求達到時對分布式緩存或者數據庫有保護作用。
[0014]根據本公開和附圖的下面的詳細描述,對本領域的普通技術人員來說其它的目的、特征、以及優點將是顯而易見的。
【專利附圖】
【附圖說明】
[0015]附圖圖示了本發明的實施例,并與說明書一起用于解釋本發明的原理。在附圖中:
[0016]圖1示出了現有技術中更新某個數值的示意圖。
[0017]圖2是根據本發明的實施例的用于提交更新請求的線程的示意圖。
[0018]圖3是根據本發明的實施例的更新緩沖區的內存結構示意圖。
[0019]圖4是根據本發明的實施例的基于緩沖區的異步更新的方法的流程圖。
【具體實施方式】
[0020]根據本發明的實施例公開了一種基于緩沖區的異步更新的方法。在以下描述中,為了說明的目的,闡述了多個具體細節以提供對本發明的實施例的全面理解。然而,對于本領域人員顯而易見的是,本發明的實施例可以在沒有這些具體細節的情況下實現。
[0021]如在此所使用的“線程池”是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創建線程后自動啟動這些任務。線程池線程都是后臺線程。每個線程都使用默認的堆棧大小,以默認的優先級運行,并處于多線程單元中。在Java中常使用線程池在多線程環境下執行任務,用于處理多個文件的讀寫,分析等功能。
[0022]如在此所使用的“鎖”是在多線程環境下一個常用的工具類,用于在代碼塊間做同步操作,保證在鎖覆蓋的范圍內,代碼的串行執行,常用于解決并發問題。
[0023]如在此所使用的“線程”指的是Java中的線程,它是執行代碼的最小單元。通常在線程池的統一管理下,執行各類代碼。
[0024]如在此使用的“分布式存儲系統”是指將數據分散存儲在多臺獨立的設備上。傳統的網絡存儲系統采用集中的存儲服務器存放所有數據,存儲服務器成為系統性能的瓶頸,也是可靠性和安全性的焦點,不能滿足大規模存儲應用的需要。分布式網絡存儲系統采用可擴展的系統結構,利用多臺存儲服務器分擔存儲負荷,利用位置服務器定位存儲信息,它不但提高了系統的可靠性、可用性和存取效率,還易于擴展。
[0025]根據本發明解決其技術問題所采用的技術方案,在接受更新請求時僅將更新結果緩存在程序本地,當更新次數達到用戶設定的閥值或者周期性的間隔某個時間段后再向分布式緩存或者數據庫中發出更新請求,以便實現更新請求在程序本地的緩沖,減少分布式緩存或者數據庫的服務壓力,同時減少向分布式緩存或者數據庫發送的請求量。同時,在使用更新閥值這種更新策略時,根據更新的頻繁程度,動態的調整更新閥值,以實現在應對突然到來的大量更新請求時,起到請求在程序本地緩沖的作用,以減少對分布式緩存或者數據庫的壓力。
[0026]值得注意的是,本發明提供了一種非常好的解決方案并提供了一些默認實現方式,并且有很好的擴展性,除了默認的執行方式,還提供了觸發策略和持久化策略的接口供使用者自行實現“什么時候觸發更新”,“更新到分布式緩存中還是數據庫中”,有很強的靈活性。
[0027]圖2是根據本發明的實施例的用于提交更新請求的線程的示意圖。如圖2所示,對于提交更新請求的線程,具體實現步驟如下:
[0028]1.當有更新請求產生時,調用本發明的更新接口,提交更新請求;
[0029]2.本發明通過更新請求中的密鑰(key),計算出散列碼(hashcode)的值,并用hashcode與處理線程的個數取摸,計算出偏移量,從而找到相應的處理線程;
[0030]3.將更新請求封裝后放到處理線程的處理隊列中,供線程獲取。
[0031]hashcode是jdk根據對象的地址或者字符串或者數字算出來的int類型的數值。取模(Mod)運算的含義為求余。例如llMod 2,值為1,并且任何數與2取模,結果只可能為0或者1,即求余數的結果只能為小于被余數到大于等于0之間的整數。
[0032]根據本發明的實施例,通過hashcode與處理線程數取模的計算使得某個線程只處理一定數量的更新請求,并且因為每次更新請求的key值不變,hashcode就不會變,余數也不會變,從而每次該key的更新請求都有固定的線程處理,這樣的好處是更新次數統計,本次緩存初始化時都不需要加鎖同步執行,在高并發下,合理利用多線程分散處理更新請求,并且因為不需要加鎖的關系,提高了處理效率。
[0033]圖3是根據本發明的實施例的更新緩沖區的內存結構示意圖。如圖3所示,線程與請求隊列一一對應。圖3內容結構的特點在于將更新請求通過本發明的Hash算法分配到了不同的請求隊列上,借用隊列做到了請求的異步更新(更新請求只要將請求提交到請求隊列就完成了更新操作)。而現有的技術通常是直接將更新請求發送給數據庫或者分布式緩存,等待數據庫或者分布式緩存更新成功后,才算完成了更新操作。現有做法最明顯的缺點在于:1.更新請求要等待數據庫或者分布式緩存更新成功才算完畢,更新較耗時;2.每次更新請求到來都需要更新到數據庫或者分布式緩存,對數據庫或者分布式緩存有較大的請求壓力,而本發明因為是異步合并更新請求后更新,所以上述兩個缺點均不存在。
[0034]圖4是根據本發明的實施例的基于緩沖區的異步更新的方法的流程圖。具體地,對于處理線程:具體實現步驟如下:
[0035]1.判斷隊列是否為空,若為空,則當前線程沉睡,等待提交更新請求的線程放入更新請求后恢復執行。若不為空,則進行第二步;
[0036]2.取出隊列元素,準備處理更新請求;
[0037]3.計算出最新的更新閥值;
[0038]4.將更新請求更新到本地;
[0039]5.檢查本次更新是否觸發了更新策略;如果滿足更新條件,則執行第六步,否則,返回到第一步,繼續獲取更新請求處理;
[0040]6.將本地最新的更新結果更新到分布式緩存或者數據庫中。
[0041]觸發更新策略的情形包括但不限于,更新次數達到步驟三設定的最新的更新閥值,或者是本次更新在更新周期內,具體根據使用時指定的策略而定。本發明不僅提供了更新次數或者更新周期作為觸發分布式緩存或者數據庫更新的更新條件,而且提供了觸發條件和更新方式的接口,使得使用者更靈活的定制觸發條件和更新方式。然而,本領域技術人員將理解,雖然本發明提供了更新次數或者更新周期作為觸發條件,但是本發明包括但不限于這兩種判斷方式,原則上,任何可以判斷是否需要更新的方法都應該在本發明的保護范圍內。
[0042]本發明通過動態計算閥值的算法:每次處理更新請求時,將處理隊列的長度和人為設定的保護閥值相比較,取較大者作為請求的更新閥值,實現了更新頻率與更新請求數的關聯,使得本發明在應對大量更新請求時,請求的更新閥值會隨著請求量增大,減小更新頻率,使得對分布式緩存或者數據庫有更好的保護作用。并在請求量減少后,閥值逐漸減小,更新頻率逐漸增加。提高可行性的同時保證了更新結果盡可能快的更新到分布式緩存或者數據庫中。實現了可用性和及時性的平衡。
[0043]例如,根據一個實施例,如果使用的更新策略是按更新次數更新的策略,則使用以下算法來計算最新的更新閥值,以便動態調整更新閥值,本算法假設更新分布式緩存或者數據庫的耗時遠遠高于更新本地耗時,算法描述如下:獲取當前線程處理隊列的大小,a)如果當前線程處理隊列的大小小于系統默認的最小閥值,則將當前更新請求的閥值設置為該最小閥值山)如果當前線程處理隊列的大小大于最小閥值,則直接采用當前隊列的大小作為當前更新請求的閥值。
[0044]這是因為:當大量請求到來,或者更新分布式緩存或者數據庫緩慢,導致線程的處理隊列不斷增長時,閥值相應升高,從而減少更新分布式緩存或者數據庫的頻率,加快本地處理速度,從而降低處理隊列的大小。當隊列變短時,說明更新請求的提交不是非常頻繁,因此,更新閥值與隊列長度一起變短,更新分布式緩存或者數據庫的頻率升高,保證更新請求能盡可能快的更新到分布式緩存或者數據庫中。
[0045]通過本發明的技術方案,可以實現更新的異步化,更新線程不必等待更新結果可以繼續執行;通過更新閥值或者更新周期的合理設定,可以避免臟寫情況的產生。
[0046]而且,通過本發明,可以大大降低對分布式緩存或者數據庫等持久化服務的更新壓力,特別是在突然大量的更新請求時,因為有動態更新閥值的設定,從而最大程度上避免對分布式緩存或者數據庫照成相應的請求壓力,提高分布式緩存或者數據庫的可用性。
[0047]上述實施例僅是本發明的優選實施例,并不用于限制本發明。對本領域技術人員顯而易見的是,在不脫離本發明精神和范圍的情況下,可以對本發明的實施例進行各種修改和改變。因此,本發明意在涵蓋落入如權利要求所限定的本發明的范圍之內的所有的修改或變型。
【權利要求】
1.一種基于緩沖區的異步更新的方法,包括: 提交更新請求; 判斷隊列是否為空; 如果所述隊列不為空,則取出隊列元素,以準備處理所述更新請求; 計算出最新的更新閾值; 將所述更新請求更新到本地; 檢查所述更新是否觸發了更新策略;以及 如果觸發了所述更新策略,則更新分布式緩存或者數據庫。
2.根據權利要求1所述的方法,其中,所述提交更新請求的步驟進一步包括: 通過所述更新請求中的密鑰計算出散列碼的值; 通過用所述散列碼與處理線程的個數取模,計算出偏移量,以找到相應的處理線程;以及 將所述更新請求封裝后放入所述相應的處理線程的處理隊列中,以供線程獲取。
3.根據權利要求2所述的方法,其中將所述更新請求封裝后放入所述相應的處理線程的處理隊列中的步驟進一步包括:將同一類型的所述更新請求指向同一個處理線程,并放入同一個處理隊列。
4.根據權利要求1所述的方法,進一步包括:如果所述隊列為空,則當前線程沉睡,等待提交更新請求的線程放入更新請求后恢復執行。
5.根據權利要求1或2所述的方法,其中,所述計算出最新的更新閾值的步驟進一步包括: 每次更新請求計算前設定保護閥值, 獲取當前線程處理隊列的大小, a)如果當前線程處理隊列的大小小于保護閥值,則將當前更新請求的更新閥值設置為所述保護閥值; b)如果當前線程處理隊列的大小大于保護閥值,則直接采用當前隊列的大小作為當前的更新閥值。
6.根據權利要求1所述的方法,其中,觸發更新策略包括更新次數達到所述最新的更新閥值、或者本次更新在更新周期內。
【文檔編號】G06F17/30GK104376096SQ201410682991
【公開日】2015年2月25日 申請日期:2014年11月24日 優先權日:2014年11月24日
【發明者】劉錕洋 申請人:北京京東尚科信息技術有限公司, 北京京東世紀貿易有限公司