当前位置: 首页 > 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.gsyq.cn/news/41882.html

相关文章:

  • 2025年工业冷水机品牌供应商/加工厂/批量定制新推荐排行榜白皮书
  • 详细介绍:【MongoDB的RLE压缩数据存储】
  • 模拟赛日志
  • 2025年工作服定制哪家工艺精湛?专业工作服定制生产厂推荐
  • 2025年安全检测检验公司排行榜:十大权威机构深度解析
  • 算法社Python基础入门面试题库(新手版含答案) - 指南
  • 深入解析:一键把本地项目推到 GitHub:通用脚本 + 小白友好指南
  • Java的多态和重载
  • 2025 年分离机源头厂家最新推荐排行榜:聚焦国内优质品牌,助力企业精准选型碟片式分离机/离心分离机/全自动分离机公司推荐
  • 维修厂家推荐排行榜单2025:权威评测
  • 2025年色谱仪品牌新推荐排行榜白皮书,赛智液相色谱仪怎么样
  • GESP202309 五级 巧夺大奖题解
  • 2025年肯德基门闭门器优质厂家权威推荐榜单:钢制肯德基门/仿铜肯德基门/肯德基门型材源头厂家精选
  • feg
  • 2025 年 11 月竹制品防霉剂,防虫防霉剂,鞋子防霉剂厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!
  • 减压风暴小程序:释放压力的休闲新选择,助力流量变现新机遇
  • 2025年市场上破碎机工厂推荐排行榜前十名
  • 吴恩达深度学习课程二: 改善深层神经网络 第一周:深度学习的实践 课后作业和代码实践
  • 读书笔记:分区维护:让数据库管理更轻松高效
  • 2025年11月6日
  • 2025年钣金机架工厂权威推荐榜单:铝型材设备机架/铝型材防护罩/设备机架制作源头厂家精选
  • PG故障处理:PG归档空间耗尽案例分析
  • Applied Machine learning and AI for egnineers与NPL with transform等书推荐
  • 2025年PCBA电路板加工厂哪家售后好?
  • 12c RAC添加节点
  • 十五五规划释放AI产业新信号,边缘智能或成下一个风口
  • 2025年山东霍尼韦尔继电器品牌权威推荐:山东霍尼韦尔固体继电器/山东霍尼韦尔继电器选型/山东霍尼韦尔低压控制元件源头供应商精选
  • 量化选股与量化交易第857篇:通达信主升操盘 - Leone
  • 【中大厂前端】Java常见面试题 - 教程
  • 量化选股与量化交易第858篇:通达信擒龙三把锁 - Leone