La práctica del sistema de computación gráfica de alto rendimiento Plato en Nebula Graph

Este artículo se publicó por primera vez en la cuenta pública Nebula Graph Community

La práctica del sistema de computación gráfica de alto rendimiento Plato en Nebula Graph

1. Introducción a la computación gráfica

1.1 Base de datos de grafos frente a computación de grafos

Las bases de datos de gráficos están orientadas a escenarios OLTP, enfatizando adiciones, eliminaciones, modificaciones y consultas, y una consulta a menudo solo involucra una pequeña cantidad de datos en todo el gráfico, mientras que la computación de gráficos está orientada a escenarios OLAP, a menudo analizando y calculando todo el gráfico. datos.

1.2 Arquitectura de distribución del sistema de computación gráfica

De acuerdo con la arquitectura distribuida, los sistemas de computación gráfica se dividen en autónomos y distribuidos.

La ventaja de un sistema de computación de gráficos de una sola computadora es que el modelo es simple y no hay necesidad de considerar la comunicación distribuida y la segmentación de gráficos.

La plataforma de computación gráfica distribuida divide los datos gráficos en múltiples máquinas para procesar datos gráficos a mayor escala, pero inevitablemente presenta la sobrecarga de la comunicación distribuida.

1.3 División de gráficos

Hay dos formas principales de dividir el gráfico: Edge-Cut y Vertex-Cut.

Segmentación de bordes: los datos de cada punto solo se almacenarán en una máquina, pero algunos bordes se interrumpirán y distribuirán a varias máquinas. Como se muestra en la Figura (a), los datos del punto A solo se almacenan en la máquina 1, y los datos del punto B solo se almacenan en la máquina 2. Para el borde AB, se almacena en la máquina 1 y la máquina 2. Dado que el punto A y el punto B están distribuidos en diferentes máquinas, generará una sobrecarga de comunicación durante el proceso de cálculo iterativo.

División de puntos: cada borde solo se almacenará en una máquina, pero algunos puntos se pueden dividir y distribuir en varias máquinas. Como se muestra en la figura (b), el borde AB se almacena en la máquina 1, el borde BC se almacena en la máquina 2, el borde CD se almacena en la máquina 3 y el punto B se asigna a dos máquinas 1 y 2, y el punto C se asigna a 2,3 dos máquinas. Dado que los puntos se almacenan en varias máquinas, mantener la coherencia de los datos de vértices también genera una sobrecarga de comunicación.

1.4 Modelo computacional

El modelo de programación está dirigido a desarrolladores de aplicaciones de computación gráfica y se puede dividir en un modelo de programación centrado en nodos, un modelo de programación centrado en el borde o en la ruta y un modelo de programación centrado en subgráficos.

El modelo computacional es un problema al que se enfrentan los desarrolladores de sistemas de computación gráfica, que incluye principalmente el modelo de ejecución sincrónica y el modelo de ejecución asincrónica. Los más comunes son el modelo BSP (Bulk Synchronous Parallel Computing Model) y el modelo GAS.

Modelo BSP: El proceso de cálculo del modelo BSP consta de una serie de pasos iterativos, cada uno de los cuales se denomina superpaso. Los sistemas que adoptan el modelo BSP incluyen principalmente Pregel, Hama, Giraph, etc. El modelo BSP tiene una estructura tanto horizontal como vertical. Verticalmente, el modelo BSP consta de una serie de superpasos en serie. Horizontalmente (como se muestra), un superpaso se divide en tres fases:

  • En la fase de computación local, cada procesador solo realiza cálculos sobre los datos almacenados en la memoria local.
  • En la fase de comunicación global, los nodos de la máquina intercambian datos entre sí.
  • Fase de sincronización de vallas, esperando el final de todas las actividades de comunicación.

Modelo GAS: El modelo GAS se propone en el sistema PowerGraph y se divide en una etapa de recolección de información (Gather), una etapa de aplicación (Apply) y una etapa de distribución (Scatter).

  • Fase Gather , encargada de recopilar información de los vértices vecinos.
  • La fase Aplicar se encarga de procesar localmente la información recopilada y actualizarla en los vértices.
  • Fase de dispersión , encargada de enviar nueva información a los vértices vecinos.

2. Introducción al sistema de computación gráfica Gemini

Gemini es más influyente en la industria, sus principales puntos técnicos incluyen: CSR/CSC, push/pull, maestro y espejo, gráfico disperso y denso, trabajo cooperativo de comunicación e informática, particionamiento basado en fragmentos, subparticionamiento con reconocimiento de NUMA Espera.

Gemini utiliza el corte de bordes para particionar los datos del gráfico de una manera basada en fragmentos y es compatible con la estructura de Numa. Para los datos particionados, use CSR para almacenar información externa y use CSC para almacenar información interna. En el proceso de cálculo iterativo, los vecinos salientes se actualizan mediante push para gráficos dispersos, y la información de los vecinos entrantes se extrae en gráficos densos mediante pull.

Si se corta un borde, el vértice en un extremo del borde es el maestro y el vértice en el otro extremo es el espejo. El espejo se llama marcador de posición.Durante el proceso de cálculo de extracción, los vértices del espejo en cada máquina extraerán la información de sus vértices maestros vecinos entrantes para un cálculo y los sincronizarán a través de la red bajo el modelo de cálculo BSP. En el proceso de cálculo de empuje, el vértice maestro de cada máquina primero sincronizará su información con su vértice espejo y luego el espejo actualizará sus vecinos salientes.

En la fase de comunicación del BSP, cada máquina Node_ienvía a su próxima máquina Node_i+1y la última máquina envía a la primera máquina. Node_i-1La información también es recibida por cada máquina cuando se envía, y el cómputo local se realiza inmediatamente después de recibir la información. La superposición de comunicación y computación puede ocultar el tiempo de comunicación y mejorar la eficiencia general.

Para obtener más detalles, consulte el documento "Gemini: un sistema de procesamiento de gráficos distribuido centrado en la computación" .

3. Integración del sistema informático de gráfico Plato y Nebula Graph

3.1 Introducción al Sistema de Cómputo de Gráficos Plato

Plato es el sistema informático gráfico de grado industrial de código abierto de Tencent basado en el artículo de Gemni. Plato puede ejecutarse en clústeres x86 comunes, como clústeres de Kubernetes, clústeres de Yarn, etc. En el nivel del sistema de archivos, Plato proporciona una variedad de interfaces para admitir los sistemas de archivos convencionales, como HDFS, Ceph, etc.

3.2 Integración con Nebula Graph

Hicimos un desarrollo secundario basado en Plato para acceder a la fuente de datos Nebula Graph.

3.2.1 Nebula Graph como fuente de datos de entrada y salida

Aumente la fuente de datos de Plato, admita Nebula Graph como fuente de datos de entrada y salida, lea directamente los datos de Nebula Graph para el cálculo de gráficos y escriba los resultados del cálculo directamente en Nebula Graph.

La capa de almacenamiento de Nebula Graph proporciona una interfaz de escaneo para particiones, y es fácil escanear datos de vértices y bordes en lotes a través de esta interfaz:

ScanEdgeIter scanEdgeWithPart(std::string spaceName,
                                  int32_t partID,
                                  std::string edgeName,
                                  std::vector<std::string> propNames,
                                  int64_t limit = DEFAULT_LIMIT,
                                  int64_t startTime = DEFAULT_START_TIME,
                                  int64_t endTime = DEFAULT_END_TIME,
                                  std::string filter = "",
                                  bool onlyLatestVersion = false,
                                  bool enableReadFromFollower = true);

ScanVertexIter scanVertexWithPart(std::string spaceName,
                                      int32_t partId,
                                      std::string tagName,
                                      std::vector<std::string> propNames,
                                      int64_t limit = DEFAULT_LIMIT,
                                      int64_t startTime = DEFAULT_START_TIME,
                                      int64_t endTime = DEFAULT_END_TIME,
                                      std::string filter = "",
                                      bool onlyLatestVersion = false,
                                      bool enableReadFromFollower = true);

En la práctica, primero obtenemos la distribución de particiones en el espacio especificado y asignamos la tarea de escaneo de cada partición a cada nodo del clúster de Plato, y cada nodo luego asigna la tarea de escaneo de partición a cada nodo que se ejecuta en el nodo. Lectura paralela y rápida de datos. Una vez que se completa el cálculo del gráfico, los resultados del cálculo se escriben en Nebula Graph en paralelo a través del cliente Nebula.

3.2.2 Codificador de ID distribuido

Gemini y Plato requieren que los ID de vértices aumenten continuamente desde 0, pero la mayoría de los ID de vértices de datos reales no cumplen con este requisito, especialmente Nebula Graph admite ID de tipo cadena desde la versión 2.0.

Por lo tanto, necesitamos convertir el ID original de un tipo int o cadena a un int que se incremente continuamente desde 0 antes del cálculo. Plato implementa internamente un codificador de ID independiente, es decir, cada máquina en el clúster de Plato almacena de manera redundante la relación de mapeo de todas las ID. Cuando la cantidad de puntos es relativamente grande, cada máquina solo necesita cientos de GB de memoria para almacenar la tabla de mapeo de ID, porque necesitamos implementar un mapeador de ID distribuido, cortar la relación de mapeo de ID en varias copias y almacenarlas por separado.

Distribuimos las ID originales en diferentes máquinas mediante hash y asignamos ID globales que comienzan desde 0 y aumentan en paralelo en paralelo. Después de generar la relación de asignación de ID, cada máquina tendrá una parte de la tabla de asignación de ID. Luego, los datos del borde se procesan según el punto de inicio y el punto final, y se envían a la máquina correspondiente para su codificación, y los datos finales son los datos que se pueden usar para el cálculo. Una vez que se completa el cálculo, los datos requeridos deben volver a asignarse a la identificación comercial, y el proceso es similar al anterior.

3.2.3 Algoritmo suplementario

Con base en Plato, hemos agregado algoritmos como sssp, apsp, similitud jaccard y conteo triangular, y hemos agregado soporte para entrada y salida a la fuente de datos Nebula Graph para cada algoritmo. Los algoritmos soportados actualmente son:

nombre del archivo Nombre del algoritmo Clasificación
apsp.cc Todo al camino más corto sendero
sssp.cc Ruta más corta de fuente única sendero
tree_stat.cc profundidad/ancho del árbol Características del gráfico
nstepdegrees.cc n orden Características del gráfico
hiperanf.cc Estimación de la distancia media del gráfico Características del gráfico
cuenta_triangulos.cc conteo de triángulos Características del gráfico
kcore.cc Centralidad del nodo
pagerank.cc Rango de página Centralidad del nodo
bnc.cc intermediación Centralidad del nodo
cnc.cc Cercanía Centralidad Centralidad del nodo
cgm.cc cálculo de componentes conectados descubrimiento comunitario
lpa.cc Propagación de etiquetas descubrimiento comunitario
hanp.cc HANP descubrimiento comunitario
metapath_randomwalk.cc Representación gráfica Aprendizaje
node2vec_randomwalk.cc Representación gráfica Aprendizaje
fast_unfolding.cc Lovaina agrupamiento
infomap_simple.cc agrupamiento
jaccard_similitud.cc semejanza
mutuo.cc otro
antorcha.cc otro
bfs.cc recorrido primero en anchura otro

4. Instalación y operación del despliegue de Plato

4.1 Implementación del clúster

Plato usa MPI para la comunicación entre procesos. Al implementar Plato en un clúster, debe instalar Plato en el mismo directorio o usar NFS. Vea cómo hacerlo: https://mpitutorial.com/tutorials/running-an-mpi-cluster-within-a-lan/

4.2 Scripts y archivos de configuración para ejecutar el algoritmo

scripts/run_pagerank_local.sh

#!/bin/bash

PROJECT="$(cd "$(dirname "$0")" && pwd)/.."

MAIN="./bazel-bin/example/pagerank" # process name

WNUM=3
WCORES=8

#INPUT=${INPUT:="$PROJECT/data/graph/v100_e2150_ua_c3.csv"}
INPUT=${INPUT:="nebula:${PROJECT}/scripts/nebula.conf"}
#OUTPUT=${OUTPUT:='hdfs://192.168.8.149:9000/_test/output'}
OUTPUT=${OUTPUT:="nebula:$PROJECT/scripts/nebula.conf"}
IS_DIRECTED=${IS_DIRECTED:=true}  # let plato auto add reversed edge or not
NEED_ENCODE=${NEED_ENCODE:=true}
VTYPE=${VTYPE:=uint32}

ALPHA=-1
PART_BY_IN=false

EPS=${EPS:=0.0001}
DAMPING=${DAMPING:=0.8}
ITERATIONS=${ITERATIONS:=5}

export MPIRUN_CMD=${MPIRUN_CMD:="${PROJECT}/3rd/mpich-3.2.1/bin/mpiexec.hydra"}

PARAMS+=" --threads ${WCORES}"
PARAMS+=" --input ${INPUT} --output ${OUTPUT} --is_directed=${IS_DIRECTED} --need_encode=${NEED_ENCODE} --vtype=${VTYPE}"
PARAMS+=" --iterations ${ITERATIONS} --eps ${EPS} --damping ${DAMPING}"

# env for JAVA && HADOOP
export LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/amd64/server:${LD_LIBRARY_PATH}

# env for hadoop
export CLASSPATH=${HADOOP_HOME}/etc/hadoop:`find ${HADOOP_HOME}/share/hadoop/ | awk '{path=path":"$0}END{print path}'`
export LD_LIBRARY_PATH="${HADOOP_HOME}/lib/native":${LD_LIBRARY_PATH}

chmod 777 ./${MAIN}
${MPIRUN_CMD} -n ${WNUM} -f ${PROJECT}/scripts/cluster ./${MAIN} ${PARAMS}
exit $?

Descripción de parámetros

  • INPUTLos parámetros y los OUPUTparámetros especifican la fuente de datos de entrada y la fuente de datos de salida del algoritmo, respectivamente. Actualmente, se admiten archivos csv locales, archivos HDFS y Nebula Graph. Cuando la fuente de datos de entrada y salida es Nebula Graph, INPUTy el OUPUTformulario esnebula:/path/to/nebula.conf
  • WNUM es la suma de la cantidad de procesos que se ejecutan en todas las máquinas del clúster. Se recomienda que cada máquina se ejecute como 1 o procesos de nodo NUMA. WCORE es la cantidad de subprocesos por proceso. La configuración máxima recomendada es la cantidad de subprocesos de hardware. de la máquina.

scripts/nebulosa.conf

## read/write
--retry=3 # 连接 Nebula Graph 时的重试次数
--space=sf30 # 要读取或写入的 space 名称

## read from nebula
--meta_server_addrs=192.168.8.94:9559 # Nebula Graph 的 metad 服务地址
--edge=LIKES # 要读取的边的名称
#--edge_data_field # 要读取的作为边的权重属性的名称
--read_batch_size=10000 # 每次 scan 时的 batch 的大小

## write to nebula
--graph_server_addrs=192.168.8.94:9669 # Nebula Graph 的 graphd 服务地址
--user=root # graphd 服务的登陆用户名
--password=nebula # graphd 服务的登陆密码
# insert or update
--mode=insert # 写回 Nebula Graph 时采用的模式: insert/update
--tag=pagerank # 写回到 Nebula Graph 的 tag 名称
--prop=pr # 写回到 Nebula Graph 的 tag 对应的属性名称
--type=double # 写回到 Nebula Graph 的 tag 对应的属性的类型
--write_batch_size=1000 # 写回时的 batch 大小
--err_file=/home/plato/err.txt # 写回失败的数据所存储的文件

guiones/clúster

El archivo de clúster especifica la IP de la máquina del clúster en la que ejecutar el algoritmo.

192.168.15.3
192.168.15.5
192.168.15.6

Lo anterior es la aplicación de Plato en Nebula Graph. Actualmente, esta función está integrada en Nebula Graph Enterprise Edition. Si está utilizando la versión de código abierto de Nebula Graph, debe conectar Plato según sus propias necesidades.


¿Tecnología de base de datos de gráficos de intercambio? Para unirse al grupo de intercambio de Nebula, complete primero su tarjeta de presentación de Nebula y el asistente de Nebula lo llevará al grupo ~~

Atención a la cuenta pública

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4169309/blog/5470887
Recomendado
Clasificación