Skip to content

Commit

Permalink
add: gossip protocol.
Browse files Browse the repository at this point in the history
  • Loading branch information
auula committed Nov 1, 2024
1 parent 3218623 commit aa35a72
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 15 deletions.
85 changes: 79 additions & 6 deletions server/gossip/gossip.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,87 @@
package gossip

import (
"errors"
"hash/fnv"
"sort"
"sync"
"time"
)

type Status struct {
Nodes map[string]*Node // 所有已知节点的信息
Self *Node // 本节点信息
Mutex sync.Mutex // 保护 Nodes 的并发访问
Interval time.Duration // 心跳间隔
LossThresh time.Duration // 失效阈值
const MinNeighbors = 3 // 最小节点数,奇数

type Node struct {
ID string // 节点唯一标识
Address string // 节点地址
Heartbeat int // 心跳计数
Timestamp int64 // 最新心跳时间
Alive bool // 节点状态
Hash uint32 // 节点哈希值,用于一致性哈希
}

type Cluster struct {
Neighbors map[string]*Node // 所有已知节点的信息
Self *Node // 本节点信息
Mutex sync.Mutex // 保护 Nodes 的并发访问
Interval time.Duration // 心跳间隔
Timeout time.Duration // 失效阈值
HashRing []*Node // 一致性哈希存储范围的键
}

func NewNode(id, addr string) *Node {
node := &Node{
ID: id,
Address: addr,
Heartbeat: 0,
Timestamp: time.Now().Unix(),
Alive: true,
}
// 计算节点的哈希值
node.Hash = NodeHash(id)
return node
}

func NewCluster(id, addr string, interval, timeout time.Duration) *Cluster {
self := NewNode(id, addr)
return &Cluster{
Neighbors: map[string]*Node{id: self},
Self: self,
Interval: interval,
Timeout: timeout,
HashRing: []*Node{self}, // 将自身添加到哈希环,多个节点形成一个哈希环
}
}

// AddNodes 批量添加数据节点
func (c *Cluster) AddNodes(nodes ...Node) error {
c.Mutex.Lock()
defer c.Mutex.Unlock()

// 必须是奇数数量的节点集群
if len(nodes) < MinNeighbors {
return errors.New("")
}

// 设置节点哈希值并将节点加入到邻居中
for _, node := range nodes {
// 通过节点 ID 算出在哈希环中的值
node.Hash = NodeHash(node.ID)
c.Neighbors[node.ID] = &node
// 节点对应哈希值也要放到一致性节点环中
c.HashRing = append(c.HashRing, &node)
}

// 对一致性哈希环中的节点按哈希值排序
sort.Slice(c.HashRing, func(i, j int) bool {
return c.HashRing[i].Hash < c.HashRing[j].Hash
})

return nil
}

// NodeHash 计算节点的唯一哈希值
func NodeHash(key string) uint32 {
h := fnv.New32a()
h.Write([]byte(key))
return h.Sum32()
}
9 changes: 0 additions & 9 deletions server/gossip/node.go

This file was deleted.

0 comments on commit aa35a72

Please sign in to comment.