memcached深度分析(5)

發表于:2015-07-10來源:uml.org.cn作者:火龍果軟件點擊數: 標簽:數據庫
Memcached的內存管理方式是非常精巧和高效的,它很大程度上減少了直接alloc系統內存的次數,降低函數開銷和內存碎片產生幾率,雖然這種方式會造成一些

  Memcached的內存管理方式是非常精巧和高效的,它很大程度上減少了直接alloc系統內存的次數,降低函數開銷和內存碎片產生幾率,雖然這種方式會造成一些冗余浪費,但是這種浪費在大型系統應用中是微不足道的。

  Memcached的理論參數計算方式

  影響 memcached 工作的幾個參數有:

  常量REALTIME_MAXDELTA 60*60*24*30

  最大30天的過期時間

  conn_init()中的freetotal(=200)

  最大同時連接數

  常量KEY_MAX_LENGTH 250

  最大鍵長

  settings.factor(=1.25)

  factor將影響chunk的步進大小

  settings.maxconns(=1024)

  最大軟連接

  settings.chunk_size(=48)

  一個保守估計的key+value長度,用來生成id1中的chunk長度(1.2)。id1的chunk長度等于這個數值加上item結構體的長度(32),即默認的80字節。

  常量POWER_SMALLEST 1

  最小classid(1.2)

  常量POWER_LARGEST 200

  最大classid(1.2)

  常量POWER_BLOCK 1048576

  默認slab大小

  常量CHUNK_ALIGN_BYTES (sizeof(void *))

  保證chunk大小是這個數值的整數倍,防止越界(void *的長度在不同系統上不一樣,在標準32位系統上是4)

  常量ITEM_UPDATE_INTERVAL 60

  隊列刷新間隔

  常量LARGEST_ID 255

  最大item鏈表數(這個值不能比最大的classid小)

  變量hashpower(在1.1中是常量HASHPOWER)

  決定hashtable的大小

  根據上面介紹的內容及參數設定,可以計算出的一些結果:

  1、在memcached中可以保存的item個數是沒有軟件上限的,之前我的100萬的說法是錯誤的。

  2、假設NewHash算法碰撞均勻,查找item的循環次數是item總數除以hashtable大小(由hashpower決定),是線性的。

  3、Memcached限制了可以接受的最大item是1MB,大于1MB的數據不予理會。

  4、Memcached的空間利用率和數據特性有很大的關系,又與DONT_PREALLOC_SLABS常量有關。 在最差情況下,有198個slab會被浪費(所有item都集中在一個slab中,199個id全部分配滿)。

  Memcached的定長優化

  根據上面幾節的描述,多少對memcached有了一個比較深入的認識。在深入認識的基礎上才好對它進行優化。

  Memcached本身是為變長數據設計的,根據數據特性,可以說它是“面向大眾”的設計,但是很多時候,我們的數據并不是這樣的“普遍”,典型的情況中,一種是非均勻分布,即數據長度集中在幾個區域內(如保存用戶 Session);另一種更極端的狀態是等長數據(如定長鍵值,定長數據,多見于訪問、在線統計或執行鎖)。

  這里主要研究一下定長數據的優化方案(1.2),集中分布的變長數據僅供參考,實現起來也很容易。

  解決定長數據,首先需要解決的是slab的分配問題,第一個需要確認的是我們不需要那么多不同chunk長度的slab,為了最大限度地利用資源,最好chunk和item等長,所以首先要計算item長度。

  在之前已經有了計算item長度的算法,需要注意的是,除了字符串長度外,還要加上item結構的長度32字節。

  假設我們已經計算出需要保存200字節的等長數據。

  接下來是要修改slab的classid和chunk長度的關系。在原始版本中,chunk長度和classid是有對應關系的,現在如果把所有的chunk都定為200個字節,那么這個關系就不存在了,我們需要重新確定這二者的關系。一種方法是,整個存儲結構只使用一個固定的id,即只使用199個槽中的1個,在這種條件下,就一定要定義DONT_PREALLOC_SLABS來避免另外的預分配浪費。另一種方法是建立一個hash關系,來從item確定classid,不能使用長度來做鍵,可以使用key的NewHash結果等不定數據,或者直接根據key來做hash(定長數據的key也一定等長)。這里簡單起見,選擇第一種方法,這種方法的不足之處在于只使用一個id,在數據量非常大的情況下,slab鏈會很長(因為所有數據都擠在一條鏈上了),遍歷起來的代價比較高。

  前面介紹了三種空間冗余,設置chunk長度等于item長度,解決了第一種空間浪費問題,不預申請空間解決了第二種空間浪費問題,那么對于第一種問題(slab內剩余)如何解決呢,這就需要修改POWER_BLOCK常量,使得每一個slab大小正好等于chunk長度的整數倍,這樣一個slab就可以正好劃分成n個chunk。這個數值應該比較接近1MB,過大的話同樣會造成冗余,過小的話會造成次數過多的alloc,根據chunk長度為200,選擇1000000作為POWER_BLOCK的值,這樣一個slab就是100萬字節,不是1048576。三個冗余問題都解決了,空間利用率會大大提升。

原文轉自:http://www.uml.org.cn/sjjm/201411134.asp

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97