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

严格递增的ID生成算法并非全局严格递增 #324

Open
pedrogao opened this issue Sep 25, 2024 · 16 comments
Open

严格递增的ID生成算法并非全局严格递增 #324

pedrogao opened this issue Sep 25, 2024 · 16 comments
Labels
question Further information is requested

Comments

@pedrogao
Copy link

Module: camellia-id-gen
Version: all
Content: 严格递增的ID生成算法并非全局严格递增,这里似乎没有考虑 redis 宕机,主备切换的问题

由于 redis 本身是AOF,主从异步复制的机制,如果 master 宕机,切换到从库,那么 list 可能仍然包含已经 pop 出去的旧数据,这样就会造成ID回拨,就无法保证全局严格递增了

还是有啥其它的保证机制吗?我目前没有发现

https://github.com/netease-im/camellia/blob/master/docs/camellia-id-gen/strict.md

image
@pedrogao pedrogao added the question Further information is requested label Sep 25, 2024
@caojiajun
Copy link
Collaborator

这个确实是没有考虑的,基于redis都有这个问题。
但是好像目前有一些强一致的redis-compatible实现

@pedrogao
Copy link
Author

分布式场景下,需要将 seq 读写收敛到一个单点,才能保证 seq 全局单调增,但是这由与多节点容灾相悖,受CAP影响,全局单调增感觉实现不太现实

@caojiajun
Copy link
Collaborator

你们什么场景需要严格递增的发号器?

@pedrogao
Copy link
Author

你们什么场景需要严格递增的发号器?

太好了,刚想讨论这个点,感觉您肯定会有经验,这里我们讨论一下

其实在自研IM场景下,针对某个会话下的消息,每个消息都有唯一的seq,那么 seq 必然是有序的,且最好是全局单调递增的,这样就能保证会话下的消息能收敛有序

我看了很多的im,但似乎都没能实现全局单调递增(可能不现实)

请问你们在落地im的过程中,消息的排序是如何保证的?seq有哪些约束?

@caojiajun
Copy link
Collaborator

云信的im系统中,不要求严格递增(或者说真的不严格递增了也不会产生破坏性),感觉不太建议im系统中强依赖这个

@pedrogao
Copy link
Author

云信的im系统中,不要求严格递增(或者说真的不严格递增了也不会产生破坏性),感觉不太建议im系统中强依赖这个

那业务上是怎么会话消息有序的?或者说有啥业务上的解法,感觉趋势递增的话,会造成im消息突然乱掉,很影响体验

@caojiajun
Copy link
Collaborator

按毫秒时间戳排?

@pedrogao
Copy link
Author

按毫秒时间戳排?

毫秒时间戳 + 8位 seq 吗?应该是这个方案 https://github.com/netease-im/camellia/blob/master/docs/camellia-id-gen/strict2.md?

@caojiajun
Copy link
Collaborator

你说的排序,只是为了ui上的排序吗,还是会涉及消息的收发和ack?

@pedrogao
Copy link
Author

你说的排序,只是为了ui上的排序吗,还是会涉及消息的收发和ack?

ui上,消息收发或者ack依赖消息id

@caojiajun
Copy link
Collaborator

ui上的,完全按照timestamp排序即可吧,即使后发先到也无所谓,只要下次打开再刷新也行

ack的话不建议强依赖这个,不然反而容易丢消息

@pedrogao
Copy link
Author

ui上的,完全按照timestamp排序即可吧,即使后发先到也无所谓,只要下次打开再刷新也行

ack的话不建议强依赖这个,不然反而容易丢消息

这里有个比较麻烦的点,如果按照秒级 timestamp 来排序,那么客户端如何计算与服务端之间的消息增量?没有明确的seq做标识,客户端就只能无脑pull了

@pedrogao
Copy link
Author

  • seq 必须存储,且必须保持主从同步复制,异步会导致 seq 回拨;
  • 发号器必须有容灾,一个实例挂了,另外一个实例能继续work;
  • seq 想要保证全局单调递增,则必须收敛到一个点读写;
  • 单点读写肯定会影响吞吐量,因此必须得加缓存,一旦有了缓存,就变成了多点发号,单调递增会退化为趋势递增;

这些矛盾是一个不可能三角:

image

首先我们必须需要吞吐量和容灾,这是发号器稳定工作支撑IM的根本,另外对于单调性,如果无宕机,那么就是全局单调递增的,可一旦发生了,那就必须退化为趋势递增。
这里的不可能三角与CAP几乎一致,无灾的情况下能保证一致性,一旦发生了,只能牺牲一致性。

从这个点上,发散讨论一下

@caojiajun
Copy link
Collaborator

都是各种取舍

要加微信群讨论么 :)

@pedrogao
Copy link
Author

都是各种取舍

要加微信群讨论么 :)

来,给个微信群

@caojiajun
Copy link
Collaborator

加我微信拉你进群:hdnxttl

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

No branches or pull requests

2 participants