在java中产生uuid的方式是使用java.util.UUID。
UUID.randomUUID().toString();
我在测试redis性能时,使用uuid产生测试数据,发现多线程测试redis的rpush接口的时候,性能老是上不去。
查看cpu利用率也不高,网卡流量也不大。就是tps上不去。但是如果用两台client去测,又可以达到更高的tps。
后来直接用jstack查看了下堆栈,发现大多数线程停留在:
java.lang.Thread.State: BLOCKED (on object monitor) at java.security.SecureRandom.nextBytes(Unknown Source) - waiting to lock <0x00000005ffe1c548> (a java.security.SecureRandom) at java.util.UUID.randomUUID(Unknown Source) |
原来uuid的生成遇到了性能瓶颈。于是我单独测试了下生成随机uuid的性能,发现无论是1个线程还是32个线程还是300个线程,它的tps只能到10万级别。
甚至是线程数越大,tps越低。tps在每个机器上都不一样,有的机器上测试tps只有5万。我们就以一台双核4G内存的虚拟机为例:
tps在 140000+
我们看randomUUID方法的javadoc的描述是:
The UUID is generated using a cryptographically strong pseudo random number generator
也就是说uuid使用了一个强随机数,也也保证了uuid的不重复性。
public static UUID randomUUID() { SecureRandom ng=numberGenerator; if(ng == null) numberGenerator=ng=new SecureRandom(); byte[] randomBytes=new byte[16]; ng.nextBytes(randomBytes); return new UUID(randomBytes); } |
再看SecureRandom的javadoc
Note: Depending on the implementation, the generateSeed and nextBytes methods may block as entropy is being gathered, for example, if they need to read from /dev/random on various unix-like operating systems.
也就是说SecureRandom的nextBytes方法,依赖随机数的产生,如果随机数不够了,它有可能就会堵塞在那边。 比如随机数的产生是读取unix类系统的/dev/random文件。
我们再去看有关/dev/random的信息:
Linux中的随机数可以从两个特殊的文件中产生,一个是/dev/urandom.另外一个是/dev/random。他们产生随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。如果当前环境噪音变化的不是很剧烈或者当前环境噪音很小,比如刚开机的时候,而当前需要大量的随机比特,这时产生的随机数的随机效果就不是很好了。
这就是为什么会有/dev/urandom和/dev/random这两种不同的文件,后者在不能产生新的随机数时会阻塞程序,而前者不会(ublock),当然产生的随机数效果就不太好了,这对加密解密这样的应用来说就不是一种很好的选择。/dev/random会阻塞当前的程序,直到根据熵池产生新的随机字节之后才返回,所以使用/dev/random比使用/dev/urandom产生大量随机数的速度要慢。
jdk默认的是读取/dev/random文件产生强随机数,但是如果不是为了产生加密随机数,我们可以设置jdk读取/dev/urandom产生随机数,从而生成随机uuid。
在java启动项中增加-Djava.security.egd=file:/dev/./urandom 配置项(不能写作/dev/urandom,关于这个,网上有相关八卦历史~)
再去相同的机器上测试uuid的性能:
tps在 720000+
相关推荐
java UUID16的生成下载 UUID ,解压后生成的.java,可以在编译器中运行main方法
GUID是一个128位长的数字,一般用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复
JAVA UUID 生成.txt
<groupId>com.fasterxml.uuid</groupId> <artifactId>java-uuid-generator <packaging>bundle <name>Java UUID Generator <version>3.1.5</version>
Java Uuid生成器(JUG) JUG是一组用于处理UUID的Java类:使用任何标准方法生成UUID,有效输出,排序等。 它根据生成UUID(有关更多说明,另请参见) JUG由Tatu Saloranta( )最初于2002年编写,并且经过多年的...
java 生成8位UUID,解决UUID2太长的问题,欢迎下载。后续代码,陆续放出
java生成唯一索引,Long型,区别uuid
主要介绍了java获取UUID与UUID的校验,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
UUID生成工具类
jdk与javauuidgenerator生成uuid
fast-uuid:用于快速高效地解析和编写UUID的Java库
最近自己开发时需要一个16位纯数字的UUIDUtil,所以封装了一个纯数字16位的UUIDUtil,返回Long型UUid,希望可以帮到大家!
import java.util.UUID; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget....
uuid生成,可生成16个字符的唯一码。使用方法,见main函数
java生成16位随机数
短8位uuid 用于兑换码,不重复,,本人用很好用,,分享给大家
NULL 博文链接:https://bear999.iteye.com/blog/672569
LongId-智能简单的Java UUID生成器替换为自动递增的ID,尤其是在多服务器多数据中心环境中。 为响应Snowflake和Snowizard的复杂性而创建,它只是一个类。 好处: 当用作主键时,SQL插入将始终在表的底部ID始终大于...
java-uuid-generator-3.1.3.jar 部分开源源代码用到这里面的类。