数据库读写分离详解( 五 )

如何改造我们现在已经知道了Snowflake 算法的核心原理,并且知道了其有64位的二进制数据,那我们就可以根据自己业务进行改造以更好的来为我们业务服务 。一般不同的公司对其进行改造的方式都不尽相同,但是道理都是一样的 。我们可以这么做:

  1. 我们是减少序列号的位数,增加机器ID的位数,是为了用来支撑我们单IDC的更多机器 。
  2. 将我们业务ID加入进去用来区分我们不同的业务 。比如,1位0 + 41位时间戳 + 6位IDC(64个IDC) + 6位业务信息(支撑64种业务) + 10位自增序列(每毫秒1024个ID)

数据库读写分离详解

文章插图
 
如此,我们就可以在单机房部署这么一个统一ID发号器,然后用Keeplive 保证高可用(对于高可用不熟悉的回去看看哈「高可用」你们服务器挂了怎么办,我们是这样做的)可以将不同的业务模块ID加入进去,这样的好处是即使哪个业务出问题了,我只看ID号我就分析出来,比如,我看到现在ID号有我的订单ID业务,我就去看订单模块 。
开发如何使用现在我们知道Snowflake 算法原理了,还知道了我们可以进行改造了 。那我们开发人员该怎么去使用,来为我们业务生成统一的唯一ID呢?
1,直接嵌入到业务代码
嵌入业务代码的意思就是,这个snowflake算法就部署在和我们业务相同的服务器上,这样我们代码使用的时候,就不用了跨网络调用,性能相对比较好 。但是也是有缺点的,因为我们的业务机器肯定是很多的,这就意味着我们发号器算法需要更多的机器ID位数 。同时,太多的业务服务器我们会很难保证业务机器id的唯一性,这里就需要引用zookeeper一致性组件来保证每次机器重启都能能获得唯一的机器ID 。
2,独立部署成发号器服务
也就是说,我们将其作为单独的服务部署到单独的机器上,已对外提供服务 。这样就是多了网络的传输,不过影响不大,比如,我可以将其部署成一个主备的方式对外提供发号服务,机器ID可以用作序列号使用,这样也就是会有更多的自增序号,有部分大厂就是以这样单独的服务提供出来的 。
开发中避坑大法1,虽然snowflake很优秀,但是它是基于系统时间的,万一我们系统的时间不准怎么办,就会造成我们的ID会重复 。那我们的做法就是,要利用系统的对时功能,一旦发现时间不一致,就暂停发号器,等到时钟准了在启用 。
2,还有一个坑比较关键,也是常发生的,就是当我们的QPS并发不高的时候,比如每毫秒只生成一个ID号,这样就是直接结果是,每次生成的ID末尾都是1,这样我们分库分表就会出现问题呀对吧,因为我们用这个ID去分库分表呀,会造成数据不均匀,是吧,忘记了去复习哈(数据库分库分表方案,优化大量并发写入所带来的性能问题)那我们怎么解决呢?
我们可以将时间戳记录从毫秒记录改为秒记录,这样我一秒可以发好多个号了
生成的序列号起始号随机启动,比如这一秒起始号是10,我下一秒随机了变成了28,这样就更加分散开了 。
总结,今天我们针对分库分表之后带来的第一个直接影响我们开发的问题,就是主键ID唯一性的问题,然后说到了使用Snowflake算法去解决,并且对其原理和使用进行了详细的讲解,同时,还将其在使用中遇到的坑给讲出来了,也对其进行了填坑分析,让大家直接避免遇到同样的问题 。当然生成唯一ID有多种,我们根据业务选择合适我们自己的就好

【数据库读写分离详解】


推荐阅读