讨论/系统设计/高并发生成8位数字唯一标识/
高并发生成8位数字唯一标识

环境与限制条件:
高并发访问 200个请求每秒,
对每个请求生成一个8位数字唯一标识,
相近的请求标识不允许直接递增返回,
此标识要存储到数据库,
不允许用redis,只有一个mysql,
后台程序可能随时会重启,
要求最快,耗费计算时间和存储空间最小,
请求获取标识的成功率最高。
服务器内存2G,带宽5Mbps,

你的方法是?

展开讨论
Zhenchuan Ren发起于 2020-02-21
最近编辑于 2020-02-21

1, 3, 2, 5, 4, 7, 6, 9, 8, 11......
每生成一个写一下文件,记录当前进度...嘻嘻...

开玩笑啦:

  1. 可以走纯文件分段分配:
    每次记录segment.txt 内容为一个数字,第一次为1
    每次启动读取segment.txt,数字作为当前分位段:
    第一次应该是1号分位段内存预分配1~1000(第二个分位段1001~2000依次类推), random.shuffle之后,每次拿一个,先用添加方式写入last_alloc.txt, 内容为{id} , 再返回给用户
    如果这1000个分配完了就更新segment.txt然后领取下一个分位段,并且重置last_alloc.txt为空,再次用random.shuffle分配...
    如果中途发生kill -9 重启,那么由于每次可以通过segment.txt获取上次分位段信息,并且,可以获取最近last_alloc.txt信息... 基本速度就是最快(最好用ssd哦)...

  2. 可以走纯mysql预分配
    先random.shuffle 100000000,写入mysql(一次1亿个太多的话,可以10万10万的刷),
    mysql每一行是 id, status, status,两列都有索引, id为主键,
    然后每次分配,就是每次获取status为未分配的最小的id, 分配后status标记成已经分配,预计同一台机器的mysql 5ms一个id应该是可以
    并发可以用mysql的cas update的写法,冲突就多次重试...
    虽然没有上面那个文件方式顺序读写那么极端快速(毕竟多了一次网络交互)但也很猛了。
    主键索引顺序索引查询方式也是很快了...

题目要点:
随时可能重启:也就是每次分配必须先写文件再返回用户,不然一旦kill -9找不到当前已经分配的记录
要求最快,耗费计算时间和存储空间最小:直接用纯文件避免网络交互,ssd硬盘,小文件1000数字(二进制int数1000),保证内容小于4KB,每次刷新极快。

展开全部 5 讨论