Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a CostFunction that understands the relationship between partition and metrics #1148

Closed
garyparrot opened this issue Nov 21, 2022 · 16 comments · Fixed by #1240
Closed

Comments

@garyparrot
Copy link
Collaborator

garyparrot commented Nov 21, 2022

我們需要一個 CostFunction,能夠根據叢集目前的分佈,來給出輸入流量和輸出流量的平衡程度。

過去有一個 ReplicaDiskInCost 可以做到類似的效果,但是因為 ?#955 (review) 的原因被刪除了。

EDIT: #754 (comment) 其他相關的討論

這個東西的替代方案好像是 BrokerInputCost

https://github.com/skiptests/astraea/blob/8104a8298498c4aab4b8eb5a13da3ccf9b3dcde3/common/src/main/java/org/astraea/common/cost/BrokerInputCost.java#L30-L59

這個 BrokerInputCost 的實作沒有根據 ClusterInfo 去生成一個分數,他只是單純把過去看到的輸入負載加起來。這個 CostFunction 在 Balancer 大量生成的虛假分佈中,每個分佈都是一樣的分數。

所以 BrokerInputCost 的實作不適合用在 Balancer,我們需要一個像 ReplicaDiskInCost 一樣能理解 ClusterInfo 和輸入輸出負載關聯的 Cost Function。

@garyparrot garyparrot self-assigned this Nov 21, 2022
@garyparrot
Copy link
Collaborator Author

@chia7712 FYI

@garyparrot
Copy link
Collaborator Author

這個 BrokerInputCost 裡面用到的 ServerMetrics.BrokerTopic.Meter 只能統計到每個節點的 Topic 的輸入流量。我們需要能夠看到 TopicPartition 層級的流量。

對此我能想到的方法是像 ReplicaDiskInCost 一樣從 Log 增長速度去統計流量,如果不走 metrics 這條路的話,我們可以考慮從 Admin 去撈和記錄每個 Partition 現在的大小(?),我個人是比較偏向後者這條路,因為他不需要 JMX 就可以動

@chia7712
Copy link
Contributor

我們需要能夠看到 TopicPartition 層級的流量。

請問一下,這個目的是什麼?例如是沿用 cluster cost 的介面,讓“partition彼此的流量差異太高"跟分數綁在一起。還是說是 balancer 要明確拿到各個 TopicPartition 的分數?

@garyparrot
Copy link
Collaborator Author

請問一下,這個目的是什麼?例如是沿用 cluster cost 的介面,讓“partition彼此的流量差異太高"跟分數綁在一起。還是說是 balancer 要明確拿到各個 TopicPartition 的分數?

第一個例子我不太確定意思,但不是第二個例子的意思。

這個 BrokerInputCost 裡面用到的 ServerMetrics.BrokerTopic.Meter 只能統計到每個節點的 Topic 的輸入流量。我們需要能夠看到 TopicPartition 層級的流量。

ServerMetrics.BrokerTopic.Meter 這個 metrics 反映某節點在這個 topic 的流量是多少。如果這個節點有 5 個此 topic 下的 partition。那我們看到的流量數字會是 x = i + j + k + l + m 五個 topic/partition 輸入未知數的和。我們沒辦法使用這種數字來判斷給定的 ClusterInfo 效能,如果今天轉移 j 的 Partition 到其他節點,我們不知道要如何從 x 中去萃取出那個 j 部分。

@garyparrot
Copy link
Collaborator Author

請問一下,這個目的是什麼?

就是如果你沒有拿到 TopicPartition 的流量,你沒辦法計算一個給定叢集的效能狀況(然後 BrokerIputCost 只能拿到 Topic 等級的效能狀況,基於上面的理由他沒辦法明確計算),然後 Balancer 不需要明確拿到 TopicPartition 的分數,但 CostFunction 需要拿到 TopicPartition 的分數。

@chia7712
Copy link
Contributor

就是如果你沒有拿到 TopicPartition 的流量,你沒辦法計算一個給定叢集的效能狀況(然後 BrokerIputCost 只能拿到 Topic 等級的效能狀況,基於上面的理由他沒辦法明確計算),然後 Balancer 不需要明確拿到 TopicPartition 的分數,但 CostFunction 需要拿到 TopicPartition 的分數。

拿到TopicPartition這一的顆粒度的流量沒問題,不過我好奇的是有打算如何跟 cost function的介面結合?也就是說Balancer 預期拿到什麼東西?

@garyparrot
Copy link
Collaborator Author

不過我好奇的是有打算如何跟 cost function的介面結合?也就是說Balancer 預期拿到什麼東西?

ClusterCost

@chia7712
Copy link
Contributor

ClusterCost

從這點要如何去看 TopicPartition 這一層的分數?還是說就如我上面 #1148 (comment) 提到的概念?partitions 之間的大小差異太大就給一個比較差的分數?

@qoo332001
Copy link
Collaborator

這邊在之前討論算是我不小心忽略掉的問題

從這點要如何去看 TopicPartition 這一層的分數?還是說就如我上面 #1148 (comment) 提到的概念?partitions 之間的大小差異太大就給一個比較差的分數?

balancer端主要還是看ClusterCost的分數來決定叢集狀態,但是如同前面提到的,這個ClusterCost必須要由PartitionCost->BrokerCost->ClusterCost疊起來,原因如下:

  • 現有的BrokerInputCost是使用JMX metrics來計算BrokerCost,而這樣只能計算"當前叢集狀態的分數",在balancer端產生計畫的時候沒辦法拿"未來會產生的JMX metrics"來評估"預計搬移分佈的分數",所以原本的做法為 :
    • 計算出每個partition的log size寫入速度(PartitionCost)
    • 透過ClusterInfo的分佈以及PartitionCost來算出BrokerCost預計搬移分佈的分數,最後算出ClusterCost

@chia7712
Copy link
Contributor

計算出每個partition的log size寫入速度(PartitionCost)
透過ClusterInfo的分佈以及PartitionCost來算出BrokerCost預計搬移分佈的分數,最後算出ClusterCost

這邊提到的是搬移分佈,請問是指move cost嗎?

另外同樣老問題:

  1. PartitionCost的具體用途是什麼?
  2. 如果用途只是用來產生Broker CostCluster Cost,那為何不直接從broker-level開始統計就好?

@qoo332001
Copy link
Collaborator

qoo332001 commented Nov 21, 2022

這邊提到的是搬移分佈,請問是指move cost嗎

不是,單純指的是某個balancer預計要變成的分佈(ClusterInfo#replicas),這邊跟MoveCost無關,單純想算出一個(實際或預計搬移的)分佈表現好壞

PartitionCost的具體用途是什麼?

在Balancer這邊,他可以是一個方法就好,不一定要是Interface,用途是算出每個replica的寫入流量,目的就是要能用這個算出BrokerCost

如果用途只是用來產生Broker Cost和Cluster Cost,那為何不直接從broker-level開始統計就好?

現在的BrokerInputCost#brokerCost目前是透過JMX metrics來計算,但JMX metrics的如果要拿寫入/讀取的流量只能拿到Broker/Topic level的資料(BytesInPerSec/BytesOutPerSec),Balancer在大量產生計畫的時候傳進CostFunction的參數除了ClusterInfo提供的分佈(ex. ClusterInfo#replicas)以外,其他資訊像是ClusterBean都是傳入當前叢集的(搬移前),所以如果用BytesInPerSec/BytesOutPerSec來計算分數的話,假分佈算出來的分數會跟當前分佈的分數一樣,因為是用一樣的metrics來計算的

簡單講一下要如何計算Balancer要用的ClusterCost:

  1. 使用ClusterInfo#replicas拿到分佈(不論是當前的還是planGenerator產生的)
  2. 想辦法使用LogMetrics.Log.SIZE(紀錄每個replica log size的metrics)來算出每一個replica在一段時間內寫入的速度,這邊原本是從一大包Metrics透過timestamps跟Log size變化來算,未來會改成用 Statistic on gauge #1024 統計
  3. 每個broker上的replica流量加總即為BrokerCost

上面如果使用BytesInPerSec/BytesOutPerSec,在計算一個還沒有搬移的計畫的分數時無法使用,因為沒辦法得知每個broker在當下的預計流量會變成多少

@chia7712
Copy link
Contributor

上面如果使用BytesInPerSec/BytesOutPerSec,在計算一個還沒有搬移的計畫的分數時無法使用,因為沒辦法得知每個broker在當下的預計流量會變成多少

所以就流量這個議題來看的話,會需要 partition level 的分數是因為 balancer 需要知道新配置的「流量分數」是多少,而目前的流量分數是用 metrics 來算的話,因為我們沒有「新的 metrics」,所以會導致新的配置算出跟舊的一樣的分數?

@qoo332001
Copy link
Collaborator

所以就流量這個議題來看的話,會需要 partition level 的分數是因為 balancer 需要知道新配置的「流量分數」是多少,而目前的流量分數是用 metrics 來算的話,因為我們沒有「新的 metrics」,所以會導致新的配置算出跟舊的一樣的分數?

這麼說也沒錯,但是planGenerator產生出來的計畫是未來可能會搬移的計畫,所以當下也沒辦法可以拿到這個"預計要搬移的分佈的metrics",所以研會延伸出上面的partitionCost的方法來解決

@chia7712
Copy link
Contributor

但是planGenerator產生出來的計畫是未來可能會搬移的計畫,所以當下也沒辦法可以拿到這個"預計要搬移的分佈的metrics",所以研會延伸出上面的partitionCost的方法來解決

我的建議如下:

  1. 責任分工要明確,這應該是 cost function 的責任,不應該變成 balancer 需要介入的事情
  2. ClusterBean 要提供足夠的搜尋條件讓各個 cost function 可以去拼湊,balancer 唯一要做的是餵食 cluster bean 給cost function
  3. ClusterBean 的資料來源要從 metrics collector

綜合上述,實作方式應該是 cost function 從 cluster bean 取得 partition level 的數字,然後根據目前的叢集 cluster info 來拼湊出分數

@qoo332001
Copy link
Collaborator

責任分工要明確,這應該是 cost function 的責任,不應該變成 balancer 需要介入的事情

抱歉我可能上面沒說清楚,我上面提到的三個步驟是在原本的ReplicaDiskIn裡面做的

綜合上述,實作方式應該是 cost function 從 cluster bean 取得 partition level 的數字,然後根據目前的叢集 cluster info 來拼湊出分數

原本在ReplicaDiskIn是這樣子做的沒錯,或許現在可以重構BrokerInputCost,用上面的方法來算ClusterCost,然後原本的BrokerCost照原本的方法不動?

@chia7712
Copy link
Contributor

原本在ReplicaDiskIn是這樣子做的沒錯,或許現在可以重構BrokerInputCost,用上面的方法來算ClusterCost,然後原本的BrokerCost照原本的方法不動?

應該是說以這個為例子,我們要依序完成下方工作:

  1. ClusterBean要能取得 partition-level byte-in/byte-out,要完成這個功能要先做到 1) MetricsCollector 可以產生 ClusterBean、2) ClusterBean 要可以提供基於類型+時間的統計查詢
  2. 有了partition-level byte-in/byte-out後,就可以像你說的那樣,依照“目前”的 cluster info 來重建 broker/cluster cost

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants