MongoDB請求出戰(zhàn)!助力騰訊零售優(yōu)碼降本增效
本文主要分享騰訊智慧零售團(tuán)隊(duì)優(yōu)碼業(yè)務(wù)在MongoDB中的應(yīng)用,采用騰訊云MongoDB作為主存儲服務(wù)給業(yè)務(wù)帶來了較大收益,主要包括:高性能、快捷的DDL操作、低存儲成本、超大存儲容量等收益,極大的降低了業(yè)務(wù)存儲成本,并提高了業(yè)務(wù)迭代開發(fā)效率。
一、業(yè)務(wù)場景
更多信息可以訪問騰訊優(yōu)碼官方網(wǎng)站獲得:

1.1 正品通

1.2 門店通

1.3 會員通

二、碼存儲選型
2.1 需求和方案
海量數(shù)據(jù):騰訊優(yōu)碼做的商品二維碼,隨著越來越多的商品使用騰訊優(yōu)碼業(yè)務(wù),二維碼數(shù)據(jù)開始呈現(xiàn)指數(shù)級增長。
關(guān)聯(lián)存儲:碼與碼之間存在1:1和1:N:N的關(guān)聯(lián)關(guān)系,需要存儲這種關(guān)系,并且提供相應(yīng)的關(guān)聯(lián)查詢。
多維度查詢:針對不同的應(yīng)用場景需要提供不同維度的條件查詢。

數(shù)據(jù)同步和一致性問題:這個問題在數(shù)據(jù)量不大的情況下不會有影響。但是如果數(shù)據(jù)量百億甚至千億時(shí)就是一個非常嚴(yán)重的問題。
數(shù)據(jù)容量問題:一般情況下 MySql 的單表數(shù)據(jù)最好維持在百萬級一下,如果單表數(shù)據(jù)量過大之后讀寫都是個問題。那么如果要存儲千億數(shù)據(jù)就要幾千上萬張表,如此多的分表需要業(yè)務(wù)自己維護(hù)時(shí)開發(fā)運(yùn)維都是幾乎不可行的。
成本問題:數(shù)據(jù)冗余存儲,會增加額外的存儲成本。同時(shí)ES 為了保證數(shù)據(jù)可靠性和查詢性能,需要更多的機(jī)器和內(nèi)存。而且 ES 存在數(shù)據(jù)膨脹問題,對于同樣的數(shù)據(jù),需要相當(dāng)MySql來說更大的磁盤。
DDL運(yùn)維問題:MySql 在分庫分布之后,因?yàn)镈DL語句需要操作大量的庫表,因此非常耗時(shí),同時(shí)也容易出錯。根據(jù)我們以前的項(xiàng)目經(jīng)驗(yàn)來說,當(dāng)有幾百張表,單表幾十萬數(shù)據(jù)時(shí),一個簡單的增加字段的DDL語句也需要1小時(shí)甚至更久才能完成。
開發(fā)成本問題:此方案需要業(yè)務(wù)自己維護(hù)分庫分表、數(shù)據(jù)同步和根據(jù)需求選取不同的查詢引擎。不僅整個架構(gòu)復(fù)雜,同時(shí)在做業(yè)務(wù)需求時(shí)需要慎重考慮,稍不注意使用錯的存儲引擎就可能導(dǎo)致性能問題。
水平擴(kuò)容問題:MySql 分庫分表要擴(kuò)容需要業(yè)務(wù)手動 rehash 搬遷數(shù)據(jù),成本非常高,而且很難處理擴(kuò)容過程中的數(shù)據(jù)讀寫問題。

無DDL問題:因?yàn)镸ongoDB 是No Schema 的,因此可以避免MySql的DDL問題。
數(shù)據(jù)自動均勻:MongoDB 有自動rebalance 功能,可以在數(shù)據(jù)分布不均勻的時(shí)候,自動搬遷數(shù)據(jù),保證各個分片間的負(fù)載均勻。
更低的成本:MongoDB 自帶數(shù)據(jù)壓縮,在同等數(shù)據(jù)下,MongoDB 需求的磁盤更少。
更高的性能:MongoDB 最大化的利用了內(nèi)存,在大部分場景下?lián)碛薪咏鼉?nèi)存數(shù)據(jù)庫的性能。經(jīng)過測試MongoDB的單分片讀性能約為3萬QPS。
更多的讀寫方式:雖然MongoDB沒有ES的倒排索引,其支持的查詢方式略遜于ES。但是,MongoDB在擁有大部分ES的查詢能力的同時(shí),其性能遠(yuǎn)高與ES;而且相對MySql 來說MongoDB 的字段類型支持內(nèi)嵌對象和數(shù)組對象,因此能滿足跟多的讀寫需求。
2.3 方案對比
通過前面的分析,我們初步判斷MongoDB擁有更好的表現(xiàn)。因此為了進(jìn)一步確定MongoDB的優(yōu)勢,我們深入對比了MySQL + ES 與MongoDB在各方面的表現(xiàn)。
2.3.1 存儲成本對比


無數(shù)據(jù)同步鏈路:使用MongoDB不需要數(shù)據(jù)同步,因此就不需要維護(hù)canal服務(wù)和kafka隊(duì)列,大大減少開發(fā)和運(yùn)維難度。
人力成本收益:在MySQL+ES架構(gòu)下每次對MySQL集群做添加字段變更,都需運(yùn)維 一定的人日投入,并且存在業(yè)務(wù)抖動風(fēng)險(xiǎn),同時(shí)影響業(yè)務(wù)迭代發(fā)布進(jìn)度,迭代發(fā)布耗時(shí)且風(fēng)險(xiǎn)大。
開發(fā)維護(hù)成本:MongoDB存儲架構(gòu)簡單,一份存儲,無數(shù)據(jù)一致性壓力。
動態(tài)擴(kuò)容:MongoDB 支持隨時(shí)動態(tài)擴(kuò)容,基本不存在容量上限問題,而MySQL在擴(kuò)容時(shí)需要業(yè)務(wù)手動rehash變遷數(shù)據(jù),并自己保證數(shù)據(jù)一致性和完整性。
2.3.3 性能對比

三、MongoDB分片
集群優(yōu)化過程
3.1 分片集群片建選擇+預(yù)分片
use?db_code_xx??sh.enableSharding("db_code_xx")??//n為實(shí)際分片數(shù)??sh.shardCollection("db_code_xx.t_code_xx",?{"id":?"hashed"},?false,{numInitialChunks:8192*n})??
3.2 低峰期滑動窗口設(shè)置
CPU消耗過高,遷移過程甚至消耗90%左右CPU
業(yè)務(wù)訪問抖動,耗時(shí)增加
慢日志增加
異常告警增多
use?config??db.settings.update({"_id":"balancer"},{"$set":{"activeWindow":{"start":"00:00","stop":"06:00"}}},true)?
3.3 寫多數(shù)派優(yōu)化


cmgo-xx:SECONDARY> rs.conf().settings.chainingAllowedtrue??cmgo-xx:SECONDARY>???
cmgo-xx:SECONDARY> rs.status().syncSourceHostxx.xx.xx.xx:7021??cmgo-xx:SECONDARY>???
cfg?=?rs.config()??cfg.settings.chainingAllowed?=?falsers.reconfig(cfg)??
關(guān)于作者
﹀
﹀
﹀
云上MongoDB常見索引問題及最優(yōu)索引規(guī)則大全
騰訊云與MongoDB達(dá)成戰(zhàn)略合作,為全球用戶提供最新MongoDB服務(wù)
↓↓點(diǎn)擊閱讀原文,了解更多優(yōu)惠


