day 23 - 取号机 AUTO_INCREMENT(MYSQL) > INCR(Redis) > snowflake演算法

取号机制是专案中很常会使用到的项目。在我们的生活中小到饮料店的取餐单、银行的号码牌, 大到公文系统的公文编号、医院的病历号以及我们的身分证字号, 都存在取号机制, 取号机制是用来辨别项目是唯一的方式。

将MYSQL 栏位设定成AUTO_INCREMENT来建立唯一识别码, 资料写入DB之後就可以有不重复的编号, 有需要再把编号拿出来使用, 这在很久以前用在公文/表单系统时还可以, 当时的专案不太讲究处理速度, 也不会发生高并发写入的状况,以当时的状况来说, 用起来也算是相安无事/images/emoticon/emoticon10.gif。 这个方式遇到大量同时写入需求时, 由於资料库写入时会把整张表锁住, 写入速度会变慢, 也会发生Duplicate entry 'xxx' for key 'PRIMARY'的错误, 。
MYSQL 有提供参数innodb_autoinc_lock_mode可以设定AUTO_INCREMENT写入状况, 可参考官网

  • innodb_autoinc_lock_mode = 0 (“traditional” lock mode)
    • 写入时会取全表锁住, 效能最差
  • innodb_autoinc_lock_mode = 1 (“consecutive” lock mode) (default)
    • 批次写入时会保证同一批id会连续, 会先分配多个id, 所以会锁住分配的那一块
  • innodb_autoinc_lock_mode = 2 (“interleaved” lock mode)
    • 不锁表, 只锁住处理分配id的部分, 一次取一个id, 效能最好

第二种取号方式是透过Redis。Redis是single thread的架构,内部是采原子式操作,就算高并发的去打Redis, 它的INCR指令在每次执行时能确保一次都只有一个请求被操作, 所以可以用来实现取号机制。概念就像是一个调酒师可以为多个客人提供服务, 但是他一次只能调出一杯酒交付给一位客人, 但最终每个客人都能拿到酒。/images/emoticon/emoticon07.gif
另外Redis是在记忆体上面操作, 他的效能会比在资料库上面来的好, 除了用INCR实现取号机制之外, Redis提供的锁也可以依照不同的使用情境选择不同的储存型别来实现其他的取号方式。


最後是这几年我们采用的产生唯一码的方式:Snowflake。
snowflake 是Twitter用来产生有序的全域唯一ID的演算法, 为了在分散式系统中让每台机器都能产生不重复ID纪录每秒上万条的讯息, Twiter内部提出了snowflake演算法, 它不需要依赖任何套件, 也不需要网路就可以运作。
我们使用的套件是bwmarrin/snowflake
用法:

// nodeID := GetSnowFlakeNodeIdKey(min, max)
// nodeID for 测试用 直接使用 1
nodeID := int64(1)
node, err = snowflake.NewNode(nodeID)
node.Generate().Int64()

带入snowflake.NewNode的nodeID要把角色区分出来,所以会在GetSnowFlakeNodeIdKey这个function依照使用情境来取得不重复的nodeID, 服务有多Pod时每个Pod都要能取得不重复的nodeID。
此外,如果是新旧系统整并时, 要注意是不是有资料整合的情况, 如果两边都使用snowflake取号就会有拿到同样ID的机会, 所以还有一个sonyflake演算法可以使用喔/images/emoticon/emoticon81.gif

参考资料:


<<:  GCP Container Registry

>>:  Day17-Redux 篇-用 Redux Toolkit 实作范例

[DAY04] 建立 Datastore 和 Dataset (下)

DAY04 建立 Datastore 和 Dataset (下) 今天我们就要把昨天建立好的 dat...

L2TP最不可能用於加密 VPN 连接中的数据

-VPN 访问(来源:ActForNet) VPN 是一种通过隧道连接节点的虚拟网路。L2F、PP...

新增装备 - VSCode 套件介绍

前情提要 身後传来了声音:「哈罗,我叫艾草,是你的入门引导学姊。」 我回头一看却没看到人。 「这里!...

iOS APP 开发 OC 第二十天,@class 物件互相引用 重现文字狱烧书,苏轼冤狱而死。

tags: OC 30 day 创建一个类 如何创建一个书的class? 首先点击add File的...

Day25 参加职训(机器学习与资料分析工程师培训班),Python程序设计

建立网路的其他写法 from tensorflow.keras.models import Sequ...