UPD Prueba de la API REST en Golang. 120 000 [# / seg] no es el límite?

Noté una comparación no muy positiva de Java vs GO. Pruebas realizadas por una gran cantidad de usuarios .


Decidí comprobar si todo es tan color de rosa con Go.
Mirando hacia el futuro, diré que al almacenar en caché en la memoria y crear JSON sobre la marcha, logré obtener hasta 120,000 [# / seg] en 8 núcleos físicos.


Script de solicitud GET básico:


  • Si los datos se encuentran en la memoria caché en la memoria y son válidos, entonces formamos JSON a partir de la estructura
  • Si no hay datos en la memoria caché, los buscamos en Bolt DB, si los encontramos, leemos el JSON terminado
  • Si no hay datos en Bolt DB, los solicitamos de la base de datos, guárdelos en la memoria caché
  • Los datos en la memoria caché en memoria se acumulan en el canal del búfer, después de la acumulación de aproximadamente 10,000 elementos, se descartan como un solo guardado en Bolt DB
  • Si los datos en la base de datos han cambiado (actualización / inserción), se transmite una notificación a través de pg_notify y los datos en el caché se marcan como no válidos, la próxima vez que se lea, se leerá nuevamente desde la base de datos

Debajo de los resultados de la prueba de corte y el código del banco de pruebas GitHub


Actualización 05/06/2020


Hubo una oportunidad de probar en la nube de Oracle .
get_db_memory_json1


  • el soporte se ensambla en 3 servidores: 8 Core Intel (16 núcleos virtuales), 120 Memory (GB), Oracle Linux 7.7
  • NVMe — 6.4 TB NVMe SSD Storage min 250k IOPS (4k block)
  • — 8.2 Network Bandwidth (Gbps)
  • PostgreSQL — 16 000 [get/sec], oncurrency 1024, 60 [ms]. Get 360 000 000 . JSON 1800 .
  • — 100 000 — 120 000 [get/sec], oncurrency 1024, 2 [ms].
  • PostgreSQL — 10 000 [insert/sec].
  • 2 4 8 Core, .


  • JSON Bolt DB 2 HDD, SSD
  • PostgreSQL HDD SDD 100
  • Bolt DB SDD HDD 100
  • JSON " " 10 PostgreSQL SDD
  • — Failed requests Concurrency 16 384


,
GitHub. 4000 , .


, JSON encoder/decode — JSON 2 .


HTTP Get handler JSON


BenchmarkHandler_DeptGetHandler-2         1000000          41277 ns/op     4845.26 MB/s        10941 B/op          259 allocs/op

HTTP Get handler francoispqt/gojay


BenchmarkHandler_DeptGetHandler-2         1000000          13300 ns/op     15036.97 MB/s         3265 B/op           11 allocs/op

:


  • PostgreSQL 11 Windows 10, — 30 .
  • — 10 000 000 , 100 000 000 .
  • JSON 1500 , 1 10 .
  • — core i7-3770 — 4 core (8 thread), 16 , HDD (WD 2.0TB WD2000fyyz), SSD (Intel 530 Series).
  • ApacheBench, concurrency level 1 4096, 1 000 000 .
  • Windows, .
  • RAID . .

:



Concurrency Level , ApacheBench " ".


GET PostgreSQL — HDD ( )


Concurrency LevelRequests per secondTime per req.99% percentile
136.84 [#/sec] (mean)27.145 [ms] (mean)116 [ms]
238.27 [#/sec] (mean)52.262 [ms] (mean)165 [ms]
441.34 [#/sec] (mean)96.755 [ms] (mean)268 [ms]
845.02 [#/sec] (mean)177.687 [ms] (mean)420 [ms]
1647.56 [#/sec] (mean)336.428 [ms] (mean)813 [ms]
12849.19 [#/sec] (mean)2602.228 [ms] (mean)13055 [ms]
51250.5 [#/sec] (mean)10122.343 [ms] (mean)19394 [ms]
204851.91 [#/sec] (mean)39453.681 [ms] (mean)57018 [ms]

GET PostgreSQL — SSD ( )


Concurrency LevelRequests per secondTime per req.99% percentile
1713.82 [#/sec] (mean)1.401 [ms] (mean)2 [ms]
21914.61 [#/sec] (mean)1.045 [ms] (mean)2 [ms]
43326.52 [#/sec] (mean)1.202 [ms] (mean)2 [ms]
84599.95 [#/sec] (mean)1.739 [ms] (mean)4 [ms]
164599.80 [#/sec] (mean)3.478 [ms] (mean)9 [ms]
1285243.76 [#/sec] (mean)24.410 [ms] (mean)102 [ms]
5125354.35 [#/sec] (mean)95.623 [ms] (mean)506 [ms]
20485285.83 [#/sec] (mean)387.451 [ms] (mean)2871 [ms]

GET BOLT DB — HDD (JSON BOLT DB)


Concurrency LevelRequests per secondTime per req.99% percentile
181.55 [#/sec] (mean)12.262 [ms] (mean)38 [ms]
267.04 [#/sec] (mean)29.832 [ms] (mean)97 [ms]
472.51 [#/sec] (mean)55.167 [ms] (mean)183 [ms]
892.48 [#/sec] (mean)86.502 [ms] (mean)291 [ms]
1689.42 [#/sec] (mean)178.923 [ms] (mean)550 [ms]
12886.76 [#/sec] (mean)1475.378 [ms] (mean)11280 [ms]
51292.38 [#/sec] (mean)2771.145 [ms] (mean)10238 [ms]
2048100.56 [#/sec] (mean)20366.847 [ms] (mean)18632 [ms]
4096106.98 [#/sec] (mean)38289.063 [ms] (mean)37074[ms]

GET BOLT DB — SSD (JSON BOLT DB)


Concurrency LevelRequests per secondTime per req.99% percentile
13411.07 [#/sec] (mean)0.293 [ms] (mean)1 [ms]
27468.21 [#/sec] (mean)0.268 [ms] (mean)1 [ms]
49501.15 [#/sec] (mean)0.421 [ms] (mean)2 [ms]
810481.68 [#/sec] (mean)0.763 [ms] (mean)3 [ms]
1610052.14 [#/sec] (mean)1.592 [ms] (mean)5 [ms]
12810754.02 [#/sec] (mean)11.903 [ms] (mean)20 [ms]
51211030.61 [#/sec] (mean)46.416 [ms] (mean)66 [ms]
204810634.72 [#/sec] (mean)192.577 [ms] (mean)362 [ms]
409610659.04 [#/sec] (mean)384.275 [ms] (mean)720 [ms]

GET


Concurrency LevelRequests per secondTime per req.99% percentile
19178.22 [#/sec] (mean)0.109 [ms] (mean)1 [ms]
222580.40 [#/sec] (mean)0.089 [ms] (mean)1 [ms]
436163.33 [#/sec] (mean)0.111 [ms] (mean)1 [ms]
856109.17 [#/sec] (mean)0.143 [ms] (mean)1 [ms]
1643942.75 [#/sec] (mean)0.364 [ms] (mean)2 [ms]
12855005.53 [#/sec] (mean)2.327 [ms] (mean)6 [ms]
51235338.01 [#/sec] (mean)14.489 [ms] (mean)25 [ms]
204838090.35 [#/sec] (mean)53.767 [ms] (mean)228 [ms]
409630196.47 [#/sec] (mean)135.645 [ms] (mean)609 [ms]

Oracle



Oracle 3- :


  • VM.DenseIO2.8 — 8 Core Intel (16 virtual core), 120 Memory (GB), Oracle Linux 7.7
  • NVMe — 6.4 TB NVMe SSD Storage (1 drives) min 250k IOPS (4k block)
  • — 8.2 Network Bandwidth (Gbps)
  • — PostgreSQL 12. .
  • ApacheBench:
    • concurrency level 4 16384
    • 10 000 1 000 000 .
    • 2 8 ApacheBench ( ab 1 )

Banco de pruebas


GET


  • JSON — 1800 . Dept 10 Emp.
  • Dept — 33 000 000, Emp — 330 000 000 .

:


  • GET PostgreSQL
  • GET JSON BBolt ( 74 )
  • GET ( map)

.


Requests per second Concurrency.


get_db_memory_json1


Time per req. [ms] Concurrency ( ).


get_db_memory_json1


99% percentile [ms] Concurrency.


get_db_memory_json1


99% percentile [ms] Concurrency ( ).


get_db_memory_json1


backend 100 000 [#/sec] BBolt (oncurrency 128).
1600% , 1464%.
/ NVMe 0,02 [ms] (500 000 IOPS).


get_db_memory_json1



Benchmark, HTTP Get handler 13300 ns


BenchmarkHandler_DeptGetHandler-2         1000000          13300 ns/op     15036.97 MB/s         3265 B/op           11 allocs/op

ApacheBench, mean — 0.088 ms.
0.088 — 0.013 = 0.055 ms.


:


  • net/http.(*conn).serve — (61.85%)
  • net/http.(*connReader).backgroundRead — (7.04%)
  • runtime.gcBgMarkWorker — (18.30%)

HTTP server (61.85%):


  • — net/http.(*conn).readRequest — (9.29%). .
  • — net/http.(*response).finishRequest — (21.74%). .
  • — net/http.(*ServeMux).ServeHTTP — (23.33%).

img


readRequest, finishRequest backgroundRead (39.66%), IO Windows — internalpoll.(ioSrv).ExecIO — (24.78%).


Veamos qué hizo nuestro controlador principal net / http. (* ServeMux) .ServeHTTP:


  • Análisis de URL y procesamiento de parámetros - github.com/gorilla/mux.(*Route).Match - (2.29%)
  • Generando JSON desde una estructura en memoria - github.com/francoispqt/gojay.marshal - (9.92%)
  • Trabajando con el caché en memoria - (4.53%)

img


All Articles