一篇文教你在 Java 中利用 redis 实现分布式全局唯一标识服务

本文介绍了如何在分布式系统中利用 Redis 的 INCR 命令生成全局唯一标识,解决数据库自增字段在分库分表场景下的问题。通过 Java 实现了一个服务,满足全局唯一、高性能、顺序性以及可附加业务属性的需求,适用于订单、会员等不同实体类型的标识生成,并提供了测试用例验证其功能。
摘要由CSDN通过智能技术生成

获取全局唯一标识的方法介绍

在一个IT系统中,获取一个对象的唯一标识符是一个普遍的需求。在以前的单体应用中,如果数据库是一个单数据库的结构。通常可以利用数据库的自增字段来获取这个唯一标识。

例如,在 Mysql 数据库中,我们可以通过 sql 语句创建一个自增长的 int 字段类型的表。如下所示

CREATE TABLE student
(
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(16),
    PRIMARY KEY (id)
)

然后插入两条数据

INSERT INTO student(name) VALUE('yanggch');
INSERT INTO student(name) VALUE('grace');

通过 SQL 语句查看表数据

 SELECT * FROM student;

得到如下的结果

可以看到,虽然我们在通过 SQL 插入数据的时候没有指定 id 字段的值,但是因为该字段的 AUTO_INCREMENT 自增长的特性,自动的给两条记录添加了1和2两个值。

这个方法有两个主要问题。一个是如果是一个分库分表的数据库结构,那么在分布在不同实例中的同一个表中的id是重复的。另一个问题是记录插入到数据库里后,我们在代码中并不能知道刚刚插入数据库的记录的主键的值到底是什么。如果我们的一个业务是要同时插入一条主表记录一节一系列以这条主表记录主键为外键的子表记录,我们在插入子表记录的时候,不知道对应的外键的值是多少。导致无法插入。例如如果我们有一个下单业务,要求在订单表中插入一条订单记录,同时在订单明细中插入多条在这个订单中购买的商品的详细信息的记录。订单数据插入成功后,我们不知道订单的主键的值,所以我们也就无法正确的插入商品详细信息记录了。

另外一个利用数据库自增字段属性获取唯一标识方式是在数据库中建立一个带一个自增字段的数据表。每次在表中插入一条记录,然后将这条记录的值取出来作为主键值。这个的问题是每次要另外在数据表中插入一条记录,同时在多用户使用的环境下,要严格保证你取到的记录就是你插入的记录。否则会导致主键重复。着会让获取唯一标识符的速度变得比较慢。同时,这个方式在分库分表的结构下,也不能让唯一标识在全局唯一。

还有一些其他的方式。例如用 uuid 算法可以保证全局唯一,也能保证高性能。但是他生成是一个字符串,不能保证顺序性,同时也太长了。

所以在分布式架构中,我们就需要一个满足如下条件的唯一标识符服务

  • 全局唯一

  • 高性能

  • 具备顺序性

  • 可以附加其他业务属性

这里我们可以用 redis 的 INCR 命令来作为生成全局的唯一标识符。INCR 命令的语法是

INCR key

根据 redis 的官网的 INCR 命令介绍,它是一个原子操作,效果是是将 redis 数据库中 key 的值加一并且返回这个结果。如果 key

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值