好代碼實踐:基於 Redis 的輕量級分佈式均衡消費隊列
一 我對好代碼的看法
1 什麼是好代碼
如果你讀過《設計模式之美》,你可能會覺得玩轉各種設計模式,符合設計模式的 6 大基本原則的代碼就是好代碼;如果讀過《clean code》,你可能會覺得好代碼的一個標準是——整潔;如果你經常研讀 Spring 源碼,你可能會覺得精妙的設計、高度的抽象、靈活的配置纔是好代碼,就像是一本書,一千個讀者眼中有一千個哈姆雷特,每個人按照自己的認知都會有自己的判斷。
2 我認爲的好代碼
如前文所述,不同的人對好代碼的認知標準是不同的,我認爲的好代碼,也侷限於我的認知水平,也許今天我覺得是好代碼,隨着認知的提升,改天也會有不同的想法;就目前的認知而言,我認爲的好代碼的一些特點:
可用性
對,你沒看錯,好代碼,一定是可用的,可以 work 的,如果一段代碼只是看着好看,用了各種花裏胡哨的編碼技巧、手法,但是不能 work,那就失去了它存在的意義了。所以,好代碼,最最最重要的一個特點就是可用性。
可讀性
我認爲好代碼的第二個特點就是可讀性,我們的寫代碼的目標用戶有兩類,第一類是給編譯器看的;第二類是給維護它的程序員看的。針對第一類用戶,只要你符合它的語法規範,它就認識,它就可以執行;而第二類用戶,就是後期不斷的維護它、升級它的程序員同學,如果這段代碼,維護它的人都讀不懂,那他的長期存在的意義也就不大了。
其他優秀的特點
可維護性、可擴展性、可複用性、強魯棒性、可測試性等。
好代碼的其他優秀特點太多了,不一一列舉了。
3 讓 code 在計算機上起舞
回到根源,我們寫代碼的目的是幹嘛?爲的是把我們的所思所想通過計算機認識的指令告訴它,讓它來替我們做我們想做的事情。好代碼,不僅可以簡單地完成我們的所思所想,更能夠快速、高效、完備地執行。讓我們的 code 一起在計算機上起舞吧。
二 我們爲什麼要做
2020 年五一期間,當大家都在享受五一假期的快樂時光時,我們突然收到 hbase 報警,整個 hbase 的 IO 壓力已經接近瓶頸,直接影響數據讀寫,臨時擴容 hbase 才勉強支撐過去。按照這個發展趨勢,一旦遇到業務高峯時,hbase 的讀寫直接會給整個業務鏈路帶來瓶頸問題。爲了能夠解決海量巴槍數據實時寫入 hbase+solr 時產生的高 IO 壓力,我們設計出一款基於 redis 實現的輕量級分佈式均衡消費隊列,實現巴槍數據按照一定規則進行 sharding 到不同的隊列中,實現批量數據攢批去重,然後按批寫入 hbase+solr,從而降低 hbase+solr 的 IO 壓力。
三 我們怎麼做的
組件整體設計思路:
整個組件主要分爲三大核心模塊,master(主節點)、writer(數據寫入節點)、worker(工作節點)。
設計機制:弱中心機制,任何一個配置好的節點都可能成爲 master(主節點)、writer(數據寫入節點)、worker(工作節點),具備高可用能力,不存在單機單點瓶頸問題。
master(主節點)職責:
-
負責實時探活 worker(工作節點)是否有變化,掉線情況;
-
負責分配任務隊列到存活的 worker(工作節點);
-
負責實時檢測整個 redis 隊列的負載情況。
writer(數據寫入節點)職責:
-
負責分配實時寫入任務 sharding 到不同的隊列;
-
負責檢測當前寫入隊列的負載情況。
worker(工作節點)職責:
-
負責實時彙報當前 worker(工作節點)的狀態,保持心跳;
-
負責定時消費該 worker(工作節點)負責的數據。
偉大的 linux 大神曾說過,"Talk is cheap,讓我看看代碼"。
四 我們做了什麼
1 整個組件的包結構圖
2 簡潔的代碼結構
-
清晰的註釋,介紹類的作用和職責
-
啓動項配置,靈活的配置,控制模塊是否啓動。
-
lambda-logger/lambda 表達式,通過簡潔語法結構,輕量化代碼冗餘,提高代碼簡潔度。
-
斷言判斷,替換傳統的 if-else 判斷,提高代碼的可讀性。
整個工程一共 60 個類,核心代碼共 1623 行, 平均每個類的代碼行數爲 27.05 行,最大的一個類代碼行數不超過 200 行。
3 強大的擴展性
通過鉤子回調方式的設計,方便接入的用戶能夠快速的注入自己的回調實現方法,進行快速擴展業務能力。
4 線上日誌展示截圖
日誌文件
master 隊列分配日誌
worker 數據消費日誌
writer 隊列負載檢測日誌
redis 消費隊列監控大盤
五 我們的收益
組件部署上線之時,hbase 服務端監控指標變化,實現 hbase 整體使用水位接近 50% 的優化。
hbase IOPS 使用監控
hbase CPU 使用監控
六 我們的展望
-
獨立抽象組件,基於 Redis 的輕量級分佈式均衡消費隊列,是一個全自主創新研發出來的,高可用,可擴展的基礎組件,目前已經封裝成爲一個獨立的 spring-boot-starter,具備高複用性和高擴展性能力。
-
廣闊的使用場景,基於組件靈活的配置,在涉及的分佈式任務隊列場景時,都可以使用到它,例如任務中心分發等可以做到天然的均衡負載。
-
擁抱開源,未來希望將組件開源出去。
七 我的一些理解
好代碼,給人第一個印象的感覺,就像一篇好文章一樣,讀起來朗朗上口。不同的文章有不同的風格體裁,不同的代碼也有不同的編程風格要求。Python 有嚴格的縮進,像詩歌一樣工整對仗;C 語言面向過程像散文一樣形散神聚,意境深邃;Java 語言面向對象又像是寫小說一樣,能勾勒出一個一個人物形象。但是無論哪一種文章體裁,他的可讀性和可理解性都非常重要,只有文章是可讀的可理解的,纔會吸引更多的讀者去讀它,讓他流傳下去,代碼也一樣,它的可維護性和可讀性也非常重要,保證代碼可用性,提高代碼的簡潔程度和可維護程度,才能讓我們的代碼在計算機上跑的更遠,更久。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/2cOhU3L88E3_ZV3ywl136A