直播回顧 | 雲原生混部系統 Koordinator 架構詳解(附完整PPT)

語言: CN / TW / HK

作者: 張佐瑋 李濤

2022 年 4 月,阿里雲原生混部系統 Koordinator 宣佈正式開源。經過了幾個月的迭代,Koordinator 目前已經陸續釋出了 4 個版本,可以有效幫助企業客戶改進雲原生工作負載執行的效率、穩定性和計算成本。

昨天(6 月 15 日),在阿里巴巴雲棲直播間中,來自 Koordinator 社群的張佐瑋(佑禕) 、李濤(呂風)兩位技術專家從專案的架構和特性出發,分享了 Koordinator 是如何應對混部場景下的挑戰,特別是提升混部場景下工作負載的執行的效率和穩定性,以及對後續技術演進的思考與規劃。我們也將本次直播的核心內容進行了整理,希望能給大家帶來一些深入的啟發。

點選連結,立即檢視直播回放!

https://yqh.aliyun.com/live/detail/28787

關注阿里云云原生公眾號,後臺回覆【0615】獲取完整 PPT

混部技術的介紹和發展

混部的概念可以從兩個角度來理解,從節點維度來看,混部就是將多個容器部署在同一個節點上,這些容器內的應用既包括線上型別,也包括離線型別;從叢集維度來看,混部是將多種應用在一個叢集內部署,通過預測分析應用特性,實現業務在資源使用上的錯峰填谷,以達到提升叢集資源利用率的效果。

基於以上的理解,我們就可以明確混部需要解決的目標問題以及技術方案。本質上,我們實施混部的初衷是源自對資料中心資源利用效率的不懈追求。埃森哲報告顯示,2011 年公有云資料中心的機器利用率平均不到 10%,意味著企業的資源成本極高,而另一方面隨著大資料技術的發展迅速,計算作業對資源的需求越來越大。事實上,大資料通過雲原生方式上雲已成為了必然趨勢,據 Pepperdata 在 2021 年 12 月的調查報告,相當數量的企業大資料平臺已經開始向雲原生技術遷移。超過 77% 的受訪者反饋預計到 2021 年底,其 50% 的大資料應用將遷移到  Kubernetes 平臺。於是,選擇批處理型別任務與線上服務型別應用混合部署,就順理成章的成為了業界通用的混部方案選型。公開資料顯示,通過混部,相關技術領先企業的資源利用率得到了大幅提升。

面對混部技術,在具體關注的問題上,不同角色的管理人員會有各自的側重點。

對於叢集資源的管理員來說,他們期望可以簡化對叢集資源的管理,實現對各類應用的資源容量,分配量,使用量的清晰洞察,提升叢集資源利用率,以達到降低 IT 成本的目的。

對於線上型別應用的管理員來說,他們則更關注容器混合部署時的互相干擾的,因為混部會更容易產生資源競爭,應用響應時間會出現長尾(tail latency),導致應用服務質量下降。

而離線型別應用的管理員更期望混部系統可以提供分級可靠的資源超賣,滿足不同作業型別的差異化資源質量需求。

針對以上問題,Koordinator 提供了以下機制,可以充分滿足不同角色對混部系統的技術需求:

  • 面向混部場景的資源優先順序和服務質量模型
  • 穩定可靠的資源超賣機制
  • 細粒度的容器資源編排和隔離機制
  • 針對多種型別工作負載的排程能力增強
  • 複雜型別工作負載的快速接入能力

Koordinator 簡介

下圖展示了 Koordinator 系統的整體架構和各元件的角色分工,其中綠色部分描述了 K8s 原生系統的各個元件,藍色部分是 Koordinator 在此基礎上的擴充套件實現。從整個系統架構來看,我們可以將 Koordinator 分為中心管控和單機資源管理兩個維度。在中心側,Koordiantor 在排程器內部和外部分別都做了相應的擴充套件能力增強;在單機側,Koordinator 提供了 Koordlet 和 Koord Runtime Proxy 兩個元件,負責單機資源的精細化管理和 QoS 保障能力。

1.png

Koordinator 各元件的詳細功能如下

  • Koord-Manager

    • SLO-Controller:提供資源超賣、混部 SLO 管理、精細化排程增強等核心管控能力。
    • Recommender:圍繞資源畫像為應用提供相關的彈效能力。
    • Colocation Profile Webhook:簡化 Koordinator 混部模型的使用,為應用提供一鍵接入的能力,自動注入相關優先順序、QoS 配置。
  • Koord extensions for Scheduler:面向混部場景的排程能力增強。

  • Koord descheduler:提供靈活可擴充套件的重排程機制。
  • Koord Runtime Proxy:作為 Kubelet 和 Runtime 之間的代理,滿足不同場景的資源管理需求,提供外掛化的註冊框架,提供相關資源引數的注入機制。
  • Koordlet:在單機側負責 Pod 的 QoS 保障,提供細粒度的容器指標採集,以及干擾檢測和調節策略能力,並支援一系列的 Runtime Proxy 外掛,用於精細化的隔離引數注入。

在 Koordinator 的設計模型中,一個核心的設計概念就是優先順序(Priority),Koordinator 定義了四個等級,分別是 Product、Mid、Batch、Free ,Pod 需要指定申請的資源優先順序,排程器會基於各資源優先順序總量和分配量做排程。各優先順序的資源總量會受高優先順序資源的 request 和 usage 影響,例如已申請但未使用的 Product 資源會以 Batch 優先順序再次分配。節點各資源優先順序的具體容量,Koordinator 會以標準的 extend-resource 形式更新在 Node 資訊中。

下圖展示了一個節點各資源優先順序的容量情況,其中黑色的直線 total 代表了節點的物理資源總量,紅色折線代表了高優先順序 Product 的真實使用量,藍色折線到黑色直線之間反映了 Batch 優先順序的資源超賣變化情況,可以看到當 Product 優先順序處於資源消耗的低谷時,Batch 優先順序可以獲得更多的超賣資源。事實上,資源優先順序策略的激進或保守,決定了叢集資源的超賣容量,這點我們也可以從圖中綠色直線對應的 Mid 資源優先順序超賣情況分析看出。

2.png

如下表所示,Koordinator 以 K8s 標準的 PriorityClass 形式對各資源優先順序進行了定義,代表 Pod 申請資源的優先順序。在多優先順序資源超賣情況下,當單機資源緊張時,低優先順序 Pod 會被壓制或驅逐。此外,Koordinator 還提供了 Pod 級別的子優先順序(sub-priority),用於排程器層面的精細化控制(排隊,搶佔等)。

3.jpeg

Koordinator 的設計中另一個核心的概念是服務質量(Quality of Service),Koordinator 將 QoS 模型在 Pod Annotation 級別進行了擴充套件定義,它代表了 Pod 在單機執行過程中的資源質量,主要表現為使用的隔離引數不同,當單機資源緊張時會優先滿足高等級 QoS 的需求。如下表所示,Koordinator 將 QoS 整體分為 System(系統級服務),Latency Sensitive(延遲敏感性的線上服務),Best Effort(資源消耗型的離線應用)三類,根據應用效能敏感程度的差異,Latency Sensitive 又細分為 LSE,LSR 和 LS。

4.jpeg

在 Priority 和 QoS 的使用上,二者整體是正交的兩個維度,可以排列組合使用。不過受模型定義和實際的需求情況影響,部分排列組合存在約束。下表展示了混部場景中經常使用到的一些組合,其中“O”表示常用的排列組合,“X”表示基本使用不到的排列組合。

5.jpeg

各場景的實際使用舉例如下。

  • 典型場景:

    • Prod + LS:典型的線上應用,通常對應用時延要求較高,對資源質量要求較高,也需要保證一定的資源彈效能力。
    • Batch + BE:用於混部場景中的低優離線,對資源質量有相當的忍耐度,例如批處理型別的 Spark/MR 任務,以及 AI 型別的訓練任務
  • 典型場景的增強:

    • Prod + LSR/LSE:比較敏感的線上應用,可以接受犧牲資源彈性而換取更好的確定性(如CPU綁核),對應用時延要求極高。
    • Mid/Free + BE:與“Batch + BE”相比主要區別是對資源質量要求的高低不同。
  • 非典型的應用場景:

    • Mid/Batch/Free + LS:用於低優先順序的線上服務、近線計算以及AI推理類等任務,這些任務相較於大資料型別任務,它們無法接受過低的資源質量,對其他應用的干擾也相對較低;而相較於典型的線上服務,它們又可以忍受相對較低的資源質量,例如接受一定程度的驅逐。

Quick Start

Koordinator 支援多種工作負載的靈活接入混部,這裡我們以 Spark 為例,介紹如何使用混部超賣資源。在 K8s 叢集中執行 Spark 任務有兩種模式:一種是通過 Spark Submit 提交,也就是在本地使用 Spark 客戶端直接連線 K8s 叢集,這種方式比較簡單快捷,不過在整體的管理能力上有所缺乏,常用於開發自測;另一種方式是通過 Spark Operator 提交,如下圖所示,它定義了 SparkApplication CRD,用於 Spark 作業的描述,使用者可以通過 kubectl 客戶端將提交 SparkApplication CR 到 APIServer,隨後由 Spark Operator 負責作業生命週期以及 Driver Pod 的管理。

6.png

憑藉 Koordinator 能力的加持,ColocationProfile Webhook 會自動為 Spark 任務的 Pod 注入相關混部配置引數(包括QoS,Priority,extened-resource等),如下所示。Koordlet 在單機側負責 Spark Pod 在混部後不會影響線上應用效能表現,通過將 Spark 與線上應用進行混部,可以有效提升叢集整體資源利用率。

```

Spark Driver Pod example

apiVersion: v1 kind: Pod metadata: labels: koordinator.sh/qosClass: BE ... spec: containers: - args: - driver ... resources: limits: koordinator.sh/batch-cpu: "1000" koordinator.sh/batch-memory: 3456Mi requests: koordinator.sh/batch-cpu: "1000" koordinator.sh/batch-memory: 3456Mi ... ```

關鍵技術介紹

資源超發 - Resource Overcommitment

在使用 K8s 叢集時,使用者很難準確的評估線上應用的資源使用情況,不知道該怎麼更好的設定 Pod 的 Request 和 Limit,因此往往為了保障線上應用的穩定性,都會設定較大的資源規格。在實際生產中,大部分線上應用的實際 CPU 利用率大多數時候都比較低,高的可能也就百分之十幾或者二十幾,浪費了大量已經被分配但未使用的資源。

7.png

Koordinator 通過資源超發機制回收複用這部分分配但未被使用的資源。Koordinator 根據指標資料評估線上應用的 Pod 有多少資源是可以回收的(如上圖所示,標記為 Reclaimed 的部分就是可被回收的資源),這些可回收的資源就可以超發給低優先順序的工作負載使用,例如一些離線任務。為了讓這些低優先順序工作負載方便使用這些資源,Koordinator 會把這些超發資源更新到 NodeStatus 中(如下面所示的 node info)。當線上應用有突發的請求需要處理時要求使用更多的資源,Koordinator 通過豐富的 QoS 增強機制幫助線上應用拿回這些資源以保證服務質量。

```

node info

allocatable: koordinator.sh/bach-cpu: 50k # milli-core koordinator.sh/bach-memory: 50Gi

pod info

annotations: koordinator.sh/resource-limit: {cpu: “5k”} resources: requests koordinator.sh/bach-cpu: 5k # milli-core koordinator.sh/bach-memory: 5Gi ```

負載均衡排程 - Load-Aware Scheduling

超發資源可以極大的提升叢集的資源利用率,但也會凸顯叢集內節點之間資源利用率不均勻的現象。這個現象在非混部環境下也是存在的,只是因為 K8s 原生是不支援資源超發機制,節點上的利用率往往不是很高,一定程度上掩蓋了這個問題。但當混部時,資源利用率會上升到比較高的水位時就暴露了這個問題。

利用率不均勻一般是節點之間不均勻以及出現區域性的負載熱點,區域性的負載熱點會可能影響工作負載的整體執行效果。另一個是在負載高的節點上,線上應用和離線任務之間可能會存在的嚴重的資源衝突,影響到線上應用的執行時質量。

8.png

為了解決這個問題, Koordinator 的排程器提供了一個可配置的排程外掛控制叢集的利用率。該排程能力主要依賴於 koordlet 上報的節點指標資料,在排程時會過濾掉負載高於某個閾值的節點,防止 Pod 在這種負載較高的節點上無法獲得很好的資源保障,另一方面是避免負載已經較高的節點繼續惡化。在打分階段選擇利用率更低的節點。該外掛會基於時間視窗和預估機制規避因瞬間排程太多的 Pod 到冷節點機器出現一段時間後冷節點過熱的情況。

9.png

應用接入管理 - ClusterColocationProfile

我們在 Koordinator專案開源之初就考慮到,需要降低 Koordinator 混部系統的使用門檻,讓大家可以簡單快速的灰度和使用混部技術獲得收益。因此 Koordinator 提供了一個 ClusterColocationProfile CRD,通過這個 CRD 和對應的 Webhook ,可以在不侵入存量叢集內的元件的情況下,按需針對不同的 Namespace 或者不同的工作負載,一鍵開啟混部能力,Webhook 會根據該 CRD 描述的規則對新建立的 Pod 自動的注入 Koorinator 優先順序、QoS 配置和其他混部協議等。

apiVersion: config.koordinator.sh/v1alpha1 kind: ClusterColocationProfile metadata: name: colocation-profile-example spec: namespaceSelector: matchLabels: koordinator.sh/enable-colocation: "true" selector: matchLabels: sparkoperator.k8s.io/launched-by-spark-operator: "true" qosClass: BE priorityClassName: koord-batch koordinatorPriority: 1000 schedulerName: koord-scheduler labels: koordinator.sh/mutated: "true" annotations: koordinator.sh/intercepted: "true" patch: spec: terminationGracePeriodSeconds: 30

舉個例子,上面是 ClusterColocationProfile 的一個例項,表示所有帶有 koordinator.sh/enable-colocation=true 標籤的 Namespace 和該 Namespace 下 SparkOperator 作業建立的 Pod 都可以轉為 BE 型別的 Pod(BTW:SparkOperator 建立的 Pod 時會增加標籤 sparkoperator.k8s.io/launched-by-spark-operator=true 表示這個 Pod 是 SparkOperator 負責的)。

只需要按照如下步驟就可以完成混部接入:

$ kubectl apply -f profile.yaml $ kubectl label ns spark-job -l koordinator.sh/enable-colocation=true $ # submit Spark Job, the Pods created by SparkOperator are co-located other LS Pods.

QoS 增強 – CPU Suppress

Koordinator 為保障線上應用在混部場景下的執行時質量,在單機側提供了豐富的 QoS 增強能力。

首先向大家介紹 CPU Suppress(CPU 動態壓制)特性 。前面向大家介紹了,線上應用大多時候並不會完全用完申請到的資源,會有大量的空閒資源,這些空閒資源除了可以通過資源超發給新建立的離線任務使用外,還可以在節點上還沒有新的離線任務需要執行時,儘可能的把空閒的 CPU 資源共享給存量的離線任務。如這個圖中所示,當 koordlet 發現線上應用的資源空閒,並且離線任務使用的 CPU 還沒有超過安全閾值,那麼安全閾值內的空閒 CPU 就可以共享給離線任務使用,讓離線任務可以更快的執行。因此線上應用的負載的高低決定了 BE Pod 總共有多少可用 CPU。當線上負載升高時,koordlet 會通過 CPU Suppress 壓制 BE Pod,把共享的 CPU 還給線上應用。

10.png

QoS 增強 – 基於資源滿足度的驅逐

CPU Suppress 線上應用的負載升高時可能會頻繁的壓制離線任務,這雖然可以很好的保障線上應用的執行時質量,但是對離線任務還是有一些影響的。雖然離線任務是低優先順序的,但頻繁壓制會導致離線任務的效能得不到滿足,嚴重的也會影響到離線的服務質量。而且頻繁的壓制還存在一些極端的情況,如果離線任務在被壓制時持有核心全域性鎖等特殊資源,那麼頻繁的壓制可能會導致優先順序反轉之類的問題,反而會影響線上應用。雖然這種情況並不經常發生。

11.png

為了解決這個問題,Koordinator 提出了一種基於資源滿足度的驅逐機制。我們把實際分配的CPU總量 與 期望分配的 CPU 總量的比值成為 CPU 滿足度。當離線任務組的 CPU 滿足度低於閾值,而且離線任務組的 CPU 利用率超過 90% 時,koordlet 會驅逐一些低優先順序的離線任務,釋放出一些資源給更高優先順序的離線任務使用。通過這種機制能夠改善離線任務的資源需求。

QoS 增強 - CPU Burst

我們知道 CPU 利用率是一段時間內 CPU 使用的平均值。而且我們大多數時候都是以一種較粗的時間單位粒度觀察統計 CPU 利用率,這個時候觀察到 CPU 利用率的變化是基本穩定的。但如果我們以較細的時間單位粒度觀察統計 CPU 利用率,可以看到 CPU 使用的突發特徵非常明顯,是不穩定的。如下圖以 1s 粒度觀察利用率(紫色)和 100ms 粒度觀察的利用率(綠色)對比。

12.png

細粒度資料觀測表明CPU 突發和壓制是常態。Linux核心中通過 CFS 頻寬控制器 cgroup CPU 的消耗,它限制了 cgroup 的 CPU 消耗上限,因此經常會遇到一些突發流量下業務短時間內被狠狠地 throttle,產生長尾延遲,造成服務質量下降,如下圖所示,Req2 因為 CPU 被壓制,延期到第 200ms 才得到處理。

13.png

為了解決這個問題,Koordinator 基於 CPU Burst 技術幫助線上應用應對突發情況。CPU Burst 允許工作負載在有突發請求處理使用CPU 資源時,使用日常的 CPU 資源。比如容器在日常執行中使用的 CPU 資源未超過 CPU 限流,空餘的CPU資源將會被積累。後續當容器執行需要大量 CPU 資源時,將通過 CPU Burst 功能突發使用 CPU 資源,這部分突發使用的資源來源於已積累的資源。如下圖所示,突發的 Req2 因為有積累的 CPU 資源,通過 CPU Burst 功能得以避免被 throttle,快速的處理了請求。

14.png

QoS 增強 – Group Identity

在混部場景下,Linux 核心雖然提供了多種機制滿足不同優先順序的工作負載的排程需求,但當一個線上應用和一個離線任務同時執行在一個物理核上時,因為在離線任務都共享相同的物理資源,線上應用的效能不可避免的會被離線任務干擾從而效能下降。Alibaba Cloud Linux 2 從核心版本 kernel-4.19.91-24.al7 開始支援 Group Identity 功能,Group Identity 是一種以 cgroup 組為單位實現的排程特殊優先順序的手段,簡單講,當線上應用需要更多資源時,通過 Group Identity 可以暫時壓制離線任務保障線上應用可以快速的響應。

要使用這個特性比較簡單,可以配置 cpu cgroup  的 cpu.bvt_warp_ns 即可。在 Koordinator 裡,BE 類離線任務對應配置為 -1,即最低優先順序, LS/LSR 等線上應用型別設定為 2,即最高優先順序。

15.jpeg

QoS 增強 – Memory QoS

容器在使用記憶體時主要有以下兩個方面的約束:

  • 自身記憶體限制:當容器自身的記憶體(含Page Cache)接近容器上限時,會觸發核心的記憶體回收子系統,這個過程會影響容器內應用的記憶體申請和釋放的效能。
  • 節點記憶體限制:當容器記憶體超賣(Memory Limit>Request)導致整機記憶體不足,會觸發核心的全域性記憶體回收,這個過程對效能影響較大,極端情況甚至導致整機異常。

為了提高應用執行時效能和節點的穩定性,Koordinator 引入Memory QoS 能力,為應用提升記憶體效能。當功能開啟時,koordlet 依據自適應配置記憶體子系統(Memcg),在保障節點記憶體資源公平的基礎上,優化記憶體敏感型應用的效能。

16.png

後續演進計劃

精細化 CPU 編排 - Find-grained CPUOrchestration

我們正在設計和實現精細化 CPU 編排機制。

我們為什麼要提供這個編排機制呢?隨著資源利用率的提升進入到混部的深水區,需要對資源執行時的效能做更深入的調優,更精細的資源編排可以更好的保障執行時質量,從而通過混部將利用率推向更高的水平。

我們把 Koordinator QoS 線上應用 LS 型別做了更細緻的劃分,分為 LSE、LSR 和 LS 三種類型。拆分後的 QoS 型別具備更高的隔離性和執行時質量。通過這樣的拆分,整個 Koordinator QoS 語義更加精確和完整,並且相容 K8s 已有的 QoS 語義。

而且我們針對 Koordinator QoS,設計了一套豐富靈活的 CPU 編排策略,如下表所示。

17.jpeg

18.png

Koordinator QoS 對應的 CPU 編排策略

另外,針對 LSR 型別,還提供了兩種綁核策略,可以幫助使用者平衡效能和經濟收益。

  • SameCore 策略:更好的隔離性,但彈性空間小。
  • Spread 策略:中等的隔離性,但可以通過其他隔離策略優化;使用得當可以獲得比 SameCore 策略更好的效能;有一定的彈性空間。

19.png

Koordinator 的這套精細化 CPU 編排方案相容 K8s 已有的 CPUManager 和 NUMA Topology Manager 機制的。也就是說存量叢集使用 Koordinator 時不會影響存量的 Pod,可以安全放心的灰度使用。

資源預留 - Resource Reservation

資源預留是我們另一個正在設計的特性。資源預留可以幫助解決資源管理的痛點。例如有時候像大家熟悉的網際網路業務場景,都有非常強的峰谷特徵。那麼我們可以在峰值到達前預留資源確保一定有資源滿足峰值請求。另外像大家在擴容時可能也會遇到的問題,發起擴容後因為沒有資源 Pod 就 Pending 在叢集裡,如果能在擴容前提前確認是否資源,沒資源時加新機器就能有更好的體驗。還有像重排程場景,可以通過資源預留保障被驅逐的 Pod 一定有資源可以用,可以極大的降低重排程的資源風險,更安全放心的使用重排程能力。

Koordinator 的資源預留機制不會侵入 K8s 社群已有的 API 和程式碼。並支援 PodTemplateSpec,模仿一個Pod 通過排程器找到最合適的節點。並支援宣告所有權的方式支援 Pod 優先使用預留資源,例如當一個真正的 Pod 排程時,會優先嚐試根據 Pod 的特徵找到合適的預留資源,否則繼續使用叢集內空閒的資源。

下面是一個 Reservation CRD 的例子(最終以 Koordinator 社群通過的設計為準)

kind: Reservation metadata: name: my-reservation namespace: default spec: template: ... # a copy of the Pod's spec resourceOwners: controller: apiVersion: apps/v1 kind: Deployment name: deployment-5b8df84dd timeToLiveInSeconds: 300 # 300 seconds nodeName: node-1 status: phase: Available ...

精細化 GPU 排程 - GPU Scheduling

精細化 GPU 排程是我們未來期望提供的一種能力。GPU 和 CPU 在資源特徵上差異比較大,而且在像機器學習的模型訓練場景中,一個訓練作業會因為不同的拓撲結構導致不同的效能差異,例如根據機器學習作業內 worker 之間不同的拓撲組合,會得到不同的效能,這不僅體現在叢集內節點之間,而且即使單個節點上,GPU 卡之間也因為像是否使用 NVLINK 也會有巨大的效能差異,這讓整個 GPU 的排程分配邏輯變的十分複雜。而且 GPU 和 CPU 的計算任務在叢集內混部時,怎麼避免兩種資源的浪費,也是需要考慮解決優化的問題。

20.png

規格推薦 - Resource Recommendation

後續 Koordinator 還會提供基於畫像的規格推薦能力。前面也提到,使用者是很難精確評估應用程式的資源使用情況的,Request 和 Limit 到底是什麼關係,到底該怎麼設定 Request/Limit,對於我這個應用來說哪種組合才是最合適的?經常高估或者低估 Pod 資源規格,導致資源浪費甚至穩定性風險。

Koordinator 會提供資源畫像能力,採集並加工分析歷史資料,推薦更準確的資源規格。

21.png

社群建設

目前為止,我們在最近兩個多月釋出了四個版本。前面幾個版本主要提供了資源超發、QoS 增強的能力,並且還開源了新的元件 koord-runtime-proxy。在 0.4 版本中,我們開始在排程器上發力,首先開放了負載均衡排程能力。目前 Koordinator 社群正在實現 0.5 版本,在這個版本中,Koordinator 會提供精細化 CPU 編排和資源預留的能力,在之後的規劃中,我們還會在重排程、Gang 排程、GPU 排程、彈性 Quota 等實現一些新的創新。

22.jpeg

23.jpeg

非常期待您在使用 Koordinator 積極的反饋遇到的任何問題、幫助改善文件、修復 BUG 和新增新功能

  • If you find a typo, try to fix it!
  • If you find a bug, try to fix it!
  • If you find some redundant codes, try to remove them!
  • If you find some test cases missing, try to add them!
  • If you could enhance a feature, please DO NOT hesitate!
  • If you find code implicit, try to add comments to make it clear!
  • If you find code ugly, try to refactor that!
  • If you can help to improve documents, it could not be better!
  • If you find document incorrect, just do it and fix that!
  • ...

此外,我們還於週二 19:30 至 20:30 籌辦了社群定期雙週會,歡迎廣大志同道合的夥伴新增交流群瞭解更多資訊。

24.jpeg

微信群

255.jpeg

釘釘群

點選此處,立即瞭解 Koordinator 專案!