高併發大容量NoSQL解決方案探索

大數據時代,企業對於DBA也提出更高的需求。同時,NoSQL做爲近幾年新崛起的一門技術,也受到愈來愈多的關注。本文將基於個推SRA孟顯耀先生所負責的DBA工做,和大數據運維相關經驗,分享兩大方向內容:1、公司在KV存儲上的架構演進以及運維須要解決的問題;2、對NoSQL如何選型以及將來發展的一些思考。web

據官方統計,截止目前(2018年4月20日)NoSQL有225個解決方案,具體到每一個公司,使用的都是其中很小的一個子集,下圖中藍色標註的產品是當前個推正在使用的。後端

NoSQL的由來緩存

1946年,第一臺通用計算機誕生。但一直到1970年RDMBS的出現,你們才找到通用的數據存儲方案。到21世紀,DT時代讓數據容量成爲最棘手的問題,對此谷歌和亞馬遜分別提出了本身的NoSQL解決方案,好比谷歌於2006年提出了Bigtable。2009年的一次技術大會上,NoSQL一詞被正式提出,到如今共有225種解決方案。服務器

NoSQL與RDMBS的區別主要在兩點:第一,它提供了無模式的靈活性,支持很靈活的模式變動;第二,可伸縮性,原生的RDBMS只適用於單機和小集羣。而NoSQL一開始就是分佈式的,解決了讀寫和容量擴展性問題。以上兩點,也是NoSQL產生的根本緣由。網絡

實現分佈式主要有兩種手段:副本(Replication)和分片(Sharding)。Replication能解決讀的擴展性問題和HA(高可用),可是沒法解決讀和容量的擴展性。而Sharding能夠解決讀寫和容量的擴展性。通常NoSQL解決方案都是將兩者組合起來。架構

Sharding主要解決數據的劃分問題,主要有基於區間劃分(如Hbase的Rowkey劃分)和基於哈希的劃分。爲了解決哈希分佈式的單調性和平衡性問題,目前業內主要使用虛擬節點。後文所述的Codis也是用虛擬節點。虛擬節點至關於在數據分片和託管服務器之間創建了一層虛擬映射的關係。運維

目前,你們主要根據數據模型和訪問方式進行NoSQL分類。tcp

個推經常使用的幾種NoSQL解決方案分佈式

個推Redis系統規模以下圖。下面介紹一下運維過程遇到的幾個問題。函數

首先是技術架構演進過程。個推以面向APP開發者提供消息推送服務起家,在2012年以前,個推的業務量相對較小,當時咱們用Redis作緩存,用MySQL作持久化。在2012-2016年,隨着個推業務的高速發展,單節點已經沒法解決問題。在MySQL沒法解決高QPS、TPS的狀況下,咱們自研了Redis分片方案。此外,咱們還自研了Redis客戶端,用它來實現基本的集羣功能,支持自定義讀寫比例,同時對故障節點的監測和隔離、慢監控以及每一個節點健康性進行檢查。但這種架構沒有過多考慮運維效率的問題,缺乏運維工具。

當咱們計劃完善運維工具的時候,發現豌豆莢團隊將Codis開源,給咱們提供了一個不錯的選項。

 

個推Codis+的優點

Codis是proxy-based架構,支持原生客戶端,支持基於web的集羣操做和監控,而且也集成了Redis Sentinel。能夠提升咱們運維的工做效率,且HA也更容易落地。

可是在使用過程當中,咱們也發現一些侷限。所以咱們提出了Codis+,即對Codis作一些功能加強。

第1、 採用2N+1副本方案,解決故障期間Master單點的問題。

第2、Redis準半同步。設置一個閾值,好比slave僅在5秒鐘以內可讀。

第3、資源池化。能經過相似HBase增長RegionServer的方式去進行資源擴容。

 

此外,還有機架感知功能和跨IDC的功能。Redis自己是爲了單機房而設置的,沒有考慮到這些問題。

那麼,爲何咱們不用原生的rRedis cluster?這裏有三個緣由:1、原生的集羣,它把路由轉發的功能和實際上的數據管理功能耦合在一個功能裏,若是一個功能出問題就會致使數據有問題;2、在大集羣時,P2P的架構達到一致性狀態的過程比較耗時,codis是樹型架構,不存在這個問題。3、集羣沒有通過大平臺的背書。

此外,關於Redis,咱們最近還在看一個新的NoSQL方案Aerospike,咱們對它的定位是替換部分集羣Redis。Redis的問題在於數據常駐內存,成本很高。咱們指望利用Aerospike減小TCO成本。Aerospike有以下特性:

1、Aerospike數據能夠放內存,也能夠放SSD,並對SSD作了優化。

2、資源池化,運維成本繼續下降。

3、支持機架感知和跨IDC的同步,但這屬於企業級版本功能。

目前咱們內部如今有兩個業務在使用Aerospike,實測下來,發現單臺物理機搭載單塊Inter SSD 4600,能夠達到接近10w的QPS。對於容量較大,但QPS要求不高的業務,能夠選擇Aerospike方案節省TCO。

 

在NoSQL演進的過程當中,咱們也遇到一些運維方面的問題。

 

標準化安裝

咱們共分了三個部分:OS標準化、Redis文件和目錄標準、Redis參數標準化,所有用saltstack + cmdb實現;

擴容和縮容

在技術架構不斷演進過程當中,擴容和縮容的難度也在變低,緣由之一在於codis緩解了一部分問題。固然,若是選擇Aerospike,相關操做就會很是輕鬆。

作好監控,下降運維成本

大部分的運維同窗都應該認真閱讀《SRE:Google運維揭祕》,它在理論層面和實踐層面提出了不少很是有價值的方法論,強烈推薦。

個推Redis監控複雜性

三種集羣架構:自研、codis2和codis3,這三種架構採集數據的方式並不相同。

三類監控對象:集羣、實例、主機,須要有元數據維護邏輯關係,並在全局作聚合。

三種個性化配置:個推的Redis集羣,有的集羣須要有多副本,有的不須要。有的節點容許滿作緩存,有的節點不容許滿。還有持久化策略,有的不作持久化,有的作持久化,有的作持久化+異地備份,這些業務特色對咱們監控靈活性提出很高的要求。

Zabbix是一個很是完備的監控系統,約三年多的時間裏,我都把它做爲主要的監控系統平臺。可是它有兩個缺陷:一是它使用MySQL做爲後端存儲,TPS有上限;二是不夠靈活。好比:一個集羣放在一百臺機器上,要作聚合指標,就很困難。

小米的open-falcon解決了這個問題,可是也會產生一些新問題。好比告警函數不多,不支持字符串,有時候會增長手工的操做等等。後來咱們對它進行功能性補充,便沒有遇到大的問題。

下圖是個推運維平臺。

第一個是IT硬件資源平臺,主要維護主機維度的物理信息。好比說主機在哪一個機架上接的哪一個交換機,在哪一個機房的哪個樓層等等,這是作機架感知和跨IDC等等的基礎。

第二個是CMDB,這個是維護主機上的軟件信息,主機上裝了哪些實例,實例屬於哪些集羣,咱們用了哪些端口,這些集羣有什麼個性化的參數配置,包括告警機制不同,全是經過CMDB實現。CMDB的數據消費方包含grafana監控系統和監控採集程序,採集程序由咱們本身開發。這樣CMDB數據會活起來。若是隻是一個靜態數據沒有消費方,數據就會不一致。

grafana監控系統聚合了多個IDC數據,咱們運維天天只需看一下大屏就夠了。

Slatstack,用於實現自動化發佈,實現標準化並提升工做效率。

採集程序是咱們自行研發的,針對公司的業務特色定製化程度很高。還有ELK(不用logstach,用filebeat)作日誌中心。

 

經過以上這些,咱們搭建出個推整個監控體系。

下面講一下搭建過程當中遇到的幾個坑。

 

1、主從重置,會致使主機節點壓力爆增,主節點沒法提供服務。

主從重置有不少緣由。

Redis版本低,主從重置的機率很高。Redis3主從重置的機率比Redis2大大減小,Redis4支持節點重啓之後也能增量同步,這是Redis自己進行了不少改進。

咱們如今主要使用的是2.8.20,屬於比較容易能產生主從重置。

Redis的主從重置通常是觸發了以下條件中的一個。

一、repl-backlog-size過小,默認是1M,若是你有大量的寫入,很容易擊穿這個緩衝區;二、repl-timeout,Redis主從默認每十秒鐘ping一次,60秒鐘ping不推就會主從重置,緣由多是網絡抖動、總節點壓力過大,沒法響應這個包等;三、tcp-baklog,默認是511。操做系統的默認是限制到128,這個能夠適度提升,咱們提升到2048,這個能對網絡丟包現象進行必定容錯。

以上都是致使主從重置的緣由,主從重置的後果很嚴重。Master壓力爆增沒法提供服務,業務就把這個節點定爲不可用。響應時間變長 Master所在全部主機的節點都會受到影響。

 

2、節點過大,部分是人爲緣由形成的。第一是拆分節點的效率較低,遠遠慢於公司業務量的增加。此外,分片太少。咱們的分片是500個,codis是1024,codis原生是16384個,分片太少也是個問題。若是作自研的分佈式方案,你們必定要把分片數量,稍微設大一點,避免業務發展超過你預期的狀況。節點過大以後,會致使持久化的時間增加。咱們30G的節點要持久化,主機剩餘內存要大於30G,若是沒有,你用Swap致使主機持久化時間大幅增加。一個30G的節點持久化可能要4個小時。負載太高也會致使主從重置,引發連鎖反應。

關於咱們遇到的坑,接下來分享幾個實際的案例。

第一個案例是一次主從重置。這個狀況是在春節前兩天出現的,春節前屬於消息推送業務高峯期。咱們簡單還原一下故障場景。首先是大規模的消息下發致使負載增長;而後,Redis Master壓力增大,TCP包積壓,OS產生丟包現象,丟包把Redis主從ping的包給丟了,觸發了repl-timeout 60秒的閾值,主從就重置了。同時因爲節點過大,致使Swap和IO飽和度接近100%。解決的方法很簡單,咱們先把主從斷開。故障緣由首先是參數不合理,大都是默認值,其次是節點過大讓故障效果進行放大。

第二個案例是codis最近遇到的一個問題。這是一個典型的故障場景。一臺主機掛掉後,codis開啓了主從切換,主從切換後業務沒有受影響,可是咱們去從新接主從時發現接不上,接不上就報了錯。這個錯也不難查,其實就是參數設置太小,也是因爲默認值致使。Slave從主節點拉數據的過程當中,新增數據留在Master緩衝區,若是Slave還沒拉完,Master緩衝區就超過上限,就會致使主從重置,進入一個死循環。

基於這些案例,咱們整理了一份最佳實踐。

1、配置CPU親和。Redis是單機點的結構,不親和會影響CPU的效率。

2、節點大小控制在10G。

3、主機剩餘內存最好大於最大節點大小+10G。主從重置須要有同等大小的內存,這個必定要留夠,若是不留夠,用了Swap,就很難重置成功。

4、儘可能不要用Swap。500毫秒響應一個請求還不如掛掉。

5、tcp-backlog、repl-backlog-size、repl-timeout適度增大。

6、Master不作持久化,Slave作AOF+定時重置。

 

最後是我的的一些思考和建議。選擇適合本身的NoSQL,選擇原則有五點:

一、業務邏輯。首先要了解自身業務特色,好比是KV型就在KV裏面找;若是是圖型就在圖型裏找,這樣範圍一下會減小70%-80%。

二、負載特色,QPS、TPS和響應時間。在選擇NoSQL方案時,能夠從這些指標去衡量,單機在必定配置下的性能指標能達到多少?Redis在主機足夠剩餘狀況下,單臺的QPS40-50萬是徹底OK的。

三、數據規模。數據規模越大,須要考慮的問題就越多,選擇性就越小。到了幾百個TB或者PB級別,幾乎沒太多選擇,就是Hadoop體系。

四、運維成本和可不可監控,可否方便地進行擴容、縮容。

五、其它。好比有沒有成功案例,有沒有完善的文檔和社區,有沒有官方或者企業支持。可讓別人把坑踩過以後咱們平滑過去,畢竟本身踩坑的成本仍是蠻高的。

結語:關於NoSQL的釋義,網絡上曾有一個段子:從1980年的know SQL,到2005年的Not only SQL,再到今日的No SQL!互聯網的發展伴隨着技術概念的更新與相關功能的完善。而技術進步的背後,則是每一位技術人的持續的學習、周密的思考與不懈的嘗試。

相關文章
相關標籤/搜索