nsq源码分析(2):nsqlookup之RegistrationDB数据库

nsq源码分析(2):nsqlookup之RegistrationDB数据库

RegistrationDB保存集群中nsqd的拓扑信息及注册和心跳信息
nsqlookupd参考资料

RegistrationDB结构体

RegistrationDB是一个map类型 map[Registration]Producers ,在读写操作过程中使用读写锁来保证数据一致性

nsqlookupd/registration_db.go

type RegistrationDB struct {
    sync.RWMutex
    registrationMap map[Registration]Producers
}

// nsqd的注册信息
type Registration struct {
    Category string // 类别,client、topic、channel。其中client则表示nsqd在第一次连接nsqlookup的IDENTITY验证信息
    Key      string // topic名称
    SubKey   string // channel名称
}
type Registrations []Registration

// nsqd主机相关信息
type PeerInfo struct {
    lastUpdate       int64  // nsqd的心跳更新时间
    id               string // nsqd的ip地址作为唯一标识
    RemoteAddress    string `json:"remote_address"`    // ip地址
    Hostname         string `json:"hostname"`          // 主机名
    BroadcastAddress string `json:"broadcast_address"` // 广播地址
    TCPPort          int    `json:"tcp_port"`          // tcp端口
    HTTPPort         int    `json:"http_port"`         // http端口
    Version          string `json:"version"`           // nsqd版本
}

// nsqd相关信息
type Producer struct {
    peerInfo     *PeerInfo // nsqd主机相关信息
    tombstoned   bool      // nsqd是否被逻辑删除
    tombstonedAt time.Time // 被标识为tombstoned的时间戳
}

/*
逻辑删除:让某一个topic不在集群中的某个nsqd上生产
在TombstoneLifetime时间周期内(默认45s),生产者不会在/lookup查询中列出该nsqd节点,并阻止consumer重新发现这个nsqd节点
*/

Registration的增删查

// add a registration key
// 当nsqd创建topic或channel时注册到nsqlookup
func (r *RegistrationDB) AddRegistration(k Registration) {
    r.Lock()
    defer r.Unlock()
    _, ok := r.registrationMap[k]
    if !ok {
        r.registrationMap[k] = Producers{}
    }
}

// remove a Registration and all it's producers
// 当nsqd删除topic或channel时从nsqlookup中删除
func (r *RegistrationDB) RemoveRegistration(k Registration) {
    r.Lock()
    defer r.Unlock()
    delete(r.registrationMap, k)
}

// 查找注册信息
func (r *RegistrationDB) FindRegistrations(category string, key string, subkey string) Registrations {
    r.RLock()
    defer r.RUnlock()
    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
}

Producer的增删查

// add a producer to a registration
// 添加Producer
func (r *RegistrationDB) AddProducer(k Registration, p *Producer) bool {
    r.Lock()
    defer r.Unlock()
    producers := r.registrationMap[k]
    found := false
    for _, producer := range producers {
        if producer.peerInfo.id == p.peerInfo.id {
            found = true
        }
    }
    if found == false {
        r.registrationMap[k] = append(producers, p)
    }
    return !found
}

// remove a producer from a registration
// 删除Producer
func (r *RegistrationDB) RemoveProducer(k Registration, id string) (bool, int) {
    r.Lock()
    defer r.Unlock()
    producers, ok := r.registrationMap[k]
    if !ok {
        return false, 0
    }
    removed := false
    cleaned := Producers{}
    for _, producer := range producers {
        if producer.peerInfo.id != id {
            cleaned = append(cleaned, producer)
        } else {
            removed = true
        }
    }
    // Note: this leaves keys in the DB even if they have empty lists
    r.registrationMap[k] = cleaned
    return removed, len(cleaned)
}

// 查找Producers信息
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 r.registrationMap[k]
    }

    results := Producers{}
    for k, producers := range r.registrationMap {
        if !k.IsMatch(category, key, subkey) {
            continue
        }
        for _, producer := range producers {
            found := false
            for _, p := range results {
                if producer.peerInfo.id == p.peerInfo.id {
                    found = true
                }
            }
            if found == false {
                results = append(results, producer)
            }
        }
    }
    return results
}

// 通过id查找注册信息
func (r *RegistrationDB) LookupRegistrations(id string) Registrations {
    r.RLock()
    defer r.RUnlock()
    results := Registrations{}
    for k, producers := range r.registrationMap {
        for _, p := range producers {
            if p.peerInfo.id == id {
                results = append(results, k)
                break
            }
        }
    }
    return results
}

你可能感兴趣的:(nsq源码分析)