当前位置: 首页 > news >正文

raft 读请求源码走读


概述

raft-example 提供了一个简化版的 KV 存储,本文围绕 raft-example 对读请求进行源码走读。

源码版本为 etcd release-3.6

raftexample

程序结构

raftexample 程序结构如下所示:

➜  raftexample git:(release-3.6) ✗ tree
.
├── Procfile
├── README.md
├── doc.go
├── httpapi.go
├── kvstore.go
├── kvstore_test.go
├── listener.go
├── main.go
├── raft.go
├── raft_test.go
└── raftexample_test.go

etcd raft 作为 raft 库只实现 raft 算法层的内容,对于节点通信,键值存储等都不涉及,需要用户自己提供。本文只介绍 raft 算法和存储相关内容,对节点通信等不做介绍。

启动 raftexample

进入 main.go 查看 raftexample 的启动流程:

func main() {  // 初始化启动参数cluster := flag.String("cluster", "http://127.0.0.1:9021", "comma separated cluster peers")  id := flag.Int("id", 1, "node ID")  kvport := flag.Int("port", 9121, "key-value server port")  join := flag.Bool("join", false, "join an existing cluster")  flag.Parse()  // 初始化 proposeC 和 confChangeC 通道proposeC := make(chan string)  defer close(proposeC)  confChangeC := make(chan raftpb.ConfChange)  defer close(confChangeC)  // 初始化 kvstore,kvstore 负责存储 KVvar kvs *kvstore  getSnapshot := func() ([]byte, error) { return kvs.getSnapshot() }  // 创建 raftNodecommitC, errorC, snapshotterReady := newRaftNode(*id, strings.Split(*cluster, ","), *join, getSnapshot, proposeC, confChangeC)  // 创建 KVStorekvs = newKVStore(<-snapshotterReady, proposeC, commitC, errorC)  // 作为客户端监听读写请求 serveHTTPKVAPI(kvs, *kvport, confChangeC, errorC)  
}

启动流程中,重点在于 proposeCconfChangeCcommitC 通道。在 newRaftNode 函数创建 raft 应用层节点。外部(客户端层)通过 proposeCconfChangeC 发送消息给 raft 应用层,客户端通过 commitC 接收消息。

newKVStore 函数中创建 KV 存储:

type kvstore struct {  proposeC    chan<- string // channel for proposing updates  mu          sync.RWMutex  kvStore     map[string]string // current committed key-value pairs  snapshotter *snap.Snapshotter  
}

raftexample 使用 map 存储键值对。

serveHTTPKVAPI 会创建 http handler 用来处理读写等请求。

httpKVAPI.ServeHTTP 中有多个请求处理分支,这里仅以 http.MethodGet 方法为例分析读请求是如何处理的:

func (h *httpKVAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {  key := r.RequestURI  defer r.Body.Close()  switch r.Method {case http.MethodGet:  if v, ok := h.store.Lookup(key); ok {  w.Write([]byte(v))  } else {  http.Error(w, "Failed to GET", http.StatusNotFound)  }default:  w.Header().Set("Allow", http.MethodPut)  w.Header().Add("Allow", http.MethodGet)  w.Header().Add("Allow", http.MethodPost)  w.Header().Add("Allow", http.MethodDelete)  http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)  }  
}

读请求处理流程

进入 h.store.Lookup查看读请求是如何处理的:

func (s *kvstore) Lookup(key string) (string, bool) {  s.mu.RLock()  defer s.mu.RUnlock()  v, ok := s.kvStore[key]  return v, ok  
}

非常简单,读数据直接从 kvStore 中取数据即可。


http://www.jsqmd.com/news/33241/

相关文章:

  • 2025年铱星模块生产商新推荐排行榜,专业铱星模块厂家权威测评
  • 跨平台的文件夹映射cifs
  • 2025年工业冷水机品牌供应商/加工厂/批量定制新推荐排行榜白皮书
  • 2025 年护眼食品品牌最新推荐榜单权威发布:聚焦老字号传承与新品牌实力,附选购指南
  • 详细介绍:【MongoDB的RLE压缩数据存储】
  • 模拟赛日志
  • 2025年工作服定制哪家工艺精湛?专业工作服定制生产厂推荐
  • 20251106noip模拟赛
  • 2025年安全检测检验公司排行榜:十大权威机构深度解析
  • 算法社Python基础入门面试题库(新手版含答案) - 指南
  • 2025年安全检测检验公司推荐榜前十名:专业洞察与选择指南
  • 开发管理
  • 错题+trick 集
  • WebStorm 解决无法正确识别Vue3组合式API的问题
  • 激活函数之Tanh
  • 深入解析:一键把本地项目推到 GitHub:通用脚本 + 小白友好指南
  • 2025年凝胶糖果代加工厂推荐,山东佰诺生物科技公司
  • Java的多态和重载
  • 2025 年分离机源头厂家最新推荐排行榜:聚焦国内优质品牌,助力企业精准选型碟片式分离机/离心分离机/全自动分离机公司推荐
  • TXC-38.4
  • ICPC 模板
  • 维修厂家推荐排行榜单2025:权威评测
  • 市面上有实力的维修厂家排名:2025年最新榜单
  • 2025年度隔热膜、防爆膜、木纹膜、磨砂膜公司综合实力榜:技术创新与市场应用深度解析(安徽龙葵智能化建筑遮阳工程有限公司)
  • 国标GB28181算法算力平台EasyGBS助力智慧医院打造全方位视频监控联网服务体系
  • 2025年市面上冷再生机实力厂家推荐排行
  • Keil 生成 Bin 文件最正确的姿势
  • 2025年色谱仪品牌新推荐排行榜白皮书,赛智液相色谱仪怎么样
  • GESP202309 五级 巧夺大奖题解
  • 2025年肯德基门闭门器优质厂家权威推荐榜单:钢制肯德基门/仿铜肯德基门/肯德基门型材源头厂家精选