java uuid

The way to generate uuid in java is to use java.util.UUID.

UUID.randomUUID().toString();

When I tested the performance of redis, I used uuid to generate test data, and found that when I tested the rpush interface of redis with multi-threading, the performance always failed.
Check that the CPU utilization is not high, and the network card traffic is not large. Just can't get on tps. But if you use two clients to test, you can achieve a higher tps.

Later, I checked the lower stack directly with jstack and found that most threads stayed at:

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)

It turned out that the generation of uuid encountered a performance bottleneck. So I tested the performance of generating random uuid separately, and found that whether it is 1 thread, 32 threads or 300 threads, its tps can only reach 100,000.
Even the larger the number of threads, the lower the tps. The tps is different on each machine, and the test tps on some machines is only 50,000. Let's take a virtual machine with dual-core 4G memory as an example:

tps at 140000+

Let's look at the javadoc description of the randomUUID method:
The UUID is generated using a cryptographically strong pseudo random number generator
, which means that uuid uses a strong random number, which also ensures the non-repetitiveness of 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.

That is to say, the nextBytes method of SecureRandom relies on the generation of random numbers. If the random numbers are not enough, it may be blocked there. For example, the generation of random numbers is to read the /dev/random file of the Unix-like system.

Let's look at the information about /dev/random again:

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+

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326326106&siteId=291194637