Tengo una aplicación Java OSGi (Apache Felix) que se ejecuta en RHEL 7.4 que lee UDP multicast en ~ 975 paquetes / segundo (1038 octetos de longitud). A continuación traduce los datos en XML, simula que va a través de un dispositivo de límite, y lo traduce de nuevo en UDP paquetes de multidifusión. Hay varios subprocesos implicados y está escrito de manera que si el dispositivo simulado límite toma un tiempo para procesar una carga útil, que amortigua y envía una carga útil más grande sea la próxima vez a través.
Al mirar la latencia de los paquetes a través de este escenario de prueba de integración, dos máquinas diferentes grados de escritorio son significativamente más rápido que los servidores de gama bastante altas que esperamos implementar con.
- Servidor de latencia de 5 segundos. HW: Dual Xeon [email protected], 128G RAM, 16 físico, 21 núcleos lógicos, RAID 1 SAS SSD.
- Escritorio A <1 segundo. HW Xeon [email protected], 64G RAM, 4 físico, 8 núcleos lógicos, 500G SSD
- Escritorio B <1 segundo. HW [email protected], 16G RAM, 4 físico, 8 núcleos lógicos, duro de 1 TB 7200 RPM.
Sólo mencionar que el disco duro está completo ya que esta aplicación no escriba en el disco. Sobre el papel que el servidor debe realizar por lo menos tan rápido como los dos equipos de sobremesa.
Cosas que he Eliminado:
- tarjetas de red. He probado tanto con la NIC física y el dispositivo simulado por si acaso no hay diferencias significativas entre las NIC.
- Número de núcleos lógicos. He intentado desactivar 16 y 24 de los servidores de núcleos lógicos en un esfuerzo para descartar variables.
- Versión de Java. Los tres han sido tratado con OpenJDK y Java de Oracle con las versiones idénticas (Java
1.8.0
), produciendo los mismos resultados. - banderas de Java son idénticos y todos se relacionan con Felix (directorio de instalación, las propiedades de configuración, y el tarro para ejecutar).
- SELinux. Lo he intentado en los tres modos (discapacitados, hacer cumplir, permisiva). No esperaba una diferencia aquí, pero estoy agarrando para nada en este momento.
- Las versiones del kernel. He tratado de la prueba en contra
3.10.0
,4.13.0
y4.15.0
con resultados similares.
ark.intel.com comparación procesador
He aquí dos ejemplos de gráficos para ilustrar el tema. Esta prueba envía 260,960 paquetes UDP a través de 4 minutos 10 segundos para la dirección de multidifusión A, y después de haber sido procesado a través de la aplicación, los paquetes se envían a direcciones de multidifusión B. tcpdump
registros de las marcas de tiempo de ambos y sustracción produce la latencia. Las tres aplicaciones (remitente, la aplicación, tcpdump
están en la misma máquina).
En primer lugar el hardware del servidor con la interfaz ficticia
i7 hardware de escritorio en contra de la interfaz comodín
Tenga en cuenta el eje Y la diferencia de escala. Servidor es de 0-4 segundos, i7 de escritorio es 0-1 segundos. El eje X que aparece difícil de leer es el número de paquetes.
siguiente intento
I was running a local integration verison of the application. I then eliminated almost 100% of the work begin done by the application and saw growing latencies on the server hardware. I then tried -Xmx100G -Xms100G
essentially to keep the garbage collector from running EVER and saw the following results (< 1 second consistent latency).
Which led me to Java 8's Available Garbage Collectors.
Default Garbage Collector select on the server hardware was New: ParallelScavenge, Old: ParallelOld. Here's the resulting latency graph without the XML conversion, as simple a test as I could make it to duplicate the issue.
Explicitly selecting the Garbage First Garbage Collector -XX:+UseG1GC
selected New: G1New, Old: G1Old and it's resulting latency graph wasn't great:
Explicitly selecting the Concurrent Mark Sweep Garbage Collector -XX:+UseConcMarkSweepGC
selected New: ParNew, Old: ConcurrentMarkSweep and it's resulting latency graph looked excellent:
It appeared like the problem was solved. Once I added all the components back into place, I'm still getting unacceptable latencies. I'm still running tests to see if I can isolate the issue.
Strace Results
Trying strace -c -o /path/to/file -f
yielded the following top system calls
First the i7's desktop strace
report (truncated at the top 10 items)
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
93.71 1418.604132 959 1479659 134352 futex
1.74 26.294223 730395 36 poll
1.74 26.288786 314 83645 4 read
1.41 21.373672 73 293618 epoll_pwait
1.19 17.952475 120 149854 2 recvfrom
0.10 1.448453 2 909731 getrusage
0.06 0.896903 3 281407 sendto
0.03 0.394695 2 198041 write
0.01 0.182809 10 18246 mmap
0.01 0.120735 6 20582 sched_yield
Now for the server's strace
report:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
97.46 2119.311196 2642 802183 131276 futex
1.28 27.734136 6933534 4 poll
0.59 12.840448 49 263597 epoll_wait
0.41 8.885742 113 78387 2 recvfrom
0.07 1.575401 6 263671 sendto
0.07 1.515999 6 262256 epoll_ctl
0.04 0.902788 54 16800 sched_yield
0.03 0.743231 10 75455 write
0.02 0.490052 6 84509 7 read
0.01 0.170152 4 42732 lseek
I'm unclear what I should conclude from this. The desktop is many times faster in both the futex
and the poll
system call. I still don't understand why the application is so much more latent on the faster hardware.
Profiling
I've profiled the software on both pieces of hardware showing similar locations for hotspots which seems to rule that out.
I confirmed I was using the performance
CPU governor with RedHat: CPUfreq Coverners
I ran across a VMWare ESXi report of problematic BIOS settings Virtual Machine Application runs slower than expected on EXSi
Which pointed directly to my answer. The default on this Dell R630 was "Performance Per Watt (DAPC)" (DAPC: Dell Active Power Controller). Switching to "Performance" fixed this issue entirely. The machine felt much snappier at the console, and latencies were much lower than the desktop was able to achieve which was what I expected given the CPU differences.
Steps to change the BIOS on a Dell R630 (and likely others) on startup:
- F2 to enter System Setup
- Select "System BIOS"
- Select "System Profile Settings"
- Ensure first entry is set to "Performance" default is "Performance Per Watt"
- Select "Back"
- Select "Finish"
- Select "Yes" to save changes with system reset
- Select "OK" to the settings were saved successfully
Here's the resulting latency graph(s), they're using the same 1 second scale.
Default GC on the server(s):
Concurrent Mark Sweep GC on the server(s):
First Generation GC on the server(s):
Not much difference between the G1GC and the CMSGC, but both are clearly better latency than the default (which is expected).
Graphs of Logical Core Clock Speed
Los símbolos son difíciles de ver, pero hay 32 puntos diferentes en estos dos gráficos. En general se puede decir rápidamente cuál era el rendimiento, y cuál fue el desempeño por vatio-DAPC.
Rendimiento por vatio (DAPC):
Actuación
Junto trazado. El rendimiento en Balas Rojas, el rendimiento por vatio en los círculos azules abiertos
Este fue capturado durante 300 segundos de flujo de datos con el conjunto de BIOS en consecuencia. Así es como lo capturan los datos en caso de que alguien quiere saber:
for i in `seq 300`; do
paste /sys/devices/system/cpu/cpu[0-9]*/cpufreq/cpuinfo_cur_freq
sleep 1
done > performance.log