Retomando InceptionDB y sus optimizaciones
Estoy volviendo a retomar InceptionDB después de dos meses enfocando el rato libre que me queda en sacar adelante flowtest.io (quiero pensar que será el servicio que va a revolucionar la forma de testear APIs).
A pesar del tiempo que ha pasado, recuerdo con total claridad que estaba trabajando en optimizar el rendimiento, tenía la meta psicológica de superar el millón de inserts por segundo (en un sólo nodo). El millón no fue difícil de superar, pero con la IA estaba empeñado en pasar el millón holgadamente. En realidad estaba empeñado en llevarlo un poco más allá del absurdo y de lo necesario explorando varias alternativas y atacando las distintas capas de abstracción de Inception.
He vuelto a repetir los últimos tests y el resultado es tan salvaje que parece que algo está mal. Selecciono el primer benchmark: INSERT, lo ejecuto y casi al mismo tiempo termina. Tiene que estar mal! El log es claro ha insertado 1 millón en menos de 200ms pero yo no me lo creo, pienso que habré dejado la persistencia desactivada y estará trabajando sólo en memoria, o que no hay control de concurrencia y se están solapando los datos, o que ha contado los datos enviados pero el server los ha tirado a /dev/null.
sent: 1000000
took: 182.928406ms
Throughput: 5466619.55 rows/sec
Closing 'col-1779494946505865611'...
http: Server closed
Desconfío, puedo pensar mil motivos más pero pongo un break point justo antes de eliminar la base de datos y vuelvo a ejecutar. Casi idéntico resultado a pesar de estar depurando pero ahora tengo esto: /tmp/inceptiondb_bench_811457574/col-1779494946505865611 y no está vacío pero solamente ocupa 41MiB. Sin pensar mucho, lo muevo al directorio de datos de mi Inception local, lo arranco, cargo la página y ahí está, 1M. Y parece que los datos están correctos incluso.
Todavía no me lo creo, creo un índice, lanzo query con orden ascendente y encuentro el primer documento, el 0. Cambio el orden y también está el último documento, el 999999. Parece que está todo en orden. Dejo de prestarle atención a la pantalla para comprobar que sigo respirando.
Se me ocurre escribir un artículo del blog pero antes repito la prueba. Esta vez con 10 millones.
sent: 10000000
took: 1.078983549s
Throughput: 9267981.90 rows/sec
Closing 'col-1779498339775263815'...
http: Server closed
Casi 10 millones por segundo, que estimo serán 410 MiB. Claramente está todavía muy lejos de alcanzar el cuello de botella de disco que llega en pruebas reales a 9.4 GiB/s, no llega ni al 5%.
El benchmark tiene varios tests para medir el rendimiento de escenarios específicos: INSERT, PATCH, REMOVE pero hay otros que no recordaba: INSERTPK, INSERTBTREE, RETRIEVEBTREE, RETRIEVEFS.
Voy a ejecutar todos y dejo constancia del rendimiento de cada uno.
INSERT
Throughput: 8785855.31 rows/sec
Throughput Open: 8780487.73 rows/sec
INSERTPK
Throughput: 5890949.19 rows/sec
Throughput Open: 2374067.17 rows/sec
INSERTBTREE
Throughput: 1766108.26 rows/sec
Throughput Open: 3165092.19 rows/sec
RETRIEVEBTREE
Throughput: 5412335.80 docs/sec
RETRIEVEFS
Throughput insert: 9249222.80 rows/sec
Throughput Full scan (no filter): 13145243.10 docs/sec
Throughput Full scan with filter: 4265889.26 docs/sec
PATCH
Throughput: 2735628.98 rows/sec
Throughput Open: 9973488.60 rows/sec
REMOVE
Throughput: 1622765.40 rows/sec
Throughput Open: 14321483.85 rows/sec
En general se supera el millón por segundo en todas las operaciones. Por cierto, déjame recordarte que el Throughput Open es la misma operación pero al arrancar la base de datos. Esto es relevante porque Inception se basa únicamente en journal para persistir datos, por lo tanto para volver a recuperar el estado tiene que leer todo el journal antes de estar operativo de nuevo.