節約內存:Instagram的Redis實踐(轉)

一、問題:

數據庫表數據量極大(千萬條),要求讓服務器更加快速地響應用戶的需求。
二、解決方案:
1.通過高速服務器Cache緩存數據庫數據
2.內存數據庫
三、主流解Cache和數據庫對比
從以上各數據可知,對于我們產品最可行的技術方案有兩種:
1.Memcached?? ? ? ? 內存Key-Value Cache
2.Redis?? ? ? ? ? ? ? ? ? ? 內存數據庫

四,節約內存:Instagram的Redis實踐

Instagram可以說是網拍App的始祖級應用,也是當前最火熱的拍照App之一,Instagram的照片數量已經達到3億,而在Instagram里,我們需要知道每一張照片的作者是誰,下面就是Instagram團隊如何使用Redis來解決這個問題并進行內存優化的。

首先,這個通過圖片ID反查用戶UID的應用有以下幾點需求:

  • 查詢速度要足夠快
  • 數據要能全部放到內存里,最好是一臺EC2的 high-memory 機型就能存儲(17GB或者34GB的,68GB的太浪費了)
  • 要合適Instagram現有的架構(Instagram對Redis有一定的使用經驗,比如這個應用)
  • 支持持久化,這樣在服務器重啟后不需要再預熱

Instagram的開發者首先否定了數據庫存儲的方案,他們保持了KISS原則(Keep It Simple and Stupid),因為這個應用根本用不到數據庫的update功能,事務功能和關聯查詢等等牛X功能,所以不必為這些用不到的功能去選擇維護一個數據庫。

于是他們選擇了Redis,Redis是一個支持持久化的內存數據庫,所有的數據都被存儲在內存中(忘掉VM吧),而最簡單的實現就是使用Redis的String結構來做一個key-value存儲就行了。像這樣:

SET media:1155315 939
GET media:1155315
> 939

其中1155315是圖片ID,939是用戶ID,我們將每一張圖片ID為作key,用戶uid作為value來存成key-value對。然后他們進行了測試,將數據按上面的方法存儲,1,000,000數據會用掉70MB內存,300,000,000張照片就會用掉21GB的內存。對比預算的17GB還是超支了。

(NoSQLFan:其實這里我們可以看到一個優化點,我們可以將key值前面相同的media去掉,只存數字,這樣key的長度就減少了,減少key值對內存的開銷【注:Redis的key值不會做字符串到數字的轉換,所以這里節省的,僅僅是media:這6個字節的開銷】。經過實驗,內存占用會降到50MB,總的內存占用是15GB,是滿足需求的,但是Instagram后面的改進任然有必要)

于是Instagram的開發者向Redis的開發者之一Pieter Noordhuis詢問優化方案,得到的回復是使用Hash結構。具體的做法就是將數據分段,每一段使用一個Hash結構存儲,由于Hash結構會在單個Hash元素在不足一定數量時進行壓縮存儲,所以可以大量節約內存。這一點在上面的String結構里是不存在的。而這個一定數量是由配置文件中的hash-zipmap-max-entries參數來控制的。經過開發者們的實驗,將hash-zipmap-max-entries設置為1000時,性能比較好,超過1000后HSET命令就會導致CPU消耗變得非常大。

于是他們改變了方案,將數據存成如下結構:

HSET "mediabucket:1155" "1155315" "939"
HGET "mediabucket:1155" "1155315"
> "939"

通過取7位的圖片ID的前四位為Hash結構的key值,保證了每個Hash內部只包含3位的key,也就是1000個。

再做一次實驗,結果是每1,000,000個key只消耗了16MB的內存。總內存使用也降到了5GB,滿足了應用需求。

(NoSQLFan:同樣的,這里我們還是可以再進行優化,首先是將Hash結構的key值變成純數字,這樣key長度減少了12個字節,其次是將Hash結構中的subkey值變成三位數,這又減少了4個字節的開銷,如下所示。經過實驗,內存占用量會降到10MB,總內存占用為3GB)

HSET "1155" "315" "939"
HGET "1155" "315"
> "939"

優化無止境,只要肯琢磨。希望你在使用存儲產品時也能如此愛惜內存。

參考:

  • http://blog.nosqlfan.com/html/3379.html
  • http://instagram-engineering.tumblr.com/post/12202313862/storing-hundreds-of-millions-of-simple-key-value
  • http://www.open-open.com/lib/view/open1409643182369.html

轉載于:https://www.cnblogs.com/JoannaQ/p/4470272.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251526.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251526.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251526.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

多數公司容易犯的5個大數據錯誤

多數公司容易犯的5個大數據錯誤 如今,大數據革命驅動了現代工業發展,每天都有越來越多的企業采用大數據技術。然而,盡管大量數據已經存在和應用了很長時間,但如何使用它,仍然存在許多嚴重的錯誤。 以下是企業容易犯的5…

vue --- SPA模式的組件

SPA&#xff1a;單頁應用(Single Page App),具體好處,百度搜索 我們可以想象一個場景&#xff0c;有兩個頁面,每個頁面的頭部都有一張 Logo 圖片.如果每次都寫成原始 HTML 的話,代碼就會重復. // 頁面1的代碼如下:<div classlogo><img srcurl> </div>// 頁面…

(2.15)備份與還原--使用作業備份、清理過期備份、清理歷史記錄、事務日志是否備份過...

一、建立作業備份數據庫 打開SQL SERVER MANAGEMENT STUDIO&#xff0c;啟動SQL SERVER代理服務&#xff08;注意在“控制面板-管理工具-服務”中設置SQL SERVER AGENT的啟動類型為自動&#xff09;。啟動后點擊“作業-新建作業”&#xff0c;彈出一個作業屬性的窗口&#xff0…

javascript+HTML+CSS面試題

今天參加面試&#xff0c;考了我三個小時&#xff0c;考暈了&#xff0c;趕緊補習補習javascript的知識&#xff01;&#xff08;另&#xff1a;人事部明明說招HTML5CSS3jQuery&#xff0c;考1個半小時左右&#xff0c;怎么變成了考傳統DIVCSSjavascript啦&#xff0c;嗚嗚嗚~~…

android 對話框

android 8種對話框&#xff08;Dialog&#xff09;使用方法匯總 作者&#xff1a;gzdaijie本文為作者原創&#xff0c;轉載請注明出處&#xff1a;https://www.cnblogs.com/gzdaijie/p/5222191.html 目錄 1.寫在前面2.代碼示例2.1 普通Dialog&#xff08;圖1與圖2&#xff09;2…

Java 多線程 之 suspend掛起 線程實例

http://www.verejava.com/?id16992945731073 package com.suspend.resume; /*題目: 人們在火車站的售票窗口排隊買火車票1. 北京西站開門2. 打開售票窗口3. 北京西站有10張去長沙的票4. 打開2個售票窗口, 5 假設每個售票窗口每隔1秒鐘買完一張票1. 根據 名詞 找類人們(Person…

算法 --- 插入排序的JS實現

let A [5, 2, 4, 6, 1 ,3];// 插入排序 insertionSort (A) > {console.log("原數組>>>", A);for (let j1; j<A.length; j) {let key A[j];i j -1;while ( i > -1 && A[i] > key) {A[i1] A[i];i i-1;}A[i 1] key;}console.log(&q…

SAFESHE錯誤

今天寫驅動編譯的時候遇到一個問題&#xff0c;link一個比較老的lib時&#xff0c;報錯&#xff1a; error LNK2026: module unsafe for SAFESEH image 解決辦法&#xff1a; 在Source文件中加入一行 NO_SAFESEHTRUE 編譯時候執行 build -cZg轉載于:https://www.cnblogs.com/fa…

python之正則(一)

1.常用正則表達式: \d:數字[0-9] &#xff0c;實例:a\dc -> a1c\D:非數字[^\d],實例:a\Dc -> abc\s:空白字符[<空格>\t\r\n\f\v] 實例:a\sc ->a c\S:非空白字符[^\s] 實例:a\Sc ->abc\w:單詞字符[A-Za-z0-9_] 實例:a\wc ->abc\W:非單詞字符[^\W] *:匹配前…

邏輯讀、物理讀

邏輯讀、物理讀、預讀的基本概念轉載于:https://www.cnblogs.com/mySerilBlog/p/9208215.html

算法 --- 歸并排序的js實現

let mergeSort (A, p, q, r) > {console.log("原數組>>>", A);let n1 q - p 1;let n2 r - q;let L new Array();let R new Array();for (let i 1; i < n1 1; i) {L[i -1] A[p i - 1];}for (let j 1; j < n2 1; j) {R[j-1] A[q j];}L[…

c#中的代理和事件

事件&#xff08;event&#xff09;是一個非常重要的概念&#xff0c;我們的程序時刻都在觸發和接收著各種事件&#xff1a;鼠標點擊事件&#xff0c;鍵盤事件&#xff0c;以及處理操作系統的各種事件。所謂事件就是由某個對象發出的消息。比如用戶按下了某個按鈕&#xff0c;某…

個人技術博客

一. Volley框架 在進行和服務器交互的時候需要發送請求&#xff0c;發現了volley這個好用易上手的框架。volley是一個異步網絡通信框架&#xff0c;它的優點在于輕量級、適用于量小但傳送頻繁的請求操作 搭建請求的第一步就是新建一個請求隊列RequestQueue queue Volley.newRe…

軟件構造 第一章第二節 軟件開發的質量屬性

?軟件構造 第一章第二節 軟件開發的質量屬性 1.軟件系統質量指標 External quality factors affect users 外部質量因素影響用戶 Internal quality factors affect the software itself and its developers 內部質量因素影響軟件本身和它的開發者 External quality results fr…

css --- 讓不同的瀏覽器加載不同的CSS

// 通過條件注釋讓不同的瀏覽器加載不同的CSS <!--[if !IE]><!--> 除IE外都可識別 <!--<![endif]--> <!--[if IE]><!--> 所有的IE可識別 <![endif]--> <!--[if IE 6]> 僅IE6可識別 <![endif]--> <!--[if lt IE 6]> I…

??? ?? ??.??

abcdefg a?? abca abcbca abcabcdeda Cc ?? ??? [a] [ac] [a-c] [Cc] ??? 1>* ( 0~???) 2> (1~???) 3.? () 4 {1,2} {Min,Max} [??]*{} ???.??…

css自媒體查詢

準備工作1&#xff1a;設置Meta標簽 首先我們在使用Media的時候需要先設置下面這段代碼&#xff0c;來兼容移動設備的展示效果&#xff1a; <meta name"viewport" content"widthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalableno">…

css --- 清除浮動

有時我們需要用到浮動,但又不想由于浮動的某些特性影響布局,這時就需要清除浮動 清除浮動主要應用的是CSS中的clear屬性,clear屬性定義了元素的哪一側不允許出現浮動元素. 下面是兩種應用比較廣泛的清除浮動的方法: // 在需要的地方添加定義了clear:both的空標簽 <style>…

數據可視化實現技術(canvas/svg/webGL)

數據可視化的實現技術和工具比較轉載于:https://www.cnblogs.com/knuzy/p/9215632.html

Python 字符串操作(string替換、刪除、截取、復制、連接、比較、查找、包含、大小寫轉換、分割等)...

http://www.cnblogs.com/huangcong/archis.strip() .lstrip() .rstrip(,) 去空格及特殊符號復制字符串Python1 #strcpy(sStr1,sStr2)2 sStr1 strcpy3 sStr2 sStr14 sStr1 strcpy25 print sStr2連接字符串Python1 #strcat(sStr1,sStr2)2 sStr1 strcat3 sStr2 append4 sStr1…