我已经考虑了很多,但无法想出一个我很满意的解决方案.
基本上这就是问题:记录100k Chats(有些慢,有些更快)到cassandra.因此保存userId,channelId,timestamp和消息.
Cassandra已经支持水平扩展,我在这里没有问题.
现在,我读取这些聊天的软件通过TCP(IRC)完成.对于顶级1k通道,通常会有300条消息/秒,而单个IRC连接无法处理我的实验.
我现在想要构建的是记录器的多个实例(使用Docker / Kubernetes)并在它们之间共享负载.理想情况下,如果我有4个工人和1k个聊天(例如).他们每个人都会加入至少250个频道.我说至少是因为我想要可选的冗余,所以我可以在同一个聊天中有2个记录器,以确保没有消息丢失.
重复项没有问题,因为所有消息都有唯一的ID.
现在,我将如何最好地动态分享工人之间加入的当前渠道.我想避免拥有主人或控制点.还应该很容易添加更多的工人,然后减少其他工人的负担.
有关这种行为的好文章吗?也许已经定义了好的概念或协议?就像我说的,我想避免另一个中央控制点,所以没有rabbitmq,redis或其他什么.
编辑:我已经研究过像Raft Consensus Algorithm这样的东西了,但是我认为这没有意义,因为我不希望我的客户就共享状态达成一致,而是将它们之间的状态“平等地”分开.
如上所述,问题可以通过使用Cassandra本身作为中介并在工作者之间共享聊天信道分配信息来解决.
因此(普通部分)渠道将具有ID和分配的工作人员ID,以及可选的冗余情况 – 所需的工作人员数量(2或您想要处理此聊天的任何数量的工作人员).工作人员在将自己分配到频道之前会检查是否已有足够的受理人.如果是这样,将继续下一个频道.如果不是,请将自己分配给频道.这是其中一个选项(或者您可以让工作人员持有通道ID,但由于冗余很少,因此这种方式似乎更简单).工人可以限制他们可以处理的渠道,并且不会通过分配更多渠道来超越它.
现在我们只需处理将过多工人分配到同一渠道,超出要求并通过监控所有相同渠道耗尽工人能力的情况.否则,如果他们一次启动,则渠道可能会分配比所需更多的工作人员.即使在描述的情况下不太可能产生真正的问题(只是比请求的冗余多一点),您可以通过优先考虑工作人员来解决这个问题.就像在加拿大雇用学校教师一样,不列颠哥伦比亚省是在资历基础上完成的 – 最高级的人首先得到工作,除了在这里,工人自己而不是学校管理部门自愿完成工作.这意味着,每个工人都必须检查所有已分配的渠道,并且如果此时需要的工人数量超过需要,将检查所有受让人中是否具有最低优先级.如果是,它将辞职 – 删除自己并停止处理频道.
这需要分配工人的不同优先级,这可以通过简单地将每个工具分别设置为下一个序列号(最老的具有最高优先级,或者如果您担心旧的,可能正在死亡的工人占用所有加载,并希望新的,以保持更多,同时仍然新鲜).更精细的是,这也可以通过使用Cassandra Lightweight transactions来完成,如答案here(one by AlonL)之一中所述.只有少数(你提到~4)工作者应该工作,并且在其他答案中提到的关于缩放的问题对于几个整数优先级没有大问题.此外,代替顺序编号分配,要求工作人员在初始化时自动分配随机32位整数优先级几乎没有碰撞的机会,因此循环“直到没有冲突”应该在第一次迭代时退出(这将导致第二次迭代很少需要显式测试的代码路径).
诀窍主要是限制需要同步的数据量,并将监管负担放在工人自己身上.不需要共识算法,因为没有太多的复杂性,我们没有处理大量潜在的欺诈工人,试图在更高级别的同行之前获得任务.
我应该提到的唯一问题是,如果通道脱机导致工人停止处理,则可能存在隐式工作人员轮换.下次频道上线时,您将获得不同的工作人员作业.