1. 程式人生 > >(八)實際專案中涉及到的快取資料結構及演算法

(八)實際專案中涉及到的快取資料結構及演算法

軟體開發中常用的快取演算法主要有:FIFO-先進先出演算法,LRU-最近最久未使用,LFU-最近最少使用。實際專案中快取演算法對這些都有涉及。

一、理論:

1.FIFO(First Input First Output):

特點:先進先出,符合公平性,實現簡單。

資料結構:使用對列

淘汰原則:如果一個數據最先進入快取中,則應該最早淘汰掉。也就是說,當快取滿的時候,應當把最先進入快取的資料給淘汰掉。

2.LRU(Least Recently Used):

特點:按照時間長短,最不經常使用的快取資料,先淘汰。

資料結構:連結串列和hashmap

淘汰原則:如果一個數據在最近一段時間沒有被訪問到,那麼在將來它被訪問的可能性也很小。

3.LFU(Least Frequently Used):

特點:按照訪問次數,最近最少使用的快取資料,先淘汰。

資料結構:陣列、hashmap、堆

淘汰原則:如果一個數據在最近一段時間內使用次數很少,那麼在將來一段時間內被使用的可能性也很小。

二、實際專案中使用(java專案為例):

1.ehcache框架:

Ehcache配置引數(具體引數含義請查詢資料):


快取的3 種清空策略 :

FIFO :first in first out (先進先出).
LFU : Least Frequently Used (最不經常使用).意思是一直以來最少被使用的。快取的元素有一個hit 屬性,hit 值最小的將會被清出快取。
LRU :Least Recently Used(最近最少使用). (ehcache 預設值).快取的元素有一個時間戳,當快取容量滿了,而又需要騰出地方來快取新的元素的時候,那麼現有快取元素中時間戳離當前時間最遠的元素將被清出快取。

2.Redis快取回收策略配置:


(一)、最大快取設定

示例:maxmemory 15000mb 
單位:mb,gb。
預設為0,沒有指定最大快取,如果有新的資料新增,超過最大記憶體,則會使redis崩潰,所以一點要設定。
設定maxmemory之後,配合的要設定快取資料回收策略。

(二)、回收策略演算法設定

 當maxmemory限制到達的時候,Redis將採取的準確行為是由maxmemory-policy配置指令配置的。 
    以下策略可用: 
(1)、noeviction:當到達記憶體限制時返回錯誤。當客戶端嘗試執行命令時會導致更多記憶體佔用(大多數寫命令,除了DEL和一些例外)。
(2)、allkeys-lru:回收最近最少使用(LRU)的鍵,為新資料騰出空間。
(3)、volatile-lru:回收最近最少使用(LRU)的鍵,但是隻回收有設定過期的鍵,為新資料騰出空間。
(4)、allkeys-random:回收隨機的鍵,為新資料騰出空間。
(5)、volatile-random:回收隨機的鍵,但是隻回收有設定過期的鍵,為新資料騰出空間。
(6)、volatile-ttl:回收有設定過期的鍵,嘗試先回收離TTL最短時間的鍵,為新資料騰出空間。

使用策略規則:
(1)、如果資料呈現冪律分佈,也就是一部分資料訪問頻率高,一部分資料訪問頻率低,則使用allkeys-lru。
(2)、如果資料呈現平等分佈,也就是所有的資料訪問頻率都相同,則使用allkeys-random。
 
redis回收演算法,實際不是嚴謹的LRU演算法,而是抽樣回收資料,這樣算是為了減少消耗記憶體使用,但是抽樣回收的快取和全部資料回收快取差異非常小,或者根本就沒有。

(三)、生產使用

(1)、先預測好系統所需要的記憶體高峰,部署相對應記憶體的快取伺服器。
(2)、設定maxmemory和相對應的回收策略演算法,設定最好為實體記憶體的3/4,或者比例更小,因為redis複製資料等其他服務時,也是需要快取的。以防快取資料過大致使redis崩潰,造成系統出錯不可用。犧牲一部分快取資料,儲存整體系統可用性。

3.Memcached快取策略:

(一).memcached快取原理:

Memcached有兩個核心元件組成:服務端(ms)和客戶端(mc)。首先mc拿到ms列表,並對key做hash轉化,根據hash值確定kv對所存的ms

位置。然後在一個memcached的查詢中,mc先通過計算key的hash值來確定kv對所處在的ms位置。當ms確定後,客戶端就會發送一個查詢請求

給對應的ms,讓它來查詢確切的資料。因為ms之間並沒有護衛備份,也就不需要互相通訊,所以效率較高。

(二)、快取策略:     

       Memcached會優先使用已超時的記錄空間,但即使如此,也會發生追加新紀錄時空間不足的情況。此時就要使用名為Least Recently Used (LRU)機制來分配空間。這就是刪除最少使用的記錄的機制。因此當memcached的記憶體空間不足時獲取到新空間時,就從最近未使用的記錄中搜索,並將空間分配給新的記錄。

(三)、客戶端程式碼示例:

spring整合memcache示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="memcachedPool" class="com.danga.MemCached.SockIOPool" 
		factory-method="getInstance" init-method="initialize">
		<constructor-arg>
			<value>neeaMemcachedPool</value>
		</constructor-arg>
		<property name="servers">
			<list>
				<value>127.0.0.1:11211</value>
			</list>
		</property>
		<property name="initConn">
			<value>20</value>
		</property>
		<property name="minConn">
			<value>10</value>
		</property>
		<property name="maxConn">
			<value>50</value>
		</property>
		<property name="nagle">
			<value>false</value>
		</property>
		<property name="socketTO">
			<value>3000</value>
		</property>
	</bean>
	<bean id="memcachedClient" class="com.danga.MemCached.MemCachedClient">
		<constructor-arg>
			<value>neeaMemcachedPool</value>
		</constructor-arg>
	</bean>
</beans>

測試用例:

public class MemcachedSpringTest {  
  
    private MemCachedClient cachedClient;  
      
    @Before  
    public void init() {  
        ApplicationContext context = new ClassPathXmlApplicationContext("com/luo/config/beans.xml");  
        cachedClient = (MemCachedClient)context.getBean("memcachedClient");  
    }  
      
    @Test  
    public void testMemcachedSpring() {  
        UserBean user = new UserBean("luo", "hi");  
        cachedClient.set("user", user);  
        UserBean cachedBean = (UserBean)user;  
        Assert.assertEquals(user, cachedBean);  
    }  
}  

注意點:

memcached是在伺服器端的記憶體中快取物件的,沒有持久化到硬碟,是一個純記憶體式的分散式快取服務系統;

相關推薦

()實際專案涉及到的快取資料結構演算法

軟體開發中常用的快取演算法主要有:FIFO-先進先出演算法,LRU-最近最久未使用,LFU-最近最少使用。實際專案中快取演算法對這些都有涉及。 一、理論: 1.FIFO(First Input First Output): 特點:先進先出,符合公平性,實現簡單。 資料結構:

Java HashMap涉及資料結構實現

提供的功能 基於雜湊表實現的Map; 非執行緒安全的Map實現; 鍵和值都可以為null(因為有處理null的情形); 基本操作get()和put()的時間消耗是固定的; 資料儲存結構會隨著HashMap的數量而變換成不同的資料結構。 涉及到的概念 預設初始化容量 最大容量 預設的負載係數(load f

【unity3d-C#學習筆記】C#常用的資料結構遍歷方法

常用的集合類:ArrayList,Queue,Stack,SortedList,Hashtable 陣列: Array: 1.資料儲存在連續的記憶體上。 2.陣列的語速都是同類型的。 3.陣列

【厚積薄發系列】C++專案總結7—實際專案記憶體洩漏問題排查常見情況總結

需求背景:C/C++專案中,有時候最頭痛不是業務需求實現問題而是隨著專案的日益龐大過程中記憶體洩漏帶來的問題。記憶體洩漏不僅會導致程式記憶體不夠導致程式崩潰,還會導致記憶體碎片,更嚴重還會引起系統莫名其妙的崩潰和閃退。所以在專案中解決記憶體洩漏問題勢在必行。解決思路:分兩種情

資料結構演算法--棧

順序棧 三個基本屬性 棧的儲存資料data 棧的最大儲存量maxSize 棧頂top Python實現 # Python 2.7 class sqStack(object): # 初始化 def __init__(self,

資料結構演算法--線性表

順序線性表 三個基本屬性 儲存空間的起始位置data 線性表的最大儲存量maxSize 線性表的當前長度length Python實現 # Python 2.7 class seqList(object): # 初始化 def

資料結構演算法學習(一)

一、資料結構範疇   資料結構是一門與程式設計密切相關的課程,而程式設計就是演算法+資料結構,演算法即是處理資料的策略,而資料結構就是表達程式設計的模型,可以說任何一個程式設計問題,我們都可以從演算法和模型出發。概而言之,資料結構就是描述了程式設計的數學模型及在其程式設計上的表示和實現。 二、基本概念

MySQL索引背後的資料結構演算法原理

作者 張洋 | 釋出於 2011-10-18 MySQL 索引 B樹 優化 摘要 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型

資料結構演算法——單鏈表逆轉(C語言)(不間斷更新)

題目來源:浙大程式設計類實驗輔助教學平臺 本題要求實現一個函式,將給定的單鏈表逆轉。 函式介面定義: List Reverse( List L ); 其中List結構定義如下: typedef struct Node *PtrToNode; stru

MySQL索引的資料結構演算法原理

原文連結:MySQL索引背後的資料結構及演算法原理 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型別,如BTree索引,雜湊索引,全文索引等等。為了避

MySQL索引背後的資料結構演算法原理(employees例項)

摘要 http://blog.codinglabs.org/articles/theory-of-mysql-index.html 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援

MySQL索引設計背後的資料結構演算法詳解

在我們公司的DB規範中,明確規定: 1、建表語句必須明確指定主鍵 2、無特殊情況,主鍵必須單調遞增 對於這項規定,很多研發小夥伴不理解。本文就來深入分析MySQL索引設計背後的資料結構和演算法,從而幫你釋疑以下幾個問題: 1、為什麼InnoDB表需要主鍵? 2、為什麼建議InnoDB表主鍵是單調

轉:MySQL索引背後的資料結構演算法原理

@rover這個是C++模板 --胡滿超 stack<Postion> path__;這個裡面 ”<> “符號是什麼意思?我在C++語言裡面沒見過呢? 初學者,大神勿噴。

MySQL索引資料結構演算法原理學習筆記

1、預備知識 (1)儲存介質一般為主存和磁碟 (2)主存(RAM)支援隨機存取,磁碟定址需要定位【磁軌】和【扇區】,對應產生【尋道時間】和【旋轉時間】,因此磁碟的存取速度往往是主存的【幾百分之一】 (3)由於【區域性性原理】的歸納,以及磁碟IO非常耗時

【轉】MySQL索引背後的資料結構演算法原理

摘要 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型別,如BTree索引,雜湊索引,全文索引等等。為了避免混亂,本文將只關注於BTree

常用查詢資料結構演算法(Python實現)

目錄 一、基本概念 二、無序表查詢 三、有序表查詢 3.1 二分查詢(Binary Search) 3.2 插值查詢 3.3 斐波那契查詢 四、線性索引查詢 4.1 稠密索引 4.2 分塊索引 4.3 倒排索引 五、二叉排序樹 六、 平衡二叉樹 七、多路查詢樹(B樹) 7.1 2-3樹 7.2 2-3-4樹

原理:資料結構-索引 && 應用篇:MySQL索引背後的資料結構演算法原理詳解

特點簡介: 索引檔案比資料檔案小,可以有效地裝載到記憶體。通過對記憶體索引檔案的查詢定位到記錄,然後通過一次磁碟物件讀取操作就可以獲取到需要搜尋的物件。 靜態索引結構和動態索引結構啥區別? 我認為靜態是指新節點的加入對原有的索引結構不會發生改變,比如:稠密索引直接把新節點

轉MySQL索引背後的資料結構演算法原理

摘要 本文以MySQL資料庫為研究物件,討論與資料庫索引相關的一些話題。特別需要說明的是,MySQL支援諸多儲存引擎,而各種儲存引擎對索引的支援也各不相同,因此MySQL資料庫支援多種索引型別,如BTree索引,雜湊索引,全文索引等等。為了避免混亂,本文將只關注

經典資料結構演算法-Java實現-附原始碼(可下載)

閒暇之餘,將自己之前敲過的資料結構與演算法程式碼整理了一下,最後放在一個工程下面:具體分類:剛看了下專案目錄,少了排序分類介紹圖,在這裡補上(此圖來源於網上)最後,程式碼比較多,只展示下排序演算法的程式碼。package com.lzz.algorithm.sorting;

資料結構演算法——帶頭結點的鏈式表操作集(C語言)

要求實現帶頭結點的鏈式表操作集。 函式介面定義: List MakeEmpty(); Position Find( List L, ElementType X ); bool Insert( List L, ElementType X, Positio