好程式碼實踐:基於Redis的輕量級分散式均衡消費佇列

語言: CN / TW / HK

簡介: 好程式碼,給人第一個印象的感覺,就像一篇好文章一樣,讀起來朗朗上口。不同的文章有不同的風格體裁,不同的程式碼也有不同的程式設計風格要求。Python有嚴格的縮排,像詩歌一樣工整對仗;C語言面向過程像散文一樣形散神聚,意境深邃;Java語言面向物件又像是寫小說一樣,能勾勒出一個一個人物形象。但是無論哪一種文章體裁,他的可讀性和可理解性都非常重要,只有文章是可讀的可理解的,才會吸引更多的讀者去讀它,讓他流傳下去,程式碼也一樣,它的可維護性和可讀性也非常重要,保證程式碼可用性,提高程式碼的簡潔程度和可維護程度,才能讓我們的程式碼在計算機上跑的更遠,更久。


作者 | 玄翰
來源 | 阿里技術公眾號

一 我對好程式碼的看法

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語言面向物件又像是寫小說一樣,能勾勒出一個一個人物形象。但是無論哪一種文章體裁,他的可讀性和可理解性都非常重要,只有文章是可讀的可理解的,才會吸引更多的讀者去讀它,讓他流傳下去,程式碼也一樣,它的可維護性和可讀性也非常重要,保證程式碼可用性,提高程式碼的簡潔程度和可維護程度,才能讓我們的程式碼在計算機上跑的更遠,更久。

本文為阿里雲原創內容,未經允許不得轉載。

 

分享到: