Optimización de carga nun proxecto Highload con ElasticSearch

Ola Habr! Chámome Maxim Vasiliev, traballo como analista e xefe de proxectos en FINCH. Hoxe gustaríame contarvos como, mediante ElasticSearch, puidemos procesar 15 millóns de solicitudes en 6 minutos e optimizar as cargas diarias no sitio dun dos nosos clientes. Por desgraza, teremos que prescindir de nomes, xa que temos un NDA, esperamos que o contido do artigo non sufra isto. Imos.

Como funciona o proxecto

No noso backend, creamos servizos que garanten o rendemento dos sitios web e das aplicacións móbiles dos nosos clientes. A estrutura xeral pódese ver no diagrama:

Optimización de carga nun proxecto Highload con ElasticSearch

No proceso de traballo, procesamos un gran número de transaccións: compras, pagos, operacións con saldos de usuarios, para o que almacenamos moitos rexistros, así como importamos e exportamos estes datos a sistemas externos.

Tamén hai procesos inversos cando recibimos datos do cliente e os transferimos ao usuario. Ademais, aínda hai procesos para traballar con pagos e programas de bonificación.

Breve antecedente

Inicialmente, utilizamos PostgreSQL como único almacén de datos. As súas vantaxes estándar para un DBMS: a presenza de transaccións, unha linguaxe de mostraxe de datos desenvolvida, unha ampla gama de ferramentas para a integración; combinado cun bo rendemento satisfizo as nosas necesidades durante bastante tempo.

Almacenamos absolutamente todos os datos en Postgres: desde transaccións ata noticias. Pero o número de usuarios creceu, e con el o número de solicitudes.

Para entender, o número anual de sesións en 2017 só no sitio de escritorio é de 131 millóns. En 2018 - 125 millóns. 2019 de novo 130 millóns. Engade outros 100-200 millóns desde a versión móbil do sitio e da aplicación móbil, e ti recibirá un gran número de solicitudes.

Co crecemento do proxecto, Postgres deixou de facer fronte á carga, non tivemos tempo: apareceron un gran número de consultas diversas, para as que non puidemos crear un número suficiente de índices.

Entendemos que existía a necesidade doutros almacéns de datos que proporcionasen as nosas necesidades e quitasen a carga de PostgreSQL. Consideráronse como opcións posibles Elasticsearch e MongoDB. Este último perdeu nos seguintes puntos:

  1. Velocidade de indexación lenta a medida que crece a cantidade de datos nos índices. Con Elastic, a velocidade non depende da cantidade de datos.
  2. Non hai busca de texto completo

Así que escollemos Elastic para nós e preparámonos para a transición.

Transición a Elastic

1. Iniciamos a transición do servizo de busca de puntos de venda. O noso cliente dispón dun total de preto de 70 puntos de venda, e isto require varios tipos de buscas no sitio e na aplicación:

  • Busca de texto por nome da cidade
  • Xeobusca nun radio determinado desde algún punto. Por exemplo, se o usuario quere ver que puntos de venda están máis preto da súa casa.
  • Busca por un cadrado determinado: o usuario debuxa un cadrado no mapa e móstranse todos os puntos deste raio.
  • Busca por filtros adicionais. Os puntos de venda difieren entre si na variedade

Se falamos da organización, entón en Postgres temos unha fonte de datos tanto para o mapa como para as noticias, e en Elastic Snapshots tómanse dos datos orixinais. O caso é que inicialmente Postgres non puido facer fronte á busca por todos os criterios. Non só había moitos índices, tamén podían superpoñerse, polo que o programador de Postgres perdeuse e non entendía que índice usar.

2. A continuación foi a sección de noticias. Publicacións aparecen no sitio todos os días para que o usuario non se perda no fluxo de información, os datos deben ser ordenados antes de emitir. Isto é o que serve a busca: podes buscar no sitio por coincidencia de texto e, ao mesmo tempo, conectar filtros adicionais, xa que tamén se realizan a través de Elastic.

3. Despois movemos o procesamento da transacción. Os usuarios poden comprar un determinado produto no sitio e participar nun sorteo de premios. Despois de tales compras, procesamos unha gran cantidade de datos, especialmente os fins de semana e festivos. A modo de comparación, se os días ordinarios o número de compras está entre 1,5 e 2 millóns, en vacacións a cifra pode chegar aos 53 millóns.

Ao mesmo tempo, os datos deben procesarse no menor tempo posible: aos usuarios non lles gusta esperar o resultado durante varios días. Non hai forma de acadar estes prazos a través de Postgres: a miúdo recibimos bloqueos e mentres procesabamos todas as solicitudes, os usuarios non podían comprobar se recibiron premios ou non. Isto non é moi agradable para os negocios, polo que trasladamos o procesamento a Elasticsearch.

Periodicidade

Agora as actualizacións configúranse en función de eventos, segundo as seguintes condicións:

  1. Puntos de venda. En canto recibimos datos dunha fonte externa, comezamos inmediatamente a actualización.
  2. Novas. En canto se edita algunha noticia no sitio, envíase automaticamente a Elastic.

Aquí de novo paga a pena mencionar as vantaxes de Elastic. En Postgres, ao enviar unha solicitude, hai que esperar ata que procese con honestidade todos os rexistros. Podes enviar 10 rexistros a Elastic e comezar a traballar inmediatamente, sen esperar a que os rexistros se distribúan en todos os fragmentos. Por suposto, algúns fragmentos ou réplicas poden non ver os datos de inmediato, pero todo estará dispoñible moi pronto.

Métodos de integración

Hai 2 formas de integrarse con Elastic:

  1. A través dun cliente nativo sobre TCP. O controlador nativo está a desaparecer aos poucos: xa non se admite, ten unha sintaxe moi incómoda. Polo tanto, practicamente non o usamos e tentamos abandonalo por completo.
  2. A través dunha interface HTTP que pode usar tanto solicitudes JSON como sintaxe Lucene. O último é un motor de texto que usa Elastic. Nesta versión, temos a posibilidade de enviar por lotes solicitudes JSON a través de HTTP. Esta é a opción que intentamos utilizar.

Grazas á interface HTTP, podemos utilizar bibliotecas que proporcionan unha implementación asíncrona do cliente HTTP. Podemos aproveitar Batch e a API asíncrona, o que dá como resultado un alto rendemento, o que axudou moito nos días da gran promoción (máis información a continuación)

Algúns números para comparar:

  • Gardando usuarios de recompensas de Postgres en 20 fíos sen agrupar: 460713 rexistros en 42 segundos
  • Cliente elástico + reactivo para 10 fíos + lote para 1000 elementos: 596749 rexistros en 11 segundos
  • Cliente elástico + reactivo para 10 fíos + lote para 1000 elementos: 23801684 entradas en 4 minutos

Agora escribimos un xestor de solicitudes HTTP que crea JSON como Batch / non Batch e o envía a través de calquera cliente HTTP, independentemente da biblioteca. Tamén pode escoller enviar solicitudes de forma sincronizada ou asíncrona.

Nalgunhas integracións, aínda usamos o cliente de transporte oficial, pero isto é só cuestión da seguinte refactorización. Neste caso, utilízase para o procesamento un cliente personalizado construído sobre a base de Spring WebClient.

Optimización de carga nun proxecto Highload con ElasticSearch

gran promoción

Unha vez ao ano, o proxecto acolle unha gran promoción para os usuarios - este é o mesmo Highload, xa que neste momento traballamos con decenas de millóns de usuarios ao mesmo tempo.

Normalmente os picos de carga ocorren durante as vacacións, pero esta promoción está a un nivel completamente diferente. O ano pasado, o día da promoción, vendemos 27 unidades de bens. Os datos foron tratados durante máis de media hora, o que causou molestias aos usuarios. Os usuarios recibiron premios pola participación, pero quedou claro que o proceso debía acelerarse.

A principios de 2019, decidimos que necesitábamos ElasticSearch. Durante todo un ano, organizamos o tratamento dos datos recibidos en Elastic e a súa emisión na api da aplicación móbil e da páxina web. Como resultado, ao ano seguinte durante a campaña, procesamos 15 entradas en 131 minutos.

Xa que temos moita xente que quere mercar produtos e participar no sorteo de premios en promocións, esta é unha medida temporal. Agora estamos enviando información actualizada a Elastic, pero no futuro pensamos transferir a información arquivada dos últimos meses a Postgres como almacenamento permanente. Para non atascar o índice Elastic, que tamén ten as súas limitacións.

Conclusión/Conclusións

Polo momento, transferimos todos os servizos que queriamos a Elastic e detímonos neste momento. Agora estamos construíndo un índice en Elastic encima do almacenamento persistente principal en Postgres, que se fai cargo da carga do usuario.

No futuro, pensamos transferir servizos se entendemos que a solicitude de datos se fai demasiado diversa e se busca un número ilimitado de columnas. Esta xa non é unha tarefa de Postgres.

Se necesitamos unha busca de texto completo na funcionalidade ou se temos moitos criterios de busca diferentes, xa sabemos que hai que traducilo a Elastic.

⌘⌘⌘

Grazas por ler. Se a túa empresa tamén usa ElasticSearch e ten os seus propios casos de implementación, comunícanos. Será interesante saber como están os demais 🙂

Fonte: www.habr.com

Engadir un comentario