braft
braft copied to clipboard
如果想用hostname做peer ID,怎样改比较方便呢?
比如在k8s里面用braft,stateful应用只能保证hostname不变,但是IP每次重启就变了。
数据会变化吗?
数据不变,不如数据存在EBS或者EFS里面。
但是k8s里面重启pod/container之后,IP是会变的,这样起来后,braft会需要重新set peers,然后还是会同步所有的数据。
期望是,用k8s的stateful部署,这样可以做到hostname不变但是IP还是会变,在braft里面用hostname去标记所有的meta,这样pod/container重启之后就不用重新同步数据了。
hostname和ip的对应关系能保证一致性么. 一个方案是peerid支持naming service,但是这样查询ip肯定就不是实时生效了。有两个问题:
- 节点重启到发现恢复需要的时间会更长
- 这里可能存在ABA问题(比如两个节点同时重启,ip互换).
2018-04-19 14:16 GMT+08:00 Peng Du [email protected]:
数据不变,不如数据存在EBS或者EFS里面。
但是k8s里面重启pod/container之后,IP是会变的,这样起来后,braft会需要重新set peers,然后还是会同步所有的数据。
期望是,用k8s的stateful部署,这样可以做到hostname不变但是IP还是会变,在braft里面用hostname去标记所有的meta, 这样pod/container重启之后就不用重新同步数据了。
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/brpc/braft/issues/18#issuecomment-382622891, or mute the thread https://github.com/notifications/unsubscribe-auth/AGfYT4OwT-C9S-SCEgcAcjmimkpnvI66ks5tqCvPgaJpZM4TbHFV .
不能保证。k8s的stateful只能保证每次重启hostname不变,但是IP是不做限制的(刚被释放的IP,是否会被立即重用,这个我不确定,但是我感觉应该会有限制,待确认)。
我现在简单的改了一个版本: 1,peerID里面不用butil::EndPoint,自己用hostname + port来代替 2,建立braft::Channel的时候,把hostname+port再转换成butil::EndPoint
这样解决了一个问题是: 1,node重启后,重新加入raft group后,不用再去sync所有的snapshot+binlog
但是还有个问题: 1,leader的replicator是在peers加入的时候建立brpc::Channel的,在那个阶段我把hostname解析成了IP。但是node重启后,leader并不知道背后的IP已经变了。
感觉这个问题在brpc::Channel层面解决会更好一点。
我现在暂时的解决方式是:外围的master/tools发现node重启后,会给leader发请求remove_peers,在node起来后,在add_peers。 但是如果braft能够自动处理的话就更好了。
BTW:etcd的raft实现是支持用hostname的,可能因为他们原生就是要用在k8s上的吧。
支持hostname并不难,让braft::PeerId适配下就好了,现在所有的传输和存储格式都是string,这不会带来兼容性问题。 另外 brpc::Channel是支持动态更新hostname到ip的映射. 但是更新会有一点delay(主动refresh). 这里主要还是得确认几点;
- hostname会不会查出多个ip
- ip在多少时间内不会被重用.
2018-04-19 15:01 GMT+08:00 Peng Du [email protected]:
不能保证。k8s的stateful只能保证每次重启hostname不变,但是IP是不做限制的(刚被释放的IP,是否会被立即重用, 这个我不确定,但是我感觉应该会有限制,待确认)。
我现在简单的改了一个版本: 1,peerID里面不用butil::EndPoint,自己用hostname + port来代替 2,建立braft::Channel的时候,把hostname+port再转换成butil::EndPoint
这样解决了一个问题是: 1,node重启后,重新加入raft group后,不用再去sync所有的snapshot+binlog
但是还有个问题: 1,leader的replicator是在peers加入的时候建立brpc::Channel的,在那个阶段我把hostname解析成了IP。 但是node重启后,leader并不知道背后的IP已经变了。
感觉这个问题在brpc::Channel层面解决会更好一点。
我现在暂时的解决方式是:外围的master/tools发现node重启后,会给leader发请求remove_peers, 在node起来后,在add_peers。 但是如果braft能够自动处理的话就更好了。
BTW:etcd的raft实现是支持用hostname的,可能因为他们原生就是要用在k8s上的吧。
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/brpc/braft/issues/18#issuecomment-382631877, or mute the thread https://github.com/notifications/unsubscribe-auth/AGfYT7GHpHGe4XkuIYmRuHdHJydZx4Baks5tqDZLgaJpZM4TbHFV .
1,一个hostname只会有1个IP 2,如果两个node很快的交换IP,确实会有你说的ABA问题啦。我要确认下多久内不会被重用。
另外要避免这个场景下的ABA问题的话,在sync data的协议中,leader默认把follower的hostname也发过去,follower发现hostname不匹配的话,就refuse请求。
brpc::Channel的更新支持:
133 // Connect this channel to a group of servers whose addresses can be
134 // accessed via `naming_service_url' according to its protocol. Use the
135 // method specified by `load_balancer_name' to distribute traffic to
136 // servers. Use default options if `options' is NULL.
137 // Supported naming service("protocol://service_name"):
138 // bns://<node-name> # Baidu Naming Service
139 // file://<file-path> # load addresses from the file
140 // list://addr1,addr2,... # use the addresses separated by comma
141 // http://<url> # Domain Naming Service, aka DNS.
142 // Supported load balancer:
143 // rr # round robin, choose next server
144 // random # randomly choose a server
145 // la # locality aware
146 // c_murmurhash/c_md5 # consistent hashing with murmurhash3/md5
147 // "" or NULL # treat `naming_service_url' as `server_addr_and_port'
148 // # Init(xxx, "", options) and Init(xxx, NULL, options)
149 // # are exactly same with Init(xxx, options)
150 int Init(const char* naming_service_url,
151 const char* load_balancer_name,
152 const ChannelOptions* options);
是指的这个吗?
// http://
如果是的话,我待会儿改了试一下。
测试过了,这个能解决问题。 // http:// # Domain Naming Service, aka DNS.
能否开启gitter讨论? @chenzhangyi
@pdu 现在没有k8s的测试环境, 你的改动如果比较成熟了,欢迎提交PR,或者可以发起更多的讨论. @lingji 根据我们之前的经验, 『即时聊天』并不是一个非常高效的途径
@pdu 我看了你的修改,string类型的addr,建议考虑支持www.abc.com和1.2.3.4两种格式,直接hostname2ip只有www.abc.com这种。不过最好的方式应该修改brpc中EndPoint,让它支持string类型的hostname和ip addr。
@chenzhangyi @ipconfigme 谢谢你们的建议。我也是觉得在brpc:EndPoint中支持更好。
我现在是计划在项目中用braft,等改动成熟了,我来提交PR。
这个更适合改raft的PeerId 而不是Endpoint
On Thu, May 10, 2018 at 4:50 PM, Peng Du [email protected] wrote:
@chenzhangyi https://github.com/chenzhangyi @ipconfigme https://github.com/ipconfigme 谢谢你们的建议。我也是觉得在brpc:EndPoint中支持更好。
我现在是计划在项目中用braft,等改动成熟了,我来提交PR。
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/brpc/braft/issues/18#issuecomment-387994116, or mute the thread https://github.com/notifications/unsubscribe-auth/AGfYT8ZGTyFk1gcbkoef8xs6a_4c74ZXks5tw_8-gaJpZM4TbHFV .
@pdu 啥时候有pr?
遇到类似的问题,有个想法
- peer id 仅用 string 标识(现有的保留向前兼容)
- braft 加一个选项,初始化 channel 时候根据这个选项调
ns_url
那个构造函数 - 用户自己实现、注册
NamingService
。比如这里想用域名看起来可以复用已有的DomainNamingService
,peer id 用http://xxxx
就行了
Hi @pdu ,你们进展怎么样?是否已经成功落地到k8s上了?
您好,邮件已收到...
这个特性我实现了,如果需要的话,我提了一个 pull request:https://github.com/baidu/braft/pull/429
您好,邮件已收到...