精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

當前位置:存儲企業動態 → 正文

Reddit如何使用Memcached來存儲3TB的緩存數據

責任編輯:editor006 作者:薛命燈 |來源:企業網D1Net  2017-01-26 21:53:11 本文摘自:INFOQ

Reddit是著名的社交新聞網站,光是在2012年,它的獨立訪客就達到了4000萬,頁面瀏覽量達到了370億次。幾年過去了,網站用戶有增無減,而隨著用戶的增多,網站的響應速度卻一直在改進。這要得益于Reddit使用了大量的緩存。而隨著網站規模不斷增長,緩存數量也隨著增加,那么Reddit是如何做到在增大緩存規模的同時又能保證它們的響應速度的?

我們知道,緩存的命中率越高,整體速度就越快,因為不需要重新從數據源加載數據。除此之外,如何管理緩存,比如緩存的過期時間,新舊緩存的交換,以及緩存的設計等等,它們對緩存的整體性能都有很大影響。來自Reddit的工程師Daniel Ellis在Reddit官方博客上分享了他們是如何使用Memcached集群來存儲網站的緩存數據的。

Reddit的緩存規模和基本策略

Reddit目前使用了54個規格為r3.2xlarge的AWS EC2實例,每個實例擁有61GB內存,也就是說總的緩存大小差不多是3.3TB,而且這些緩存并不包括應用程序的本地緩存。Reddit的緩存包含了多種類型的數據,包括數據庫對象、查詢結果集、函數調用,還有一些看起來不太像緩存的東西,比如限定速率、分布式鎖等等。如何管理這么大規模的緩存是一件很挑戰性的事情,Reddit采用的是“不要把所有雞蛋放在同一個籃子里”的基本策略。也就是說,他們并不是把3.3TB的內存看成一個總的大緩存池,而是按照負載類型對緩存進行分類,每種類型占用一定數量的緩存空間。這樣做有幾個好處:

首先,按照負載類型對緩存進行分區,每種類型的緩存可以獨立地伸縮。例如,對于數據庫緩存來說,如果它的命中率降低,交換率變高,同時數據庫變慢,那么就要考慮對數據庫緩存進行擴展,而它的擴展不會影響到其它類型的緩存。

其次,按照負載類型對緩存進行分區,可以有針對性地對某種類型的緩存進行負載測試,從而預測該類型緩存的使用規模,并作出權衡。

第三個好處跟Memcached的內存分配模型有關系。Memcached按照板塊(slab)來分配內存,例如,1至96字節的對象可能被放到板塊1,97至120字節的對象被放到板塊2,并依此類推。這樣做可以避免出現內存碎片。不過,Memcached的這種分配機制不能動態變化,也就是說一旦設定好了這種模式就不能對其進行修改。如果一開始設定了用來存儲1KB的對象,但后來想用它來存儲500KB的對象,那么交換率就會變得很高。而按照負載類型來區分緩存,那么就可以根據實際數據類型的大小類設定板塊大小。

新版本的Memcached可能支持slab_automove功能,不過這是后話了。

Reddit的緩存類型

接下來我們來看看Reddit的幾種緩存類型。

數據庫對象緩存(thing-cache)

Instances 16 r3.2xlarge
Memcached Version

1.4.30

Total RAM 976 GB
Get Rate ~800k/s
Set Rate ~13k/s
Miss % 1.2-2%
Typical Object Size 384-1184 bytes

數據庫對象緩存是Reddit最大的緩存池。這些對象是無schema的,開發人員可以很容易地對這些對象添加新屬性,而無需對數據庫schema進行變更。這些對象包括用戶評論、鏈接和賬戶等等。該類型緩存是Reddit最繁忙也最有用的緩存,命中率高達99%。

主緩存(cache-main)

Instances 11 r3.2xlarge
Memcached Version

1.4.30

Total RAM

671 GB

Get Rate

~82k/s

Set Rate ~10k/s
Miss %

~75%

Typical Object Size <96 bytes

主緩存是Reddit第二大緩存池。這個緩存是一般性的緩存,里面存放的所有用來展示/r/all的結果集。不過從表格中可以看到,這個緩存的命中率并不高,大概只有25%左右。

渲染緩存(cache-render)

Instances 8 r3.2xlarge
Memcached Version

1.4.30

Total RAM

488 GB

Get Rate

~224k/s

Set Rate ~103k/s
Miss %

~45-55%

Typical Object Size 240-2320 bytes

第三大緩存用來存放渲染過的頁面模板或頁面片段。這個緩存相對安全,就算發生失效,也不會對系統造成太大影響。它的命中率只有大概50%左右,畢竟頁面信息需要不斷更新,所以渲染過的頁面模板或片段也需要更新。再則,就算這個緩存失效,也不會給數據庫負載帶來多大影響,因為用來渲染頁面的上下文內容已經在其它獨立的緩存中加載過了。不過,因為緩存的key是基于上下文內容生成的,如果key發生變化,模板就需要重新緩存,這個需要消耗額外的CPU,也會使頁面響應時間變長。

持久緩存(cache-perma)

Instances 6 r3.2xlarge
Memcached Version 1.4.17
Total RAM

366 GB

Get Rate

24k/s

Set Rate 4k/s
Miss % <1%
Typical Object Size 96-120 bytes

最后一個要細說的緩存,也是命中率最高的緩存——持久緩存,它的命中率超過了99%。這個緩存用來存放數據庫的查詢結果,還有用戶評論和鏈接。為什么管這個緩存叫持久緩存,因為他們使用了讀-改-寫(read-modify-write)的模式。例如,在用戶新增一個評論時,他們會同時更新緩存和后端的數據庫(Cassandra),而不是簡單地讓緩存失效,這樣就避免了需要再次從數據庫加載數據。

非緩存對象池

之前提過,除了上述的幾種緩存,Reddit還使用了速率限定和分布式鎖。

對于一個并發量很大的網站來說,采取速率限定是很重要的一個措施,它可以避免用戶無限制地消耗網站的資源。他們按照時間段把不同的key存放在不同的bucket里,每個key的TTL會隨著每次調用逐步增加。通過檢查這些TTL就可以確保它們不會超出限定的范圍。因為一旦超過限定范圍,該用戶就無法再做任何操作。

另一方面,得益于Memcached的“add”原子操作命令,他們可以實現分布式鎖。因為“add”命令每次會產生一個新的key,只要這個key原先不存在,那么就相當于獲得了一把鎖。鎖用完了就會被移除,下一次調用“add”會生成新的鎖。這個操作保證同時只有一個進程可以獲得這個鎖。不過這也是他們的痛點之一。因為這里存在單點故障問題,一旦需要做遷移或維護,會讓整個網站不可用。Reddit團隊計劃在未來逐步減少甚至避免使用這種鎖。

其它緩存池

除了上述幾種緩存,Reddit還有一些小型的緩存池,比如對象關系的緩存、函數調用結果的緩存等等。因為這些緩存都不大,這里不一一贅述。

mcrouter

上面介紹了Reddit的緩存分區策略,以及各種緩存類型的特點。接下來,我們來看看Reddit是如何使用mcrouter來滿足各種復雜的使用場景的。

mcrouter是由Facebook開源的Memcached連接池。為什么要用連接池?就像訪問數據庫要使用數據庫連接池一樣,使用連接池可以對連接進行重用和管理,避免了重復創建和銷毀連接的開銷。Reddit有很多應用服務器,每個服務器上面運行著多個工作進程,如果這些進程獨自向緩存集群發起連接,那么連接數量會暴增。無法重用連接是一種資源浪費,同時會給緩存集群帶來更大壓力。通過在應用服務器上使用mcrouter,當前服務器上所有進程到緩存集群的連接可以形成一個連接池,并通過mcrouter這個唯一的出口連接到相應的緩存上。

除了作為連接池,mcrouter還能處理很多復雜的場景。mcrouter提供了多種路由類型,比如PrefixSelectorRoute,它通過匹配key的前綴來決定應該到哪個緩存上獲取數據。這樣就可以把特定功能的操作路由到特定的緩存上。

如果要往緩存集群里增加新的緩存實例,那么可以使用WarmUpRoute。新加入的緩存實例被稱為“冷”緩存,而原先的實例叫作“熱”緩存。WarmUpRoute的工作原理是說,把所有寫操作路由到“冷”緩存上,而把未命中的讀操作路由到“熱”緩存上,然后把在“熱”緩存上命中的緩存結果異步地更新到“冷”緩存上,那么下次同樣的讀操作就也可以在“冷”緩存上命中。通過拷貝“熱”緩存里的數據可以避免操作數據庫,保證性能不會受到影響。

mcrouter還提供了FailoverRoute,顧名思義,這個特性可以避免緩存的單點故障,因為它會為一種類型的緩存創建多個緩存池,如果其中一個失效了,請求會被路由到另一個備份的緩存實例上。

Reddit還使用了影子緩存。不同于WarmUpRoute,WarmUpRoute只是把未命中的讀操作拷貝到新實例上,而影子緩存會把讀操作和寫操作都拷貝一份到新的實例上,但前提是不改變數據源。通過影子緩存,他們可以對緩存的負載情況進行觀察,因為新加的實例作為舊實例的“影子”而存在,在不影響舊實例的前提下可以看到整個緩存的工作情況。

mcrouter還支持數據復制,這個功能不僅為緩存提供了高可用性,同時防止出現緩存熱點。

自定義監控

緩存有時候會變成一個黑盒,所以對它們進行監控是很有必要的。GitHub上有一個叫做Diamond的Python腳本可以收集Memcached的基本統計信息,比如對象的交換和命中率等等。不過這些信息還太簡單,Reddit團隊需要知道在發生對象交換時,緩存內部還發生了其它什么狀況。因為通過Memcached的“stats slabs”命令可以看到板塊的度量指標,于是他們基于這些命令自己寫了一個追蹤板塊度量指標的工具。他們還開發了一個簡陋的可視化儀表盤:

Reddit團隊還開發了另外一個工具,叫作mcsauna。這個工具被部署在每個緩存服務器上,它可以檢測網絡流量,并根據配置規則把不同的key保存在不同的bucket里,然后把結果輸出到文件上。FilesCollector會收集這些文件,分析里面的key,并以圖形化的方式呈現出來。從這些圖形上可以看出那些熱點的key。

  展望

緩存為提升網站的響應速度做出了不可磨滅的貢獻。而在如何使用緩存方面,Reddit還有很長的路要走。接下來,他們可能要想著如何通過服務發現來對配置進行自動化,從而實現緩存的自動擴展,而不需要人工的介入。而隨著Memcached版本的不斷改進,他們也要針對現有系統進行調整,從而最大化緩存的性能。

關鍵字:RedditMemcached

本文摘自:INFOQ

x Reddit如何使用Memcached來存儲3TB的緩存數據 掃一掃
分享本文到朋友圈
當前位置:存儲企業動態 → 正文

Reddit如何使用Memcached來存儲3TB的緩存數據

責任編輯:editor006 作者:薛命燈 |來源:企業網D1Net  2017-01-26 21:53:11 本文摘自:INFOQ

Reddit是著名的社交新聞網站,光是在2012年,它的獨立訪客就達到了4000萬,頁面瀏覽量達到了370億次。幾年過去了,網站用戶有增無減,而隨著用戶的增多,網站的響應速度卻一直在改進。這要得益于Reddit使用了大量的緩存。而隨著網站規模不斷增長,緩存數量也隨著增加,那么Reddit是如何做到在增大緩存規模的同時又能保證它們的響應速度的?

我們知道,緩存的命中率越高,整體速度就越快,因為不需要重新從數據源加載數據。除此之外,如何管理緩存,比如緩存的過期時間,新舊緩存的交換,以及緩存的設計等等,它們對緩存的整體性能都有很大影響。來自Reddit的工程師Daniel Ellis在Reddit官方博客上分享了他們是如何使用Memcached集群來存儲網站的緩存數據的。

Reddit的緩存規模和基本策略

Reddit目前使用了54個規格為r3.2xlarge的AWS EC2實例,每個實例擁有61GB內存,也就是說總的緩存大小差不多是3.3TB,而且這些緩存并不包括應用程序的本地緩存。Reddit的緩存包含了多種類型的數據,包括數據庫對象、查詢結果集、函數調用,還有一些看起來不太像緩存的東西,比如限定速率、分布式鎖等等。如何管理這么大規模的緩存是一件很挑戰性的事情,Reddit采用的是“不要把所有雞蛋放在同一個籃子里”的基本策略。也就是說,他們并不是把3.3TB的內存看成一個總的大緩存池,而是按照負載類型對緩存進行分類,每種類型占用一定數量的緩存空間。這樣做有幾個好處:

首先,按照負載類型對緩存進行分區,每種類型的緩存可以獨立地伸縮。例如,對于數據庫緩存來說,如果它的命中率降低,交換率變高,同時數據庫變慢,那么就要考慮對數據庫緩存進行擴展,而它的擴展不會影響到其它類型的緩存。

其次,按照負載類型對緩存進行分區,可以有針對性地對某種類型的緩存進行負載測試,從而預測該類型緩存的使用規模,并作出權衡。

第三個好處跟Memcached的內存分配模型有關系。Memcached按照板塊(slab)來分配內存,例如,1至96字節的對象可能被放到板塊1,97至120字節的對象被放到板塊2,并依此類推。這樣做可以避免出現內存碎片。不過,Memcached的這種分配機制不能動態變化,也就是說一旦設定好了這種模式就不能對其進行修改。如果一開始設定了用來存儲1KB的對象,但后來想用它來存儲500KB的對象,那么交換率就會變得很高。而按照負載類型來區分緩存,那么就可以根據實際數據類型的大小類設定板塊大小。

新版本的Memcached可能支持slab_automove功能,不過這是后話了。

Reddit的緩存類型

接下來我們來看看Reddit的幾種緩存類型。

數據庫對象緩存(thing-cache)

Instances 16 r3.2xlarge
Memcached Version

1.4.30

Total RAM 976 GB
Get Rate ~800k/s
Set Rate ~13k/s
Miss % 1.2-2%
Typical Object Size 384-1184 bytes

數據庫對象緩存是Reddit最大的緩存池。這些對象是無schema的,開發人員可以很容易地對這些對象添加新屬性,而無需對數據庫schema進行變更。這些對象包括用戶評論、鏈接和賬戶等等。該類型緩存是Reddit最繁忙也最有用的緩存,命中率高達99%。

主緩存(cache-main)

Instances 11 r3.2xlarge
Memcached Version

1.4.30

Total RAM

671 GB

Get Rate

~82k/s

Set Rate ~10k/s
Miss %

~75%

Typical Object Size <96 bytes

主緩存是Reddit第二大緩存池。這個緩存是一般性的緩存,里面存放的所有用來展示/r/all的結果集。不過從表格中可以看到,這個緩存的命中率并不高,大概只有25%左右。

渲染緩存(cache-render)

Instances 8 r3.2xlarge
Memcached Version

1.4.30

Total RAM

488 GB

Get Rate

~224k/s

Set Rate ~103k/s
Miss %

~45-55%

Typical Object Size 240-2320 bytes

第三大緩存用來存放渲染過的頁面模板或頁面片段。這個緩存相對安全,就算發生失效,也不會對系統造成太大影響。它的命中率只有大概50%左右,畢竟頁面信息需要不斷更新,所以渲染過的頁面模板或片段也需要更新。再則,就算這個緩存失效,也不會給數據庫負載帶來多大影響,因為用來渲染頁面的上下文內容已經在其它獨立的緩存中加載過了。不過,因為緩存的key是基于上下文內容生成的,如果key發生變化,模板就需要重新緩存,這個需要消耗額外的CPU,也會使頁面響應時間變長。

持久緩存(cache-perma)

Instances 6 r3.2xlarge
Memcached Version 1.4.17
Total RAM

366 GB

Get Rate

24k/s

Set Rate 4k/s
Miss % <1%
Typical Object Size 96-120 bytes

最后一個要細說的緩存,也是命中率最高的緩存——持久緩存,它的命中率超過了99%。這個緩存用來存放數據庫的查詢結果,還有用戶評論和鏈接。為什么管這個緩存叫持久緩存,因為他們使用了讀-改-寫(read-modify-write)的模式。例如,在用戶新增一個評論時,他們會同時更新緩存和后端的數據庫(Cassandra),而不是簡單地讓緩存失效,這樣就避免了需要再次從數據庫加載數據。

非緩存對象池

之前提過,除了上述的幾種緩存,Reddit還使用了速率限定和分布式鎖。

對于一個并發量很大的網站來說,采取速率限定是很重要的一個措施,它可以避免用戶無限制地消耗網站的資源。他們按照時間段把不同的key存放在不同的bucket里,每個key的TTL會隨著每次調用逐步增加。通過檢查這些TTL就可以確保它們不會超出限定的范圍。因為一旦超過限定范圍,該用戶就無法再做任何操作。

另一方面,得益于Memcached的“add”原子操作命令,他們可以實現分布式鎖。因為“add”命令每次會產生一個新的key,只要這個key原先不存在,那么就相當于獲得了一把鎖。鎖用完了就會被移除,下一次調用“add”會生成新的鎖。這個操作保證同時只有一個進程可以獲得這個鎖。不過這也是他們的痛點之一。因為這里存在單點故障問題,一旦需要做遷移或維護,會讓整個網站不可用。Reddit團隊計劃在未來逐步減少甚至避免使用這種鎖。

其它緩存池

除了上述幾種緩存,Reddit還有一些小型的緩存池,比如對象關系的緩存、函數調用結果的緩存等等。因為這些緩存都不大,這里不一一贅述。

mcrouter

上面介紹了Reddit的緩存分區策略,以及各種緩存類型的特點。接下來,我們來看看Reddit是如何使用mcrouter來滿足各種復雜的使用場景的。

mcrouter是由Facebook開源的Memcached連接池。為什么要用連接池?就像訪問數據庫要使用數據庫連接池一樣,使用連接池可以對連接進行重用和管理,避免了重復創建和銷毀連接的開銷。Reddit有很多應用服務器,每個服務器上面運行著多個工作進程,如果這些進程獨自向緩存集群發起連接,那么連接數量會暴增。無法重用連接是一種資源浪費,同時會給緩存集群帶來更大壓力。通過在應用服務器上使用mcrouter,當前服務器上所有進程到緩存集群的連接可以形成一個連接池,并通過mcrouter這個唯一的出口連接到相應的緩存上。

除了作為連接池,mcrouter還能處理很多復雜的場景。mcrouter提供了多種路由類型,比如PrefixSelectorRoute,它通過匹配key的前綴來決定應該到哪個緩存上獲取數據。這樣就可以把特定功能的操作路由到特定的緩存上。

如果要往緩存集群里增加新的緩存實例,那么可以使用WarmUpRoute。新加入的緩存實例被稱為“冷”緩存,而原先的實例叫作“熱”緩存。WarmUpRoute的工作原理是說,把所有寫操作路由到“冷”緩存上,而把未命中的讀操作路由到“熱”緩存上,然后把在“熱”緩存上命中的緩存結果異步地更新到“冷”緩存上,那么下次同樣的讀操作就也可以在“冷”緩存上命中。通過拷貝“熱”緩存里的數據可以避免操作數據庫,保證性能不會受到影響。

mcrouter還提供了FailoverRoute,顧名思義,這個特性可以避免緩存的單點故障,因為它會為一種類型的緩存創建多個緩存池,如果其中一個失效了,請求會被路由到另一個備份的緩存實例上。

Reddit還使用了影子緩存。不同于WarmUpRoute,WarmUpRoute只是把未命中的讀操作拷貝到新實例上,而影子緩存會把讀操作和寫操作都拷貝一份到新的實例上,但前提是不改變數據源。通過影子緩存,他們可以對緩存的負載情況進行觀察,因為新加的實例作為舊實例的“影子”而存在,在不影響舊實例的前提下可以看到整個緩存的工作情況。

mcrouter還支持數據復制,這個功能不僅為緩存提供了高可用性,同時防止出現緩存熱點。

自定義監控

緩存有時候會變成一個黑盒,所以對它們進行監控是很有必要的。GitHub上有一個叫做Diamond的Python腳本可以收集Memcached的基本統計信息,比如對象的交換和命中率等等。不過這些信息還太簡單,Reddit團隊需要知道在發生對象交換時,緩存內部還發生了其它什么狀況。因為通過Memcached的“stats slabs”命令可以看到板塊的度量指標,于是他們基于這些命令自己寫了一個追蹤板塊度量指標的工具。他們還開發了一個簡陋的可視化儀表盤:

Reddit團隊還開發了另外一個工具,叫作mcsauna。這個工具被部署在每個緩存服務器上,它可以檢測網絡流量,并根據配置規則把不同的key保存在不同的bucket里,然后把結果輸出到文件上。FilesCollector會收集這些文件,分析里面的key,并以圖形化的方式呈現出來。從這些圖形上可以看出那些熱點的key。

  展望

緩存為提升網站的響應速度做出了不可磨滅的貢獻。而在如何使用緩存方面,Reddit還有很長的路要走。接下來,他們可能要想著如何通過服務發現來對配置進行自動化,從而實現緩存的自動擴展,而不需要人工的介入。而隨著Memcached版本的不斷改進,他們也要針對現有系統進行調整,從而最大化緩存的性能。

關鍵字:RedditMemcached

本文摘自:INFOQ

電子周刊
回到頂部

關于我們聯系我們版權聲明隱私條款廣告服務友情鏈接投稿中心招賢納士

企業網版權所有 ©2010-2024 京ICP備09108050號-6 京公網安備 11010502049343號

^
  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 玉龙| 勃利县| 泸西县| 三门县| 诸暨市| 延庆县| 晋中市| 防城港市| 高清| 洱源县| 汉川市| 保亭| 余姚市| 黄平县| 沛县| 霞浦县| 贺州市| 马关县| 沈阳市| 鄂托克前旗| 湾仔区| 云林县| 体育| 勃利县| 明星| 车险| 离岛区| 新平| 那曲县| 沾益县| 禄劝| 凤山县| 景谷| 高安市| 甘泉县| 尚志市| 临海市| 南陵县| 金溪县| 余江县| 嘉定区|