當前位置:首頁 » 硬碟大全 » 緩存策略的十大優缺點
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

緩存策略的十大優缺點

發布時間: 2022-06-09 12:08:16

⑴ 高速緩存,內存和硬碟三種儲存器各有什麼優缺點

高速緩存,有cpu的緩存和硬碟的緩存。都是用於存貯需要馬上處理的數據,對壽命和反應、速度有很高的要求。
內存,用於載入硬碟的程序,斷電清除記憶,8gb/s傳輸速度。
固態硬碟,存儲資料。容量比較小,但近年來已經有大容量但是很貴。主流240g,傳輸速度500mb/s.
機械硬碟,存貯資料。容量比較大4t,單碟1t。主流單碟1tb=1000gb=1000,000mb,傳輸速度200-60mb/s.

⑵ JDBC鏈接資料庫的方法有幾種各自的優缺點

它代表最低級別的持久性策略。本地框架各不相同,但大多數有著相似的特徵。 大多數 JDBC 解決方案把所有的數據訪問包裝在數據訪問對象中,對象中包裝有一個關系表。從那裡,您可以把數據留在結果集或者選擇把結果集中的每一行映射到一個對象。Java 技術開發人員傾向於映射到輕值對象(light value objects)。一個特殊的替代方案是 Martin Fowler 的有效記錄設計模式,這種設計模式提供針對數據表中行的包裝程序。每一個有效記錄都有訪問每一列的方法,以及保存、刪除或更新行的方法。 長處 基於JDBC 的解決方案提供良好的控制能力。您要寫更多的代碼來解決預料中的問題,但是您有訪問資料庫的所有權利,並且可以讓它只做您想要它做的事。純 JDBC 給予您非常好的靈活性。 弱點 關系資料庫和對象並不是一回事 —— 這里有一點分歧。您不得不處理一些面向對象的概念,如繼承。您還必須自己管理每一個對象,寫查詢程序來完成創建、讀取、更新或刪除操作。如果要提升性能,需要提供您自己的緩存。 總結 對於那些技術不好但了解 sql 的 Java 程序員來說,JDBC 是一個很好的選擇。如果您需要更好的訪問 SQL 或者在進行批處理計算或報告,那麼 JDBC 也能勝任。 變種 有幾個框架和工具可以幫助您擴展 JDBC。一些工具,像 Velocity 和 MiddleGen,會生成數據訪問對象,給出資料庫表的描述。Spring 提供依賴注入和面向方面的編程,這使得服務和依賴關系的集成更加容易。但是總得來說,應用程序結構和策略應該保持一致。 對象關系映射程序 OOP 和關系資料庫基於根本不同的基礎。通常,很難把兩者混合起來。如果您有一個現有的關系模式或一個可能頻繁改變的關系模式,那麼 ORM 框架也許正是您需要的。大多數的 ORM 試圖讓您透明地處理對象。您提供一個 POJO,然後,通過使用代碼生成(EJB)、位元組碼操縱(JDO)或反射(Hibernate),框架與持久性相關聯。每種技術都有它的長處和弱點,因此大多數的框架使用多種方法來完成工作。 您需要告訴應用程序如何映射資料庫表到應用程序的類。您可以用一個獨立的 XML 文件或程序代碼中的注釋來達到目的。這些注釋可以採取 Java 5 注釋的形式(使用 XDoclet 之類的工具)。如果模式和對象模型不會走到一起,我一般會將代碼和配置文件分離。 持久性框架讓您從資料庫載入一系列的對象。您可以顯示它們,或操縱它們並把它們存回到關系資料庫。大多數的 ORM 框架提供擴展,比如兩級緩存。一般來說,第一級緩存保證事務的完整性,第二級保證跨集群中機器的一致性。盡管有多種實現,但是您應該准確理解緩存策略。 您需要用於管理配置和依賴性的策略。您的應用程序可能需要選擇一個事務策略並使用數據源和連接池。正如在前面的章節中所學到的那樣,Spring 和 ORM 能很好地為您處理這些問題。這里有一些可用的 ORM。 EJB 企業級 JavaBean 提供兩種標准化的持久性策略,EJB 1.x 標准 和 2.x 標准。第二個標准做的更好,但仍然過於復雜。EJB 專家組承認這一事實並將提供第三個標准,即 EJB 3 JSR;但是該標准將對所有的 Java Enterprise Edition (JEE) 用戶可用,不僅僅是對 EJB 用戶可用。因此,EJB 持久性標准實際上是一條死路,因為新的應用程序想要目標方案接近期望的 JSR 220 標准。 Hibernate Hibernate 很快變成了持久性的事實上的標准。它快速,有效,而且是免費的。因為 Hibernate 讓您制定任意的 POJO 持久性,所以它必須有一種方法把持久性關聯到一個對象而不必改動代碼。Hibernate 主要通過反射來提供透明性,但是它通過動態代理混合在一些運行時位元組碼操縱中。使用反射,Hibernate 可以在事務完成前後查看對象的狀態。如果狀態發生改變,Hibernate 可以把它保存到資料庫中。代理幫助 Hibernate 實現一些其他的特性,比如懶散載入(lazy loading)。(把動態代理想像成一個坐在目標對象前面的對象,它有一個與目標對象相同的介面。每當您調用某些方法或訪問實例變數時,代理都可以自由地調用持久層。) Hibernate 僅支持關系資料庫,而且它與 SQL 結合的緊密程度比大多數其他的持久性框架要高。Hibernate 使用類似於 SQL 的查詢語言,這種相似性對用戶的幫助很大。如果需要,您也可以在 Hibernate 中直接使用 SQL。 像JDO 一樣,Hibernate 擁有兩級緩存。第一級緩存叫做會話,給您一個存放持久性對象的地方。您可以把對象載入緩存並操縱它們。然後決定何時通過在會話上調用刷新(flush)或提交(commit)來將更改持久存儲到資料庫中。 Hibernate 幫助您管理關系。如果您定義一個關系,比如雇員屬於部門,Hibernate 將對其進行管理。如果您載入一個部門的信息,您可以決定是在載入一個部門時載入所有的雇員信息(熱切載入),還是等待載入雇員信息(懶散載入)。 長處 Hibernate 有一個靈活的映射機制。一些場景比其他場景付出更多的努力來映射,但是如果您能在一個關系模式中表示它,那麼也許在 Hibernate 中有一種方法來映射到它。Hibernate 的性能比大多數的框架要好而且還在不斷提升。文檔很優秀,收購 JBoss 後,支持也在改善。JBoss 小組也把 Hibernate 放置在一個合適的位置以搶在競爭者之前實現 JSR 200 持久性標准。 對Hibernate 來說,與其他開放源碼框架和商業框架的集成比其他的替代框架要好。一般來說,Spring 與 Hibernate 的集成比與其他任何一個持久性框架的集成要好。 Hibernate 是一個創新的框架。在推動與 SQL 的集成上,它比大多數其他的框架走的更遠。它具有一些其他框架不支持的特性,比如會話過濾。還有一支強大的公共和商業開發人員團隊為其工作。 弱點 如果您是一家大公司,那麼您可能要用不支付許可費來彌補支持上的欠缺。Hibernate 比替代框架更加難以管理。例如,您沒有 SolarMetric 的 Kodo JDO 產品提供的豐富的管理控制台。您也沒有 Versant 的 JDP 產品提供的豐富的用戶界面工具。 最後,Hibernate 不像一些持久性框架那麼專業。例如,對於一些邊緣情況,比如管理懶散載入,Kodo JDO 有非常好的錯誤信息和更加可預測的行為。 JDO 如果您想要帶持久性框架的 Betamax,JDO 1.x 就足夠了 —— 雖然時運似乎在轉向 JDO 2,更不用說 JSR 220 持久性標准了。在過去三年左右的時間里,最好的技術持久性框架來自 JDO 社區。JDO 通過位元組碼增強機制實現了透明性。JDO 2 多少會放鬆這個限制。 JDO 提供一種叫做 JDO QL 的查詢語言。對緩存和提取定義了懶散/熱切提取場景的組(可以在每次查詢的基礎上定義這樣的場景),它有正式的性能擴展。JDO 還為分離式處理(detached processing)提供一個模型,以便您能夠從一個 JDO 會話(叫做 PersistenceManager)分離一個對象,改變並重新附加該對象。然後資料庫應用所有更改。 JDO 還為任意的數據存儲提供透明的持久性。在現實世界中,大多數的數據是非關系型的,JDO 自己就能很好地為該社區提供解決方案。 長處 JDO 的各種供應商各有長處。Kodo 產品在需要極限持久性場景的利基市場賣得很好。Kodo 執行快速,並得到廣泛的認同:它對任何一個 JDO 產品都有最好的映射支持。(我要說,就現在來看,它的映射支持是業界最好的。)Kodo 還在可管理性方面領先。(Versant 產品也有著非常快的速度。)顯然,它的最大優點是針對映射支持的用戶界面。 弱點 對JDO 弱點的任何處理都必須從市場份額開始。作為一個標准,JDO 應當得到更好的保護,但是到目前為止,這個標准並不是非常成功。具有諷刺意味的是,JSR 220 持久性標準的出現很可能會對 JDO 造成打擊。許多 JDO 供應商已經宣布在他們的產品中支持 JSR 220。您將會看到一個更強大的標准,而且好的 JDO 供應商將能夠在那些市場中佔有一席之地。JSR 220 標准將會開放,而且新的標准將從那裡快速產生,您將會看到顧客使用同樣的標准來嘗試 JDO。由於疲弱的市場表現, JDO 需要在開放源碼社區中更好地表現。Versant 向 Eclipse 小組捐贈它的產品是在正確的方向上前進了一步。 其他 Top Link、OJB 和 Cayenne 正在追趕 Hibernate,但是它們不可能趕上了(出於許多因素)。在接下來的幾期文章中,我將用其他的語言如 Ruby 或 Python 來探索幾個框架。 混合解決方案 本文將在介紹完一種混合解決方案後結束。大多數的 ORM 解決方案把一個類映射到一個關系資料庫模式,而諸如 iBATIS 之類的混合框架則把類映射到一個 SQL 查詢的結果。 對於iBATIS,您提供一個 XML 文件,它指定查詢和從那些查詢到對象的映射。您能得到 ORM 的一些好處,比如一致緩存策略、獨立於代碼庫的 SQL 和限定的關系管理。 長處 iBATIS 還有一些 ORM 框架沒有的優點。您有對 SQL 的嚴格控制的權利,不必擔心對象/關系的不匹配,也不必投入幾個月來學習一個對象/關系映射框架。 弱點 iBATIS 不會給予您 ORM 所做的一切。您需要編碼查詢來完成每一次的資料庫訪問,而不是您自己來完成訪問。與資料庫的結合更加緊密。並依靠您選擇的 SQL 方言。

⑶ 磁碟寫入緩存策略開還是關

在一定程度上提高硬碟的讀寫速度,開啟該功能,甚至少有磁碟碎片產生,但有優點必然有缺點,硬碟寫入緩存的知名缺點就是突然斷電的計算機,不能很好的保證數據的完整性。
Win10啟用磁碟寫入緩存的方法:
1、首先按Win+X鍵,或右擊開始按鈕,在彈出的菜單中點擊「設備管理器」;
2、在彈出的硬碟屬性窗口中,切換至「策略」項,勾選「啟用設備上的寫入緩存」,點擊確定即可。(如果想關閉此功能,則取消勾選即可)。

⑷ android有哪幾種緩存方式,優缺點是什麼

二級緩存工作機制。

1.所謂二級緩存實際上並不復雜,當Android端需要獲得數據時比如獲取網路中的圖片,我們首先從內存中查找(按鍵查找),內存中沒有的再從磁碟文件或sqlite中去查找,若磁碟中也沒有才通過網路獲取。

2.當獲得來自網路的數據,就以key-value對的方式先緩存到內存(一級緩存),同時緩存到文件或sqlite中(二級緩存)。注意:內存緩存會造成堆內存泄露,所有一級緩存通常要嚴格控制緩存的大小,一般控制在系統內存的1/4。

3.網路中的數據是變化的,數據一旦放入緩存中,再取該數據就是從緩存中獲得,這樣豈不是不能體現數據的變化?在緩存數據時會設置有效時間,比如說30分鍾,若超過這個時間數據就失效並釋放空間,然後重新請求網路中的數據。

⑸ JAVA幾種緩存技術介紹說明

1、TreeCache / JBossCache

JBossCache是一個復制的事務處理緩存,它允許你緩存企業級應用數據來更好的改善性能。緩存數據被自動復制,讓你輕松進行JBoss伺服器之間 的集群工作。JBossCache能夠通過JBoss應用服務或其他J2EE容器來運行一個MBean服務,當然,它也能獨立運行。

2、WhirlyCache

Whirlycache是一個快速的、可配置的、存在於內存中的對象的緩存。它能夠通過緩存對象來加快網站或應用程序的速度,否則就必須通過查詢資料庫或其他代價較高的處理程序來建立。

3、SwarmCache

SwarmCache是一個簡單且有效的分布式緩存,它使用IP multicast與同一個區域網的其他主機進行通訊,是特別為集群和數據驅動web應用程序而設計的。SwarmCache能夠讓典型的讀操作大大超過寫操作的這類應用提供更好的性能支持。

4、JCache

JCache是個開源程序,正在努力成為JSR-107開源規范,JSR-107規范已經很多年沒改變了。這個版本仍然是構建在最初的功能定義上。

5、ShiftOne

ShiftOne Java Object Cache是一個執行一系列嚴格的對象緩存策略的Java lib,就像一個輕量級的配置緩存工作狀態的框架。

⑹ 深度緩存演算法的優缺點

深度緩存演算法中物體投影到象平面上的次序是任意的,無須將場景中的表面進行排序,物體之間的遮擋關系是通過深度緩存器進行深度比較加以確定的,演算法易於實現。
深度緩存演算法只能顯示距離視點最近的物體,而且這些物體都是不透明的,無法看到被遮擋的物體。
深度緩存演算法經常執行一些最終不起作用的中間計算過程。由於對象按任意次序進行處理,因此有些表面進行了顏色計算但事後又被更近的表面所代替。為了緩減這一問題,有些圖形軟體提供選項讓用戶調整表面測試的深度范圍。例如,通過深度測試排除較遠的對象。使用該選項還可以排除非常靠近投影平面的對象。高檔計算機圖形系統一般集成了深度緩存演算法的硬體實現。

⑺ .Net的Cache和Memcached有什麼優缺點

如果你的伺服器只有一台,且資料庫讀寫壓力不大,就沒必要使用Memcached。HttpRuntime.Cache是本地緩存,Memcached是分布式緩存,兩者的區別在於:

本地緩存
本地緩存可能是大家用的最多的一種緩存方式了,不管是本地內存還是磁碟,其速度快,成本低,在有些場合非常有效。
但是對於web系統的集群負載均衡結構來說,本地緩存使用起來就比較受限制,因為當資料庫數據發生變化時,你沒有一個簡單有效的方法去更新本地緩存;然而,你如果在不同的伺服器之間去同步本地緩存信息,由於緩存的低時效性和高訪問量的影響,其成本和性能恐怕都是難以接受的。

分布式緩存
前面提到過,本地緩存的使用很容易讓你的應用伺服器帶上「狀態」,這種情況下,數據同步的開銷09會比較大;尤其是在集群環境中更是如此!
分布式緩存這種東西存在的目的就是為了提供比RDB更高的TPS和擴展性,同時有幫你承擔了數據同步的痛苦;優秀的分布式緩存系統有大家所熟知的Memcached、Redis(當然也許你把它看成是NoSQL,但是我個人更願意把分布式緩存也看成是NoSQL),還有淘寶自主開發的Tair等。
對比關系型資料庫和緩存存儲,其在讀和寫性能上的差距可謂天壤之別;就拿淘寶的Tair來說,mdb引擎的單機QPS已在10w以上,ldb的也達到了5w~7w,而集群的性能會更高(目前uic所用的Tair集群QPS高達數十萬!)。
所以,在技術和業務都可以接受的情況下,我們可以盡量把讀寫壓力從資料庫轉移到緩存上,以保護看似強大,其實卻很脆弱的關系型資料庫。

⑻ 緩存存儲與傳統存儲對比的優缺點有哪些

1.三星暫時沒有提供網路查詢真偽,包修,生產日期等信息的。
2.三星手機通過序列號串號或者手機版本號等是不能鑒別手機真偽的。眾所周知,由於目前市面上克隆機較多,單憑手機串號即IMEI號是無法確定手機真偽。
3.如果要鑒別手機真偽的話,請務必攜帶上購機發票、包修卡和手機,建議到當地的三星服務中心檢測手機是否可以保修,這個是最好也是最為准確的一種方法。

⑼ Redis 和 Memcached 各有什麼優缺點,主要的應用場景是什麼樣的

Redis的作者Salvatore Sanfilippo曾經對這兩種基於內存的數據存儲系統進行過比較:

1、Redis支持伺服器端的數據操作:Redis相比Memcached來說,擁有更多的數據結構和並支持更豐富的數據操作,通常在Memcached里,你需要將數據拿到客戶端來進行類似的修改再set回去。這大大增加了網路IO的次數和數據體積。在Redis中,這些復雜的操作通常和一般的GET/SET一樣高效。所以,如果需要緩存能夠支持更復雜的結構和操作,那麼Redis會是不錯的選擇。

2、內存使用效率對比:使用簡單的key-value存儲的話,Memcached的內存利用率更高,而如果Redis採用hash結構來做key-value存儲,由於其組合式的壓縮,其內存利用率會高於Memcached。

3、性能對比:由於Redis只使用單核,而Memcached可以使用多核,所以平均每一個核上Redis在存儲小數據時比Memcached性能更高。而在100k以上的數據中,Memcached性能要高於Redis,雖然Redis最近也在存儲大數據的性能上進行優化,但是比起Memcached,還是稍有遜色。


具體為什麼會出現上面的結論,以下為收集到的資料:

1、數據類型支持不同

與Memcached僅支持簡單的key-value結構的數據記錄不同,Redis支持的數據類型要豐富得多。最為常用的數據類型主要由五種:String、Hash、List、Set和Sorted Set。Redis內部使用一個redisObject對象來表示所有的key和value。redisObject最主要的信息如圖所示:

type代表一個value對象具體是何種數據類型,encoding是不同數據類型在redis內部的存儲方式,比如:type=string代表value存儲的是一個普通字元串,那麼對應的encoding可以是raw或者是int,如果是int則代表實際redis內部是按數值型類存儲和表示這個字元串的,當然前提是這個字元串本身可以用數值表示,比如:」123″ 「456」這樣的字元串。只有打開了Redis的虛擬內存功能,vm欄位欄位才會真正的分配內存,該功能默認是關閉狀態的。

1)String

  • 常用命令:set/get/decr/incr/mget等;

  • 應用場景:String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類;

  • 實現方式:String在redis內部存儲默認就是一個字元串,被redisObject所引用,當遇到incr、decr等操作時會轉成數值型進行計算,此時redisObject的encoding欄位為int。

  • 2)Hash

  • 常用命令:hget/hset/hgetall等

  • 應用場景:我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;

  • 實現方式:Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的介面。如圖所示,Key是用戶ID, value是一個Map。這個Map的key是成員的屬性名,value是屬性值。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。當前HashMap的實現有兩種方式:當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding為ht。

  • 3)List

  • 常用命令:lpush/rpush/lpop/rpop/lrange等;

  • 應用場景:Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;

  • 實現方式:Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構。

  • 4)Set

  • 常用命令:sadd/spop/smembers/sunion等;

  • 應用場景:Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動排重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且set提供了判斷某個成員是否在一個set集合內的重要介面,這個也是list所不能提供的;

  • 實現方式:set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。

  • 5)Sorted Set

  • 常用命令:zadd/zrange/zrem/zcard等;

  • 應用場景:Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。當你需要一個有序的並且不重復的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。

  • 實現方式:Redis sorted set的內部使用HashMap和跳躍表(SkipList)來保證數據的存儲和有序,HashMap里放的是成員到score的映射,而跳躍表裡存放的是所有的成員,排序依據是HashMap里存的score,使用跳躍表的結構可以獲得比較高的查找效率,並且在實現上比較簡單。

  • 2、內存管理機制不同

    在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。當物理內存用完時,Redis可以將一些很久沒用到的value交換到磁碟。Redis只會緩存所有的key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個操作,直到子線程完成swap操作後才可以進行修改。當從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

    對於像Redis和Memcached這種基於內存的資料庫系統來說,內存管理的效率高低是影響系統性能的關鍵因素。傳統C語言中的malloc/free函數是最常用的分配和釋放內存的方法,但是這種方法存在著很大的缺陷:首先,對於開發人員來說不匹配的malloc和free容易造成內存泄露;其次頻繁調用會造成大量內存碎片無法回收重新利用,降低內存利用率;最後作為系統調用,其系統開銷遠遠大於一般函數調用。所以,為了提高內存的管理效率,高效的內存管理方案都不會直接使用malloc/free調用。Redis和Memcached均使用了自身設計的內存管理機制,但是實現方法存在很大的差異,下面將會對兩者的內存管理機制分別進行介紹。

    Memcached默認使用Slab Allocation機制管理內存,其主要思想是按照預先規定的大小,將分配的內存分割成特定長度的塊以存儲相應長度的key-value數據記錄,以完全解決內存碎片問題。Slab Allocation機制只為存儲外部數據而設計,也就是說所有的key-value數據都存儲在Slab Allocation系統里,而Memcached的其它內存請求則通過普通的malloc/free來申請,因為這些請求的數量和頻率決定了它們不會對整個系統的性能造成影響Slab Allocation的原理相當簡單。 如圖所示,它首先從操作系統申請一大塊內存,並將其分割成各種尺寸的塊Chunk,並把尺寸相同的塊分成組Slab Class。其中,Chunk就是用來存儲key-value數據的最小單位。每個Slab Class的大小,可以在Memcached啟動的時候通過制定Growth Factor來控制。假定圖中Growth Factor的取值為1.25,如果第一組Chunk的大小為88個位元組,第二組Chunk的大小就為112個位元組,依此類推。

    當Memcached接收到客戶端發送過來的數據時首先會根據收到數據的大小選擇一個最合適的Slab Class,然後通過查詢Memcached保存著的該Slab Class內空閑Chunk的列表就可以找到一個可用於存儲數據的Chunk。當一條資料庫過期或者丟棄時,該記錄所佔用的Chunk就可以回收,重新添加到空閑列表中。從以上過程我們可以看出Memcached的內存管理制效率高,而且不會造成內存碎片,但是它最大的缺點就是會導致空間浪費。因為每個Chunk都分配了特定長度的內存空間,所以變長數據無法充分利用這些空間。如圖 所示,將100個位元組的數據緩存到128個位元組的Chunk中,剩餘的28個位元組就浪費掉了。

    Redis的內存管理主要通過源碼中zmalloc.h和zmalloc.c兩個文件來實現的。Redis為了方便內存的管理,在分配一塊內存之後,會將這塊內存的大小存入內存塊的頭部。如圖所示,real_ptr是redis調用malloc後返回的指針。redis將內存塊的大小size存入頭部,size所佔據的內存大小是已知的,為size_t類型的長度,然後返回ret_ptr。當需要釋放內存的時候,ret_ptr被傳給內存管理程序。通過ret_ptr,程序可以很容易的算出real_ptr的值,然後將real_ptr傳給free釋放內存。

    Redis通過定義一個數組來記錄所有的內存分配情況,這個數組的長度為ZMALLOC_MAX_ALLOC_STAT。數組的每一個元素代表當前程序所分配的內存塊的個數,且內存塊的大小為該元素的下標。在源碼中,這個數組為zmalloc_allocations。zmalloc_allocations[16]代表已經分配的長度為16bytes的內存塊的個數。zmalloc.c中有一個靜態變數used_memory用來記錄當前分配的內存總大小。所以,總的來看,Redis採用的是包裝的mallc/free,相較於Memcached的內存管理方法來說,要簡單很多。

    3、數據持久化支持

    Redis雖然是基於內存的存儲系統,但是它本身是支持內存數據的持久化的,而且提供兩種主要的持久化策略:RDB快照和AOF日誌。而memcached是不支持數據持久化操作的。

    1)RDB快照

    Redis支持將當前數據的快照存成一個數據文件的持久化機制,即RDB快照。但是一個持續寫入的資料庫如何生成快照呢?Redis藉助了fork命令的 on write機制。在生成快照時,將當前進程fork出一個子進程,然後在子進程中循環所有的數據,將數據寫成為RDB文件。我們可以通過Redis的save指令來配置RDB快照生成的時機,比如配置10分鍾就生成快照,也可以配置有1000次寫入就生成快照,也可以多個規則一起實施。這些規則的定義就在Redis的配置文件中,你也可以通過Redis的CONFIG SET命令在Redis運行時設置規則,不需要重啟Redis。

    Redis的RDB文件不會壞掉,因為其寫操作是在一個新進程中進行的,當生成一個新的RDB文件時,Redis生成的子進程會先將數據寫到一個臨時文件中,然後通過原子性rename系統調用將臨時文件重命名為RDB文件,這樣在任何時候出現故障,Redis的RDB文件都總是可用的。同時,Redis的RDB文件也是Redis主從同步內部實現中的一環。RDB有他的不足,就是一旦資料庫出現問題,那麼我們的RDB文件中保存的數據並不是全新的,從上次RDB文件生成到Redis停機這段時間的數據全部丟掉了。在某些業務下,這是可以忍受的。

    2)AOF日誌

    AOF日誌的全稱是append only file,它是一個追加寫入的日誌文件。與一般資料庫的binlog不同的是,AOF文件是可識別的純文本,它的內容就是一個個的Redis標准命令。只有那些會導致數據發生修改的命令才會追加到AOF文件。每一條修改數據的命令都生成一條日誌,AOF文件會越來越大,所以Redis又提供了一個功能,叫做AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一條記錄的操作只會有一次,而不像一份老文件那樣,可能記錄了對同一個值的多次操作。其生成過程和RDB類似,也是fork一個進程,直接遍歷數據,寫入新的AOF臨時文件。在寫入新文件的過程中,所有的寫操作日誌還是會寫到原來老的AOF文件中,同時還會記錄在內存緩沖區中。當重完操作完成後,會將所有緩沖區中的日誌一次性寫入到臨時文件中。然後調用原子性的rename命令用新的AOF文件取代老的AOF文件。

    AOF是一個寫文件操作,其目的是將操作日誌寫到磁碟上,所以它也同樣會遇到我們上面說的寫操作的流程。在Redis中對AOF調用write寫入後,通過appendfsync選項來控制調用fsync將其寫到磁碟上的時間,下面appendfsync的三個設置項,安全強度逐漸變強。

  • appendfsync no 當設置appendfsync為no的時候,Redis不會主動調用fsync去將AOF日誌內容同步到磁碟,所以這一切就完全依賴於操作系統的調試了。對大多數Linux操作系統,是每30秒進行一次fsync,將緩沖區中的數據寫到磁碟上。

  • appendfsync everysec 當設置appendfsync為everysec的時候,Redis會默認每隔一秒進行一次fsync調用,將緩沖區中的數據寫到磁碟。但是當這一次的fsync調用時長超過1秒時。Redis會採取延遲fsync的策略,再等一秒鍾。也就是在兩秒後再進行fsync,這一次的fsync就不管會執行多長時間都會進行。這時候由於在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞。所以結論就是,在絕大多數情況下,Redis會每隔一秒進行一次fsync。在最壞的情況下,兩秒鍾會進行一次fsync操作。這一操作在大多數資料庫系統中被稱為group commit,就是組合多次寫操作的數據,一次性將日誌寫到磁碟。

  • appednfsync always 當設置appendfsync為always時,每一次寫操作都會調用一次fsync,這時數據是最安全的,當然,由於每次都會執行fsync,所以其性能也會受到影響。

  • 對於一般性的業務需求,建議使用RDB的方式進行持久化,原因是RDB的開銷並相比AOF日誌要低很多,對於那些無法忍數據丟失的應用,建議使用AOF日誌。

    4、集群管理的不同

    Memcached是全內存的數據緩沖系統,Redis雖然支持數據的持久化,但是全內存畢竟才是其高性能的本質。作為基於內存的存儲系統來說,機器物理內存的大小就是系統能夠容納的最大數據量。如果需要處理的數據量超過了單台機器的物理內存大小,就需要構建分布式集群來擴展存儲能力。

    Memcached本身並不支持分布式,因此只能在客戶端通過像一致性哈希這樣的分布式演算法來實現Memcached的分布式存儲。下圖給出了Memcached的分布式存儲實現架構。當客戶端向Memcached集群發送數據之前,首先會通過內置的分布式演算法計算出該條數據的目標節點,然後數據會直接發送到該節點上存儲。但客戶端查詢數據時,同樣要計算出查詢數據所在的節點,然後直接向該節點發送查詢請求以獲取數據。

    相較於Memcached只能採用客戶端實現分布式存儲,Redis更偏向於在伺服器端構建分布式存儲。最新版本的Redis已經支持了分布式存儲功能。Redis Cluster是一個實現了分布式且允許單點故障的Redis高級版本,它沒有中心節點,具有線性可伸縮的功能。下圖給出Redis Cluster的分布式存儲架構,其中節點與節點之間通過二進制協議進行通信,節點與客戶端之間通過ascii協議進行通信。在數據的放置策略上,Redis Cluster將整個key的數值域分成4096個哈希槽,每個節點上可以存儲一個或多個哈希槽,也就是說當前Redis Cluster支持的最大節點數就是4096。Redis Cluster使用的分布式演算法也很簡單:crc16( key ) % HASH_SLOTS_NUMBER。

    為了保證單點故障下的數據可用性,Redis Cluster引入了Master節點和Slave節點。在Redis Cluster中,每個Master節點都會有對應的兩個用於冗餘的Slave節點。這樣在整個集群中,任意兩個節點的宕機都不會導致數據的不可用。當Master節點退出後,集群會自動選擇一個Slave節點成為新的Master節點。

⑽ 分析將數據放到緩存,XML文件,資料庫的優缺點

緩存一般指內存,存放比較常用的需要經常修改的數據比較合適,不適合存放比較大的數據。
XML 數據可以存放一些配置參數,可以表示比較復雜的結構,XML 文件比較小的話還可以,太大的話嚴重影響系統執行效率。
資料庫存放結構化的數據,資料庫的緩存機制和查詢機制可以非常方便的進行數據檢索和更新,在數據安全上資料庫做的比較好。
至於優缺點主要看實際應用,合適的就是最好的。