解鎖 ElasticJob 雲原生實踐的難題

宋小生的部落格發表於2023-11-27

發生了什麼

最近在逛 ElasticJob 官方社群時發現很多小夥伴都在頭疼這個 ElasticJob 上雲的問題,ElasticJob 本就號稱分散式彈性任務排程框架,怎麼在雲原生環境就有了問題了呢,這就要從 Kubenertes 和 ElasticJob 的一些狀態化說起。

有意思的狀態

在瞭解兩者特性之前我們可以先來看下什麼是狀態?

先來看百科的介紹:

“狀態是人或事物表現出來的形態。是指現實(或虛擬)事物處於生成、生存、發展、消亡時期或各轉化臨界點時的形態或事物態勢。”

如果指 人的形態:

  • 可以包括情緒、思想、行為和生理狀態等方面,比如某某人最近的狀態不好。

如果指 事物的形態:

  • 比如系統的溫度、壓力、體積、物態、物質的量、相、各種能量等等一定時,我們就說系統處於一個狀態(state)。

狀態這個詞對開發者來說並不陌生,比如:

  • 前端 UI 元件的狀態化儲存。

  • 軟體工程中的狀態圖。

  • 程式的執行狀態。

  • 再到雲原生 Kubernetes 中提及的無狀態服務(Stateless Service)和普通有狀態服務(Stateful Service)等等。

在 Kubernetes 中, 無狀態 和 有狀態 指的是應用在容器中執行時的資料持久化需求。

無狀態應用

指的是應用在容器中執行時不會在容器中持久化儲存資料,應用容器可以隨意建立、銷燬。對於無狀態應用,請求轉發給任何一個容器例項都可以正確執行。例如,web 應用就是一種無狀態應用。

有狀態應用

則指應用在容器中執行時需要穩定的持久化儲存、穩定的網路標識、固定的 pod 啟動和停止次序。這些應用需要在不同的節點之間保持資料同步,並且需要在節點故障時能夠快速恢復。例如,資料庫、快取等都是有狀態應用。

解鎖 ElasticJob 雲原生實踐的難題

無狀態下的容器

可以看到對於大部分 計算型 (業務型) ,非儲存型的應用更推薦使用 無狀態 的模式,這樣就可以實現隨意建立(擴容),銷燬(縮容)操作了,既然大部分業務系統使用了這種無狀態容器就意味著容器的網路,儲存等總是在每一次的銷燬,建立的釋出週期中發生變更。簡單的說就是容器的 IP 在每次釋出時 總是會建立一個新的 IP。

解鎖 ElasticJob 雲原生實踐的難題

容器 IP 是如何在每次建立時產生一個新的 IP 的,這個原理可以去研究下 Kubernetes 的虛擬 IP 的產生,這裡重點說下這個 IP 變更帶來的問題,在傳統的物理機和虛擬機器下部署的服務的 IP 往往是由運維統一管控分配的,也就是說同一個應用使用哪些 IP 相對固定往往不會出現大規模的變更,但是雲原生環境下無狀態容器快速頻繁的擴縮容時哪個服務使用哪個 IP 往往並不會固定每一次變更總會有一個新的 IP 的使用。

解鎖 ElasticJob 雲原生實踐的難題

每次 IP 變更是無狀態的一種模式本身並沒有什麼問題,但是有問題的是目前現有的很多框架或者中介軟體由於產生很早,開發階段時還未遇到或者考慮到這種 IP 頻繁變更的場景,經常會藉助 IP 進行了有狀態處理,比如 Dubbo2 中的介面級服務配置,ShardingSphere-ElasticJob 的有狀態 Server IP 節點等等,這種對 IP 做了有狀態操作的框架或者中介軟體在雲原生環境頻繁變更 IP 的場景下很容易產生大量無意義的髒資料儲存,對註冊中心或者儲存都帶來了無意義的壓力。

ElasticJob 中的有狀態 IP

ShardingSphere-ElasticJob 是一個分散式任務排程框架,它由噹噹網基於 Quartz 二次開發,功能豐富強大,採用 Zookeeper 實現分散式協調,可實現任務高可用以及分片。ShardingSphere-ElasticJob 已於 2020 年 5 月 28 日成為 Apache ShardingSphere 的子專案。

解鎖 ElasticJob 雲原生實踐的難題

具體如何使用可以查閱官網,相關原理也可以查閱《中介軟體原始碼》公眾號中對 ShardingSphere-ElasticJob 分析的文章。

在 ShardingSphere-ElasticJob 中預設註冊中心使用的是分散式協調中介軟體 Zookeeper,對 IP 的處理有兩個位置:

  • instance 目錄: 一個位置是位於註冊中心 instance 目錄下的臨時節點,這個節點包含了 IP+程式資訊,藉助此目錄下的節點可以有效的實現分片邏輯。節點存在意味著程式存在,節點不存在意味著程式不存在。

  • server 目錄: 另外一個位置是位於註冊中心 server 目錄下的持久 IP 節點,這個 IP 節點是用來儲存當前 IP 例項的狀態的,比如當前例項是否處於禁用狀態, 有問題的就是這個持久的,有狀態的節點,在無狀態的容器環境下隨著容器釋出次數增多這個 IP 節點也會越來越多,註冊中心無意義的髒資料也會越來越多,對註冊中心的壓力也會呈線性增長,這就是社群使用者遇到的頭疼的問題。

解決方案

既然 ShardingSphere-ElasticJob 要上容器支援雲原生環境下的無狀態的業務,那我們就把 ShardingSphere-ElasticJob 有狀態的 IP 變成無狀態,比較優雅且徹底的方式就是廢棄掉持久化 IP 這個有狀態的功能讓 ShardingSphere-ElasticJob 徹底變成無狀態的定時排程,但是考慮到部署在物理機或者虛擬機器環境下現存的分散式定時排程業務可能已經使用到了此狀態功能,對於已經使用到此狀態 IP 的節點暫不做處理直接跳過,針對已經下線的 IP 節點則直接刪除即可。

感興趣的小夥伴可以檢視如下程式碼和 PR 進行測試試用,當然有問題也可以繼續反饋。

相關 PR 如下所示(需複製開啟):

https://github.com/apache/shardingsphere-elasticjob/pull/2251

解鎖 ElasticJob 雲原生實踐的難題

關注微信公眾號  《中介軟體原始碼》   訂閱更多內容。

相關文章