新聞中心
分布式選主
在分布式系統(tǒng)中,應用服務常常會通過多個節(jié)點(或?qū)嵗┑姆绞絹肀WC高可用。然而在某些場景下,有些數(shù)據(jù)或者任務無法被并行操作,此時就需要由一個特定的節(jié)點來執(zhí)行這些特殊的任務(或者進行協(xié)調(diào)及決策),這個特定的節(jié)點也就是領(lǐng)導者(Leader),而在多個節(jié)點中選擇領(lǐng)導者的機制也就是分布式選主(Leader Election)。

10余年的陽東網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調(diào)整陽東建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“陽東網(wǎng)站設計”,“陽東網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
如今諸多知名項目也都使用了分布式選主,例如:
- Etcd
- Kafka
- Elasticsearch
- Zookeeper
常用算法包括:
- Paxos:一種著名的分布式共識算法,原理和實現(xiàn)較為復雜(此算法基本就是共識理論的奠基之作,曾有人說:"世界上只有一種共識協(xié)議,就是 Paxos,其他所有共識算法都是 Paxos 的退化版本")。
- Raft:目前最廣泛使用的分布式共識算法之一,Etcd 使用的就是 Raft,Elasticsearch 和 Kafka 在后來的版本中也都拋棄了早期的算法并轉(zhuǎn)向了 Raft。
- ZAB(Zookeeper Atomic Broadcast):Zookeeper 使用的一致性協(xié)議,也包括選主機制。
Kubernetes Lease
在 Kubernetes 中,諸如 kube-scheduler 和 kube-controller-manager 等核心組件也需要使用分布式選主,因為其需要確保任一時刻只有一個調(diào)度器在做出調(diào)度決策,同一時間只有一個控制管理器在處理資源對象。
然而,除了核心組件,用戶的應用服務很可能也有類似分布式選主的需求,為了滿足這種通用需求,kubernetes 提供了 Lease(翻譯為“租約”)這樣一個特殊的資源對象。
如上圖所示,在 k8s 中選主是通過爭搶一個分布式鎖(Lease)來實現(xiàn)的,搶到鎖的實例成為 leader,為了確認自己持續(xù)存活,leader 需要不斷的續(xù)簽這個鎖(Lease),一旦 leader 掛掉,則鎖被釋放,其他候選人便可以競爭成為新的 leader。
Lease 的結(jié)構(gòu)也很簡單:
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
# object
spec:
acquireTime: # 當前租約被獲取的時間
holderIdentity: # 當前租約持有者的身份信息
leaseDurationSeconds: # 租約候選者需要等待才能強制獲取它的持續(xù)時間
leaseTransitions: # 租約換了多少次持有者
renewTime: # 當前租約持有者最后一次更新租約的時間Lease 本質(zhì)上與其它資源并無區(qū)別,除了 Lease,其實也可以用 configmap 或者 endpoint 作為分布式鎖,因為在底層都是 k8s 通過資源對象的 resourceVersion 字段進行 compare-and-swap,也就是通過這個字段實現(xiàn)的樂觀鎖。當然在實際使用中,建議還是用 Lease。
使用示例
使用 Lease 進行分布式選主的示例如下:
import (
"context"
"time"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/client-go/tools/leaderelection/resourcelock"
)
func main() {
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
// 配置 Lease 參數(shù)
leaseLock := &resourcelock.LeaseLock{
LeaseMeta: metav1.ObjectMeta{
Name: "my-lease",
Namespace: "default",
},
Client: clientset.CoordinationV1(),
LockConfig: resourcelock.ResourceLockConfig{
Identity: "my-identity",
},
}
// 配置 Leader Election
leaderElectionConfig := leaderelection.LeaderElectionConfig{
Lock: leaseLock,
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: func(ctx context.Context) {
// 當前實例成為 Leader
// 在這里執(zhí)行 Leader 專屬的邏輯
},
OnStoppedLeading: func() {
// 當前實例失去 Leader 地位
// 可以在這里執(zhí)行清理工作
},
OnNewLeader: func(identity string) {
// 有新的 Leader 產(chǎn)生
}
},
}
leaderElector, err := leaderelection.NewLeaderElector(leaderElectionConfig)
if err != nil {
panic(err.Error())
}
// 開始 Leader Election
ctx := context.Background()
leaderElector.Run(ctx)
}參考資料:
- https://kubernetes.io/docs/concepts/architecture/leases/
- https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/lease-v1/
- https://pkg.go.dev/k8s.io/[email protected]/tools/leaderelection
當前名稱:KubernetesLease及分布式選主
轉(zhuǎn)載源于:http://www.fisionsoft.com.cn/article/coijpgc.html


咨詢
建站咨詢
