你好,是我琉憶。
今天是週五了,再上一天班就週末了,提早祝你們週末愉快。嘿嘿。
這篇文章是本週Memcache和Redis內存數據庫常考的專題。
本週一和週三更新的文章路徑:
PHP面試常考內容之Memcache和Redis(1)
PHP面試常考內容之Memcache和Redis(2)
本週(2019.2-18至2-22)的文章內容點爲如下幾點,更新時間爲每週一三五,能夠關注本欄持續關注,感謝你的支持。html
1、什麼是Memcache?
2、Memcache有什麼特徵?
3、Memcache的內存管理機制是什麼樣的?
4、Memcache和Memcached有什麼區別?
5、如何操做Memcache?
6、如何使用Memcache作Session共享?
7、什麼是Redis?
8、如何使用Redis?
9、使用Redis須要注意哪些問題?
10、新增:Redis和Memcache有什麼不一樣?
11、新增:Redis如何實現持久化?
12、Memcache和Redis常考的面試題
本章節的內容將會被分爲三篇文章進行講解完整塊內容,第一篇主要講解一到六,第二篇主要講解七到十一(新增了十和十一),第三篇圍繞第十二點。node
本身整理了一篇「 PHP不一樣等級面試都問什麼?」的文章,關注公衆號:「 琉憶編程庫」,回覆:「 等級」,我發給你。
如下正文的部份內容來自《PHP程序員面試筆試真題解析》書籍,若是轉載請保留出處:程序員
答案:Memcache的工做就是在專門的機器內存裏維護一張巨大的hash表,存儲常常被讀寫的一些文件與數據,從而極大地提升網站的運行效率。
Memcache的程序運行在一個或多個服務器中,Memcache把所有的數據保存在內存中,經過hash表的方式,每條數據由key/value的形式構成,隨時接受客戶端的請求,而後返回結果。面試
客戶端與Memcache創建鏈接後,存儲對象主要是經過惟一的key存儲value到內存中,取數據時經過這個key從內存中獲取對應的value。因爲Memcache的數據是存儲在內存中而不是保存在cache文件中,因此Memcache訪問比較快,可是因爲這些數據不是永久化存儲,因此不建議存儲重要數據在Memcache中,由於重啓服務器後這些數據就會消失。redis
答案:Memcache是一個高性能的分佈式內存對象緩存系統,主要經過在內存裏維護一個巨大的hash表進行數據緩存。它主要是將數據存儲到內存中,而後從內存中讀取數據,從而提升讀取速度。它主要經過key-value的形式存儲各類數據,包括圖像、視頻、文件等。
它具備如下幾點優勢:算法
(1)支持多臺服務器使用Memcache,因爲Memcache的存儲數據大小必須小於內存的大小,因此能夠將Memcache使用在多臺服務器上,增長緩存容量;數據庫
(2)支持均衡請求。當使用多臺Memcache服務器時,能夠均衡請求,避免全部請求都進入一臺Memcache服務器中,避免服務器掛掉而丟失數據;編程
(3)支持分佈式,能夠解決緩存自己水平線性擴展的問題和緩存大併發下的自身性能問題,避免緩存的單點故障問題;segmentfault
(4)支持部分容災問題,若是多臺服務器存儲了Memcache數據,其中一臺Memcache服務器掛掉,部分請求仍是能夠在其它服務器的Memcache中命中,爲修復掛掉的服務器爭取一些時間。後端
答案:若是要合理地使用Memcache緩存,那麼須要注意如下幾點內容:
(1)由於Memcache支持最大的存儲對象大小爲1M,因此當合理使用Memcache緩存時,要求不能往Memcache存儲一個大於1MB的數據;
(2)Memcache存儲的全部數據,若是數據大小分佈於各類chunk大小區間,從64B到1MB都有,那麼會形成內存的極大浪費和Memcache的異常。因此須要注意數據大小的分佈區間;
(3)key的長度不能大於250個字符;
(4)虛擬主機不容許運行Memcache服務,因此不能把Memcache部署到虛擬主機中;
(5)由於Memcache能夠輕鬆訪問到,因此能夠運行在不安全的環境中,若是對數據安全要求高,那麼須要着重考慮運行環境的安全問題;
(6)由於Memcache存儲的數據都在內存中,服務器掛掉就會清空內存,因此緩存中的數據儘可能是丟失了也不會有太大影響的數據。
若是緩存中的數據量過大,那麼能夠採起如下的辦法:
(1)使用Memcache服務器集羣的方法,首先是將數據安排放在不一樣的Memcache服務器上,能夠將不一樣硬件服務器上的Memcache服務器再作成一個數據互相備份的組,避免數據的單點丟失問題;
(2)緩存數據到數據庫中,在數據庫中先建一張表來講明Memcache服務器集羣中緩存數據的存放邏輯,而後實現把緩存數據存到數據庫中,能夠保證數據庫和緩存的數據雙向存取。
答案:Redis是一個徹底開源免費的高性能key-value數據庫,具備豐富的數據類型,能夠支持數據的持久化,將內存中的數據保存在磁盤中,當重啓服務器時能夠再次加載使用。
Memcache是一個高性能的分佈式內存對象緩存系統,用於動態的Web應用中幫助數據庫減輕負擔,在內存中緩存數據和對象,減小每次訪問數據時對數據庫的訪問次數,從而提升訪問速度。
它們具備如下幾點區別:
(1)Redis和Memcache的最大區別是,雖然Memcache和Redis都是將數據存在內存中,是內存數據庫,但Redis存儲時,並非全部的數據都一直存儲在內存中,而Memcache存儲時,數據都存在內存中;
(2)數據安全問題,因爲memecache 把數據所有存在內存之中,服務器掛掉後,重啓服務器數據就會丟失,而Redis能夠按期保存數據到磁盤中作持久化存儲,當須要時能夠再加載使用。對於災難恢復,Memcache掛掉後,數據不可恢復,但Redis數據丟失後能夠經過aof恢復;
(3)Redis支持多種數據結構存儲,例如list,set,hash等數據結構的存儲,而Memcache主要是在內存中維護一個統一的巨大的hash表進行存儲數據,只支持簡單的key/value類型的數據存儲,但Memcache能夠存儲圖片、視頻、文件及數據庫檢索結果等;
(4)數據備份問題,Redis支持數據的備份,即master-slave模式的數據備份。而Memcache不支持數據持久化,因此沒法進行數據備份;
(5)在內存使用率上,使用簡單的key-value存儲的話,Memcached的內存利用率更高,而若是Redis採用hash結構來作key-value存儲,因爲其組合式的壓縮,其內存利用率會高於Memcached。具體和應用場景、數據特性有關;
(6)在線程上的比較,Memcache是支持多線程的,而Redis只支持單線程,因此CPU利用方面Memcache優於Redis;
(7)它們的擴展都須要作集羣;實現方式:master-slave、Hash;
(8)數據的讀寫方面,Redis和Memcache在寫入性能上面差異不大,讀取性能上面尤爲是批量讀取性能上Memcache更強。
答案:1.twemproxy,大概概念是,它相似於一個代理方式,使用方法和普通redis無任何區別,設置好它下屬的多個redis實例後,使用時在本須要鏈接redis的地方改成鏈接twemproxy,它會以一個代理的身份接收請求並使用一致性hash算法,將請求轉接到具體redis,將結果再返回twemproxy。使用方式簡便(相對redis只需修改鏈接端口),對舊項目擴展的首選。 問題:twemproxy自身單端口實例的壓力,使用一致性hash後,對redis節點數量改變時候的計算值的改變,數據沒法自動移動到新的節點。
2.codis,目前用的最多的集羣方案,基本和twemproxy一致的效果,但它支持在 節點數量改變狀況下,舊節點數據可恢復到新hash節點。
3.redis cluster3.0自帶的集羣,特色在於他的分佈式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
4.在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,而後去對應的redis實例操做數據。 這種方式對hash層代碼要求比較高,考慮部分包括,節點失效後的替代算法方案,數據震盪後的自動腳本恢復,實例的監控,等等。
本身整理了一篇「 PHP不一樣等級面試都問什麼?」的文章,關注公衆號:「 琉憶編程庫」,回覆:「 等級」,我發給你。
答案:(1)、會話緩存(Session Cache)
最經常使用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其餘存儲(如Memcached)的優點在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,若是用戶的購物車信息所有丟失,大部分人都會不高興的,如今,他們還會這樣嗎?
幸運的是,隨着 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣爲人知的商業平臺Magento也提供Redis的插件。
(2)、全頁緩存(FPC)
除基本的會話token以外,Redis還提供很簡便的FPC平臺。回到一致性問題,即便重啓了Redis實例,由於有磁盤的持久化,用戶也不會看到頁面加載速度的降低,這是一個極大改進,相似PHP本地FPC。
再次以Magento爲例,Magento提供一個插件來使用Redis做爲全頁緩存後端。
此外,對WordPress的用戶來講,Pantheon有一個很是好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
(3)、隊列
Reids在內存存儲引擎領域的一大優勢是提供 list 和 set 操做,這使得Redis能做爲一個很好的消息隊列平臺來使用。Redis做爲隊列使用的操做,就相似於本地程序語言(如Python)對 list 的 push/pop 操做。
若是你快速的在Google中搜索「Redis queues」,你立刻就能找到大量的開源項目,這些項目的目的就是利用Redis建立很是好的後端工具,以知足各類隊列需求。例如,Celery有一個後臺就是使用Redis做爲broker,你能夠從這裏去查看。
(4),排行榜/計數器
Redis在內存中對數字進行遞增或遞減的操做實現的很是好。集合(Set)和有序集合(Sorted Set)也使得咱們在執行這些操做的時候變的很是簡單,Redis只是正好提供了這兩種數據結構。因此,咱們要從排序集合中獲取到排名最靠前的10個用戶–咱們稱之爲「user_scores」,咱們只須要像下面同樣執行便可:
固然,這是假定你是根據你用戶的分數作遞增的排序。若是你想返回用戶及用戶的分數,你須要這樣執行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你能夠在這裏看到。
(5)、發佈/訂閱
最後(但確定不是最不重要的)是Redis的發佈/訂閱功能。發佈/訂閱的使用場景確實很是多。我已看見人們在社交網絡鏈接中使用,還可做爲基於發佈/訂閱的腳本觸發器,甚至用Redis的發佈/訂閱功能來創建聊天系統!(不,這是真的,你能夠去核實)。
答案:若是Redis被當作緩存使用,使用一致性哈希實現動態擴容縮容。
若是Redis被當作一個持久化存儲使用,必須使用固定的keys-to-nodes映射關係,節點的數量一旦肯定不能變化。不然的話(即Redis節點須要動態變化的狀況),必須使用能夠在運行時進行數據再平衡的一套系統,而當前只有Redis集羣能夠作到這樣。
答案:一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用狀況,若是大於maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
因此咱們不斷地穿越內存限制的邊界,經過不斷達到邊界而後不斷地回收回到邊界如下。
若是一個命令的結果致使大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
答案:若是你使用的是32位的Redis實例,能夠好好利用Hash,list,sorted set,set等集合類型數據,由於一般狀況下不少小的Key-Value能夠用更緊湊的方式存放到一塊兒。
答案:客戶端分區就是在客戶端就已經決定數據會被存儲到哪一個redis節點或者從哪一個redis節點讀取。大多數客戶端已經實現了客戶端分區。
代理分區 意味着客戶端將請求發送給代理,而後代理決定去哪一個節點寫數據或者讀數據。代理根據分區規則決定請求哪些Redis實例,而後根據Redis的響應結果返回給客戶端。redis和memcached的一種代理實現就是Twemproxy
查詢路由(Query routing) 的意思是客戶端隨機地請求任意一個redis實例,而後由Redis將請求轉發給正確的Redis節點。Redis Cluster實現了一種混合形式的查詢路由,但並非直接將請求從一個redis節點轉發到另外一個redis節點,而是在客戶端的幫助下直接redirected到正確的redis節點。
本身根據不一樣PHP不一樣等級面試時, 會問哪些PHP常考的知識點整理成了一篇文章
本身整理了一篇「 PHP不一樣等級面試都問什麼?」的文章,關注公衆號:「 琉憶編程庫」,回覆:「 等級」,我發給你。
更多相關面試常考真題能夠閱讀《PHP程序員面試筆試真題解析》。
預告:下週(2019.2.25至2019.3.1)一三五將更新的主題爲:PHP面試之會話控制、網絡協議、相關的面試題。
以上內容摘自《PHP程序員面試筆試真題解析》書籍,該書已在天貓、京東、噹噹等電商平臺銷售。
更多PHP相關的面試知識、考題能夠關注公衆號獲取:琉憶編程庫
對本文有什麼問題或建議均可以進行留言,我將不斷完善追求極致,感謝大家的支持。