大數(shù)據(jù)時(shí)代,企業(yè)對(duì)于DBA也提出更高的需求。同時(shí),NoSQL作為近幾年新崛起的一門技術(shù),也受到越來(lái)越多的關(guān)注。本文將基于個(gè)推SRA孟顯耀先生所負(fù)責(zé)的DBA工作,和大數(shù)據(jù)運(yùn)維相關(guān)經(jīng)驗(yàn),分享兩大方向內(nèi)容:一、公司在KV存儲(chǔ)上的架構(gòu)演進(jìn)以及運(yùn)維需要解決的問(wèn)題;二、對(duì)NoSQL如何選型以及未來(lái)發(fā)展的一些思考。
據(jù)官方統(tǒng)計(jì),截止目前(2018年4月20日)NoSQL有225個(gè)解決方案,具體到每個(gè)公司,使用的都是其中很小的一個(gè)子集,下圖中藍(lán)色標(biāo)注的產(chǎn)品是當(dāng)前個(gè)推正在使用的。
NoSQL的由來(lái)
1946年,第一臺(tái)通用計(jì)算機(jī)誕生。但一直到1970年RDMBS的出現(xiàn),大家才找到通用的數(shù)據(jù)存儲(chǔ)方案。到21世紀(jì),DT時(shí)代讓數(shù)據(jù)容量成為最棘手的問(wèn)題,對(duì)此谷歌和亞馬遜分別提出了自己的NoSQL解決方案,比如谷歌于2006年提出了Bigtable。2009年的一次技術(shù)大會(huì)上,NoSQL一詞被正式提出,到現(xiàn)在共有225種解決方案。
NoSQL與RDMBS的區(qū)別主要在兩點(diǎn):第一,它提供了無(wú)模式的靈活性,支持很靈活的模式變更;第二,可伸縮性,原生的RDBMS只適用于單機(jī)和小集群。而NoSQL一開(kāi)始就是分布式的,解決了讀寫(xiě)和容量擴(kuò)展性問(wèn)題。以上兩點(diǎn),也是NoSQL產(chǎn)生的根本原因。
實(shí)現(xiàn)分布式主要有兩種手段:副本(Replication)和分片(Sharding)。Replication能解決讀的擴(kuò)展性問(wèn)題和HA(高可用),但是無(wú)法解決讀和容量的擴(kuò)展性。而Sharding可以解決讀寫(xiě)和容量的擴(kuò)展性。一般NoSQL解決方案都是將二者組合起來(lái)。
Sharding主要解決數(shù)據(jù)的劃分問(wèn)題,主要有基于區(qū)間劃分(如Hbase的Rowkey劃分)和基于哈希的劃分。為了解決哈希分布式的單調(diào)性和平衡性問(wèn)題,目前業(yè)內(nèi)主要使用虛擬節(jié)點(diǎn)。后文所述的Codis也是用虛擬節(jié)點(diǎn)。虛擬節(jié)點(diǎn)相當(dāng)于在數(shù)據(jù)分片和托管服務(wù)器之間建立了一層虛擬映射的關(guān)系。
目前,大家主要根據(jù)數(shù)據(jù)模型和訪問(wèn)方式進(jìn)行NoSQL分類。
個(gè)推常用的幾種NoSQL解決方案
個(gè)推Redis系統(tǒng)規(guī)模如下圖。下面介紹一下運(yùn)維過(guò)程遇到的幾個(gè)問(wèn)題。
首先是技術(shù)架構(gòu)演進(jìn)過(guò)程。個(gè)推以面向APP開(kāi)發(fā)者提供消息推送服務(wù)起家,在2012年之前,個(gè)推的業(yè)務(wù)量相對(duì)較小,當(dāng)時(shí)我們用Redis做緩存,用MySQL做持久化。在2012-2016年,隨著個(gè)推業(yè)務(wù)的高速發(fā)展,單節(jié)點(diǎn)已經(jīng)無(wú)法解決問(wèn)題。在MySQL無(wú)法解決高QPS、TPS的情況下,我們自研了Redis分片方案。此外,我們還自研了Redis客戶端,用它來(lái)實(shí)現(xiàn)基本的集群功能,支持自定義讀寫(xiě)比例,同時(shí)對(duì)故障節(jié)點(diǎn)的監(jiān)測(cè)和隔離、慢監(jiān)控以及每個(gè)節(jié)點(diǎn)健康性進(jìn)行檢查。但這種架構(gòu)沒(méi)有過(guò)多考慮運(yùn)維效率的問(wèn)題,缺少運(yùn)維工具。
當(dāng)我們計(jì)劃完善運(yùn)維工具的時(shí)候,發(fā)現(xiàn)豌豆莢團(tuán)隊(duì)將Codis開(kāi)源,給我們提供了一個(gè)不錯(cuò)的選項(xiàng)。
個(gè)推Codis+的優(yōu)勢(shì)
Codis是proxy-based架構(gòu),支持原生客戶端,支持基于web的集群操作和監(jiān)控,并且也集成了Redis Sentinel??梢蕴岣呶覀冞\(yùn)維的工作效率,且HA也更容易落地。
但是在使用過(guò)程中,我們也發(fā)現(xiàn)一些局限。因此我們提出了Codis+,即對(duì)Codis做一些功能增強(qiáng)。
第一、 采用2N+1副本方案,解決故障期間Master單點(diǎn)的問(wèn)題。
第二、Redis準(zhǔn)半同步。設(shè)置一個(gè)閾值,比如slave僅在5秒鐘之內(nèi)可讀。
第三、資源池化。能通過(guò)類似HBase增加RegionServer的方式去進(jìn)行資源擴(kuò)容。
此外,還有機(jī)架感知功能和跨IDC的功能。Redis本身是為了單機(jī)房而設(shè)置的,沒(méi)有考慮到這些問(wèn)題。
那么,為什么我們不用原生的rRedis cluster?這里有三個(gè)原因:一、原生的集群,它把路由轉(zhuǎn)發(fā)的功能和實(shí)際上的數(shù)據(jù)管理功能耦合在一個(gè)功能里,如果一個(gè)功能出問(wèn)題就會(huì)導(dǎo)致數(shù)據(jù)有問(wèn)題;二、在大集群時(shí),P2P的架構(gòu)達(dá)到一致性狀態(tài)的過(guò)程比較耗時(shí),codis是樹(shù)型架構(gòu),不存在這個(gè)問(wèn)題。三、集群沒(méi)有經(jīng)過(guò)大平臺(tái)的背書(shū)。
此外,關(guān)于Redis,我們最近還在看一個(gè)新的NoSQL方案Aerospike,我們對(duì)它的定位是替換部分集群Redis。Redis的問(wèn)題在于數(shù)據(jù)常駐內(nèi)存,成本很高。我們期望利用Aerospike減少TCO成本。Aerospike有如下特性:
一、Aerospike數(shù)據(jù)可以放內(nèi)存,也可以放SSD,并對(duì)SSD做了優(yōu)化。
二、資源池化,運(yùn)維成本繼續(xù)降低。
三、支持機(jī)架感知和跨IDC的同步,但這屬于企業(yè)級(jí)版本功能。
目前我們內(nèi)部現(xiàn)在有兩個(gè)業(yè)務(wù)在使用Aerospike,實(shí)測(cè)下來(lái),發(fā)現(xiàn)單臺(tái)物理機(jī)搭載單塊Inter SSD 4600,可以達(dá)到接近10w的QPS。對(duì)于容量較大,但QPS要求不高的業(yè)務(wù),可以選擇Aerospike方案節(jié)省TCO。
在NoSQL演進(jìn)的過(guò)程中,我們也遇到一些運(yùn)維方面的問(wèn)題。
標(biāo)準(zhǔn)化安裝
我們共分了三個(gè)部分:OS標(biāo)準(zhǔn)化、Redis文件和目錄標(biāo)準(zhǔn)、Redis參數(shù)標(biāo)準(zhǔn)化,全部用saltstack + cmdb實(shí)現(xiàn);
擴(kuò)容和縮容
在技術(shù)架構(gòu)不斷演進(jìn)過(guò)程中,擴(kuò)容和縮容的難度也在變低,原因之一在于codis緩解了一部分問(wèn)題。當(dāng)然,如果選擇Aerospike,相關(guān)操作就會(huì)非常輕松。
做好監(jiān)控,降低運(yùn)維成本
大部分的運(yùn)維同學(xué)都應(yīng)該認(rèn)真閱讀《SRE:Google運(yùn)維揭秘》,它在理論層面和實(shí)踐層面提出了很多非常有價(jià)值的方法論,強(qiáng)烈推薦。
個(gè)推Redis監(jiān)控復(fù)雜性
三種集群架構(gòu):自研、codis2和codis3,這三種架構(gòu)采集數(shù)據(jù)的方式并不相同。
三類監(jiān)控對(duì)象:集群、實(shí)例、主機(jī),需要有元數(shù)據(jù)維護(hù)邏輯關(guān)系,并在全局做聚合。
三種個(gè)性化配置:個(gè)推的Redis集群,有的集群需要有多副本,有的不需要。有的節(jié)點(diǎn)允許滿做緩存,有的節(jié)點(diǎn)不允許滿。還有持久化策略,有的不做持久化,有的做持久化,有的做持久化+異地備份,這些業(yè)務(wù)特點(diǎn)對(duì)我們監(jiān)控靈活性提出很高的要求。
Zabbix是一個(gè)非常完備的監(jiān)控系統(tǒng),約三年多的時(shí)間里,我都把它作為主要的監(jiān)控系統(tǒng)平臺(tái)。但是它有兩個(gè)缺陷:一是它使用MySQL作為后端存儲(chǔ),TPS有上限;二是不夠靈活。比如:一個(gè)集群放在一百臺(tái)機(jī)器上,要做聚合指標(biāo),就很困難。
小米的open-falcon解決了這個(gè)問(wèn)題,但是也會(huì)產(chǎn)生一些新問(wèn)題。比如告警函數(shù)很少,不支持字符串,有時(shí)候會(huì)增加手工的操作等等。后來(lái)我們對(duì)它進(jìn)行功能性補(bǔ)充,便沒(méi)有遇到大的問(wèn)題。
下圖是個(gè)推運(yùn)維平臺(tái)。
第一個(gè)是IT硬件資源平臺(tái),主要維護(hù)主機(jī)維度的物理信息。比如說(shuō)主機(jī)在哪個(gè)機(jī)架上接的哪個(gè)交換機(jī),在哪個(gè)機(jī)房的哪一個(gè)樓層等等,這是做機(jī)架感知和跨IDC等等的基礎(chǔ)。
第二個(gè)是CMDB,這個(gè)是維護(hù)主機(jī)上的軟件信息,主機(jī)上裝了哪些實(shí)例,實(shí)例屬于哪些集群,我們用了哪些端口,這些集群有什么個(gè)性化的參數(shù)配置,包括告警機(jī)制不一樣,全是通過(guò)CMDB實(shí)現(xiàn)。CMDB的數(shù)據(jù)消費(fèi)方包含grafana監(jiān)控系統(tǒng)和監(jiān)控采集程序,采集程序由我們自己開(kāi)發(fā)。這樣CMDB數(shù)據(jù)會(huì)活起來(lái)。如果只是一個(gè)靜態(tài)數(shù)據(jù)沒(méi)有消費(fèi)方,數(shù)據(jù)就會(huì)不一致。
grafana監(jiān)控系統(tǒng)聚合了多個(gè)IDC數(shù)據(jù),我們運(yùn)維每天只需看一下大屏就夠了。
Slatstack,用于實(shí)現(xiàn)自動(dòng)化發(fā)布,實(shí)現(xiàn)標(biāo)準(zhǔn)化并提高工作效率。
采集程序是我們自行研發(fā)的,針對(duì)公司的業(yè)務(wù)特點(diǎn)定制化程度很高。還有ELK(不用logstach,用filebeat)做日志中心。
通過(guò)以上這些,我們搭建出個(gè)推整個(gè)監(jiān)控體系。
下面講一下搭建過(guò)程中遇到的幾個(gè)坑。
一、主從重置,會(huì)導(dǎo)致主機(jī)節(jié)點(diǎn)壓力爆增,主節(jié)點(diǎn)無(wú)法提供服務(wù)。
主從重置有很多原因。
Redis版本低,主從重置的概率很高。Redis3主從重置的概率比Redis2大大減少,Redis4支持節(jié)點(diǎn)重啟以后也能增量同步,這是Redis本身進(jìn)行了很多改進(jìn)。
我們現(xiàn)在主要使用的是2.8.20,屬于比較容易能產(chǎn)生主從重置。
Redis的主從重置一般是觸發(fā)了如下條件中的一個(gè)。
1、repl-backlog-size太小,默認(rèn)是1M,如果你有大量的寫(xiě)入,很容易擊穿這個(gè)緩沖區(qū);2、repl-timeout,Redis主從默認(rèn)每十秒鐘ping一次,60秒鐘ping不推就會(huì)主從重置,原因可能是網(wǎng)絡(luò)抖動(dòng)、總節(jié)點(diǎn)壓力過(guò)大,無(wú)法響應(yīng)這個(gè)包等;3、tcp-baklog,默認(rèn)是511。操作系統(tǒng)的默認(rèn)是限制到128,這個(gè)可以適度提高,我們提高到2048,這個(gè)能對(duì)網(wǎng)絡(luò)丟包現(xiàn)象進(jìn)行一定容錯(cuò)。
以上都是導(dǎo)致主從重置的原因,主從重置的后果很嚴(yán)重。Master壓力爆增無(wú)法提供服務(wù),業(yè)務(wù)就把這個(gè)節(jié)點(diǎn)定為不可用。響應(yīng)時(shí)間變長(zhǎng) Master所在所有主機(jī)的節(jié)點(diǎn)都會(huì)受到影響。
二、節(jié)點(diǎn)過(guò)大,部分是人為原因造成的。第一是拆分節(jié)點(diǎn)的效率較低,遠(yuǎn)遠(yuǎn)慢于公司業(yè)務(wù)量的增長(zhǎng)。此外,分片太少。我們的分片是500個(gè),codis是1024,codis原生是16384個(gè),分片太少也是個(gè)問(wèn)題。如果做自研的分布式方案,大家一定要把分片數(shù)量,稍微設(shè)大一點(diǎn),避免業(yè)務(wù)發(fā)展超過(guò)你預(yù)期的情況。節(jié)點(diǎn)過(guò)大之后,會(huì)導(dǎo)致持久化的時(shí)間增長(zhǎng)。我們30G的節(jié)點(diǎn)要持久化,主機(jī)剩余內(nèi)存要大于30G,如果沒(méi)有,你用Swap導(dǎo)致主機(jī)持久化時(shí)間大幅增長(zhǎng)。一個(gè)30G的節(jié)點(diǎn)持久化可能要4個(gè)小時(shí)。負(fù)載過(guò)高也會(huì)導(dǎo)致主從重置,引起連鎖反應(yīng)。
關(guān)于我們遇到的坑,接下來(lái)分享幾個(gè)實(shí)際的案例。
第一個(gè)案例是一次主從重置。這個(gè)情況是在春節(jié)前兩天出現(xiàn)的,春節(jié)前屬于消息推送業(yè)務(wù)高峰期。我們簡(jiǎn)單還原一下故障場(chǎng)景。首先是大規(guī)模的消息下發(fā)導(dǎo)致負(fù)載增加;然后,Redis Master壓力增大,TCP包積壓,OS產(chǎn)生丟包現(xiàn)象,丟包把Redis主從ping的包給丟了,觸發(fā)了repl-timeout 60秒的閾值,主從就重置了。同時(shí)由于節(jié)點(diǎn)過(guò)大,導(dǎo)致Swap和IO飽和度接近100%。解決的方法很簡(jiǎn)單,我們先把主從斷開(kāi)。故障原因首先是參數(shù)不合理,大都是默認(rèn)值,其次是節(jié)點(diǎn)過(guò)大讓故障效果進(jìn)行放大。
第二個(gè)案例是codis最近遇到的一個(gè)問(wèn)題。這是一個(gè)典型的故障場(chǎng)景。一臺(tái)主機(jī)掛掉后,codis開(kāi)啟了主從切換,主從切換后業(yè)務(wù)沒(méi)有受影響,但是我們?nèi)ブ匦陆又鲝臅r(shí)發(fā)現(xiàn)接不上,接不上就報(bào)了錯(cuò)。這個(gè)錯(cuò)也不難查,其實(shí)就是參數(shù)設(shè)置過(guò)小,也是由于默認(rèn)值導(dǎo)致。Slave從主節(jié)點(diǎn)拉數(shù)據(jù)的過(guò)程中,新增數(shù)據(jù)留在Master緩沖區(qū),如果Slave還沒(méi)拉完,Master緩沖區(qū)就超過(guò)上限,就會(huì)導(dǎo)致主從重置,進(jìn)入一個(gè)死循環(huán)。
基于這些案例,我們整理了一份最佳實(shí)踐。
一、配置CPU親和。Redis是單機(jī)點(diǎn)的結(jié)構(gòu),不親和會(huì)影響CPU的效率。
二、節(jié)點(diǎn)大小控制在10G。
三、主機(jī)剩余內(nèi)存最好大于最大節(jié)點(diǎn)大小+10G。主從重置需要有同等大小的內(nèi)存,這個(gè)一定要留夠,如果不留夠,用了Swap,就很難重置成功。
四、盡量不要用Swap。500毫秒響應(yīng)一個(gè)請(qǐng)求還不如掛掉。
五、tcp-backlog、repl-backlog-size、repl-timeout適度增大。
六、Master不做持久化,Slave做AOF+定時(shí)重置。
最后是個(gè)人的一些思考和建議。選擇適合自己的NoSQL,選擇原則有五點(diǎn):
1、業(yè)務(wù)邏輯。首先要了解自身業(yè)務(wù)特點(diǎn),比如是KV型就在KV里面找;如果是圖型就在圖型里找,這樣范圍一下會(huì)減少70%-80%。
2、負(fù)載特點(diǎn),QPS、TPS和響應(yīng)時(shí)間。在選擇NoSQL方案時(shí),可以從這些指標(biāo)去衡量,單機(jī)在一定配置下的性能指標(biāo)能達(dá)到多少?Redis在主機(jī)足夠剩余情況下,單臺(tái)的QPS40-50萬(wàn)是完全OK的。
3、數(shù)據(jù)規(guī)模。數(shù)據(jù)規(guī)模越大,需要考慮的問(wèn)題就越多,選擇性就越小。到了幾百個(gè)TB或者PB級(jí)別,幾乎沒(méi)太多選擇,就是Hadoop體系。
4、運(yùn)維成本和可不可監(jiān)控,能否方便地進(jìn)行擴(kuò)容、縮容。
5、其它。比如有沒(méi)有成功案例,有沒(méi)有完善的文檔和社區(qū),有沒(méi)有官方或者企業(yè)支持??梢宰寗e人把坑踩過(guò)之后我們平滑過(guò)去,畢竟自己踩坑的成本還是蠻高的。
結(jié)語(yǔ):關(guān)于NoSQL的釋義,網(wǎng)絡(luò)上曾有一個(gè)段子:從1980年的know SQL,到2005年的Not only SQL,再到今日的No SQL!互聯(lián)網(wǎng)的發(fā)展伴隨著技術(shù)概念的更新與相關(guān)功能的完善。而技術(shù)進(jìn)步的背后,則是每一位技術(shù)人的持續(xù)的學(xué)習(xí)、周密的思考與不懈的嘗試。
評(píng)論
查看更多