自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于Etcdserver包將自己的Go程序打造成高可用系統(tǒng)

開發(fā) 前端
本文就給大家演示下,如何自己動手,從零開始基于Raft協(xié)議來改造我們的已有系統(tǒng)。很多同學都知道Raft協(xié)議是一種分布式一致性算法。

背景

我們每一個系統(tǒng)開發(fā)人員都希望自己的程序永遠不宕機,高可用是很多系統(tǒng)的目標。那我們如何把自己的系統(tǒng)改造成高可用的系統(tǒng)呢?帶著這個問題,本文就給大家演示下,如何自己動手,從零開始基于raft協(xié)議來改造我們的已有系統(tǒng)。很多同學都知道Raft協(xié)議是一種分布式一致性算法。從用戶的角度出發(fā),它提供給程序設計人員的功能主要有以下2個方面

  1. 它提供了一個全局一致的存儲狀態(tài),這樣我們的程序就可以通過它在多個節(jié)點上存儲信息
  2. 它提供了容錯的功能,當leader不可用后,系統(tǒng)自動開始選舉新的leader.而且每個節(jié)點知道自己的身份是follower還是leader.這樣我們就可以利用這個功能實現(xiàn)讀寫分離。

當然很多同學講到,我們可以直接部署高可用的分布式鍵值存儲系統(tǒng)etcd,它本身具有高可用、高并發(fā)、一致性等特點,已經被廣泛應用于云計算、微服務、容器等領域了,是很多云原生系統(tǒng)的底層基石之一。但是大家很快發(fā)現(xiàn)這樣做又增加了我們系統(tǒng)的依賴,所以本文給出的解決方案是直接采用etcdserver包(go.etcd.io/etcd/server/v3/etcdserver是etcd的Go語言實現(xiàn),提供了etcd服務器的主要功能,包括集群管理、數(shù)據存儲、數(shù)據同步等)本文接下來的內容主要分為2部分,首先介紹下etcdserver的使用,然后以一個例子闡述下如何引用etcdserver包來實現(xiàn)高可用的系統(tǒng)的構建,這種構建方法不依賴于外部第三方的組件,所以它的分發(fā)與部署是比較輕便與簡單的。由于內容比較多,所以就暫定分兩期來介紹。

通過embed啟動etcdserver

我們通過go.etcd.io/etcd/server/v3/embed這個包來快速啟動集成的etcdserver。

package main

import (
   _ "context"
   "go.etcd.io/etcd/server/v3/embed"
   "log"
)

func main() {
   cfg := embed.NewConfig()
   cfg.Dir = "/Users/dongluyang1/Documents/workspace/toutiao/etcdserversample" //etcd 數(shù)據存儲的目錄,用于持久化存儲 etcd 數(shù)據。
   cfg.WalDir = ""
   cfg.Name = "test" //節(jié)點名稱
   cfg.InitialCluster = "test=http://localhost:2380" //集群名稱
   cfg.ClusterState = embed.ClusterStateFlagNew //etcd 集群的初始狀態(tài),可以是 new 或 existing。當設置為 new 時,將啟動一個新的 etcd 集群;當設置為 existing 時,將加入一個已經存在的 etcd 集群。
   cfg.AutoCompactionMode = "periodic"
   cfg.AutoCompactionRetention = "1"
   cfg.QuotaBackendBytes = 8 * 1024 * 1024 * 1024

   e, err := embed.StartEtcd(cfg)
   if err != nil {
      log.Fatalf("Failed to start etcd: %v", err)
   }
   defer e.Close()
  
   select {} //阻止主程序退出,導致etcdserver退出
}

上面的cfg參數(shù)通過StartEtcd方法傳入embed,如下所示,實際上它的值最終傳給config.ServerConfig來實現(xiàn)對etcdserver的配置。

embed.NewConfig的值傳給了config.ServerConfig來控制etcdserver的配置

我們上面的代碼簡單的給出了常用的配置,下面具體給出配置的含義

go.etcd.io/etcd/server/v3/config 包中的 serverConfig 結構體包含了 etcd 服務器的配置信息,以下是該結構體中各個參數(shù)的含義:

  • Name: etcd 集群中當前節(jié)點的名稱,可以是任何字符串,建議為集群中唯一的名稱。
  • DataDir:etcd 數(shù)據存儲的目錄,用于持久化存儲 etcd 數(shù)據。
  • ListenClientUrls: etcd 服務器監(jiān)聽客戶端請求的 URL 地址,支持多個 URL,以逗號分隔。例如:http://localhost:2379,http://localhost:4001。不填默認2379
  • ListenPeerUrls: etcd 服務器監(jiān)聽節(jié)點之間通信的 URL 地址,支持多個 URL,以逗號分隔。例如:http://localhost:2380,http://localhost:7001。不填默認2380
  • InitialCluster: etcd 集群中所有節(jié)點的信息,以 name=URL 的形式表示,各節(jié)點信息之間以逗號分隔。例如:node1=http://localhost:2380,node2=http://localhost:7001。
  • InitialClusterState: etcd 集群的初始狀態(tài),可以是 new 或 existing。當設置為 new 時,將啟動一個新的 etcd 集群;當設置為 existing 時,將加入一個已經存在的 etcd 集群。
  • InitialClusterToken: etcd 集群的唯一標識符,用于區(qū)分不同的 etcd 集群。當啟動一個新的 etcd 集群時,需要指定一個唯一的標識符。
  • AutoCompactionRetention: etcd 自動壓縮功能的保留時間,以天為單位。當 etcd 啟用自動壓縮功能時,將保留指定天數(shù)內的數(shù)據,過期數(shù)據將被刪除。
  • AutoCompactionMode: etcd 自動壓縮功能的模式,可以是 periodic 或 revision。當設置為 periodic 時,將按時間間隔壓縮數(shù)據;當設置為 revision 時,將按事務數(shù)壓縮數(shù)據。

客戶端訪問etcdserver

cli, err := clientv3.New(clientv3.Config{
   Endpoints:   []string{"localhost:2379"},
   DialTimeout: 5 * time.Second,
})
go func() {
   if err == nil {
      for {
         _, err = cli.Put(context.Background(), "yandaojiumozhi", fmt.Sprintf("mibao-%d", rand.Intn(100)))
         if err != nil {
            // handle error
         } else {
            resp, err := cli.Get(context.Background(), "yandaojiumozhi")
            if err != nil {
               // handle error
            }
            for _, ev := range resp.Kvs {
               fmt.Printf("%s : %s\n", ev.Key, ev.Value)
            }
         }
         time.Sleep(5 * time.Second)
      }
   }
}()
defer cli.Close()

上面的代碼簡單測試了,通過localhost:2379隨機寫入yandaojiumozhi,然后讀取這個key。

演示結果

上面的代碼使得我們不需要額外部署與維護第三方etcd組件,便可以再啟動我們后臺程序的同時通過embed啟動etcdserver來實現(xiàn)存儲了。

embed啟動etcdserver的邏輯

go.etcd.io/etcd/server/v3/etcdserver 包是 etcd 服務器的核心包,它包含了 etcd 服務器的所有核心邏輯。其中 EtcdServer 結構體是 etcd 服務器的核心,它負責管理 etcd 服務器的所有組件、監(jiān)聽客戶端請求、處理事務和維護 etcd 數(shù)據庫等核心任務。這個包主要負責 etcd 服務器的啟動、停止和管理。而go.etcd.io/etcd/server/v3/embed 包則負責將go.etcd.io/etcd/server/v3/etcdserver 封裝到一個可嵌入的包中,使得在應用程序中嵌入 etcd 服務器變得更加容易。所以搞明白embed如何啟動的etcdserver,我們便可以直接在我們的代碼里面啟動etcdserver,這樣便可以有更大的靈活性來做一些功能。比如判斷是否是leader等。

embed啟動etcdserver的流程圖如下所示,它的核心是在2379,2380啟動監(jiān)聽器,然后配置config.ServerConfig,以及調用NewServer,最后Start它。

embed創(chuàng)建并啟動etcdserver的流程

所以我們自己也可以寫一個embed,來創(chuàng)建并啟動etcdserver,然后通過下面的方法來判斷是不是leader。通過isLeader的判斷,來完成分布式環(huán)境下面的,不同角色自己該干的事情。

本期就先介紹這些,下一期給大家演示下分布式環(huán)境下的,節(jié)點加入,選舉等相關操作。

func check(srv *etcdserver.EtcdServer, ctx context.Context) {
   log.Info("start check LeaderChanged")
   for {
      select {
      case <-ctx.Done():
         log.Info("has Done")
         return
      case <-srv.LeaderChangedNotify():
         {
            log.Info("Leader changed")
           /*這個isLeader可以判斷當前節(jié)點是不是leader,如果是leader的話,可以做一些
           leader可以做的業(yè)務,比如它可以接受寫請求,其他的收到寫請求,都轉發(fā)leader
           */
            isLeader := srv.Leader() == srv.ID() 
           ......
         }

      }
   }
}

責任編輯:姜華 來源: 今日頭條
相關推薦

2011-05-30 09:44:48

FacebookiOSAndroid

2017-01-04 14:31:25

2018-07-29 23:09:15

Google Go技術

2018-09-13 10:11:42

思科網絡平臺

2021-06-07 19:26:50

WindowsDocker工作站

2020-01-18 15:02:48

技術研發(fā)指標

2022-03-14 15:06:15

數(shù)據戰(zhàn)略Cloudera混合云

2014-07-04 10:12:09

VimIDE

2011-06-29 09:45:44

網頁設計

2014-04-15 10:16:03

VMware

2016-09-30 10:16:39

sublimeswift

2021-10-28 22:32:39

比特幣基金金融

2019-06-27 09:05:29

操作系統(tǒng)Android 華為

2021-02-19 19:02:53

Material ShGNOME桌面Linux

2011-08-17 09:57:01

JavaScript

2011-03-21 14:43:48

成功應用移動開發(fā)者

2014-03-21 10:16:17

2009-08-02 09:01:24

Windows2008Windows7

2018-12-10 17:50:12

UCloudAIWeb

2018-12-10 17:55:35

UCloudAIWeb
點贊
收藏

51CTO技術棧公眾號