代码之家  ›  专栏  ›  技术社区  ›  gempir

水平缩放聊天日志工作程序

  •  6
  • gempir  · 技术社区  · 6 年前

    基本上这就是问题所在:在cassandra中记录100k+个聊天记录(一些比较慢,一些比较快)。所以保存userId,channelId,timestamp和消息。

    卡桑德拉已经支持横向扩展,我在这里没有问题。

    我现在要构建的是记录器的多个实例(使用Docker/Kubernetes),并在这些实例之间共享负载。所以理想情况下,如果我有4个工人和1k聊天(例如)。他们每人至少要加入250个频道。我之所以说至少是因为我想要可选的冗余,这样我就可以在同一个聊天中有两个记录者,以确保没有消息丢失。 重复没有问题,因为所有消息都有唯一的ID。

    关于这种行为有什么好文章吗?可能已经定义了好的概念或协议?就像我说的,我想避开另一个中央控制点,这样就不会有rabbitmq、redis或其他什么东西了。

    编辑:我研究过类似Raft一致性算法的东西,但我认为这没有意义,因为我不希望我的客户同意共享状态,而是“平等地”划分它们之间的状态。

    1 回复  |  直到 6 年前
        1
  •  3
  •   isp-zax    6 年前

    我认为在这种情况下寻找现有算法的描述可能不是非常有用的:问题并不复杂和通用,足以值得出版。

    如前所述,可以通过使用Cassandra本身作为中介来解决问题,并在工人之间共享聊天频道分配信息。

    所以(琐碎的部分)通道将有ID和分配的worker ID,加上在可选的冗余情况下-所需的worker数量(2个或您希望处理此聊天的任何数量的worker)。在将自身分配给通道之前,Worker将检查是否已经有足够的受让人。如果这样的话会继续到下一个频道。如果不是,则将自己分配给频道。这是一个选项(或者您可以让工人持有通道id,但由于冗余很少,这种方式似乎更简单)。工人将有一个他们可以处理的通道的限制,并且不会试图通过分配更多通道来超过它。

    现在我们只需要通过监视所有相同的通道来处理为同一个通道分配过多工人、超出要求和耗尽工人能力的情况。否则,如果一次全部启动,则频道可能会有比所需更多的已分配工作人员。即使在所描述的情况下不太可能产生真正的问题(只是比请求的冗余多一点),您也可以通过优先处理工人来处理这个问题。就像在加拿大雇用学校教师一样,卑诗省是根据资历来做的——最年长的人首先得到工作,但在这里,这是工人自己自愿做的,而不是学校管理部门。这意味着,每个工人都必须检查其分配的所有通道,如果此时需要的工人超过需要的数量,则检查其在所有分配者中是否具有最小的优先级。如果它真的这样做了,它就会辞职——移除自己并停止处理频道。

    Lightweight transactions 如其中一个答案所述 here (在 one by AlonL ). 只要几个(你提到了~4)工人就可以工作了,其他答案中提到的缩放问题对几个整数优先级来说没什么大不了的。此外,代替序号分配,要求工人在初始化时自行分配一个随机32位整数优先级几乎没有碰撞的机会,所以循环“直到没有冲突”应该在第一次迭代中退出(这将使得第二次迭代很少需要显式测试的代码路径)。

    诀窍基本上是限制需要同步的数据量,把监管的重担推给工人自己。不需要协商一致的算法,因为没有太多的复杂性,我们没有处理大量潜在的欺诈工人,试图获得更高级同行的任务。

    我要提到的唯一问题是,如果通道离线,可能会有隐式的工作线程轮换,这使得工作线程停止处理。下次频道上线时,您将得到一个不同的工作分配。