亿级流量系统架构设计与实战(八)

目的:设计一个可以生成递增long类型唯一 ID 的生成器

  • long 类型占用空间小,可以表示的 ID 范围足够大。
  • long 类型容易实现递增效果。

分布式唯一 ID

在复杂的系统中,实体需要 ID 做唯一标识,方便操作。 如:每个用户有唯一用户 ID 等等。

全局唯一与 UUID

全局唯一:无论业务实体的数据被分散到多少个数据库中,每条数据的唯一 ID 都是全局的。

UUID

UUID :通用唯一识别码 ( Universally Unique Identifier , UUID ),是计算机体系中用于识别信息的一个 128 位标识符。

UID 的标准格式由 32 个十六进制数字组成,并通过连字符“-”分隔成 “8-4-4-4-12”共 36 个字符的形式 。

例如:“6a0d3e6f-allc-4b7d-bb35-c4c530a456b0”,“123e4567-e89b-12d3-a456-426655440000 ”

  • 自增主键做唯一 ID:
    • 全局不唯一,数据量少,没有分库分表 可以满足。
    • 做了分库分表之后,数据表之间是相互独立的,插入数据时,会生成相同的自增主键。
  • UUID 做唯一 ID:
    • 生成简单,本地计算就可以生成全球唯一的 UUID。
    • 占用 36 字节,海量数据下浪费内存。
    • UUID 是无规律的,做为主键,会导致数据在磁盘中频繁移动(页分裂、页合并),影响数据库性能。

唯一 ID 生成器特点

  • 不重复
  • 空间占用小
  • 高并发、高可用:作为大多数服务的依赖方,唯一 ID 生成的操作要做到高并发,维持长期高可用。
  • 唯一 ID 可用作数据库主键:不对数据库的写操作造成负面影响,需要保证唯一 ID 对数据库主键友好。
    • 对于 InnoDB 引擎,使用自增性质的主键,唯一 ID 在数值上是递增的。
      • 不顺序插入,会有页分裂现象,增加时间开销。

单调递增和趋势递增


受限于全局时钟、延迟等分布式系统问题,单调递增的唯一 ID 生成器会有局限性,相对的,趋势递增的唯一 ID 生成器更受业界欢迎

单调递增的唯一 ID

Redis INCYBY 命令

incrby seq_id 1

生成唯一 ID 的请求到来时,唯一 ID 生成器对 seq_id 加 1,并将操作完之后的值返回。

批量获取优化

  • 唯一 ID 生成器服务可以每次从 Redis 中批量获取 ID 并存储到本地内存中。
  • 当业务服务请求到来时 , 直接从本地内存返回最小可用的 ID 。
  • 如果本地内存中没有可用的 ID, 则再次从 Redis 中批量获取。
package com.wispx.service;

import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class IdGeneratorService {
   
   

    // redis 客户端
    private StringRedisTemplate stringRedisTemplate;

    // 互斥锁
    private Lock lock = new ReentrantLock();

    // 下一个可用 ID,初始值为 -1
    private long nextIdAvailable = -1;

    // 最大可用 ID
    private long maxIdAvailable;

    /**
     * 从 Redis 中批量获取 ID
     * @param count 获取的数量
     * @return 返回 null 说明获取成功
     */
    private Exception multiGenIDFromRedis(int count){
   
   
        // 最后插入的 ID
        long lastInsertId;
        try{
   
   
            lastInsertId = (long)stringRedisTemplate.opsForValue().increment("seq_id",count);
        }<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值