• Julio Argüello @jarguello.seidor.es ·

    Campaña Viernes 11/06/2021

    El pasado viernes 11-06-21 sobre de 12 a 13 (Perú) se lanzó una campaña que supuestamente sobrecargo todo el sistema (unos 2000 usuarios concurrentes)

    Overview

    image

    Aislando el pico

    image

    Thread Pool

    image

    Garbage Collector

    image

    Slowest

    image

    Most time consuming

    image

    Bloqueos en carts

    image

    Product2Activity Selects

    image image

    SELECT item_t1.PK FROM product2activity item_t0 JOIN activities item_t1 ON item_t0.TargetPK = item_t1.PK WHERE ( item_t0.Qualifier = 'Product2Activity' AND item_t0.SourcePK = 8825590874113 AND item_t0.languagepk IS NULL) AND (item_t1.TypePkString=8796134113362 ) order by item_t0.PK ASC

    Carts Update Query

    image

    Invocada desde PDP?!

    image

    image

    UPDATE carts SET hjmpTS = 1 ,modifiedTS='2021-06-11 12:13:44.236',p_giftpapercardtotalprice=0.00000,p_guid='097894e1-dcf9-48fc-94cf-2f9bf7a934c0',p_installmentsnumber=1,p_sessionid='AB02BF43942D516E7C23C8AAA0EB24AF',p_site=8796093056040,p_store=8796093056989 WHERE PK = 9103989604395

    Database Throughput

    image

    Entre las 12:12 y las 12:17 sin mediar un incremento notable de queries el tiempo de respuesta se vio muy seriamente perjudicado

    image

    Edited by Julio Argüello
  • Julio Argüello @jarguello.seidor.es ·

    Tests 15/06/2021

    El pasado días 15-06-21 sobre de 00:20 a 02:20 (Perú) se lanzaron pruebas de carga

    Overview

    image

    Errores home

    image

    Thread Pool

    image

    Garbage Collector

    image

    Slowest

    image

    Most time consuming

    image

    PDP con muchas variantes

    image

    Product2Activity Selects

    image image

    SELECT item_t1.PK FROM product2activity item_t0 JOIN activities item_t1 ON item_t0.TargetPK = item_t1.PK WHERE ( item_t0.Qualifier = 'Product2Activity' AND item_t0.SourcePK = 8811227381761 AND item_t0.languagepk IS NULL) AND (item_t1.TypePkString=8796134113362 ) order by item_t0.PK ASC

    Carts Update Query

    image

    Invocada desde PDP?!

    image

    image

    UPDATE carts SET hjmpTS = 1 ,modifiedTS='2021-06-15 02:13:55.828',p_giftpapercardtotalprice=0.00000,p_guid='a772d3e1-7e41-480c-a752-d11fd03400d4',p_installmentsnumber=1,p_sessionid='25A676DCC7B968D1FD98026FEC6512E8',p_site=8796093056040,p_store=8796093056989 WHERE PK = 9111070670891

    Database Throughput

    image

    Edited by Julio Argüello
  • Julio Argüello @jarguello.seidor.es ·

    Network

    Antes de la prueba

    "Cantidad_de_usuarios_conectados_185)"

    image

    Primera prueba

    "Se_verifica_que_el_enlace_de_internet_comienza_a_saturarse"

    image

    Tercera prueba

    "Se_verifica_que_el_enlace_de_internet_comienza_a_saturarse"

    image

    New Relic Infrastructure Monitoring

    "Balance de las tres pruebas según NewRelic"

    Día 15

    Outbound traffic

    • Tope sostenido en torno a una media de 900 KB/sec por interface de red.
    • Lo que hace 9 MB/sec para los 10 interfaces de red
    • En torno a 72 mbps (que coincide aprox. con lo visto en la otra herramienta)

    image

    Día 11

    Outbound traffic

    • Tope sostenido superior al de las pruebas de carga.

    image

    • En ese mismo periodo el throughput del sistema es en torno a 2000 requests per minute = 33 PVS
    • Lo cual equivale a 9MB/sec = 540MB/minute --> aprox. 250 KB por petición.

    image

    Cloudflare

    • Cloudflare también refleja el pico de tráfico del día 11.

    image image

    • Aunque Cloudflare amortigua notablemente el impacto

    image image

    image

    image

    Se observa que marathon mueve menos tráfico que los ejemplos contrapuestos.

    Edited by Julio Argüello
  • Julio Argüello @jarguello.seidor.es ·

    ACCIÓN 1

    • ACCIÓN 1: (Sobre Carrusel de Productos) La recomendación no es otra que cachearlo y para ello emplear la CMS cache

    La caché está siendo efectiva:

    image

    Groovy snippet
    import groovy.json.JsonBuilder
    
    cacheManager = net.sf.ehcache.CacheManager.getInstance()
    
    
    for (name in cacheManager.getCacheNames()) {
      cache = cacheManager.getCache(name)
      s     = cache.getStatistics()  
    
      try {
      out.println String.format("Cache %s: size = (%d/%d) hit/miss = %d/%d (%f)(%f)", 
                                name, 
                                cache.getSize(),
                                cache.getCacheConfiguration().getMaxEntriesLocalHeap(),
                                s.cacheHitCount(), 
                                s.cacheMissCount(), 
                                s.cacheHitRatio(),
                                s.cacheHitCount() / (s.cacheHitCount() + s.cacheMissCount())
                               )
      //  out.println new JsonBuilder(cache).toPrettyString()
      //  out.println new JsonBuilder(  s  ).toPrettyString()
      } catch (Exception e) {
      }
    }

    ACCIÓN 2

    • ACCIÓN 2: (Sobre Carrusel de Productos) La recomendación es extender el tiempo de vida de esta cache a al menos 1 hora.

    ACCIÓN 3

    • ACCIÓN 3: Cachear los métodos de de.hybris.platform.commerceservices.price.impl.DefaultCommercePriceService

    • La caché NO está siendo efectiva.

    • El HIT ratio es muy bajo.

      • La política de invalidación es correcta.
      • Pero el TTL es muy corto (apenas 2h)
      • Y el tamaño también (apenas 10.000 entradas) Hay algún producto (ver trazas más arriba que ya por si mismo consumiría 1.000 de ellas)

    Recomendación

    • Con una política de invalidación tan minuciosa podemos usar cachés eternas

    image

    • Incrementar el tamaño de cada región a 300.000 registros en uno de los nodos y monitorizarlo.
    • Se puede hacer en caliente
      • Aplicado en https://172.30.10.155:9002/ 17/06/2021 07:17 AM
    Resize cache region
    resize "webPriceForProductCache"
    resize "fromPriceForProductCache"
    resize "allPromotionsDataCache"
    
    void resize (name) {
       cacheManager = net.sf.ehcache.CacheManager.CACHE_MANAGERS_MAP.get("methodCache")
       cache        = cacheManager.getCache(name)
       config       = cache.getCacheConfiguration(); 
       config.setTimeToLiveSeconds(0)
       config.setMaxEntriesLocalHeap(300000)
    }
    Groovy monitorization snippet
    import groovy.json.JsonBuilder
    
    cacheManager = net.sf.ehcache.CacheManager.CACHE_MANAGERS_MAP.get("methodCache")
    
    
    for (name in cacheManager.getCacheNames()) {
      cache = cacheManager.getCache(name)
      s     = cache.getStatistics()  
    
      out.println String.format("Cache %s: size = (%d/%d) hit/miss = %d/%d (%f)(%f)", 
                                name, 
                                cache.getSize(),
                                cache.getCacheConfiguration().getMaxEntriesLocalHeap(),
                                s.cacheHitCount(), 
                                s.cacheMissCount(), 
                                s.cacheHitRatio(),
                                s.cacheHitCount() / (s.cacheHitCount() + s.cacheMissCount())
                               )
      //  out.println new JsonBuilder(cache).toPrettyString()
      //  out.println new JsonBuilder(  s  ).toPrettyString()
    }
    Cache webPriceForProductCache: size = (10000/10000) hit/miss = 183566/185808 (NaN)(0.496965)
    Cache fromPriceForProductCache: size = (9315/10000) hit/miss = 206547/20567 (NaN)(0.909442)

    image

    ACCIÓN 4

    • ACCIÓN 4: Cachear el método pe.com.marathon.facades.product.impl.DefaultMrtPromotedProductFacade.getPromotionByVariants

    • La caché NO está siendo efectiva.

    • El HIT ratio es muy bajo.

      • La política de invalidación es correcta.
      • Pero el TTL es muy corto (apenas 2h)
      • Y el tamaño también (apenas 5.000 entradas)

    Recomendación

    • Incrementar el tamaño de esta cache a 300.000 registros en uno de los nodos y monitorizarlo.
    • Se puede hacer en caliente
    Cache allPromotionsDataCache: size = (5000/5000) hit/miss = 62930/120032 (NaN)(0.343951)

    ACCIÓN 5

    • ACCIÓN 5: (Sobre el grid de productos) ... De confirmarse el mal comportamiento se recomiendan otras técnicas diferentes, como por ejemplo el boosting por un campo del producto.

    • En primera instancia Ver acción 7 en lo que concierne a SolrBoostRule

    SELECT count(distinct p_propertyvalue) FROM solrboostrule
    # 10365

    ACCIÓN 6

    • ACCIÓN 6: Un DBA especializado en Hana DB ha de revisar el comportamiento del motor de base de datos

    Sobremanera comprobar qué sucede en esos picos durante los cuales la bbdd apenas responde:

    image

    image

    ACCIÓN 7

    • ACCIÓN 7: Revisar el dimensionamiento y áreas de la entity cache region.

    Recomendación

    image

    Crear regiones específicas para:

    • Media

      • Select count({pk}) / 2 from {Media} --> 2.4M
      • New Size: 200k (10%)
    • PriceRow

      • Select count({pk}) / 2 from {PriceRow} --> 200 K
      • New Size: 200k (100%)
    • Product

      • Select count({pk}) / 2 from {Product} --> 442 K
      • New Size: 200k (50%)
    • StockLevel

      • Select count({pk}) from {Stocklevel} --> 222 K
      • New Size: 100k (50%)
    • MediaContainer

      • Select count({pk}) / 2 from {MediaContainer} --> 120 K
      • New Size: 12k (10%)
    • AbstractRuleEngineRule

      • Select count({pk}) from {AbstractRuleEngineRule} --> 12 K
      • New Size: 6k (50%)
    • SolrBoostRule

      • Select count({pk}) from {SolrBoostRule} --> 14 K
      • New Size: 14k (100%)
    • Category

      • Select count({pk}) / 2 from {Category} --> 86 K
      • New Size: 80k (90%)
    • Default region

      • New Size: 200k

    Pasando de 500k a 1M registros

    ACCIÓN 8

    • ACCIÓN 8: Incrementar el tamaño de la query cache region.

    Pasarla de 20k a 200k registros

    Se puede cambiar en caliente adaptando el script de la acción 3

    ACCIÓN 9

    • ACCIÓN 9: Actualizar el driver JDBC a la versión 2.8.14 (última versión a fecha 16/06/2021)

    • El cambio se ha realizado correctamente aunque no se observa una diferencia palpable con respecto a la situación anterior.

    • Básicamente la conclusión es que cuando la bbdd responde tan mal no es algo achacable a la versión del driver JDBC. Esto no quiere decir que el cambio no haya sido para mejor, pero sí quiere decir que el margen de mejora con el nuevo driver jdbc no es comparable a lo que la acción 6 pudiera derivar.

    com.sap.db.jdbc.Driver.getVersionInfo()
    # package com.sap.db.jdbc, Java Platform API Specification, version 1.8, SAP HANA JDBC Driver, SAP SE, 2.8.12-e7a5696ad0e49322bd06d8729177ddd1b9cb4791
    
    Edited by Julio Argüello
  • Julio Argüello @jarguello.seidor.es ·

    ACCIÓN 10

    • ACCIÓN 10: Queries con flexible search restrictions

    • Y query sobre rules (ver más arriba en los reportes del día 11 y durante las pruebas)

    ACCIÓN 11

    • ACCIÓN 11: Evitar que un simple HIT en la PDP cree carros

    ACCIÓN 12

    • ACCIÓN 12: Cambiar la configuración del balanceador para que el health check no haga 2 hits por segundo a home page.

    ACCIÓN 13

    • ACCIÓN 13: Saturación interfaces de red

    ACCIÓN 14

    • ACCIÓN 14: Analizar comportamiento inyector de carga (JMeter)

    Acusa unos tiempos de respuesta exageradamente altos frente a lo que se observa en NewRelic

    • Hipotésis: tiempo de descarga / staturación de red / saturación de recursos en inyector

    (17/06/2021 15:26 Madrid) Pendiente,***: no he evaluado thread dumps durante las pruebas del día 15...

    Edited by Julio Argüello
  • Julio Argüello @jarguello.seidor.es ·

    Incorporar al informe la reducción de RAM

  • Julio Argüello @jarguello.seidor.es ·

    Slow Queries

    DefaultPromotionSourceRuleDao.findPromotions(DefaultPromotionSourceRuleDao.java:295)

    Query OOTB

    SELECT x.pr
    FROM   (
                  SELECT item_t1.p_promotion AS pr
                  FROM   rules item_t0,
                         prodforpromosourcerule item_t1
                  WHERE  (
                                item_t1.p_rule = item_t0.pk
                         AND    item_t0.p_status =8796109733979
                         AND    item_t0.p_excludefromstorefrontdisplay !=1
                         AND    item_t0.p_website IN (8796093092761)
                         AND    item_t1.p_productcode = 'bt_BL_10711083'
                         AND    (
                                       item_t0.p_startdate <= '2021-06-14 12:14:00.0'
                                OR     item_t0.p_startdate IS NULL)
                         AND    (
                                       item_t0.p_enddate >= '2021-06-14 12:14:00.0'
                                OR     item_t0.p_enddate IS NULL)
                         AND    item_t0.p_status IN (8796109733979)
                         AND    item_t1.p_promotion IS NOT NULL)
                  AND    ((
                                       item_t0.typepkstring=8796130639954
                                AND    item_t1.typepkstring=8796133163090 ))
                  UNION
                  SELECT item_t3.p_promotion AS pr
                  FROM   rules item_t2,
                         catforpromosourcerule item_t3
                  WHERE  (
                                item_t3.p_rule = item_t2.pk
                         AND    item_t2.p_status =8796109733979
                         AND    item_t2.p_excludefromstorefrontdisplay !=1
                         AND    item_t2.p_website      IN (8796093092761)
                         AND    item_t3.p_categorycode IN ('44',
                                                           'E',
                                                           'M068',
                                                           'DEPH',
                                                           'H',
                                                           'HROP',
                                                           'HROPLTS',
                                                           'DEP',
                                                           'E003',
                                                           'marathonProducts',
                                                           'DEPHCFU',
                                                           'RFUT11CMC',
                                                           'MAR')
                         AND    (
                                       item_t2.p_startdate <= '2021-06-14 12:14:00.0'
                                OR     item_t2.p_startdate IS NULL)
                         AND    (
                                       item_t2.p_enddate >= '2021-06-14 12:14:00.0'
                                OR     item_t2.p_enddate IS NULL)
                         AND    NOT EXISTS
                                (
                                       SELECT 1
                                       FROM   excludedproductforrule item_t4
                                       WHERE  (
                                                     item_t4.p_rule = item_t3.p_rule
                                              AND    item_t4.p_productcode = 'bt_BL_10711083')
                                       AND    (
                                                     item_t4.typepkstring=8796133261394 ))
                         AND    NOT EXISTS
                                (
                                       SELECT 1
                                       FROM   excludedcatforrule item_t5
                                       WHERE  (
                                                     item_t5.p_rule = item_t3.p_rule
                                              AND    item_t5.p_categorycode IN ('44',
                                                                                'E',
                                                                                'M068',
                                                                                'DEPH',
                                                                                'H',
                                                                                'HROP',
                                                                                'HROPLTS',
                                                                                'DEP',
                                                                                'E003',
                                                                                'marathonProducts',
                                                                                'DEPHCFU',
                                                                                'RFUT11CMC',
                                                                                'MAR'))
                                       AND    (
                                                     item_t5.typepkstring=8796133228626 )))
                  AND    ((
                                       item_t2.typepkstring=8796130639954
                                AND    item_t3.typepkstring=8796133195858 ))
                  UNION
                  SELECT promotion AS pr
                  FROM   (
                                SELECT item_t7.p_rule                  AS r1,
                                       item_t7.p_promotion             AS promotion,
                                       item_t7.p_conditionid           AS c1,
                                       Count( item_t7.p_categorycode ) AS count_cat1
                                FROM   rules item_t6,
                                       combine..(1,931 more chars)

    MrtCatalogAwareEurope1PriceFactory.queryPriceRows4Price(MrtCatalogAwareEurope1PriceFactory.java:89)

    OOTB / Custom ??

    SELECT x.pk
    FROM   (SELECT item_t0.pk
            FROM   pricerows item_t0
            WHERE  ( item_t0.p_productmatchqualifier IN ( 0, 8826097795073 )
                     AND item_t0.p_usermatchqualifier IN ( 0, 8796093087748 ) )
                   AND ( item_t0.typepkstring = 8796112519250
                         AND (( item_t0.p_product IS NOT NULL
                                 OR item_t0.p_catalogversion IS NULL
                                 OR item_t0.p_catalogversion IN (
                                    8796125954649, 8796125921881,
                                    8796125856345
                                                                ) )) )
            UNION
            SELECT item_t1.pk
            FROM   pricerows item_t1
            WHERE  ( item_t1.p_productmatchqualifier = -1
                     AND item_t1.p_productid = '10685158017'
                     AND item_t1.p_catalog = 8796125823576
                     AND item_t1.p_usermatchqualifier IN ( 0, 8796093087748 ) )
                   AND ( item_t1.typepkstring = 8796112519250
                         AND (( item_t1.p_product IS NOT NULL
                                 OR item_t1.p_catalogversion IS NULL
                                 OR item_t1.p_catalogversion IN (
                                    8796125954649, 8796125921881,
                                    8796125856345
                                                                ) )) )) x 
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment