秒殺

在 進(jìn)入mq之前,就進(jìn)行限流,采用令牌桶方法,這樣的話后續(xù)流量到達(dá)mq就會(huì)顯著減少

分庫分表:分庫字段以用戶字段或者訂單號(hào),用戶的話可能會(huì)出現(xiàn)數(shù)據(jù)傾斜問題,有些用戶訂單很多,出現(xiàn)超大訂單問題按訂單號(hào)分的話可能導(dǎo)致不同的訂單分散在各個(gè)庫里,這樣的話通過訂單號(hào)做唯一索引進(jìn)行防重就有問題了

分布式數(shù)據(jù)存儲(chǔ)問題可以分為:數(shù)據(jù)分片、數(shù)據(jù)復(fù)制、數(shù)據(jù)一致性binlog

1、statement 是記錄sql語句到blinlog? ? sql復(fù)雜度高時(shí),解析需要大量精力,那么bug也就可能更多

2、row? 存放實(shí)體的變更前后的狀態(tài)? 不需要解析sql

3、mixed,動(dòng)態(tài)選擇statement還是row模式寫入binlog時(shí),binlog會(huì)使用ack機(jī)制進(jìn)行穿行消費(fèi),每消費(fèi)一條,確認(rèn)一條(那么使用串行的話,消費(fèi)效率就低,單線程無法水平擴(kuò)展,架構(gòu)有缺陷)采用并行的方式。借用MQ進(jìn)行拆分,在binlog處仍然串行消費(fèi),但是至少ack數(shù)據(jù),ack數(shù)據(jù)后發(fā)送到MQ里面的某個(gè)Topic即可,因?yàn)橹谱鱝ck并轉(zhuǎn)發(fā)至MQ,不涉及業(yè)務(wù)邏輯,所以性能消費(fèi)非常小,大概只有幾毫秒或者納秒 發(fā)后仍需要串行消費(fèi),比如上面提到的同一條微博的多次修改就需要串行消費(fèi),而多條微博間的修改則可以并行消費(fèi),它不存在并發(fā)問題。

判斷需要串行消費(fèi)的數(shù)據(jù),比如同一條微博數(shù)據(jù),都會(huì)發(fā)送到 MQ 中間件的串行通道內(nèi)。在同步模塊進(jìn)行同步時(shí),MQ 中間件里的串行通道的數(shù)據(jù)均會(huì)串行執(zhí)行,而多個(gè)串行通道間則可以并發(fā)執(zhí)行。借助 MQ 中間件的此特性,既解決了亂序問題又保證了吞吐量。很多開源的 MQ 實(shí)現(xiàn)都具備此小節(jié)介紹的功能,如 Kafka 提供的 Partition 功能

多張表中使用分布式鎖,比如訂單和商品表均存儲(chǔ)了訂單號(hào),當(dāng)訂單信息或者商品信息發(fā)生變更時(shí)候,因?yàn)閷?duì)訂單號(hào)進(jìn)行加鎖沒在數(shù)據(jù)同步時(shí)候兩張表歸屬同一訂單號(hào)的數(shù)據(jù)實(shí)際為串行執(zhí)行。此方式所以可以解決redis和數(shù)據(jù)庫不一致問題,但是多張表加鎖又降低了吞吐量

采用反查的方法進(jìn)行全量覆蓋,盡量反查binlog的從庫,保證主庫的性能

采用redis的hash結(jié)構(gòu)進(jìn)行局部更新key為? 設(shè)計(jì)為訂單號(hào)+子表標(biāo)識(shí),如 Key 為 OrderId_BaseInfo,表示某一個(gè)訂單的基本信息,或者 Key 為 OrderId_SkuId,表示某一個(gè)訂單下的某個(gè)商品基本信息。在上述訂單案例的多張表變更時(shí),同步程序無須對(duì)多張表間進(jìn)行分布式加鎖協(xié)調(diào),哪張表變更就去更新緩存中對(duì)應(yīng)的局部信息即可。不管是同步性能還是實(shí)現(xiàn)難度均較好。

開發(fā)數(shù)據(jù)對(duì)比模塊,雖然binlog很多升級(jí)改造,但是也有可能導(dǎo)致數(shù)據(jù)不一致的情況,那么我們?yōu)榱吮WC數(shù)據(jù)的一致性,可以采用數(shù)據(jù)對(duì)比定期輪休比對(duì)數(shù)據(jù)庫和緩存,增加延遲重試,如果多次比對(duì)不一致的話,增肌報(bào)警,并保存當(dāng)時(shí)的數(shù)據(jù),之后以數(shù)據(jù)庫中的數(shù)據(jù)為準(zhǔn)刷新緩存延遲重試是為了防止因同步時(shí)差,出現(xiàn)短暫的數(shù)據(jù)不一致但數(shù)據(jù)最終一致性的情況,其次,保留出錯(cuò)現(xiàn)場(chǎng)是為了排查定位問題

熱點(diǎn)問題查詢雖然單機(jī)的機(jī)器配置和程序是有上線的,但是可以進(jìn)行節(jié)點(diǎn)間的主從復(fù)制,這樣不僅可以應(yīng)對(duì)查詢,而且可以做到高可用,以及開發(fā)進(jìn)程應(yīng)用前置緩存,如何發(fā)現(xiàn)熱點(diǎn)數(shù)據(jù)呢,可以采用計(jì)數(shù)器,瞬時(shí)的流量只允許一個(gè)跑到后端,其他的直接返回,跑的那個(gè)負(fù)責(zé)拉取數(shù)據(jù)刷新到應(yīng)用內(nèi)存內(nèi)最后進(jìn)行降級(jí)熔斷兜底,設(shè)置QPS為壓測(cè)的一半

如何保證寫入的時(shí)候無差錯(cuò),比如網(wǎng)絡(luò)中斷、CPU爆滿等等寫入的時(shí)候隨機(jī)寫入,并且按照權(quán)重值進(jìn)行寫入,比如新加的數(shù)據(jù)庫一般容量大,優(yōu)先寫入新加入的數(shù)據(jù)庫。我們?cè)趯懭氲臅r(shí)候可以維護(hù)一個(gè)可以用的列表,這樣在寫入的時(shí)候,如果發(fā)現(xiàn)數(shù)據(jù)庫故障,那么就把他從當(dāng)前可用的數(shù)據(jù)庫列表中移除,如果大面積的數(shù)據(jù)庫都不可用,那么我們需要進(jìn)行擴(kuò)容,那么又如何維護(hù)可用的列表呢?可以通過人工感知的方式,寫服務(wù)的時(shí)候如果超過一半的認(rèn)為掛了,那么就可以進(jìn)行下線,下線的時(shí)候我們可以增加一個(gè)告警,因?yàn)橄戮€的話是一個(gè)耗成本的事情,所以下線的時(shí)候可以設(shè)置一個(gè)告警,然后人工確認(rèn)后再進(jìn)行下線。

增加數(shù)據(jù)同步,當(dāng)寫入成功后同步其他數(shù)據(jù)模塊,如立即刷新緩存






利用緩存+數(shù)據(jù)庫構(gòu)建高可用的扣減方案利用insert代替update,insert的庫稱為任務(wù)庫,存儲(chǔ)每次扣減的原始數(shù)據(jù),不做真實(shí)扣減,也即是不做uptate

數(shù)據(jù)校驗(yàn)>開啟事務(wù)>扣減明細(xì)插入數(shù)據(jù)庫>進(jìn)行緩存扣減>事務(wù)提交主要利用了數(shù)據(jù)庫順序?qū)懭胍雀滦阅芸斓倪@一特性

任務(wù)執(zhí)行可以參考一致性hash,交由到具體的worker進(jìn)行執(zhí)行

扣減返還1、扣減完成后才能返還,必須攜帶扣減號(hào),因?yàn)闆]有扣減號(hào),無法找到當(dāng)前的扣減明細(xì)2、一次扣減可以多次返還


3、返還的數(shù)量要小于等于原始扣減的數(shù)量,需要多扣減ID進(jìn)行加鎖,保證串行化執(zhí)行,因?yàn)榉颠€的流量小所以可以使用加鎖的方法,來規(guī)避超賣的發(fā)生

4、保證接口的冪等性,可以通過數(shù)據(jù)庫設(shè)置唯一索引來防重,進(jìn)而實(shí)現(xiàn)冪等性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容