自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

存儲 存儲軟件 Redis
目前 Redis 集群存儲超過百億記錄,每天上萬億的讀取訪問。隨著業(yè)務的快速發(fā)展,我們在使用過程中碰到的問題及解決方法給大家做一個分享。主要包括以下方面: 實現(xiàn)機制高可用、業(yè)務極致定制以及服務化。

微博是從 2010 年開始引入 Redis ,現(xiàn)在 Redis 已經(jīng)廣泛應用于微博的多個業(yè)務場景,如關系、計數(shù)、通知提醒等,目前 Redis 集群存儲超過百億記錄,每天上萬億的讀取訪問。隨著業(yè)務的快速發(fā)展,我們在使用過程中碰到的問題及解決方法給大家做一個分享。主要包括以下方面: 實現(xiàn)機制高可用、業(yè)務極致定制以及服務化。

[[330217]]

Redis 2.0 時代(2010 - 2011)

實現(xiàn)機制高可用優(yōu)化

微博最早使用的是 Redis 2.0 版本,在初期業(yè)務規(guī)模不大的時候, Redis 服務運行比較穩(wěn)定。但是隨著業(yè)務數(shù)據(jù)量和訪問量的增加,一些問題逐漸暴露出來:

持久化問題

在我們大多數(shù)業(yè)務場景中 Redis 是當做存儲來使用,會開啟持久化機制。線上采用單機多實例的部署結(jié)構(gòu),服務器的內(nèi)存使用率也會比較高。由于官方版本觸發(fā) bgsave和 bgrewriteaof 操作的時間點是不可控的,依賴于相關的配置項和業(yè)務的寫入模型,因此可能會出現(xiàn)單機部署的多個 Redis 實例同時觸發(fā) bgsave 或 bgrewriteaof 操作,這兩個操作都是通過 fork 出一個子進程來完成的,由于 copy-on-write 機制,可能會導致服務器內(nèi)存很快耗盡, Redis 服務崩潰。

此外在磁盤壓力較大時(生成 rdb、aof 重寫),對 aof 的寫入及 fsync 操作可能會出現(xiàn)阻塞,雖然從 2.4 版本開始 fsync 操作調(diào)整到 bio 線程來做,主線程 aof 的寫入阻塞仍會導致服務阻塞。

主從同步問題

為了提高服務可用性,避免單點問題,我們線上業(yè)務 Redis 大多采用主從結(jié)構(gòu)部署。官方版本的主從同步機制,在網(wǎng)絡出現(xiàn)問題時(如瞬斷),會導致主從重新進行一次全量復制。對單個端口來說,如果數(shù)據(jù)量小,那么這個影響不大,而如果數(shù)據(jù)量比較大的話,就會導致網(wǎng)絡流量暴增,同時 slave 在加載 rdb 時無法響應任何請求。當然官方 2.8 版本支持了 psync 增量復制的機制,一定程度上解決了主從連接斷開會引發(fā)全量復制的問題,但是這種機制受限于復制積壓緩沖區(qū)大小,同時在主庫故障需要執(zhí)行切主操作場景下,主從仍然需要進行全量復制。

版本升級及管理問題

早期 Redis 版本運行不夠穩(wěn)定,經(jīng)常需要修復 bug、支持新的運維需求及版本優(yōu)化,導致版本迭代很頻繁。官方版本在執(zhí)行升級操作時,需要服務重啟,我們大多數(shù)線上業(yè)務都開啟了持久化機制,重啟操作耗時較長,加上使用 Redis 業(yè)務線比較多,版本升級操作的復雜度很高。由于統(tǒng)一版本帶來的運維工作量實在太高,線上 Redis 版本曾經(jīng)一度增加到十幾個,給版本管理也帶來很大的困難。

為了解決以上問題我們對 Redis 原生實現(xiàn)機制做了以下優(yōu)化:

1. 對于持久化機制,采用 rdb + aof 的持久化方式。

aof 文件按固定大小滾動,生成 rdb 文件時記錄當前 aof 的 position,全量的數(shù)據(jù)包含在 rdb 和所記錄位置點之后的 aof 文件,廢棄 aof 重寫機制,生成 rdb 后刪除無效的 aof 文件;增加了定時持久化操作的配置項 cronsave,將單機部署的多個 Redis 實例的持久化操作分散在不同的時間點進行,并且錯開業(yè)務高峰;將對 aof 的寫入操作也放到 bio 線程來做,解決磁盤壓力較大時 Redis 阻塞的問題。

2. 對于主從同步機制,借鑒 MySQL 的復制機制并做了簡化。

使用 rdb + aof 的方式,支持基于 aofpositon 的增量復制。從庫只需與主庫進行一次全量同步同步,后續(xù)主從連接斷開或切主操作,從庫都是與主庫進行增量復制。

 

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

 

對于版本升和管理級的問題, Redis 的核心處理邏輯封裝到動態(tài)庫,內(nèi)存中的數(shù)據(jù)保存在全局變量里,通過外部程序來調(diào)用動態(tài)庫里的相應函數(shù)來讀寫數(shù)據(jù)。版本升級時只需要替換成新的動態(tài)庫文件即可,無須重新載入數(shù)據(jù)。通過這樣的方式,版本升級只需執(zhí)行一條指令,即可在毫秒級別完成代碼的升級,同時對客戶端請求無任何影響。

 

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

 

除了以上幾點,也做了很多其它的優(yōu)化,如主從延遲時間檢測,危險命令認證等。通過逐步的優(yōu)化,內(nèi)部的 Redis 版本也開始進入穩(wěn)定期,應用規(guī)模也在持續(xù)的增加。

業(yè)務極致定制化時代(2012 - 2013)

RedisCounter / LongSet

在某些特定的業(yè)務場景下,隨著業(yè)務規(guī)模的持續(xù)增加, Redis 的使用又暴露出來一些問題,尤其是服務成本問題(小編:是省服務器的意思?)。為此結(jié)合特定的業(yè)務場景我們對 Redis 做了一些定制的優(yōu)化。這里主要介紹一下在關系和計數(shù)兩個業(yè)務場景下做的定制優(yōu)化。

  • 關系

微博關系業(yè)務包含添加、取消關注,判斷關注關系等相關的業(yè)務邏輯,引入 Redis 后使用的是 hash 數(shù)據(jù)結(jié)構(gòu),并且當作存儲使用。但是隨著用戶規(guī)模的快速增長,關系服務 Redis 容量達到十幾 TB,并且還在快速的增長,如何應對成本壓力?

為了解決服務成本問題,我們把 Redis 的角色由 storage 調(diào)整為 cache。

這是因為隨著用戶數(shù)量的增長,業(yè)務模型由初期的熱點數(shù)據(jù)不集中已經(jīng)轉(zhuǎn)變?yōu)橛忻黠@的冷熱之分。對于關注關系變更、判斷關注關系,hash 數(shù)據(jù)結(jié)構(gòu)是最佳的數(shù)據(jù)結(jié)構(gòu),但是存在以下問題:

  1. cache miss 后回寫關注列表性能差,對于關注數(shù)較多的微博會員,回寫操作耗時可達到 10ms,這對于單線程的 Redis 來說是致命的;
  2. Redis hash 結(jié)構(gòu)的內(nèi)存使用率不高,要保證 cahce 的命中率所需的 cache 容量仍然是很大的。

于是,我們定制了 longset 數(shù)據(jù)結(jié)構(gòu),它是一個“固定長度開放尋址的 hash 數(shù)組”,通過選擇合適的 hash 算法及數(shù)組填充率,可實現(xiàn)關注關系變更及判斷的性能與原生 Redis hash 相當,同時 cache miss 后通過 client 重建 longset 結(jié)構(gòu),實現(xiàn) O(1) 復雜度回寫。

通過定制 longset 數(shù)據(jù)結(jié)構(gòu),將關系 Redis 內(nèi)存占用降低了一個數(shù)量級(小編:這該節(jié)約了多少服務器……發(fā)獎金了嗎?),同時保證了服務性能。

 

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

 

計數(shù)

微博有很多計數(shù)場景,如用戶緯度的關注數(shù)、粉絲數(shù),微博緯度的轉(zhuǎn)發(fā)數(shù)、評論數(shù)等。計數(shù)作為微博中一項很重要的數(shù)據(jù),在微博業(yè)務中承擔了很重要的角色。為更好的滿足計數(shù)業(yè)務需求,我們基于 Redis 定制了內(nèi)部的計數(shù)服務。

原生 Redis 為了支持多數(shù)據(jù)類型,需要維護很多指針信息,存儲一份業(yè)務計數(shù)要占到約 80 個字節(jié),內(nèi)存利用率很低。為此我們定制了第一版計數(shù)器 Redis counter,通過預先分配內(nèi)存數(shù)組存儲計數(shù),并且采用 doublehash 解決沖突,減少了原生 Redis 大量的指針開銷。通過以上優(yōu)化將內(nèi)存成本降低到原來的 1/4 以下。(小編:又節(jié)約了 3 / 4 服務器……)

隨著微博的發(fā)展,微博緯度的計數(shù)不斷增加,在原來的轉(zhuǎn)發(fā)數(shù)、評論數(shù)基礎上,又增加了表態(tài)數(shù),2013 年還上線了閱讀數(shù)。 Redis counter 已不能很好的解決這類擴展問題:

  1. 存儲單條微博相關的計數(shù),需要重復存儲微博 mid 信息,并且數(shù)據(jù)全部存儲在內(nèi)存,服務成本較高;
  2. 獲取單條微博全部的計數(shù),需要調(diào)用多次計數(shù)接口,對服務端壓力很大。

為此我們又設計了改進版的計數(shù)器 CounterService,增加如下特性:

  • Schema 支持多列:支持動態(tài)加列,內(nèi)存使用精簡到 bit
  • 冷熱數(shù)據(jù)分離:頻繁訪問的熱數(shù)據(jù)存儲在 memory,訪問較少的冷數(shù)據(jù)存儲在磁盤,降低服務成本
  • LRU 緩存冷數(shù)據(jù):增加 LRU 模塊,緩存訪問到的冷數(shù)據(jù),保證冷數(shù)據(jù)的訪問性能。
  • 異步 IO 線程訪問冷數(shù)據(jù):避免冷數(shù)據(jù)的訪問影響服務的整體性能

 

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

 

通過以上的定制優(yōu)化,我們從根本上解決了計數(shù)業(yè)務的成本及性能問題。

除了以上關系、計數(shù)業(yè)務場景的定制優(yōu)化,為了滿足判斷類業(yè)務場景需求,定制了 BloomFilter 服務;為了滿足 feed 聚合業(yè)務場景需求,定制了 VerctorService 服務;為了降低服務成本,定制了 SSDCache 服務等。(小編:老板感動得流淚了)

服務化時代(2014 -)

Cache Service、SSD Cache

隨著微博業(yè)務的快速增長,Redis 集群規(guī)模也在持續(xù)增加,目前微博 Redis 集群內(nèi)存占用數(shù)十 TB,服務于數(shù)百個業(yè)務線,Redis 集群的管理依然面臨很多的問題。

數(shù)據(jù)遷移問題

隨著時間推移,越來越多的業(yè)務由于數(shù)據(jù)量的增加,單端口到內(nèi)存占用已經(jīng)達到上限,微博內(nèi)部建議單端口內(nèi)存不超過 20GB,因此需要重新拆分端口,這就涉及到數(shù)據(jù)遷移,目前遷移操作是通過內(nèi)部開發(fā)的一個遷移工具來完成的,遷移操作的成本相對較高。

數(shù)據(jù)路由問題

目前的使用方式,需要在業(yè)務代碼中實現(xiàn)數(shù)據(jù)路由規(guī)則,路由規(guī)則的變更需要重新上線代碼,業(yè)務變更復雜度較高。同時節(jié)點配置采用 DNS 的方式,存在實時性和負載不均的問題,雖然使用過程中有對應的解決策略,但是需要一定的運維干預,運維復雜度較高。

HA 系統(tǒng)不成熟

當前的 HA 系統(tǒng)更多的是采用自動發(fā)現(xiàn)問題,手動確認處理的策略,沒有實現(xiàn)真正意義的自動化,運維成本依然很高。

為了解決以上問題,我們在 Redis 基礎上實現(xiàn)服務化框架 CacheService。

CacheService 最早是為了解決內(nèi)部使用 memcached 遇到的問題而開發(fā)的服務化框架,主要包含以下幾個模塊:

配置中心 ConfigServer

微博內(nèi)部的配置服務中心,主要是管理靜態(tài)配置和動態(tài)命名服務的一個遠程服務,并能夠在配置發(fā)生變更的時候?qū)崟r通知監(jiān)聽的 ConfigClient。

資源層

實際的數(shù)據(jù)存儲引擎,初期支持 memcached,后續(xù)又擴展了 Redis、SSDCache 組件,其中 SSDCache 是為了降低服務成本,內(nèi)部開發(fā)的基于 SSD 的存儲組件,用于緩存介于 memory 和 DB 之間的 warm 數(shù)據(jù)。

代理層

代理業(yè)務端的請求,并基于設定的路由規(guī)則轉(zhuǎn)發(fā)到后端的 cache 資源,它本身是無狀態(tài)的。proxy 啟動后會去從 ConfigServer 加載后端 cache 資源的配置列表進行初始化,并接收 ConfigServer 的配置變更的實時通知。

客戶端

提供給業(yè)務方使用的 SDK 包,通過它不需要在業(yè)務代碼中實現(xiàn)數(shù)據(jù)路由規(guī)則,業(yè)務方也無需關心后端 cache 的資源。只需要簡單配置所使用的服務池名 group 和業(yè)務標識 namespace 即可使用 cache 資源,client 從 ConfigServer 獲取 proxy 的節(jié)點列表,選擇合適的 proxy 節(jié)點發(fā)送請求,支持多種負載均衡策略,同時會自動探測 proxy 節(jié)點變更。

集群管理系統(tǒng) ClusterManager

管理集群中各個組件的運行狀態(tài)以保證業(yè)務的 SLA 指標,當出現(xiàn)異常時會自動執(zhí)行運維處理。同時配置變更、數(shù)據(jù)遷移等集群操作也都是由它來負責。

 

用最少的機器支撐萬億級訪問,微博6年Redis優(yōu)化歷程

為支持 Redis 服務化,在服務化框架擴展支持了 Redis proxy,同時為了實

現(xiàn)在線數(shù)據(jù)遷移,參照 Redis cluster 的設計思想,對內(nèi)部 Redis 存儲做了改造,支持 slot 數(shù)據(jù)分片,數(shù)據(jù)遷移操作由 ClusterManager 組件執(zhí)行,完成 slot 的重新規(guī)劃及數(shù)據(jù)遷移。此外還支持 Redis 的 failover 機制,在master 或 slave 節(jié)點故障時會自動執(zhí)行容錯處理。我們 Redis 服務化項目 tribe 是從 2015 年底開始上線,處于逐步完善過程中。

總結(jié)

從對 Redis 的優(yōu)化歷程可以看出,技術的進步是由業(yè)務的需求推動的,我們需要擁抱需求。同時對于一個服務我們需要持續(xù)優(yōu)化并保證服務的運維友好性才能保證服務的生命力。后續(xù)的一些計劃,完善服務化體系中冷熱數(shù)據(jù)分級存儲機制以降低服務成本;引入新的組件以更好的滿足業(yè)務需求、進一步完善集群管理組件降低運維復雜度。

作者:劉東輝

 

劉東輝,新浪微博基礎架構(gòu)組研發(fā)工程師。2013 年加入微博,先后參與微博 Redis、CounterService、SSDCache、CacheService 等基礎組件的設計與開發(fā)工作,目前專注于分布式緩存、存儲方向。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2019-10-28 11:00:37

RedisMySQL數(shù)據(jù)庫

2019-10-31 09:32:58

Redis微博緩存

2018-05-21 09:15:06

Redis美團點評數(shù)據(jù)庫運維

2018-05-28 08:20:12

服務器Redis優(yōu)化

2018-06-05 09:31:01

微博緩存架構(gòu)設計

2021-05-19 20:41:23

日志檢索系統(tǒng)

2013-10-30 09:42:38

Facebook圖搜索大數(shù)據(jù)

2023-08-16 17:54:40

數(shù)據(jù)中心HDDSSD

2018-08-06 10:50:02

新浪微博短視頻

2014-04-22 10:34:57

新浪微博Redis

2017-06-27 15:35:02

機器學習Spark微博應用

2011-04-20 16:35:26

優(yōu)化MySQLNoSQL

2015-07-06 13:36:14

Redis微博關注關系

2023-10-14 15:29:28

RedisFeed

2015-04-16 10:35:08

微博微博如何實現(xiàn)

2013-03-26 10:40:21

2021-01-01 19:18:53

比特幣學習區(qū)塊鏈

2017-04-01 09:04:54

docker自動化

2017-04-11 09:00:24

機器學習發(fā)展歷程啟示

2020-12-03 08:01:42

機器學習人工智能AI
點贊
收藏

51CTO技術棧公眾號