1. 程式人生 > >資料庫sequence序列快取記憶體池——儘量減少排隊和資料庫的互動

資料庫sequence序列快取記憶體池——儘量減少排隊和資料庫的互動

獲取資料庫序列

林小應

1.    問題描述

              由於業務需要,應用程式中很多地方會用到資料庫序列sequence,如果每次都去資料庫獲取,會比較耗時。         在Java程式碼中,我們通常呼叫儲存過程或執行sql生成一個sequence,
select xxx.nextnvl from dual;
            如果直接呼叫儲存過程或執行sql取sequence,算上事務開銷,一次需要3~4ms。在大型分散式系統中(如江蘇電信的營業系統、淘寶網、大型社交網站),4ms將是一個很大的開銷,試想如果需要的序列已經儲存在於記憶體中,平均每次取sequence的時間損耗將低於0.01ms。

2.    期望

避免每次前往資料庫取序列,讓獲取sequence就像從記憶體中取一個物件一樣簡單、決不允許重複讀取。

3.    設計原理

                 獲取sequence的Java程式碼類似如下:

     String seq = generateSeq(String seqType);

          輸入引數:seqType

          輸出引數:sequence

       我的思路是:在記憶體中開闢一個大容器(HashMap),存放各種seqType的sequence佇列(Queue)。由一個守護執行緒來完成佇列的裝填。
       當第一次取某種型別的sequence,在容器中註冊一下,記錄下seqType。這樣守護執行緒就能察覺到,守護執行緒不斷檢測所有型別的sequence佇列。如果容量不足,就會啟動裝填機制,從資料獲取一批新的sequence將空佇列裝滿。       

 4.  實現

               具體實現過程需要保證,多執行緒環境中資源鎖的問題。這裡我們用的HashMapConcurrentHashMap,是一種執行緒安全的高效能Map。Map中的seqType所對應的“sequence佇列”,已經換成了佇列組、即一個ArrayList中存放多個sequence佇列。這樣主要是為了降低併發帶來的開銷。

         根據入參seqTypeA,首先取到的是一個ArrayList<ConcurrentLinkedQueue>,再根據ArrayList的size隨機一個整數cur,再取ArrayList中第cur個sequence佇列。併發壓力和size的大小成反比!

示意圖:

5.     JVM序列池的生命週期

                  序列池的生命週期為:第一次註冊 到 應用程式終止

6.    需要注意的問題

                 A. 不能讀到髒陣列,一個sequence不能被兩次讀到。上面我們的sequence都是從資料庫來,儲存在同步佇列ConcurrentLinkedQueue中,這一點可以保證。

          B. sequence的順序,如果從資料庫直接讀取順序是一致的。採用sequence池機制,可能後面讀到的比前面讀到的小/大。我們可以將上面的ArrayList的size設定成1就可以解決順序問題(不使用於分散式環境)。

          C.命中率問題,如果sequence池空了,主執行緒就會直接前往資料庫。為了提高命中率,我們的系統中採用了備用池——主池空了以後,立即從備用池拉一個現成的佇列替換當前佇列(這個非常有效)。

          D.靈活的配置,如佇列池的深度(佇列的長度)、寬度(ArrayList的size)、實時的開關機制等

7. 總結

        以上只能簡單說一下,我們對於這種頻繁獲取sequence情況的解決方案。我們的系統是40000000使用者,分散式系統,多資料庫。採用了sequence池機制以後,獲取sequence的時間大大縮短了。

         還有很多細節,大家動手做的時候再慢慢琢磨。

qq:346420558

相關推薦

資料庫sequence序列快取記憶體——儘量減少排隊資料庫互動

獲取資料庫序列 林小應 1.    問題描述               由於業務需要,應用程式中很多地方會用到資料庫序列sequence,如果每次都去資料庫獲取,會比較耗時。         在Java程式碼中,我們通常呼叫儲存過程或執行sql生

Direct3D基礎——預備知識:多重取樣、畫素格式、記憶體、交換鏈頁面置換、深度快取、頂點運算、裝置效能

多重取樣 用畫素矩陣表示影象的時候往往會出現塊狀效應,多重取樣便是一項用於平滑塊狀影象的技術。 圖片來自:DirectX9.03D遊戲開發程式設計基礎 左邊那條是一條鋸齒線,右邊是一條經過取樣的反走樣線,看上去要平滑的多。 D3DMULTISAMPLE_TYPE列舉型別包含

深入淺出記憶體管理--快取記憶體(cache memory)轉換後援緩衝(TLB)

快取記憶體(Cache memory) CPU的執行速度時非常快的,當今的CPU主頻都是GHZ級別的,而對於記憶體DDR來說,每次存取操作都會耗用很多的時鐘週期,這意味著,CPU需要等待很長時間來完成一次讀或者寫操作。 為了縮小CPU和DDR兩者之間速度上的不匹配造成的等待問題,硬體

squid快取記憶體伺服器的的介紹配置

1:squid 是什麼? Squid cache(簡稱為Squid)是一個流行的自由軟體(GNU通用公共許可證)的代理伺服器和Web快取伺服器。Squid有廣泛的用途,從作為網頁伺服器的前置cache伺服器快取相關請求來提高Web伺服器的速度,到為一組人共享網

mybatis 在oracle資料庫中插入資料時獲取自增ID sequence序列

在oracle中sequence就是序號,每次取的時候它會自動增加。sequence與表沒有關係。 Create Sequence 首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE許可權。 建立語句如下: CREATE SEQUEN

Redis(記憶體快取記憶體資料庫)簡介及安裝

一.Redis 1.什麼是Redis Redis是REmote DIctionary Server(遠端資料服務)的縮寫,是一個開源的使用ANSI C語言編寫 它的資料模型為Key-Value資料庫 可持久化,保證資料安全; 2.為什麼可持久化 Redis一邊執行一邊就會把記憶體中的資料

Python記憶體管理(二 arena快取

接上文: 2.1  arean 多個pool聚合起來就是arean了,當然它也有預設的大小,一般是256k,包含的poo的個數就是256 / 4 = 64 個 先看下arean:  struct arena_object { uptr address;    

Oracle資料庫序列(SEQUENCE)的用法例項需求

在Oracle資料庫中,什麼是序列呢?它的用途是什麼?序列(SEQUENCE)其實是序列號生成器,可以為表中的行自動生成序列號,產生一組等間隔的數值(型別為數字)。其主要的用途是生成表的主鍵值,可以在插入語句中引用,也可以通過查詢檢查當前值,或使序列增至下一個值。 建立

RAC環境下序列快取導致資料庫序列不同步

 一、【問題描述】最近,客戶提出,KC70的醫療賬戶使用餘額與KC04中的賬戶餘額不一致。二、【分析過程】根據資料庫後臺包查得,後臺包是根據KC70中最大的OAE001取每個人當前的餘額,按照正常的思路,序列是遞增的,應該不會有問題。查詢該人的KC70(如上圖),發現有兩條記

mybatis 在oracle資料庫中插入資料時獲取自增ID sequence序列

在oracle中sequence就是序號,每次取的時候它會自動增加。sequence與表沒有關係。 Create Sequence 首先要有CREATE SEQUENCE或者CREATE

記憶體的作用--減少記憶體碎片

1 記憶體池出現的必要性和原因 C/C++下記憶體管理是讓幾乎每一個程式設計師頭疼的問題,分配足夠的記憶體、追蹤記憶體的分配、在不需要的時候釋放記憶體——這個任務相當複雜。而直接使用系統呼叫malloc/free、new/delete進行記憶體分配和釋放,有以下弊端:

資料庫連線記憶體洩漏問題的分析解決方案

## 一、問題描述 上週五晚上主營出現部分裝置掉線,經過檢視日誌發現是由於快取系統出現長時間gc導致的。這裡的gc日誌的特點是: - 1.gc時間都在2s以上,部分節點甚至出現12s超長時間gc。 - 2.同一個節點距離上次gc時間間隔為普遍為13~15天。 ![](https://user-gold-cd

Permutation Sequence 序列排序

刷的 div www sequence htm -- bing all order The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of

java:記憶體、程序、執行緒

記憶體池: 自定義記憶體池的思想通過這個"池"字表露無疑,應用程式可以通過系統的記憶體分配呼叫預先一次性申請適當大小的記憶體作為一個記憶體池,之後應用程式自己對記憶體的分配和釋放則可以通過這個記憶體池來完成。 只有當記憶體池大小需要動態擴充套件時,才需要再呼叫系統的記憶體分配函式,其他時間對

【原始碼剖析】MemoryPool —— 簡單高效的記憶體 allocator 實現

      什麼是記憶體池?什麼是 C++ 的 allocator?       記憶體池簡單說,是為了減少頻繁使用 malloc/free new/delete 等系統呼叫而造成的效能損耗而設計的。當我們的程式需要頻繁地申請和釋放

PostgreSQL之Sequence序列(轉)

本文轉載自:https://blog.csdn.net/omelon1/article/details/78798961 Sequence序列 Sequence是一種自動增加的數字序列,一般作為行或者表的唯一標識,用作代理主鍵。 1、Sequence的建立 例子:建立一個seq_commod

(總結)關於Linux的快取記憶體 Cache Memory詳解

Linux與Win的記憶體管理不同,會盡量快取記憶體以提高讀寫效能,通常叫做Cache Memory。有時候你會發現沒有什麼程式在執行,但是使用top或free命令看到可用記憶體free項會很少,此時檢視系統的 /proc/meminfo 檔案,會發現有一項 Cached Memory:

發現可快取記憶體的 SSL 頁面

發現可快取記憶體的 SSL 頁面 是否設定快取記憶體一般是在nginx設定的。 發現可快取記憶體的 SSL 頁面 技術描述:   預設情況下,大部分 Web 瀏覽器都配置成會在使用期間快取記憶體使用者的頁面。 這表示也會快取記憶體 SSL 頁面。不建議讓 Web 瀏覽器儲存任何 SS

LRU快取記憶體演算法統計快取記憶體請求失敗的缺頁次數

1. page 表示頁面的編號 2. max_cache_size表示最大快取容量 3. len表示pages頁面陣列的大小 #include <iostream> using namespace std; int lruCountMiss(int ma

PooledByteBuf記憶體-------這個我現在不太懂

轉載自:http://blog.csdn.net/youaremoon/article/details/47910971              http://blog.csdn.net/youaremoon/article/detail