El pasado de la evolución de la arquitectura del automóvil: una buena arquitectura se evoluciona, no se diseña

Hace muchos años, leí "Los diez años de la tecnología Taobao" del maestro Ziliu . Este libro se convirtió en mi libro de iluminación arquitectónica, y una frase del libro quedó enterrada en mi mente como una semilla: "Una buena arquitectura proviene de la evolución, no del diseño " .

En 2015, me uní al equipo de I+D del pedido de automóviles especiales de China y experimenté el proceso de "evolución de la arquitectura" de la capa de datos de automóviles especiales. Esta experiencia laboral es muy inspiradora para mí, y también me hace suspirar a menudo: "Una buena arquitectura realmente evoluciona un poco".

1 Arquitectura de base de datos única

En la etapa inicial del producto, el objetivo central del equipo técnico es: "Realizar rápidamente los requisitos del producto y brindar servicios externos lo antes posible " .

En ese momento, el servicio de automóvil privado estaba conectado con una base de datos SQLServer y la capa de servicio se había dividido en cierta medida según el campo comercial.

Esta estructura es muy simple, los equipos pueden colaborar por separado y la eficiencia es extremadamente alta. Con el aumento continuo en la cantidad de pedidos de automóviles, en las horas pico de la mañana y la tarde, cuando los usuarios necesitan tomar un taxi, a menudo no hay respuesta después de hacer clic para realizar un pedido.

A nivel del sistema:

  1. Aparecen cuellos de botella en la base de datos. Las operaciones de disco frecuentes conducen a un aumento en el consumo de E/S del servidor de la base de datos. Al mismo tiempo, la asociación de tablas múltiples, la clasificación, la agrupación y la consulta condicional de campo sin índice también harán que la CPU se dispare, lo que eventualmente conducirá a un aumento en el número de conexiones a bases de datos;

  2. Tiempo de espera masivo de puerta de enlace. En un escenario de alta simultaneidad, una gran cantidad de solicitudes operan directamente en la base de datos, los recursos de conexión de la base de datos no son suficientes y se bloquea una gran cantidad de solicitudes.

2 Optimización de SQL y separación de lectura y escritura

Para aliviar la presión sobre la base de datos principal, es fácil pensar en una estrategia: la optimización de SQL . A través de la plataforma de monitoreo de rendimiento y los compañeros de clase de DBA, se analiza el SQL comercial lento y se resuelve el plan de optimización:

  1. Añadir índices razonablemente;

  2. Reduzca la asociación JOIN de múltiples tablas y reduzca la presión de lectura de la base de datos a través del ensamblaje del programa;

  3. Reduzca las transacciones grandes y libere las conexiones de la base de datos lo antes posible.

Otra estrategia es: separación de lectura y escritura .

El principio básico de la separación de lectura y escritura es permitir que la base de datos principal maneje las operaciones transaccionales de adición, modificación y eliminación (INSERT, UPDATE, DELETE), mientras que la base de datos esclava maneja las operaciones de consulta SELECT.

En el marco proporcionado por el equipo especial de arquitectura de automóviles , se admite la separación de lectura y escritura, por lo que la arquitectura de la capa de datos evoluciona a la siguiente figura:

La separación de lectura y escritura puede reducir la presión de escritura de la biblioteca principal, mientras que la biblioteca secundaria de lectura se puede expandir horizontalmente. Por supuesto, la separación de lectura y escritura todavía tiene limitaciones:

  1. La separación de la lectura y la escritura puede enfrentar el problema del retraso maestro-esclavo. Los requisitos de tiempo real son altos en el proceso de servicio de pedidos y carga de pasajeros. Debido a las preocupaciones sobre el retraso, una gran cantidad de operaciones aún utilizan la consulta de la biblioteca principal;

  2. La separación de lectura y escritura puede aliviar la presión de lectura, pero la presión de las operaciones de escritura no se ha aliviado de manera efectiva con el crecimiento explosivo del negocio.

3 Sub-base de datos de campo comercial

Aunque el nivel de aplicación se ha optimizado y la capa de datos también se ha separado de la lectura y la escritura, la presión sobre la biblioteca principal sigue siendo muy alta. A continuación, todos pensaron unánimemente en la subbase de datos del dominio comercial , es decir: dividir la base de datos en diferentes bases de datos comerciales según el dominio comercial, y cada sistema solo accede a la base de datos correspondiente al negocio.

La subbase de datos del campo comercial puede aliviar la presión de rendimiento de la biblioteca de pedidos central y, al mismo tiempo, reducir la interacción entre los sistemas y mejorar la estabilidad general del sistema.

El problema resultante es: en el caso de una sola base de datos, el simple uso de JOIN puede cumplir con los requisitos, pero después de que la base de datos comercial dividida esté en diferentes instancias, JOIN no se puede usar en todas las bases de datos, por lo que es necesario reorganizar el límite del sistema, el el sistema de negocios también necesita ser refactorizado .

El enfoque de refactorización consta de dos partes:

  1. La consulta que originalmente requería la asociación JOIN se cambió a  una llamada RPC  y los datos se ensamblaron en el programa;

  2. Los campos debidamente redundantes en las tablas de negocios se sincronizan a través de colas de mensajes o herramientas heterogéneas.

4 Caché y MQ

En el servicio de automóvil privado, el servicio de pedidos tiene la mayor concurrencia y volumen de solicitudes, y también es el servicio central en el negocio. Aunque el rendimiento del sistema ha mejorado mucho a través de la subbase de datos del campo comercial y la optimización de SQL, la presión de escritura de la base de datos de pedidos sigue siendo muy alta y el cuello de botella del sistema sigue siendo evidente.

Por lo tanto, el servicio de pedidos introduce  caché  y  MQ  .

El pasajero hace clic para llamar a un automóvil inmediatamente en el lado del cliente , el servicio de pedidos crea un pedido, primero lo guarda en la base de datos y luego guarda la información del pedido en el caché de forma sincronizada.

En el ciclo de vida del pasajero del pedido, la operación de modificación del pedido primero modifica el caché, luego envía un mensaje a  MetaQ  , el servicio de colocación de pedidos consume el mensaje y juzga si la información del pedido es normal (por ejemplo, si hay desorden). ) Si los datos del pedido son correctos, entonces se almacenan en la base de datos.

La lógica central tiene dos puntos:

  1. El clúster de caché almacena detalles de pedidos de los últimos siete días y una gran cantidad de solicitudes de lectura de pedidos se obtienen directamente del caché;

  2. En el ciclo de vida del pasajero del pedido, la operación de escritura primero modifica el caché y coloca el pedido de forma asincrónica a través de la cola de mensajes, de modo que la cola de mensajes pueda desempeñar un papel en la eliminación de picos y también reducir la presión sobre la base de datos.

Esta optimización mejoró el rendimiento general del servicio de pedidos y también sentó una base sólida para la subsiguiente subbase de datos y la subtabla de la base de datos del servicio de pedidos y la heterogeneidad.

5 De SQL Server a MySQL

El negocio sigue creciendo de manera explosiva, con cientos de miles de pedidos por día, el volumen de datos de la tabla de pedidos pronto superará los 100 millones y el techo de la base de datos se alcanzará tarde o temprano.

La subtabla de la subbase de datos de pedidos se ha convertido en el consenso del equipo técnico. Muchas soluciones de sub-bases de datos y sub-tablas en la industria se basan en la base de datos MySQL.La gerencia de la tecnología especial del automóvil decidió migrar primero toda la base de datos de pedidos de SQLServer a MySQL.

Antes de migrar, los preparativos son importantes:

  1. SQLServer y MySQL tienen algunas diferencias en la sintaxis de las dos bases de datos, y el servicio de pedidos debe adaptarse a la sintaxis de MySQL.

  2. El pedido order_id  es el incremento automático de la clave principal, pero no es adecuado en el escenario distribuido, y el ID del pedido debe ajustarse al modo distribuido.

Cuando los preparativos estén completos, comience la migración.

El proceso de migración se divide en dos partes: migración de datos completos históricos y  migración de datos incrementales .

La migración completa de datos históricos es principalmente para que los estudiantes de DBA sincronicen la base de datos de pedidos con una base de datos MySQL independiente a través de herramientas.

Migración de datos incremental: debido a que SQLServer no tiene un concepto de registro binlog, no se pueden usar soluciones similares como maxwell y canal. El equipo de pedidos refactorizó el código de servicio de pedidos, y cada vez que se escribe un pedido, enviará un mensaje MQ a MetaQ. Para garantizar la confiabilidad de la migración, también es necesario sincronizar los datos de la nueva base de datos con la base de datos anterior, es decir, se requiere una sincronización bidireccional .

Proceso de migración:

  1. Primero, el servicio de pedidos (versión SQLServer) envía un mensaje de cambio de pedido a MetaQ, en este momento no está habilitado el "consumo de mensajes de base de datos antigua", por lo que los mensajes se acumulan primero en MetaQ;

  2. A continuación, comience a migrar la cantidad total de datos históricos. Una vez completada la migración completa, active "Consumo de mensajes de la base de datos anterior", para que la nueva base de datos de pedidos se pueda sincronizar con los datos de la base de datos de pedidos anteriores;

  3. Habilite el "nuevo consumo de mensajes de la base de datos" y luego implemente el servicio de pedidos (versión MySQL). En este momento, dos versiones del servicio de pedidos se están ejecutando al mismo tiempo. Después de que los datos de detección sean correctos, aumente gradualmente el tráfico del nuevo servicio de pedidos hasta que el antiguo servicio de pedidos esté completamente fuera de línea.

6 Componentes de subtablas y subbases de datos de desarrollo propio

En general, hay dos géneros de subbase de datos y subtabla en la industria: proxy y cliente.

▍ modo proxy

Las soluciones de fragmentación de capa de proxy incluyen Mycat , cobar , etc. en la industria.

Sus ventajas: la aplicación tiene cero cambios, no tiene nada que ver con el idioma y puede reducir el consumo de conexiones mediante la conexión compartida. Desventaja: debido a que es una capa de proxy, hay un retraso adicional.

▍ modo cliente

Las soluciones de sharding de capa de aplicación incluyen sharding-jdbc , TDDL, etc. en la industria.

Sus ventajas: conexión directa a la base de datos, gastos generales reducidos, implementación sencilla y middleware ligero. Inconvenientes: No se puede reducir el consumo de conexiones, algo intrusivo, y la mayoría solo soporta el lenguaje Java.

El equipo de arquitectura de Shenzhou eligió los componentes de subtabla y subbase de datos de desarrollo propio , adoptó  el modo de cliente  y nombró a los componentes: SDDL .

El servicio de pedidos necesita importar el paquete jar SDDL y configurar  la información de la fuente de datos  , la clave de fragmentación   , las reglas de enrutamiento, etc., en el centro de configuración. El servicio de pedidos solo necesita configurar un  datasourceId  .

7 Estrategia de subtabla de subbase de datos

7.1 Dimensión del pasajero

La dimensión de consulta principal de la base de datos de pedidos de automóviles privados es: pasajero , la terminal de pasajeros tiene la frecuencia de consulta más alta según el  id_usuario  del pasajero y  el id_pedido  , elegimos id_usuario como  clave de fragmentación  , y los datos del pedido del mismo usuario se almacenan en el mismo base de datos.

El componente SDDL  de la subbase de datos y la subtabla es muy similar al algoritmo de enrutamiento cobar del middleware de base de datos de código abierto de Ali.

Para facilitar la expansión del pensamiento, primero presente brevemente el algoritmo de fragmentación de cobar.

Suponga que la tabla de pedidos debe dividirse uniformemente en 4 subbibliotecas shard0, shard1, shard2 y shard3. Primero divida [0-1023] en 4 secciones: [0-255], [256-511], [512-767], [768-1023], y luego la cadena (o subcadena, por el usuario Custom) para hacer hash, y el resultado del hash es el módulo 1024, y el segmento en el que cae  la ranura  del resultado final se enrutará a qué subbiblioteca.

El algoritmo de enrutamiento predeterminado de Cobar se puede integrar naturalmente con  el algoritmo de copo de nieve  . El order_id  usa el algoritmo de copo de nieve, y podemos guardar el valor de  la ranura  en  la ID de la máquina del trabajador de 10 dígitos  .

 La ranura  se puede detectar de forma inversa a través del order_id  del pedido , y se puede ubicar la partición en la que se almacenan los datos del pedido del usuario.

 
 

1

Entero getWorkerId (Id de pedido largo) {
  
  

2

Long workerId = (orderId >> 12) & 0x03ff;

3

volver trabajadorId.intValue();

4

}

Las diferencias entre el algoritmo de fragmentación SDDL de coche privado y cobar son:

  1. Cobar admite una cantidad máxima de fragmentos de 1024, mientras que SDDL admite una cantidad máxima de fragmentos de 1024 * 8 = 8192. También se divide en cuatro bibliotecas de orden y el rango de ranuras de cada fragmento es 2048;

  1. Para admitir fragmentos 8192, el algoritmo de copo de nieve debe ajustarse con precisión. La máquina de trabajo de 10 bits del algoritmo de copo de nieve se cambia a una máquina de trabajo de 13 bits, y la marca de tiempo también se ajusta a: marca de tiempo de 38 bits (el número de milisegundos a partir de un cierto punto en el tiempo).

7.2 Dimensiones del controlador

Aunque se ha resuelto el problema de la subbase de datos y la subtabla de pasajeros en la dimensión principal, existe otra dimensión de consulta del automóvil especial. En el cliente del conductor, el conductor debe consultar la información de la orden que se le ha asignado.

Hemos utilizado el id_usuario del pasajero como clave de fragmentación. Si consultamos el pedido de acuerdo con el  id_del_conductor  del conductor, debe transmitirse a cada subbase de datos y agregarse y devolverse. En base a esto, el equipo técnico optó por heterogeneizar los datos del pedido. de la dimensión del pasajero a la base de datos de la dimensión del conductor.

La estrategia de subbase de datos y tabla de la dimensión del conductor es la misma que la de la dimensión del pasajero, excepto que la clave de fragmentación se convierte en  driver_id  .

El canal de artefactos heterogéneos analiza los binlogs de las cuatro subbases de datos de la dimensión del pasajero y los escribe en las cuatro subbases de datos de la dimensión del conductor a través de  SDDL  .

Aquí puede tener una pregunta: aunque los pedidos se pueden sincronizar de forma heterogénea con la subbase de datos de la dimensión del controlador, después de todo, hay un ligero retraso, ¿cómo garantizar que el controlador pueda consultar los últimos datos del pedido en el lado del conductor?

En la sección sobre almacenamiento en caché y MQ , se menciona que el clúster de caché almacena detalles de pedidos de los últimos siete días, y una gran cantidad de solicitudes de lectura de pedidos se obtienen directamente del caché. El servicio de pedidos almacenará en caché la asignación entre el controlador y el pedido actual, de modo que se pueda obtener una gran cantidad de solicitudes del extremo del controlador directamente desde el caché, mientras que la frecuencia de consulta de la lista de pedidos en el extremo del controlador no es tan alta. , y el retraso de la replicación heterogénea está entre 10 milisegundos y 30 milisegundos, es perfectamente aceptable.

7.3 Dimensiones de funcionamiento

En el backend de la gestión de automóviles especiales, los operadores a menudo necesitan consultar la información del pedido, y las condiciones de consulta serán más complicadas.El método adoptado por el equipo técnico de automóviles especiales es: después de que los datos del pedido se colocan en la subbase de datos de pedidos de la dimensión del pasajero, los datos se sincronizan con Elastic Search a través del canal.

7.4 Transmisión de reloj pequeño

Hay algunas tablas de configuración en el negocio, que almacenan configuraciones importantes, y leen más y escriben menos. En la consulta comercial real, muchas tablas comerciales realizarán consultas de datos conjuntas con tablas de configuración. Pero después de dividir la base de datos horizontalmente, la tabla de configuración no se puede dividir.

El principio de la transmisión de la tabla pequeña es: transmitir automáticamente (es decir, copiar) todos los datos de la tabla pequeña (incluidas las actualizaciones incrementales) a la máquina de la tabla grande. De esta forma, la consulta JOIN distribuida original se convierte en una consulta local independiente, lo que mejora en gran medida la eficiencia.

En el escenario del automóvil privado, la transmisión de pequeños relojes es un requisito muy práctico. Por ejemplo: la tabla de ciudades es una tabla de configuración muy importante con una cantidad muy pequeña de datos, pero el servicio de pedidos, el servicio de despacho y el servicio de usuarios se basan en esta tabla.

Sincronice la tabla de ciudades de la base de datos de configuración básica con la base de datos de pedidos, la base de datos de despacho y la base de datos de usuarios a través del canal.

8 Migración fluida

Una vez que se completa el desarrollo de la subbase de datos y el componente SDDL de la subtabla, y el entorno de producción se ha verificado hasta cierto punto, las condiciones para migrar el servicio de pedidos del modo MySQL de base de datos única a la subbase de datos sub -Modo mesa están maduros.

La idea de la migración es en realidad muy similar a la de SQL Server a MySQL .

Proceso general de migración:

  1. Los estudiantes de DBA preparan cuatro bases de datos secundarias para las dimensiones de los pasajeros y cuatro bases de datos secundarias para las dimensiones del conductor, cada una de las cuales contiene datos completos en un momento reciente;

  2. Las ocho bases de datos secundarias son todos datos a escala completa, y los datos redundantes de las ocho bases de datos secundarias deben eliminarse de acuerdo con las reglas de la tabla y la base de datos secundaria;

  3. Encienda la sincronización hacia adelante, y los datos del pedido anterior se transferirán a la base de datos secundaria de la dimensión del pasajero de acuerdo con la estrategia de la tabla y la base de datos secundaria, y los datos del pedido de la base de datos de la dimensión del pasajero se copiarán heterogéneamente a la sub-base de datos de la dimensión del conductor a través del canal;

  4. Active la sincronización inversa, modifique la configuración de la fuente de datos de la aplicación de pedidos, reinicie el servicio de pedidos y los pedidos recién creados del servicio de pedidos se colocarán en la subbase de datos de la dimensión del pasajero y los datos del pedido de la dimensión del pasajero. la base de datos secundaria es heterogénea con respecto a la base de datos de pedidos completos y la base de datos de dimensiones del conductor a través del canal;

  5. Después de verificar que los datos son correctos, actualice gradualmente la configuración de la fuente de datos del servicio de pedidos para completar la migración general.

9 Plataforma de intercambio de datos

El pedido especial de automóviles se ha dividido en bases de datos y tablas, y vale la pena revisar muchos detalles:

  1. La cantidad total de migración de datos históricos requiere la intervención del DBA, y el equipo técnico no tiene herramientas o productos maduros para completarla fácilmente;

  2. La migración incremental de datos se logra a través del canal. Con el crecimiento explosivo del negocio de automóviles privados, hay cada vez más demandas de duplicación de bases de datos, construcción de índices en tiempo real y subbases de datos heterogéneas. Aunque Canal es muy bueno, todavía tiene fallas, como falta de consolas de tareas, datos capacidades de gestión de fuentes y niveles de tareas Monitoreo y alarmas, auditoría de operaciones y otras funciones.

Frente a estos problemas, el objetivo del equipo de arquitectura es construir una plataforma que pueda satisfacer la sincronización incremental en tiempo real y la sincronización completa fuera de línea entre varias fuentes de datos heterogéneas y respaldar el rápido desarrollo del negocio de la empresa.

Con base en este objetivo, el equipo de arquitectura desarrolló  dataLink  para la sincronización incremental de datos y personalizó profundamente  el dataX  de código abierto de Alibaba para una sincronización completa de datos.

10 escribir hasta el final

La evolución de la arquitectura del automóvil privado no ha sido fácil, y también hay giros y vueltas, pero paso a paso, la reserva técnica del automóvil privado es cada vez más profunda.

Luckin Coffee se incubó dentro del Grupo UCAR en 2017. Estas reservas técnicas del automóvil especial mejoraron en gran medida la eficiencia de I+D del equipo técnico de Luckin Coffee y apoyaron el rápido desarrollo del negocio. Por ejemplo, cuando se planeó por primera vez la base de datos de pedidos de Ruixing Coffee, se dividió en 8 instancias de base de datos según la dimensión del usuario y la dimensión de la tienda, respectivamente. Los componentes de la subbase de datos y la subtabla SDDL y la plataforma de intercambio de datos jugaron un papel  clave .

Bueno, este texto está escrito aquí. Nos vemos la próxima vez.


Si mi artículo es útil para usted, por favor dale me gusta, léalo y reenvíelo . Su apoyo me inspirará a publicar artículos de mayor calidad, ¡muchas gracias!

Supongo que te gusta

Origin blog.csdn.net/makemyownlife/article/details/123697722
Recomendado
Clasificación