Si usas Magento, ya sabes que OpenSearch (o Elasticsearch, su primo de zumosol que no se aclara si quiere ser Open Source o una ONG) no es opcional. Sin él, tu buscador es un desierto y tus categorías, un error 404 constante. Es el corazón de la tienda, y como todo corazón en este mundillo, a veces decide darnos infartos. 💔
Gestionar OpenSearch es como cuidar a un Gremlin: parece majo hasta que le das de comer un reindexado completo después de medianoche. De repente, la memoria Heap sube, el Circuit Breaker salta y tu tienda se queda más colgada que un cuadro de Dalí. 🎨😵
Hoy te cuento cómo pasé de tener una tienda «zombie» —sin productos en las categorías y con el buscador devolviendo un vacío existencial— a domar a la bestia. 🧟♂️✨
💀 El Escenario del Crimen (Los Efectos)
Te despiertas, abres el correo con el café aún sin hacer y tienes más alertas que un portaaviones en plena batalla naval. Empiezas a investigar y esto es lo que te encuentras:
Tienda en modo pánico: El buscador no da ni las «gracias» y los productos de las categorías han desaparecido como por arte de magia. Si no hay OpenSearch, no hay catálogo. Fin de la cita. 📉
Logs sangrando: Abres el exception.log y está petao del Error 429 (Too Many Requests) de OpenSearch o de errores index_not_found_exception. Es la forma fina que tiene el motor de decirte: «Estoy agobiado, déjame en paz.». 🤬
CRONs en coma: Te vas a la tabla cron_schedule y ves que las tareas indexer_update_all_views aparecen como Missed. Magento ha intentado lanzarlas, OpenSearch le ha cerrado la puerta en las narices y el CRON se ha ido a dormir la siesta. 😴
Reinicios inútiles: Reinicias el servicio de OpenSearch, te sientes el puto amo de los sistemas durante unos minutos, y al rato… ¡pum! vuelve a petar. Es el día de la marmota, pero con más mala leche. 🔄🧨
🕵️♂️ La Investigación (Bajando a los infiernos)
Aquí es donde empecé a sudar. ¿Por qué demonios se llena la memoria si «en teoría» el servidor tiene RAM para aburrir? Tirando del hilo, salieron estas tres joyas:
1. La trampa del Blue-Green 🔵🟢
Magento usa una mecánica de reindexado Blue-Green. Para no dejar la tienda vacía mientras reindexa, crea un índice nuevo, mete los datos y, cuando acaba, hace un «swap» (cambia uno por otro) y borra el viejo. El problema: En el momento del swap, tienes los dos índices vivos ocupando sitio. Si tu índice ocupa 2GB, necesitas 4GB de Heap solo para ese microsegundo. Si vas justo, pues eso…
2. El «Asesino» silencioso: La Caché y las sincronizaciones 🕵️♀️
Resulta que también hay caché de búsquedas que va creciendo. Si entras en una categoría, OpenSearch se guarda el resultado «por si acaso». Cuando el uso de memoria llega al 80-85%, pasa el Garbage Collector y limpia lo que puede. Pero para limpiar RAM, ¡sorpresa!, también hace falta RAM, y tiempo. 🤯
Si tienes scripts sincronizando stock, precios o calentadores de caché a lo loco, no dejas que el «barrendero» de Java pase la escoba. La memoria sube y sube hasta que ya no hay retorno. 📈🏚️
3. El Circuit Breaker (El botón del pánico) 🚨
Cuando OpenSearch ve que va a explotar, activa el Circuit Breaker. Bloquea cualquier petición nueva. En el servidor te dirá que está running, pero en realidad se está echando una siesta para no morir. Y no despertará mientras sigas agobiándole con peticiones. 💤
Puedes vigilar al enfermo con este comando (póntelo en una pantalla aparte y disfruta del drama):
watch -n60 "curl -s -X GET 'localhost:9200/_nodes/stats/jvm?pretty' | grep 'heap_used_percent'"
(Ver como el porcentaje se acerca al 90% da más miedo que un commit del becario a producción un viernes a las 18:00). 😱
💡 La Solución: Domando a la Bestia
La solución no es siempre tirar billetes al problema y meter más RAM… veamos…
Regla de oro: Update by Schedule ⏳
Si tienes los índices en Update on Save, estás jugando a la ruleta rusa. Ponlos en Update by Schedule. Deja que el CRON trabaje por lotes. Y olvídate de los reindex completos nocturnos, solo ensucian y de verdad, casi nunca son necesarios si lo demás está bien. En cualquier caso, si por algún motivo de magia negra que solo tu conoces lo necesitas, no reindexes, solo invalida y ya se ocupará el cron.
Calculando el Heap 🧪
No pongas un valor al azar. La regla es: al menos tienes que poder hacer dos reindexados completos seguidos sin que OpenSearch explote. Si al hacerlo peta, no le des más vueltas, te falta memoria. Sube, reinicia y vuelve a empezar.
Te parecerá excesivo, pero la caché come más que un adolescente en crecimiento. Si puedes, duplica ese valor obtenido. 💰
¿Dónde se cambia? En el archivo jvm.options (normalmente en /etc/opensearch/jvm.options):
# /etc/opensearch/jvm.options
# Xms y Xmx IGUALES para que Java no pierda el tiempo redimensionando.
-Xms4g
-Xmx4g
(Ojo: no le des más del 50% de la RAM física del servidor, que el SO también necesita respirar, pobre).
Ajustando el env.php 🧙♂️
Configura los batch_size en tu app/etc/env.php. Empieza con valores bajos (tipo 50) y ve subiendo hasta que los tiempos de reindex sean óptimos. Al subir los batches, los tiempos bajarán. Si subes mucho y los tiempos empeoran, baja un poco. Ese es tu «sweet spot». 🍬
'indexer' => [
'batch_size' => [
'cataloginventory_stock' => ['simple' => 50],
'catalog_category_product' => 50,
'catalogsearch_fulltext' => [
'partial_reindex' => 50,
'mysql_get' => 50,
'elastic_save' => 50
],
'catalog_product_price' => [
'simple' => 50,
'default' => 50,
'configurable' => 50
],
'inventory' => [
'simple' => 50,
'default' => 50,
'configurable' => 50
]
]
]
🤘 Conclusión para cuando OpenSearch explote (que lo hará)
No dimensiones el servidor para cuando la tienda está en calma. Hazlo pensando en el caos. 🌪️
Haz pruebas de fuego: reindex completo mientras corren tus importadores de stock. Si explota, o das más margen al Heap o haces que tus importadores sean menos agresivos (mete un tiempo de 0.5s entre productos, que no corre prisa). 🐢
Si no dejas tiempos muertos para que el Garbage Collector haga su magia, OpenSearch se vengará. Y créeme, tiene mucha memoria. 🤖💀
¡Suerte, y que el Garbage Collector te acompañe! 🤘🔥

Hey! Qué opinas sobre el artículo?