010 分布式、高并发统一ID生成方式分析、zookeeper与redis分布式锁不适合

对于ID的生成,在我们日常开发里应该是一个最基本的问题,我们先来说说最基础的ID的生成策略

简单生成策略:

        最简单的就是利用java.util.UUID工具类进行生成,ID没有排序策略,这种方式的问题就是比如我要查询一批数据,进行入库时间做数据排序的时候,只能够自己在表里设置一个create_time ,给这个字段添加索引然后进行排序。(比如雪花算法、数据库自增主键、sequence(oracle)等)

顺序ID生成方式

        使用带有生成顺序的ID生成策略,如下所示,KeyUtil里生成的ID是有时间先后顺序的,我们可以使用ID天然进行排序,这做法比较好的就是没必要浪费一个索引字段了。从数据库的角度来讲,一般能尽量减少索引,就减少索引。因为索引虽然可以提升查询性能,但也是需要占用空间的,并且一张表的最好索引不要超过3个,所以在做索引优化的时候,往往也是要根据业务进行考量。

业务ID生成方式

        使用带有业务含义的ID生成策略,这种方式也在传统应用系统、特定的场景下非常的好用。比如我们现在有一张商品货架表,这张表的数据维度是这样的,比如是按照城市和区域来划分的。

比如北京我们按照100000为基本维度数据,100010为北京的一个区域,100020则为另一个区域,以此类推,200000可能是另一个城市,200010 则为另一个城市的区域。那么我们在生成货架信息ID的时候,可以按照前六位为城市和区域的方式进行组织,后面可以拼接一个简单的32UUID字符串:

 

从前六位来看,这四条数据其中前三条数据属于一个城市下的数据信息,那么我们查询一个城市下的货架数据,查询语句可以为:

select * from goods_shelf gs

where id > '10001000000000000000000000000000000000'

•         and id <   '20000000000000000000000000000000000000'

注意:互联网行业一般情况下不会在数据库中建立外键,即join的关系,因为当数据量庞大的时候join操作极度消耗性能(具体业务具体分析,要看数据量大小而定);

 

如果想要查询1000(北京)这个城市下10区域的数据,则查询语句如下:

select * from goods_shelf gs

where id > '10001000000000000000000000000000000000'

         and id <   '10002000000000000000000000000000000000

我们的前8位都是具有业务含义的:前四位为城市维度编码,第五、六位为区域维度编码,最后两位为货架类型编码。

第一条数据ID为:1000100194aa6f136670496fa94c7945423abc25

第二条数据ID为:1000100266b1bc5399ad40408c4500420df079ab

第三条数据ID为:10002004d036aa16fedd475781063a3774b7d045

第四条数据ID为:20001008f8cd482778304f1a815a53c2bf821a51

那么我们如果想查询北京这个城市下面第一个区域的类型为01的货架集合,sql语句如下:

select * from goods_shelf gs

where id > '10001001000000000000000000000000000000000'

         and id <   '10001002000000000000000000000000000000000'

统一ID生成方式:(高并发情况)

        首先,对于高并发下如何进行ID的生成,就是建立一个统一的ID生成服务器,我们的服务去调用统一ID生成服务器去进行获取ID,这种方式,需要考虑两个最基本的问题,第一,是如何解决ID生成在并发下的重复生成问题第二,是如何承载高并发ID生成的性能瓶颈问题

        ID生成服务一定不是单点的,是分布式的,也就是有可能会生成相同的ID,并且主流的方式就是根据UUID + 时间戳等基本组合去生成的。并且高并发下也会有一些重复的问题,所以大家可能考虑分布式加锁的方式去处理此类问题.

 

1 最简单的就是利用zookeeper去进行分布式锁,但是zookeeper的写性能在QPS上千的并发下肯定是扛不住的,这也是第二个问题,如何承载该并发下的性能瓶颈。(zookeeper并不能解决并发问题,可以说zookeeper和高并发没有任何关系,zookeeper的所有场景都解决不了高并发任何问题,因为zookeeper存在性能瓶颈,其主要作用是保障统一配置服务)

注意:zookeeper的一个集群中三个结点性能效率是最高的,结点越多性能越低,所有现在比较流行将三个结点作为一个集群,然后做多个集群服务业务体系的实现,在多个集群中做数据同步。

2 所以我们又想到了Redis缓存,利用Redis的分布式锁去解决此类问题.首先第一点,Redis本身也会有性能问题,再超高的并发下可能会有延迟等一些细节问题,第二点我们的服务调用链过长,我们的服务调用可能失败,因为期间过程是调用统一ID生成服务,然后再去Redisset id,可能会出现重复情况,那么就需要进行重试,这期间可能会发生服务调用超时问题,导致我们的服务调用失败。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值