Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

1. Antecedentes de la demanda

En la práctica de la operación de datos de Internet, existe un tipo de aplicación de análisis de datos que es exclusivo del análisis de rutas de la industria de Internet. La aplicación de análisis de ruta es para mostrar visualmente el flujo ascendente y descendente de una página específica y analizar la distribución de ruta de los usuarios cuando utilizan el producto. Por ejemplo: cuando un usuario usa una APLICACIÓN, ¿cómo ingresa a la [página de detalles] desde la [página de inicio] y cuál es la proporción de usuarios que ingresan a la [página de detalles], [página de reproducción] y [página de descarga] de la [página de inicio], y nos puede ayudar a analizar qué nodo dejó el usuario.

En el diseño del plan técnico específico correspondiente a la escena, dividimos los datos de acceso según la sesión para excavar las rutas a las que los usuarios acceden con frecuencia; la función permite a los usuarios ver instantáneamente las rutas relacionadas de los nodos seleccionados, y apoya a los usuarios. para personalizar los puntos de inicio o finalización de las rutas y soporte para ver el análisis de resultados de conversión de diferentes grupos objetivo en la misma ruta de comportamiento de acuerdo con los nuevos usuarios / usuarios activos de la empresa, para satisfacer las necesidades de análisis refinado.

1.1 Escenarios de aplicación

Generalmente, los principales problemas a los que los usuarios prestan atención en escenarios donde se requiere un análisis de ruta:

  • ¿Cuáles son las principales rutas de los usuarios en la APLICACIÓN según la tasa de conversión de mayor a menor?
  • Una vez que el usuario abandona el camino esperado, ¿cuál es la dirección real?
  • ¿Cuáles son las diferencias en las rutas de comportamiento del usuario con diferentes características?

A través de un escenario empresarial real, podemos ver cómo el modelo de análisis de ruta resuelve tales problemas;

【Escena empresarial】

Analice la ruta de comportamiento principal de los "usuarios activos" para llegar a la página de destino de destino [página de video pequeña] (el volumen de datos diario es de mil millones y el tiempo de salida del resultado del cálculo es de aproximadamente 1 s).

【Operación del usuario】

  1. Seleccione la página de inicio / final y agregue la condición de filtro "Usuario";

  2. Seleccione el tipo "Visitas" / "Sesiones";

  3. Haga clic en la consulta para producir los resultados en tiempo real.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

2. Conceptos básicos

Antes de continuar con el modelo de datos específico y el diseño de la arquitectura de ingeniería, primero introduzca algunos conceptos básicos para ayudar a todos a comprender mejor este artículo.

2.1 Análisis de ruta

El análisis de rutas es uno de los métodos de minería de datos más utilizados, que se utiliza principalmente para analizar la distribución de rutas de los usuarios cuando utilizan el producto y descubrir las rutas de acceso frecuentes del usuario. Al igual que la función de embudo, el análisis de ruta explora los pasos que toman los usuarios durante su estadía en su sitio web o aplicación, pero el análisis de ruta puede estudiar múltiples rutas al azar en lugar de simplemente analizar una ruta preestablecida.

2.2 Sesión 和 Hora de la sesión

A diferencia de la sesión en la aplicación WEB, la sesión en el análisis de datos se refiere a una serie de interacciones que ocurren en el sitio web dentro de un período de tiempo específico. El significado de Session Time en este modelo es que cuando el intervalo entre dos comportamientos excede el Session Time, creemos que estos dos comportamientos no pertenecen a la misma ruta.

2.3 Diagrama de Sankey

Diagrama de Sankey (diagrama de Sankey), es decir, diagrama de división de energía de Sankey, también llamado diagrama de balance de energía de Sankey. Es un tipo específico de diagrama de flujo y el ancho de la rama en la figura corresponde al tamaño del flujo de datos. Como se muestra en la Figura 4.1-1, cada borde representa el tráfico desde el nodo anterior a ese nodo. Un cuadro completo de Sankey incluye el siguiente contenido: datos de nodo y tasa de conversión de nodo (cuadro rojo en la figura siguiente), datos de borde y tasa de conversión de borde (cuadro negro en la figura siguiente). Para el cálculo de la tasa de conversión, consulte [3.5. Cálculo de la tasa de conversión].

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

2.4 Lista de adyacencia

La construcción del diagrama de Sankey se puede simplificar al problema del almacenamiento comprimido de un gráfico. El gráfico generalmente consta de varias partes:

  • Borde
  • Punto (vértice)
  • Peso
  • 度 (grado)

En este modelo, utilizamos una lista de adyacencia para el almacenamiento. La tabla de adyacencia es una estructura de almacenamiento de compresión de gráficos de uso común. Utiliza una lista vinculada para guardar los nodos y los bordes en el gráfico mientras ignora los bordes que no existen entre los nodos, comprimiendo así la matriz. La estructura de la lista de adyacencia es la siguiente:

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

En (a), el lado izquierdo es el nodo del vértice, que contiene los datos del vértice y el puntero al primer borde; el lado derecho es el nodo del borde, que contiene el peso del borde, la información de entrada y salida, y el puntero al siguiente borde. Una lista de adyacencia completa es similar a la estructura de Hashmap, como se muestra en (b), el lado izquierdo es una tabla de secuencia, que almacena los nodos de borde en (a); cada nodo de borde corresponde a una lista vinculada para almacenar los bordes conectados al nodo. En el modelo de ruta de página, para satisfacer las necesidades del modelo, hemos modificado el nodo de vértice y la estructura del nodo de borde, consulte la sección [4.1] para obtener más detalles.

2.5 Poda de árboles

La poda es un paso importante en la construcción de un árbol y se refiere a eliminar algunos nodos sin importancia para reducir la complejidad del cálculo o la búsqueda. En el modelo de ruta de página, recortamos el árbol construido por los datos originales en el proceso de poda y eliminamos las ramas no calificadas para garantizar la integridad de cada ruta de nodo raíz a nodo hoja en el árbol.

2.6 PV y SV

PV significa Page View, el número de visitas. En este modelo, se refiere al número de visitas dentro de un período de tiempo; SV significa Session View, el número de sesiones. En este modelo, se refiere al número de sesiones donde ha aparecido la ruta de acceso. Por ejemplo, hay una ruta: A → B → C → D → A → B y la ruta dos: A → B → D, luego el PV de A → B es 2 + 1 = 3, y el SV es 1 + 1 = 2.

 Tres, diseño de modelo de datos

Esta sección presentará el diseño del modelo de datos, incluido el flujo de datos, la división de la ruta, el cálculo de ps / sv y el cálculo de la tasa de conversión final de la ruta en el diagrama de Sankey.

3.1 Flujo de datos general

Los datos provienen de un almacén de datos unificado, Spark los calcula y luego los escribe en Clickhouse, y Hive realiza una copia de seguridad en frío. El diagrama de flujo de datos se muestra en la Figura 3.1-1.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.1-1

3.2 Selección técnica

Clickhouse no es el tema central de este artículo. No lo describiré en detalle aquí, solo explicaré brevemente las razones para elegir Clickhouse.

El motivo de la elección es que Clickhouse es un almacenamiento en columnas, que es extremadamente rápido. Eche un vistazo al tamaño de los datos y la velocidad de consulta (a la fecha de redacción de este artículo):

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.2-1

La velocidad de consulta de cientos de miles de millones de datos obtenidos al final es así,

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.2-2

3.3 Modelado de datos

3.3.1 Obtener información de la página y dividir la sesión

El modelo de ruta de página obtiene los identificadores de página correspondientes basados ​​en varios ID de eventos para realizar el análisis de la ruta de la página. El concepto de Sesión se puede ver en la Sección 2.2, que no se repetirá aquí. En la actualidad, utilizamos una división de sesión más flexible, de modo que los usuarios pueden consultar la información de conversión de la página del usuario en varias granularidades de tiempo (5, 10, 15, 30, 60 minutos) de la sesión.

Supongamos que hay usuario ay usuario b. Los eventos de comportamiento del usuario a ese día son E1, E2, E3 ..., y las páginas correspondientes son P1, P2, P3 ..., y la hora del evento es T1, T2, T3 ..., el intervalo de sesión seleccionado es tg. Como se muestra en la figura, T4-T3> tg, por lo que P1, P2, P3 se dividen en la primera sesión, P4, P5 se dividen en la segunda sesión y P6 y las páginas siguientes también se dividen en la nueva sesión.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

El pseudocódigo se implementa de la siguiente manera:

def splitPageSessions(timeSeq: Seq[Long], events: Seq[String], interval: Int)
                     (implicit separator: String): Array[Array[Array[String]]] = {
  // 参数中的events是事件集合,timeSeq是相应的事件发生时间的集合
  if (events.contains(separator))
    throw new IllegalArgumentException("Separator should't be in events.")
  if (events.length != timeSeq.length)
    throw new Exception("Events and timeSeq not in equal length.")
  val timeBuf = ArrayBuffer[String](timeSeq.head.toString) // 存储含有session分隔标识的时间集合
  val eventBuf = ArrayBuffer[String](events.head) // 存储含有session分隔标识的事件集合
  if (timeSeq.length >= 2) {
    events.indices.tail.foreach { i =>
      if (timeSeq(i) - timeSeq(i - 1) > interval * 60000) { // 如果两个事件的发生时间间隔超过设置的时间间隔,则添加分隔符作为后面划分session的标识
        timeBuf += separator;
        eventBuf += separator
      }
      timeBuf += timeSeq(i).toString;
      eventBuf += events(i)
    }
  }
  val tb = timeBuf.mkString(",").split(s",\\$separator,").map(_.split(",")) // 把集合通过标识符划分成为各个session下的时间集合
  val eb = eventBuf.mkString(",").split(s",\\$separator,").map(_.split(",")) // 把集合通过标识符划分成为各个session下的事件集合
  tb.zip(eb).map(t => Array(t._1, t._2)) // 把session中的事件和发生时间对应zip到一起,并把元组修改成数组类型,方便后续处理
}

3.3.2 Desduplicación de páginas adyacentes

Diferentes eventos pueden corresponder a la misma página, y las mismas páginas adyacentes deben filtrarse, por lo que lo que se debe hacer después de dividir la sesión es eliminar los duplicados de las páginas adyacentes.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-2

El resultado obtenido después de la deduplicación de páginas adyacentes es así

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-3

3.3.3 Obtenga las primeras / últimas cuatro páginas de cada página

Luego, realice un análisis de la función de ventana en los datos anteriores para obtener los cuatro niveles de páginas antes y después de cada página en cada sesión, donde el sid se empalma de acuerdo con el ID de identificación del usuario y el número de sesión, por ejemplo, para la primera sesión. 0 del usuario a mencionado anteriormente Se generarán los siguientes 7 registros, la página de la figura se muestra como la página actual y la página vacía está representada por -1

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-4

Calcula el resto, obtendrás un total de 7 + 7 + 6 + 4 + 5 = 29 registros. Obtenga todos los registros de la siguiente manera

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

3.3.4 Cuente el pv / sv de las rutas positivas y negativas

Tome page y page_id_previous1, page_id_previous2, page_id_previous3, page_id_previous4 para obtener la ruta negativa de cinco niveles (path_direction es 2), tome page y page_id_next1, page_id_next2, page_id_next3, page_id_next4 para obtener la ruta sv positiva de cinco niveles (de ruta) -duplicar según sid), obtenga los siguientes datos dfSessions,

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Mirar directamente los datos anteriores puede resultar una pérdida, por lo que aquí hay dos ejemplos de datos, los primeros datos de resultado

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-4

Esta es una ruta de datos de resultado positiva (path_direction es 1). En la siguiente figura, es una ruta de izquierda a derecha. Las dos rutas correspondientes son las siguientes

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-5

Los datos del segundo resultado

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-6

También es un dato de resultado de ruta positivo, donde pv es 2, y las dos rutas correspondientes son las siguientes. La razón por la que sv es 1 es que el sid de las dos rutas es el mismo, y ambas son las rutas generadas por el usuario a en la sesión S1

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 3.3-7

3.3.5 Calcular el pv / sv de todos los niveles de caminos

Luego, de acuerdo con los datos de dfSessions, la suma de pv y sv se calcula de acuerdo con la agrupación page_id_lv1, y se obtienen los pv y sv de la ruta de primer nivel. La ruta_dirección se establece en 0 para la ruta de primer nivel.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Luego, calcule de manera similar pv y sv de las rutas de segundo, tercer, cuarto y quinto nivel, y combine todos los resultados para obtener lo siguiente

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

3.4 Escritura de datos

Los datos de resultados analizados y calculados por Spark deben escribirse en Clickhouse para los servicios en línea y en Hive como una copia de seguridad de los datos en frío, que se puede utilizar para la recuperación de datos de Clickhouse.

La tabla Clickhouse utiliza una estructura de tabla distribuida (distribuida). La tabla distribuida en sí no almacena ningún dato, pero actúa como un proxy transparente para la fragmentación de datos, enrutando automáticamente los datos a cada nodo del clúster, por lo que el motor de la tabla distribuida debe cooperar Úselo con otros motores de tablas de datos. Los datos de la tabla del modelo de análisis de ruta de usuario se almacenan en cada fragmento del clúster. El método de fragmentación utiliza fragmentación aleatoria. Aquí, la escritura de datos de Clickhouse está involucrada. Vamos a explicarlo.

Con respecto a este punto, en la etapa inicial del modelo, utilizamos el método de escritura de tablas distribuidas para escribir datos. El proceso de escritura específico es el siguiente:

  1. El cliente establece una conexión jdbc con el nodo A en el clúster y escribe datos a través de solicitudes HTTP POST;
  2. Después de recibir los datos, el fragmento A hará dos cosas: primero, dividir los datos de acuerdo con las reglas de fragmentación y, segundo, escribir los datos que pertenecen al fragmento actual en su propia tabla local;
  3. El fragmento A escribe los datos que pertenecen al fragmento remoto en un archivo bin temporal en el directorio de la unidad de partición. La regla de nomenclatura es la siguiente: /database@host:port/[increase_num].bin;
  4. El fragmento A intenta establecer una conexión con el fragmento remoto;
  5. Habrá otro conjunto de tareas de monitoreo para monitorear los archivos bin temporales generados anteriormente y enviar estos datos a los fragmentos remotos, y cada pieza de datos se envía en un solo hilo;
  6. El fragmento remoto recibe datos y los escribe en la tabla local;
  7. El fragmento A confirma que la escritura está completa.

Mediante el proceso anterior, se puede apreciar que la tabla Distribuida se encarga de la escritura de datos de todos los fragmentos, por lo que el tráfico entrante y saliente de los nodos que establecen la conexión jdbc tendrá picos extremadamente altos, lo que provocará los siguientes problemas:

  1. La carga de un solo nodo es demasiado alta, lo que se refleja principalmente en la memoria, el tráfico entrante y saliente de la tarjeta de red, el número de espera de la conexión TCP, etc., y el estado de la máquina es muy deficiente;
  2. Cuando el negocio crezca, se conectarán más modelos a Clickhouse para OLAP, lo que significa una mayor cantidad de datos. Si continúa escribiendo de la forma actual, inevitablemente se producirá la caída de una sola máquina. En el estado actual de alta disponibilidad,, El tiempo de inactividad de una sola máquina provocará la indisponibilidad de todo el clúster;
  3. En el futuro, definitivamente haremos la alta disponibilidad del clúster ck y usaremos ReplicatedMergeTree más confiable. Cuando use este motor para escribir datos, habrá inconsistencias de datos debido a la escritura en la tabla distribuida.

Para este fin de datos, se modificó el sondeo de DNS para escribir la tabla local. Después de la modificación:

  • El número de espera de conexión TCP de la máquina utilizada para la conexión JDBC cayó de 90 a 25, una reducción de más del 72%;
  • El flujo máximo de entrada de la máquina utilizada para la conexión JDBC se ha reducido de 645 M / sa 76 M / s, una reducción de más del 88%;
  • El flujo de salida de la máquina utilizada para la conexión JDBC debido a la distribución de datos es de aproximadamente 92 M / s. Después de la transformación, esta parte del flujo de salida se borra a cero.

Además, cuando la tabla distribuida es responsable de escribir datos en fragmentos remotos, hay dos formas de escritura asíncrona y escritura síncrona. Si se realiza la escritura asíncrona, el mensaje de escritura exitosa se devolverá después de que la tabla distribuida se escriba en el fragmento local. .Si es Escritura síncrona devolverá un mensaje de éxito después de que se hayan escrito todos los fragmentos. La situación por defecto es escritura asíncrona. Podemos controlar el tiempo de espera de escritura síncrona modificando los parámetros.

def splitPageSessions(timeSeq: Seq[Long], events: Seq[String], interval: Int)
                     (implicit separator: String): Array[Array[Array[String]]] = {
  // 参数中的events是事件集合,timeSeq是相应的事件发生时间的集合
  if (events.contains(separator))
    throw new IllegalArgumentException("Separator should't be in events.")
  if (events.length != timeSeq.length)
    throw new Exception("Events and timeSeq not in equal length.")
  val timeBuf = ArrayBuffer[String](timeSeq.head.toString) // 存储含有session分隔标识的时间集合
  val eventBuf = ArrayBuffer[String](events.head) // 存储含有session分隔标识的事件集合
  if (timeSeq.length >= 2) {
    events.indices.tail.foreach { i =>
      if (timeSeq(i) - timeSeq(i - 1) > interval * 60000) { // 如果两个事件的发生时间间隔超过设置的时间间隔,则添加分隔符作为后面划分session的标识
        timeBuf += separator;
        eventBuf += separator
      }
      timeBuf += timeSeq(i).toString;
      eventBuf += events(i)
    }
  }
  val tb = timeBuf.mkString(",").split(s",\\$separator,").map(_.split(",")) // 把集合通过标识符划分成为各个session下的时间集合
  val eb = eventBuf.mkString(",").split(s",\\$separator,").map(_.split(",")) // 把集合通过标识符划分成为各个session下的事件集合
  tb.zip(eb).map(t => Array(t._1, t._2)) // 把session中的事件和发生时间对应zip到一起,并把元组修改成数组类型,方便后续处理
}

3.5 Cálculo de la tasa de conversión

Seleccione la dimensión correspondiente en la página de inicio y seleccione la página de inicio:

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

El backend se consultará en Clickhouse,

  • La profundidad del nodo seleccionado (node_depth) es 1 y la página de primer nivel (page_id_lv1) son los datos de la página seleccionada, y se obtienen la página de primer nivel y su sv / pv,

  • La profundidad del nodo seleccionado (node_depth) es 2 y la página de primer nivel (page_id_lv1) son los datos de la página seleccionada. Tome los 10 primeros en orden inverso de sv / pv para obtener la página de segundo nivel y su sv / pv,

  • La profundidad del nodo seleccionado (node_depth) es 2 y la página de primer nivel (page_id_lv1) son los datos de la página seleccionada. Tome los 20 primeros en orden inverso de sv / pv para obtener la página de tercer nivel y su sv / pv,

  • La profundidad del nodo seleccionado (node_depth) es 2 y la página de primer nivel (page_id_lv1) son los datos de la página seleccionada. Tome los 30 primeros en orden inverso de sv / pv para obtener la página de cuarto nivel y su sv / pv,

  • La profundidad del nodo seleccionado (node_depth) es 2 y la página de primer nivel (page_id_lv1) son los datos de la página seleccionada. Tome los 50 primeros en orden inverso de sv / pv para obtener la página de quinto nivel y su sv / pv,

Reglas de cálculo de la tasa de conversión:

Tasa de conversión de página:

Supongamos que hay rutas ABC, ADC, ABDC, donde ABCD son cuatro páginas diferentes respectivamente.

Calcule la tasa de conversión de la página C de tres niveles:

(Todas las páginas de tres niveles en la ruta con una profundidad de nodo de 3 son la suma pv / sv de la ruta de C) ÷ (el pv / sv de la página de primer nivel) 

Tasa de conversión de ruta

Suponga que hay ABC, ADC, ABDC, donde ABCD son cuatro páginas diferentes

Calcule la tasa de conversión de BC en la ruta ABC:

(El pv / sv de la ruta ABC) ÷ (la suma pv / sv de la ruta de B en todas las páginas de segundo nivel de la ruta con una profundidad de nodo de 3)

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

 Cuatro, diseño de arquitectura final de ingeniería

Esta sección explicará la arquitectura de procesamiento del extremo de ingeniería, incluidos varios aspectos: la estructura del diagrama de Sankey, la combinación de rutas, el cálculo de la tasa de conversión y la poda.

4.1 La estructura del diagrama de Sankey

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Como se puede ver en el diagrama de prototipo anterior, necesitamos construir un diagrama de Sankey. Para el fin de la ingeniería, necesitamos construir un árbol de ruta ponderado.

Simplificando la figura anterior, puede transformar la demanda en una lista de adyacencia para construir un árbol ponderado. La siguiente figura a la izquierda es nuestro diseño de lista de adyacencia. La lista de orden de la izquierda almacena cada nodo (vértice), incluida la información del nodo, como el nombre del nodo (nombre), el código de nodo (código) y un puntero a la lista de bordes (borde); cada nodo (vértice) apunta a un borde (Borde)) Lista vinculada, cada borde guarda el peso del borde actual, la información del punto final y un puntero al siguiente borde del mismo nodo.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 4.1-2

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 4.1-3 

La figura 4.1-2 es la lista de adyacencia que usamos en el modelo. A continuación, se muestran algunos cambios en la lista de adyacencia descrita en 2.4. En nuestro diagrama de Sankey, los nodos con el mismo nombre y diferentes tasas de conversión aparecerán en diferentes niveles.Estos nodos son parte de la ruta y no pueden considerarse como nodos duplicados por su nombre y no forman un bucle. Si todo el gráfico de Sankey está representado por una lista de adyacencia, dichos nodos se tratarán como el mismo nodo, haciendo que aparezca un bucle en la imagen. Por lo tanto, dividimos el diagrama de Sankey según niveles, y cada dos niveles están representados por una tabla de adyacencia, como se muestra en la Figura 4.1-2. El nivel 1 representa los nodos del nivel 1 y los bordes que apuntan al nivel 2, y el nivel 2 representa que los nodos del nivel 2 apuntan al nivel 3., y así sucesivamente.

4.2 Definición de ruta

Primero, revisemos el diagrama de Sankey:

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Observando la figura anterior, podemos encontrar que necesitamos calcular cuatro datos: el pv / sv de cada nodo, la tasa de conversión de cada nodo, el pv / sv entre nodos y la tasa de conversión entre nodos. Luego damos la definición de estos datos a continuación:

  • Nodo pv / sv = la suma de pv / sv del nodo actual en la jerarquía actual

  • Tasa de conversión de nodo = (nodo pv / sv) / (ruta de inicio del nodo pv / sv)

  • Pv / sv entre nodos = pv / sv desde el nodo anterior al nodo actual

  • Tasa de conversión entre nodos = (entre nodos pv / sv) / (nodo superior pv / sv)

Veamos los datos de ruta almacenados en Clickhouse. Primero echemos un vistazo a la estructura de la tabla:

(
  `node_depth` Int8 COMMENT '节点深度,共5个层级深度,枚举值1-2-3-4-5' CODEC(T64, LZ4HC(0)),
  `page_id_lv1` String COMMENT '一级页面,起始页面' CODEC(LZ4HC(0)),
  `page_id_lv2` String COMMENT '二级页面' CODEC(LZ4HC(0)),
  `page_id_lv3` String COMMENT '三级页面' CODEC(LZ4HC(0)),
  `page_id_lv4` String COMMENT '四级页面' CODEC(LZ4HC(0)),
  `page_id_lv5` String COMMENT '五级页面' CODEC(LZ4HC(0))
)

Los anteriores son los campos más importantes en la tabla de ruta, que indican respectivamente la profundidad del nodo y los nodos en todos los niveles. Los datos de la tabla incluyen la ruta completa y la ruta intermedia. La ruta completa se refiere a la ruta desde el punto de inicio hasta la salida, desde el punto de inicio hasta el punto final especificado, y la ruta más allá del quinto nivel se trata como la ruta del quinto nivel. La ruta intermedia se refiere a los datos intermedios generados en el proceso de cálculo de datos y no se puede utilizar como una ruta completa.

Datos de ruta:

(1) Ruta completa

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

(2) Camino incompleto

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Luego, debemos filtrar la ruta completa de los datos y organizar los datos de la ruta en una estructura de árbol.

4.3 Diseño e implementación

4.3.1 Marco general

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

La idea general de implementación del back-end es muy clara: los pasos principales son leer datos, construir tablas de adyacencia y podar. Entonces, ¿cómo realizar el filtrado de ruta completo / no completo? Usamos la poda de la capa de servicio para filtrar las rutas incompletas. El siguiente es el pseudocódigo que describe todo el proceso:

// 1-1: 分层读取原始数据
// 1-1-1: 分层构造Clickhouse Sql
    for( int depth = 1; depth <= MAX_DEPTH; depth ++){
        sql.append(select records where node_depth = depth)
    }
// 1-1-2: 读取数据
    clickPool.getClient();
    records = clickPool.getResponse(sql);
// 2-1: 获取节点之间的父子、子父关系(双向edge构造)
    findFatherAndSonRelation(records);
    findSonAndFathRelation(records);
// 3-1: 剪枝
// 3-1-1: 清除孤立节点
    for(int depth = 2; depth <= MAX_DEPTH; depth ++){
        while(hasNode()){
            node = getNode();
            if node does not have father in level depth-1:
                cut out node;
        }
    }
// 3-1-2: 过滤不完整路径
    for(int depth = MAX_DEPTH - 1; depth >= 1; depth --){
        cut out this path;
    }
// 3-2: 构造邻接表
    while(node.hasNext()){
        sumVal = calculate the sum of pv/sv of this node until this level;
        edgeDetails = get the details of edges connected to this node and the end point connected to the edges;
        sortEdgesByEndPoint(edgeDetails);
        path = new Path(sumVal, edgeDetails);
    }

4.3.2 Grupo de conexiones de Clickhouse

Hemos introducido ClickHouse en la ruta de la página y sus características no se repetirán aquí. Usamos un grupo de conexiones Http simple para conectarnos al servidor ClickHouse. La estructura del grupo de conexiones es la siguiente:

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

4.3.3 Lectura de datos

Como se describe en 2, necesitamos leer la ruta completa en los datos.

(
  `node_depth` Int8 COMMENT '节点深度,枚举值',
  `page_id_lv1` String COMMENT '一级页面,起始页面',
  `page_id_lv2` String COMMENT '二级页面',
  `page_id_lv3` String COMMENT '三级页面',
  `page_id_lv4` String COMMENT '四级页面',
  `page_id_lv5` String COMMENT '五级页面',
  `val` Int64 COMMENT '全量数据value'
)

En la estructura de la tabla anterior, se puede ver que la ruta escrita en la base de datos es una ruta con una profundidad de ≤5 después de un cribado de primer nivel. Necesitamos distinguir la ruta completa de la ruta incompleta sobre esta base, y determinar si es una ruta completa basada en node_depth y page_id_lvn y calcular el valor de cada nodo según sea necesario.

Condición de juicio de ruta completa:

  • node_depth = n, page_id_lvn = pageId (n <MAX_DEPTH)
  • node_depth = n, page_id_lvn = pageId || page_id_lvn = EXIT_NODE (n = MAX_DEPTH)

Ya conocemos las condiciones de la ruta completa, por lo que hay dos opciones para leer la ruta. Solución 1: Filtre directamente de acuerdo con las condiciones anteriores para obtener la ruta completa. Debido a las limitaciones de Clickhouse y el rendimiento del back-end, debe limitar al obtener el número; Solución 2: Leyendo capa por capa, puede calcular la cantidad total de datos, pero no se garantiza recuperar el número exacto de rutas.

A través de la observación, habrá rutas duplicadas en los datos y suponga que hay dos rutas:

A → B → C → D → EXIT_NODE

A → B → E → D → EXIT_NODE

Cuando existen las dos rutas anteriores, es necesario calcular el valor de cada nodo. En los datos reales, solo podemos obtener el valor del nodo actual a través de una ruta incompleta. Por lo tanto, la opción uno no es aplicable.

Luego, la segunda opción se puede leer capa por capa a través del siguiente pseudocódigo:

for(depth = 1; depth <= MAX_DEPTH; depth++){
    select
        node_depth as nodeDepth,
        ...,
        sum(sv) as val
    from
        table_name
    where
        ...
        AND (toInt16OrNull(pageId1) = 45)
        AND (node_depth = depth)
        ...
    group by
        node_depth,
        pageId1,
        pageId2,
        ...
    ORDER BY
        ...
    LIMIT
        ...
}

Los datos leídos son los siguientes:

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Entonces, node1_A_val = 10 + 20, node2_B_val = 9 + 15 y así sucesivamente.

4.3.4 Poda

De acuerdo con 4.3.3, extraeremos todos los datos originales jerárquicamente durante la etapa de búsqueda, y los datos originales contienen rutas completas e incompletas. La siguiente figura es un árbol construido directamente a partir de los datos originales (árbol original). De acuerdo con nuestra definición de una ruta completa: la profundidad de la ruta llega a 5 y el nodo final es la salida u otros nodos; la profundidad de la ruta no llega a 5 y el nodo final es la salida. Se puede ver que la parte roja de la figura (node4_lv1 → node3_lv2) es una ruta incompleta.

Además, los nodos aislados (nodo verde node4_lv2) aparecerán en el árbol original. Esto se debe a que, en la etapa de búsqueda, ordenamos los datos de manera jerárquica antes de obtenerlos, de modo que no se puede garantizar la relevancia de cada capa de datos. Por lo tanto, el nodo node4_lv2 se clasifica más alto en la capa lv2, y sus nodos predecesores y sucesores no pueden seleccionarse en el orden inferior, lo que conduce a la generación de nodos aislados.

Práctica del modelo de análisis del comportamiento del usuario (1) -modelo de análisis de ruta

Figura 4.3-3

Por lo tanto, después de eliminar el conjunto de datos original, todavía necesitamos filtrar para obtener la ruta que realmente necesitamos.

En el modelo, implementamos esta operación de filtrado mediante poda.

// 清除孤立节点
    for(int depth = 2; depth <= MAX_DEPTH; depth ++){
        while(hasNode()){
            node = getNode();
            if node does not have any father and son: // [1]
                cut out node;
        }
    }
// 过滤不完整路径
    for(int depth = MAX_DEPTH - 1; depth >= 1; depth --){
        cut out this path; // [2]
    }

En los pasos anteriores, obtuvimos la lista de bordes bidireccionales (relación padre-hijo y lista de relación padre-hijo). Por lo tanto, en el pseudocódigo [1] anterior, la lista de bordes se puede usar para encontrar rápidamente el predecesor y el sucesor del nodo actual para determinar si el nodo actual es un nodo aislado.

De manera similar, usamos la lista de bordes para recortar trazados incompletos. Para las rutas incompletas, solo debe preocuparse por las rutas cuya profundidad sea menor que MAX_DEPTH y el último nodo no es EXIT_NODE al podar. Luego, en el pseudocódigo [2] anterior, solo necesitamos juzgar si los nodos de la capa actual tienen bordes secuenciales (relación padre-hijo), de lo contrario, borre el nodo actual.

 Cinco, escribe al final

Basándonos en el breve tiempo de consulta y los requisitos de visualización en la consulta basada en plataforma, combinados con los recursos informáticos de almacenamiento existentes y los requisitos específicos, enumeramos los datos de ruta en la implementación, los dividimos en dos y los fusionamos. La primera vez es dentro del mismo día Se fusiona la misma ruta y la segunda vez es para resumir las rutas dentro del intervalo de fechas. Este artículo espera proporcionar una referencia para el análisis de rutas, y debe diseñarse de manera razonable en combinación con las características de cada negocio cuando se utilice, a fin de brindar un mejor servicio al negocio.

El Clickhouse involucrado en el plan no se presentará en detalle aquí. Los estudiantes interesados ​​pueden aprender más sobre él. Bienvenidos a discutir y aprender con el autor.

Autor: equipo vivo de Big Data de Internet

Supongo que te gusta

Origin blog.51cto.com/14291117/2659982
Recomendado
Clasificación