NSQ 源码分析之Lookupd--DB

本文深入探讨了NSQ Lookupd的数据存储方式,重点介绍DB如何维护NSQD的身份信息、Topic信息及Topic中的Channel信息。通过分析registration_db.go文件,理解其数据结构、查找匹配功能以及增删改查操作,为后续的lookup_protocal_v1协议分析奠定基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天主要讲的是 Lookupd数据存储方式(DB)。Lookupd主要保存三种信息,一是 NSQD 身份信息,二是 NSQD Topic 信息,三是 NSQD Topic 中 Channel 信息。

主要代码文件:

1.nsqlookupd/registration_db.go 

结构体:

type PeerInfo struct { //伙伴信息(nsqd)
	lastUpdate       int64 //上次心跳检查时间
	id               string
	RemoteAddress    string `json:"remote_address"` 
	Hostname         string `json:"hostname"`
	BroadcastAddress string `json:"broadcast_address"`
	TCPPort          int    `json:"tcp_port"`
	HTTPPort         int    `json:"http_port"`
	Version          string `json:"version"`
}

type Producer struct { //nsqd 封装
	peerInfo     *PeerInfo //nsqd 信息
	tombstoned   bool //墓碑状态
	tombstonedAt time.Time //墓碑状态开始时间
}

type RegistrationDB struct { // 注册表
	sync.RWMutex
	registrationMap map[Registration]ProducerMap
}

type Registration struct { //注册信息
	Category string  //现在主要有三种,channel,topic,及 nsqd 的身份信息(client)
	Key      string  //一个确定的值(topic channel 的名称等)或者 *
	SubKey   string //一个确定的值(topic channel 的名称等)或者 *
}
type Registrations []Registration
type Producers []*Producer
type ProducerMap map[string]*Producer

上面的结构体,总结关系如下:

FindRegistrations 函数 查找符合条件的注册记录

func (r *RegistrationDB) FindRegistrations(category string, key string, subkey string) Registrations {
	r.RLock()
	defer r.RUnlock()
    /*
        如果 key 和 subkey 都不是*。则是精确查找
    */
	if !r.needFilter(key, subkey) {
		k := Registration{category, key, subkey}
		if _, ok := r.registrationMap[k]; ok {
			return Registrations{k}
		}
		return Registrations{}
	}
	results := Registrations{}
	for k := range r.registrationMap { //匹配*查找
		if !k.IsMatch(category, key, subkey) {
			continue
		}
		results = append(results, k)
	}
	return results
}

IsMatch 函数 匹配 *

func (k Registration) IsMatch(category string, key string, subkey string) bool {
	if category != k.Category {
		return false
	}
	if key != "*" && k.Key != key {
		return false
	}
	if subkey != "*" && k.SubKey != subkey {
		return false
	}
	return true
}

FindProducers 查找符合条件的peerInfo

func (r *RegistrationDB) FindProducers(category string, key string, subkey string) Producers {
	r.RLock()
	defer r.RUnlock()
	if !r.needFilter(key, subkey) { //精确查找
		k := Registration{category, key, subkey}
        //返回切片数据
		return ProducerMap2Slice(r.registrationMap[k])
	}

	results := make(map[string]struct{})
	var retProducers Producers
	for k, producers := range r.registrationMap {
		if !k.IsMatch(category, key, subkey) { //匹配*
			continue
		}
        //收集producer
		for _, producer := range producers {
			_, found := results[producer.peerInfo.id]
			if found == false {
				results[producer.peerInfo.id] = struct{}{}
				retProducers = append(retProducers, producer)
			}
		}
	}
	return retProducers
}

其他的查询函数,基本 FindProducers 和 FindRegistrations 相似,在这里就不需要赘述.至于其他的函数,都是简单的map操作,也不做详细说明。

其他函数:

AddRegistration:向注册表注册一条信息

AddProducer:添加一条nsqd信息

RemoveProducer:移除一条nsqd信息

RemoveRegistration:移除一条注册表信息

LookupRegistrations :查找指定ID的注册信息

Filter:过滤查找

FilterByActive:查找活跃nsqd

总结:registration_db 定义了一种数据结构,来管理相关信息,可以简单的理解成主表 + 子表的形式。该文件主要实现的就是"数据表”的增删改查。

下一次分享:lookupd 中的协议 lookup_protocal_v1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值