導航:首頁 > 源碼編譯 > 內存池slab演算法

內存池slab演算法

發布時間:2024-10-25 19:56:39

php面試題 memcache和redis的區別

Redis與Memcached的區別

傳統MySQL+ Memcached架構遇到的問題

實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:

1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。

2.Memcached與MySQL資料庫數據一致性問題。

3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。

4.跨機房cache同步問題。

眾多NoSQL百花齊放,如何選擇

最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的
問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解
決以下幾種問題

1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。

2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。

3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。

4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。

面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。

Redis適用場景,如何正確的使用

前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-
backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用
Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

2 Redis支持數據的備份,即master-slave模式的數據備份。

3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。


Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。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特有內存模型前後的情況對比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used



從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。

這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行

批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程
池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。

補充的知識點:

memcached和redis的比較

1 網路IO模型

Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述
字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache
coherency和鎖的問題,比如,Memcached最常用的stats
命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。

(Memcached網路IO模型)

Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,
對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實
際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。

2.內存管理方面

Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內
存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可
能會被剔除,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

Redis使用現場申請內存的方式來存儲數據,並且很少使用free-list等方式來優化內存分配,會在一定程度上存在內存碎片,Redis
跟據存儲命令參數,會把帶過期時間的數據單獨存放在一起,並把它們稱為臨時數據,非臨時數據是永遠不會被剔除的,即便物理內存不夠,導致swap也不會剔
除任何非臨時數據(但會嘗試剔除部分臨時數據),這點上Redis更適合作為存儲而不是cache。

3.數據一致性問題

Memcached提供了cas命令,可以保證多個並發訪問操作同一份數據的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。

4.存儲方式及其它方面

Memcached基本只支持簡單的key-value存儲,不支持枚舉,不支持持久化和復制等功能

Redis除key/value之外,還支持list,set,sorted set,hash等眾多數據結構,提供了KEYS

進行枚舉操作,但不能在線上使用,如果需要枚舉線上數據,Redis提供了工具可以直接掃描其mp文件,枚舉出所有數據,Redis還同時提供了持久化和復制等功能。

5.關於不同語言的客戶端支持

在不同語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過因為Memcached發展的時間更久一些,目
前看在客戶端支持方面,Memcached的很多客戶端更加成熟穩定,而Redis由於其協議本身就比Memcached復雜,加上作者不斷增加新的功能
等,對應第三方客戶端跟進速度可能會趕不上,有時可能需要自己在第三方客戶端基礎上做些修改才能更好的使用。

根據以上比較不難看出,當我們不希望數據被踢出,或者需要除key/value之外的更多數據類型時,或者需要落地功能時,使用Redis比使用Memcached更合適。

關於Redis的一些周邊功能

Redis除了作為存儲之外還提供了一些其它方面的功能,比如聚合計算、pubsub、scripting等,對於此類功能需要了解其實現原
理,清楚地了解到它的局限性後,才能正確的使用,比如pubsub功能,這個實際是沒有任何持久化支持的,消費方連接閃斷或重連之間過來的消息是會全部丟
失的,又比如聚合計算和scripting等功能受Redis單線程模型所限,是不可能達到很高的吞吐量的,需要謹慎使用。

總的來說Redis作者是一位非常勤奮的開發者,可以經常看到作者在嘗試著各種不同的新鮮想法和思路,針對這些方面的功能就要求我們需要深入了解後再使用。

總結:

1.Redis使用最佳方式是全部數據in-memory。

2.Redis更多場景是作為Memcached的替代者來使用。

3.當需要除key/value之外的更多數據類型支持時,使用Redis更合適。

4.當存儲的數據不能被剔除時,使用Redis更合適。

談談Memcached與Redis(一)

1. Memcached簡介

Memcached是以LiveJurnal旗下Danga Interactive公司的Bard
Fitzpatric為首開發的高性能分布式內存緩存伺服器。其本質上就是一個內存key-value資料庫,但是不支持數據的持久化,伺服器關閉之後數
據全部丟失。Memcached使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上,只要安裝了libevent即可使
用。在Windows下,它也有一個可用的非官方版本(http://code.jellycan.com/memcached/)。Memcached
的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang,
Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和
WordPress等。

在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d
install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make
install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可
以為其配置不同的啟動參數。

1.1 Memcache配置

Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。

1)-p <num> Memcached的TCP監聽埠,預設配置為11211;

2)-U <num> Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;

3)-s <file> Memcached監聽的UNIX套接字路徑;

4)-a <mask> 訪問UNIX套接字的八進制掩碼,預設配置為0700;

5)-l <addr> 監聽的伺服器IP地址,默認為所有網卡;

6)-d 為Memcached伺服器啟動守護進程;

7)-r 最大core文件大小;

8)-u <username> 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;

9)-m <num> 分配給Memcached使用的內存數量,單位是MB;

10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;

11)-c <num> 最大並發連數,預設配置為1024;

12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;

13)-f <factor> 用於設置chunk大小的遞增因子;

14)-n <bytes> 最小的chunk大小,預設配置為48個位元組;

15)-t <num> Memcached伺服器使用的線程數,預設配置為4個;

16)-L 嘗試使用大內存頁;

17)-R 每個事件的最大請求數,預設配置為20個;

18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;

2. Redis簡介

Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字
符串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等
POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、
Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘
寶,國外像Flickr、Github等均在使用Redis的緩存服務。

Redis的安裝非常方便,只需從http://redis.io/download獲取源碼,然後make && make

install即可。默認情況下,Redis的伺服器啟動程序和客戶端程序會安裝到/usr/local/bin目錄下。在啟動Redis伺服器時,我們
需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。

② 鍐呭瓨綆$悊錛氫竴鏂囪繪噦Linux鍐呭瓨緇勭粐緇撴瀯鍙婇〉闈㈠竷灞

1銆佸唴瀛樻槸浠涔堬紵

1) 鍐呭瓨鍙堢О涓誨瓨錛屾槸 CPU 鑳界洿鎺ュ誨潃鐨勫瓨鍌ㄧ┖闂達紝鐢卞崐瀵間綋鍣ㄤ歡鍒舵垚錛

2) 鍐呭瓨鐨勭壒鐐規槸瀛樺彇閫熺巼蹇錛屾柇鐢典竴鑸涓嶄繚瀛樻暟鎹錛岄潪鎸佷箙鍖栬懼囷紱

2銆佸唴瀛樼殑浣滅敤

1) 鏆傛椂瀛樻斁 cpu 鐨勮繍綆楁暟鎹

2) 紜鐩樼瓑澶栭儴瀛樺偍鍣ㄤ氦鎹㈢殑鏁版嵁

3) 淇濋殰 cpu 璁$畻鏈虹殑紼沖畾鎬у拰楂樻ц兘

1銆乴inux 鍐呭瓨鍦板潃絀洪棿 Linux 鍐呭瓨綆$悊鍏ㄨ矊

2銆佸唴瀛樺湴鍧鈥斺旂敤鎴鋒&鍐呮牳鎬

3銆佸唴瀛樺湴鍧鈥斺擬MU 鍦板潃杞鎹

4銆佸唴瀛樺湴鍧鈥斺斿垎孌墊満鍒

1) 孌甸夋嫨絎

鏇村歀inux鍐呮牳瑙嗛戞暀紼嬫枃妗h祫鏂欏厤璐歸嗗彇鍚庡彴縐佷俊銆 鍐呮牳 銆戣嚜琛岃幏鍙栥

鍐呮牳瀛︿範緗戠珯錛

Linux鍐呮牳婧愮爜/鍐呭瓨璋冧紭/鏂囦歡緋葷粺/榪涚▼綆$悊/璁懼囬┍鍔/緗戠粶鍗忚鏍-瀛︿範瑙嗛戞暀紼-鑵捐璇懼爞

2) 鍒嗘靛疄鐜

5銆佸唴瀛樺湴鍧鈥斺斿垎欏墊満鍒訛紙32 浣嶏級

6銆佺敤鎴鋒佸湴鍧絀洪棿

7銆佸唴鏍告佸湴鍧絀洪棿

8銆佽繘紼嬪唴瀛樼┖闂

鍐呭瓨綆$悊綆楁硶 鈥斺斿硅ㄥ帉鑷宸辯$悊鍐呭瓨鐨勪漢鏉ヨ存槸澶╄祼鐨勭ぜ鐗

1銆佸唴瀛樼庣墖

1) 鍩烘湰鍘熺悊

2) 濡備綍閬垮厤鍐呭瓨紕庣墖

2銆佷紮浼寸郴緇熺畻娉曗斺旂粍緇囩粨鏋

1) 姒傚康

2) 澶栭儴紕庣墖

3銆佷紮浼寸郴緇熺畻娉曗斺旂敵璇峰拰鍥炴敹

1) 鐢寵風畻娉

2) 鍥炴敹綆楁硶

3) 鏉′歡

4銆佸備綍鍒嗛厤 4M 浠ヤ笂鍐呭瓨錛

1) 涓轟綍闄愬埗澶у潡鍐呭瓨鍒嗛厤

2) 鍐呮牳涓鑾峰彇 4M 浠ヤ笂澶у唴瀛樼殑鏂規硶

5銆佷紮浼寸郴緇熲斺斿弽紕庣墖鏈哄埗

1) 涓嶅彲縐誨姩欏

2) 鍙鍥炴敹欏

6銆乻lab 綆楁硶鈥斺斿熀鏈鍘熺悊

1) 鍩烘湰姒傚康

2) 鍐呴儴紕庣墖

7銆乻lab 鍒嗛厤鍣ㄧ殑緇撴瀯

璇︾粏鍙傝冿細

緇忓吀|鍥捐ВLinux鍐呭瓨鎬ц兘浼樺寲鏍稿績鎬濇兂

8銆乻lab 楂橀熺紦瀛

1) 鏅閫氶珮閫熺紦瀛

2) 涓撶敤楂橀熺紦瀛

9銆佸唴鏍告佸唴瀛樻睜

1) 鍩烘湰鍘熺悊

2) 鍐呮牳 API

10銆佺敤鎴鋒佸唴瀛樻睜

1) C++ 瀹炰緥

11銆丏MA 鍐呭瓨

1) 浠涔堟槸 DMA

2) DMA 淇″彿

out of memory 鐨勬椂浠h繃鍘諱簡鍚楋紵no錛屽唴瀛樺啀鍏呰凍涔熶笉鍙浠繪т嬌鐢ㄣ

1銆佸唴瀛樼殑浣跨敤鍦烘櫙

2銆佺敤鎴鋒佸唴瀛樺垎閰嶅嚱鏁

a) 濡傛灉褰撳墠榪炵畫鍐呭瓨鍧楄凍澶 realloc 鐨勮瘽錛屽彧鏄灝 p 鎵鎸囧悜鐨勭┖闂存墿澶э紝騫惰繑鍥 p 鐨勬寚閽堝湴鍧銆傝繖涓鏃跺 q 鍜 p 鎸囧悜鐨勫湴鍧鏄涓鏍風殑

b) 濡傛灉褰撳墠榪炵畫鍐呭瓨鍧椾笉澶熼暱搴︼紝鍐嶆壘涓涓瓚沖熼暱鐨勫湴鏂癸紝鍒嗛厤涓鍧楁柊鐨勫唴瀛橈紝q錛屽苟灝 p 鎸囧悜鐨勫唴瀹 鍒 q錛岃繑鍥 q銆傚苟灝 p 鎵鎸囧悜鐨勫唴瀛樼┖闂村垹闄

3銆佸唴鏍告佸唴瀛樺垎閰嶅嚱鏁

4銆乵alloc 鐢寵峰唴瀛

5銆佺己欏靛紓甯

6銆佺敤鎴瘋繘紼嬭塊棶鍐呭瓨鍒嗘瀽

7銆佸叡浜鍐呭瓨

1) 鍘熺悊

2) shm 鎺ュ彛

1銆丆 鍐呭瓨娉勯湶

2銆丆 閲庢寚閽

3銆丆 璧勬簮璁塊棶鍐茬獊

4銆丼TL 榪浠e櫒澶辨晥

閿欒紺轟緥錛氬垹闄ゅ綋鍓嶈凱浠e櫒錛岃凱浠e櫒浼氬け鏁

姝g『紺轟緥錛氳凱浠e櫒 erase 鏃訛紝闇淇濆瓨涓嬩竴涓榪浠e櫒

5銆丆++ 11 鏅鴻兘鎸囬拡

錛1錛夊師鐞嗗垎鏋愶細

錛2錛夋暟鎹緇撴瀯錛

錛3錛変嬌鐢ㄦ柟娉曪細

6銆丆++ 11 鏇村皬鏇村揩鏇村畨鍏

鍏銆 濡備綍鏌ョ湅鍐呭瓨

鍙浠ラ氳繃 cat /proc/slabinfo 鍛戒護鏌ョ湅

鍙浠ラ氳繃 /proc/sys/vm/drop_caches鏉ラ噴鏀

③ 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


閱讀全文

與內存池slab演算法相關的資料

熱點內容
伺服器香港地址ping不通 瀏覽:283
源碼中的工廠模式 瀏覽:707
為什麼燕窩溯源碼可以更改經銷商 瀏覽:949
和伺服器連接的交換機叫什麼 瀏覽:773
蘋果手機如何設置伺服器 瀏覽:934
迅雷下載游戲需要解壓 瀏覽:853
3d平滑命令 瀏覽:41
必須去車管所解壓 瀏覽:387
室友命令我 瀏覽:311
lol全部命令 瀏覽:40
用什麼APP查指數 瀏覽:921
什麼是作品源碼 瀏覽:671
我的理想程序員該怎麼寫 瀏覽:842
英譯中國現代散文選pdf 瀏覽:448
裝飾設計模式java 瀏覽:23
linuxshell清屏命令 瀏覽:136
惠利app是什麼 瀏覽:779
游戲埠讀取伺服器失敗怎麼弄 瀏覽:878
linux修復mbr 瀏覽:128
磁碟格式化基本命令 瀏覽:578