Fork me on GitHub

PHP 中基于 Snowflake 算法生成唯一 UUID 封装

概述

SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序。

原理

SnowFlake算法产生的ID是一个64位的整型,结构如下(每一部分用“-”符号分隔):

  1. 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
  1. 第一部分,1位标识部分,第一个 bit 为符号位,最高位为 0 表示正数;
  2. 第二部分, 41 个 bit 用于记录生成 ID 时候的时间戳,单位为毫秒,所以该部分表示的数值范围为 2^41 - 1(69 年),它是相对于某一时间的偏移量
  3. 第三部分, 10 个 bit 表示工作节点的 ID,表示数值范围为 2^10 - 1,相当于支持 1024 个节点,但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2 ^ 5 个机房(32 个机房),每个机房里可以代表 2 ^ 5 个机器(32 台机器)。
  4. 第四部分, 12 个 bit 表示每个工作节点没毫秒生成的循环自增 id,最多可以生成 2^12 -1 个 id,超出归零等待下一毫秒重新自增

SnowFlake算法生成的ID大致上是按照时间递增的,用在分布式系统中时,需要注意数据中心标识和机器标识必须唯一,这样就能保证每个节点生成的ID都是唯一的。或许我们不一定都需要像上面那样使用5位作为数据中心标识,5位作为机器标识,可以根据我们业务的需要,灵活分配节点部分,如:若不需要数据中心,完全可以使用全部10位作为机器标识;若数据中心不多,也可以只使用3位作为数据中心,7位作为机器标识。

代码:

  1. <?php
  2. /**
  3. * 生成UUID snowflake 算法。线程安全。
  4. * User: Lee Chan
  5. * Date: 2019/4/10
  6. * Time: 9:08
  7. */
  8. namespace App\Common;
  9. class Snowflake
  10. {
  11. const EPOCH = 1543223810238; // 起始时间戳,毫秒
  12. const SEQUENCE_BITS = 12; //序号部分12位
  13. const SEQUENCE_MAX = -1 ^ (-1 << self::SEQUENCE_BITS); // 序号最大值
  14. const WORKER_BITS = 10; // 节点部分10位
  15. const WORKER_MAX = -1 ^ (-1 << self::WORKER_BITS); // 节点最大数值
  16. const TIME_SHIFT = self::WORKER_BITS + self::SEQUENCE_BITS; // 时间戳部分左偏移量
  17. const WORKER_SHIFT = self::SEQUENCE_BITS; // 节点部分左偏移量
  18. protected $timestamp; // 上次ID生成时间戳
  19. protected $workerId; // 节点ID
  20. protected $sequence; // 序号
  21. protected $lock; // Swoole 互斥锁
  22. public function __construct($workerId)
  23. {
  24. if ($workerId < 0 || $workerId > self::WORKER_MAX) {
  25. trigger_error(" WorkerID 超出范围");
  26. exit(0);
  27. }
  28. $this->timestamp = 0;
  29. $this->workerId = $workerId;
  30. $this->sequence = 0;
  31. $this->lock = new \swoole_lock(SWOOLE_MUTEX);
  32. }
  33. /**
  34. * 生成ID
  35. * @return int
  36. */
  37. public function getId()
  38. {
  39. $this->lock->lock(); // 这里一定要记得加锁
  40. $now = $this->now();
  41. if ($this->timestamp == $now) {
  42. $this->sequence++;
  43. if ($this->sequence > self::SEQUENCE_MAX) {
  44. // 当前毫秒内生成的序号已经超出最大范围,等待下一毫秒重新生成
  45. while ($now <= $this->timestamp) {
  46. $now = $this->now();
  47. }
  48. }
  49. } else {
  50. $this->sequence = 0;
  51. }
  52. $this->timestamp = $now; // 更新ID生时间戳
  53. $id = (($now - self::EPOCH) << self::TIME_SHIFT) | ($this->workerId << self::WORKER_SHIFT) | $this->sequence;
  54. $this->lock->unlock(); //解锁
  55. return $id;
  56. }
  57. /**
  58. * 获取当前毫秒
  59. * @return string
  60. */
  61. public function now()
  62. {
  63. return sprintf("%.0f", microtime(true) * 1000);
  64. }
  65. }

测试

  1. $chan = new \chan(100000);
  2. $n = 100000;
  3. for ($i = 0; $i < $n; $i++) {
  4. go(function () use ($snowflake, $chan) {
  5. $id = $snowflake->getId();
  6. $chan->push($id);
  7. });
  8. }
  9. go(function () use ($chan, $n) {
  10. $arr = [];
  11. for ($i = 0; $i < $n; $i++) {
  12. $id = $chan->pop();
  13. if (in_array($id, $arr)) {
  14. exit("ID 已存在");
  15. }
  16. echo $id."\n";
  17. array_push($arr, $id);
  18. }
  19. });

结果

  1. 110518996880593279
  2. 110518996880593280
  3. 110518996880593281
  4. 110518996880593282
  5. 110518996880593283
  6. 110518996880593284
  7. 110518996880593285
  8. 110518996880593286
  9. 110518996880593287
  10. 110518996880593288
  11. 110518996880593289
  12. 110518996880593290
  13. 110518996880593291
  14. 110518996880593292
  15. 110518996880593293
  16. 110518996880593294
  17. 110518996880593295
  18. 110518996880593296
  19. 110518996880593297
  20. 110518996880593298
  21. 110518996880593299
  22. 110518996880593300
  23. 110518996880593301
  24. 110518996880593302
  25. 110518996880593303
  26. 110518996880593304
  27. 110518996880593305
  28. 110518996880593306
  29. 110518996880593307
  30. 110518996880593308
  31. 110518996880593309
  32. 110518996880593310
  33. 110518996880593311
  34. 110518996880593312
  35. 110518996880593313
  36. 110518996880593314
  37. 110518996880593315
  38. 110518996880593316
  39. 110518996880593317
  40. 110518996880593318
  41. 110518996880593319
  42. 110518996880593320
  43. 110518996880593321
  44. 110518996880593322
  45. 110518996880593323
  46. 110518996880593324
  47. 110518996880593325
  48. 110518996880593326
  49. 110518996880593327
  50. 110518996880593328
  51. 110518996880593329
  52. 110518996880593330
  53. 110518996880593331
  54. 110518996880593332
  55. 110518996880593333
  56. 110518996880593334
  57. 110518996880593335
  58. 110518996880593336
  59. 110518996880593337
  60. 110518996880593338
  61. 110518996880593339
  62. 110518996880593340
  63. 110518996880593341
  64. 110518996880593342
  65. 110518996880593343
  66. 110518996880593344
  67. 110518996880593345
  68. 110518996880593346
  69. 110518996880593347
  70. 110518996880593348
  71. 110518996880593349
  72. 110518996880593350
  73. 110518996880593351
  74. 110518996880593352
  75. 110518996880593353
  76. 110518996880593354
  77. 110518996880593355
  78. 110518996880593356
  79. 110518996880593357
  80. 110518996880593358
  81. 110518996880593359
  82. 110518996880593360
  83. 110518996880593361
  84. 110518996880593362
  85. 110518996880593363
  86. 110518996880593364
  87. 110518996880593365
  88. 110518996880593366
  89. 110518996880593367
  90. 110518996880593368
  91. 110518996880593369
  92. 110518996880593370
  93. 110518996880593371
  94. 110518996880593372
  95. 110518996880593373
  96. 110518996880593374
  97. 110518996880593375
  98. 110518996880593376
  99. 110518996880593377
  100. 110518996880593378
  101. 110518996880593379
  102. 110518996880593380
  103. 110518996880593381
  104. 110518996880593382
  105. 110518996880593383
  106. 110518996880593384
  107. 110518996880593385
  108. 110518996880593386
  109. 110518996880593387
  110. 110518996880593388
  111. 110518996880593389
  112. 110518996880593390
  113. 110518996880593391
  114. 110518996880593392
  115. 110518996880593393
  116. 110518996880593394
  117. 110518996880593395
  118. 110518996880593396
  119. 110518996880593397
  120. 110518996880593398
  121. 110518996884787200
  122. 110518996884787201
  123. 110518996884787202
  124. 110518996884787203
  125. 110518996884787204
  126. 110518996884787205
  127. 110518996884787206
  128. 110518996884787207
  129. 110518996884787208
  130. 110518996884787209
  131. 110518996884787210
  132. 110518996884787211
  133. 110518996884787212
  134. 110518996884787213
  135. 110518996884787214
  136. 110518996884787215
  137. 110518996884787216
  138. 110518996884787217
  139. 110518996884787218
  140. 110518996884787219
  141. 110518996884787220
  142. 110518996884787221
  143. 110518996884787222
  144. 110518996884787223
  145. 110518996884787224
  146. 110518996884787225
  147. 110518996884787226
  148. 110518996884787227
  149. 110518996884787228
  150. 110518996884787229
  151. 110518996884787230
  152. 110518996884787231
  153. 110518996884787232
  154. 110518996884787233
  155. 110518996884787234
  156. 110518996884787235
  157. 110518996884787236
  158. 110518996884787237
  159. 110518996884787238
  160. 110518996884787239
  161. 110518996884787240
  162. 110518996884787241
  163. 110518996884787242
  164. 110518996884787243
  165. 110518996884787244
  166. 110518996884787245
  167. 110518996884787246
  168. 110518996884787247
  169. 110518996884787248
  170. 110518996884787249
  171. 110518996884787250
  172. 110518996884787251
  173. 110518996884787252
  174. 110518996884787253
  175. 110518996884787254
  176. 110518996884787255
  177. 110518996884787256
  178. 110518996884787257
  179. 110518996884787258
  180. 110518996884787259
  181. 110518996884787260
  182. 110518996884787261
  183. 110518996884787262
  184. 110518996884787263
  185. 110518996884787264
  186. 110518996884787265
  187. 110518996884787266
  188. 110518996884787267
  189. 110518996884787268
  190. 110518996884787269
  191. 110518996884787270
  192. 110518996884787271
  193. 110518996884787272
  194. 110518996884787273
  195. 110518996884787274
  196. 110518996884787275
  197. 110518996884787276
  198. 110518996884787277
  199. 110518996884787278
  200. 110518996884787279
  201. 110518996884787280
  202. 110518996884787281
  203. 110518996884787282
  204. 110518996884787283
  205. 110518996884787284
  206. 110518996884787285
  207. 110518996884787286
  208. 110518996884787287
  209. 110518996884787288
  210. 110518996884787289
  211. 110518996884787290
  212. 110518996884787291
  213. 110518996884787292
  214. 110518996884787293
  215. 110518996884787294
  216. 110518996884787295
  217. 110518996884787296
  218. 110518996884787297
  219. 110518996884787298
  220. 110518996884787299
  221. 110518996884787300
  222. 110518996884787301
  223. 110518996884787302
  224. 110518996884787303
  225. 110518996884787304
  226. 110518996884787305
  227. 110518996884787306
  228. 110518996884787307
  229. 110518996884787308
  230. 110518996884787309
  231. 110518996884787310
  232. 110518996884787311
  233. 110518996884787312
  234. 110518996884787313
  235. 110518996884787314
  236. 110518996884787315
  237. 110518996884787316
  238. 110518996884787317
  239. 110518996884787318
  240. 110518996884787319
  241. 110518996884787320
  242. 110518996884787321
  243. 110518996884787322
  244. 110518996884787323
  245. 110518996884787324
  246. 110518996884787325
  247. 110518996884787326
  248. 110518996884787327
  249. 110518996884787328
  250. 110518996884787329
  251. ...
2019-09-27 15:43:19  LeeChan 阅读(165) 评论(0) 标签:PHP,Snowflake ,UUID ,原创 分类:技术编程