Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Migrate的疑惑 #40

Closed
molon opened this issue Jan 13, 2016 · 10 comments
Closed

关于Migrate的疑惑 #40

molon opened this issue Jan 13, 2016 · 10 comments

Comments

@molon
Copy link

molon commented Jan 13, 2016

首先很感谢这个库,由于这个库我知晓了不少分布式架构知识。
另外这个库是我学习golang以来研究的第一份源码,有个地方有些疑惑,希望能得到回答。

关于Migrate,
我查看cometchannel.go看到应该是comet在接到Migrate消息后nodeWeightMap更新到最新,然后去检查当前记录的channel key的一致性hash是否是本节点,如果不是就移除并且关闭此channel对应的所有长连接。
上述理解,应该没问题吧。

我非常疑惑的是通知Migrate的时机,是由comet节点Add事件以外的事件触发的(Del和Update)。rpc/comet.go L195

一个一致性hash环,不是应该被删除的节点上的key会被分散到其他节点。而添加节点的话,会从其他节点里匀出一部分到新节点么,那为什么在新节点出现的时候不去通知已有节点把该匀出来那些key清理掉?

如果是节点被删除,那其他正常节点也没必要有清理操作啊,他们本身已有的那些key并不会因为某节点的删除而产生所属变化啊。

可能我的问题比较小白,还请见谅,在下对golang和分布式都是初学,想了很久也没搞懂这个问题。

@Terry-Mao
Copy link
Owner

非常好的issue,我来解释下,不着急

@molon
Copy link
Author

molon commented Jan 18, 2016

@Terry-Mao 多谢毛总,静候回复。:)

@molon
Copy link
Author

molon commented Feb 17, 2016

@Terry-Mao 毛总。。。。

@Terry-Mao
Copy link
Owner

年代有点久远,删除和更新的目的踢下线是为了避免推送时候找不到channel,所以强制踢的,其实gopush做的有点复杂了,现在goim这种在线服务,扔给了router(专门的路由服务)来实现,这样从逻辑来说把router和comet 分开管理了。至于add的问题,年代有点久,我不太记得了,@thinkboy 看看

@thinkboy
Copy link
Contributor

1.添加节点会先后触发两个事件EventAdd,EventUpdate, 流程是先触发EventAdd,这个事件其他节点不会收到,也没有任何Merge操作。EventAdd处理之后会触发EventUpdate,通知到其他节点,这个事件才开始通知所有节点进行Merge操作。
这里做了一个串行操作,原因要先保证节点添加成功才开始拿节点数量做是否本节点的计算。
2.删除节点也会有部分不属于本节点的链接,所以也要通知合并下。

@molon
Copy link
Author

molon commented Feb 18, 2016

@thinkboy 感谢回复。 第一点我理解了,可是第二点的话,我查了相关的资料发现删除节点的话,似乎并不会引起正常节点的链接迁移,这个我也有测试过。
测试方法的话我贴出来:
使用https://github.com/dgryski/go-ketama 工程

func TestRemoveNode(t *testing.T)  {
    var buckets []Bucket

    for i := 1; i <= 5; i++ {
        b := &Bucket{Label: fmt.Sprintf("node%d", i), Weight: 1}
        buckets = append(buckets, *b)
    }

    k, _ := New(buckets)

    m := make(map[string]string)

    inNode5Keys := []string{}
    //测试remove node
    for i := 0; i < 1000000; i++ {
        key := strconv.Itoa(i)
        m[key] = k.Hash(key)
        if m[key]=="node5" {
            inNode5Keys = append(inNode5Keys,key)
        }
    }
    //排序node5上的key
    sort.Strings(inNode5Keys)

    //删除node5
    k,_ = New(buckets[:len(buckets)-1])

    m2 := make(map[string]string)
    //测试remove node
    for i := 0; i < 1000000; i++ {
        key := strconv.Itoa(i)
        index := sort.SearchStrings(inNode5Keys,key)
        if index<len(inNode5Keys)&&inNode5Keys[index]==key {
            continue //如果是原本放入到node5的节点忽略它
        }

        m2[key] = k.Hash(key) //5之前的节点原本存储的key的新对应的节点名称记录
    }

    //遍历m2
    errorCount := 0
    for k,n := range m2 {
        if m[k]!=n {
//          fmt.Println("o:"+m[k]+"-key:"+k+"->:"+n) //发现了由于删除节点引起的正常key的迁移
            errorCount++
        }
    }

    if errorCount>0 {
        t.Errorf("error:%d",errorCount)
    }
}

@Terry-Mao
Copy link
Owner

那可能是一个多余操作了,多谢指出

@molon
Copy link
Author

molon commented Feb 25, 2016

@Terry-Mao 非常感谢回复。学习路很艰难,日后可能还会有叨扰,见谅。:)

@molon molon closed this as completed Feb 25, 2016
@Terry-Mao
Copy link
Owner

这个项目其实本身做复杂了,可以看看goim,一直在维护和更新呢

@molon
Copy link
Author

molon commented Feb 26, 2016

@Terry-Mao ok :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants