UNIVERSIDAD NACIONAL DEL CENTRO DE LA PROVINCIA DE BUENOS AIRES FACULTAD DE CIENCIAS EXACTAS DOCTORADO EN CIENCIAS DE LA COMPUTACIÓN Mecanismos de soporte para procesamiento distribuido de algoritmos de recomendación en redes sociales por Ing. Alejandro Corbellini Dra. Daniela Godoy Directora Dra. Silvia Schiaffino Co-Directora Tesis sometida a evaluación como requisito parcial para la obtención del grado de Doctor en Ciencias de la Computación Tandil, Diciembre 2015 Resúmen Los sistemas de recomendación (RSs, del inglés Recommender Systems) se han convertido en una herramienta vital para ayudar a los usuarios a hacer frente a la enorme cantidad de información disponible en la Web. Con la aparición de la Web Social y las Redes Sociales en Línea (OSN, del inglés Online Social Networks), los RSs han permitido a los usuarios gestionar la enorme cantidad de contenido generado en los medios sociales, tales como documentos, fotos y videos. En este contexto, los RSs basados en la Red Social exploran la información disponible en la red para inferir las preferencias de los usuarios y producir sugerencias sobre diferentes ítems. Entre los problemas más sobresalientes en OSNs, sobresale el problema de sugerir personas conocidas en aquellas redes sociales basadas en amistades. Los algoritmos de recomendación de amistades utilizan el grafo que subyace a la red social para sugerir amigos, mejorando la participación de los usuarios en la plataforma y contribuyendo al crecimiento de la red. La recomendación de usuarios en OSNs se traduce generalmente a un problema de predicción de enlaces, en el cual el objetivo es inferir cuáles relaciones entre los usuarios son más propensas a ocurrir en el futuro. Computar algoritmos de predicción de enlaces en redes sociales a gran escala presenta una serie de retos en relación con la escalabilidad de las implementaciones. Muchos algoritmos de predicción de enlaces se han diseñado para ser ejecutados en una sola computadora, lo que limita el método de escalado sólo a escalado vertical, es decir, mediante la adición de más recursos al equipo donde corre el algoritmo. Este tipo de implementaciones son fáciles de desarrollar, pero difíciles de escalar debido a los costos de hardware y sus limitaciones intrínsecas. Por otro lado, distribuir el algoritmo en un conjunto de máquinas ha demostrado ser una alternativa rentable a pesar del aumento de la complejidad del desarrollo. Implementaciones complicadas, ad-hoc de algoritmos de predicción de enlaces eran comunes hasta la aparición de las bases de datos de grafos distribuidas y frameworks de procesamiento. Las bases de datos de grafos proporcionan un soporte de almacenamiento de grafos y la capacidad de realizar consultas simples, pero carecen de características avanzadas de procesamiento. Los frameworks ocultan la mayor parte de las operaciones distribuidas al usuario detrás de un modelo de procesamiento y, al mismo tiempo, fomentan buenas prácticas de procesamiento en entornos conectados por redes de computadoras. Sin embargo, la mayoría de los frameworks no integran un soporte ii para persistir grafos y responden a un modelo de procesamiento único, no siempre ajustado a la exigencia de diferentes tipos de algoritmos de predicción de enlaces. La presente tesis ofrece un enfoque alternativo mediante la implementación de un conjunto de mecanismos en un framework para el procesamiento de grafos a gran escala que combina el la persistencia de las bases de datos de grafos y las capacidades de procesamiento de múltiples modelos de procesamiento distribuido. El framework propuesto, llamado Graphly, integra una almacén de grafos distribuidos que permite reducir la cantidad de memoria ocupada por la representación del grafo, maximizando la cantidad de espacio disponible para los datos resultantes del procesamiento. Graphly también implementa un conjunto de modelos de procesamiento que permite a los desarrolladores elegir el modelo más adecuado en función de los requisitos del algoritmo y permite la comparación de los modelos en cuanto a su desempeño y a su aptitud para representar el algoritmo. Entre los modelos provistos, se encuentran los ampliamente conocidos Fork-Join y Pregel. Por otra parte, se propone un novedoso modelo de procesamiento llamado DPM (del inglés, Distributed Partitioned Merge), basado en la sencillez del estilo de programación Fork-Join, con las ventajas de un modelo centrado en vértices, tal como Pregel. Graphly también aborda una problemática en gran parte ignorada por los modelos de procesamiento existentes: la personalización de la asignación de tareas. De hecho, Graphly implementa un mecanismo llamado Mapping Strategies que permite a los usuarios personalizar la forma en que las tareas se asignan a los nodos de cómputo de acuerdo a las características de cada nodo. Por defecto, Graphly utiliza una estrategia de asignación basada en la ubicación que asigna tareas de acuerdo a la disposición de los datos en el almacén de grafos. Sin embargo, el uso de estrategias dinámicas basadas en métricas de memoria (por ejemplo, la memoria disponible de los nodos) puede ser crítico en situaciones donde los recursos son escasos y muy heterogéneos de nodo a nodo. Uno de los principales aportes de esta tesis es una comparación de algoritmos de predicción de enlaces, incluyendo algoritmos basados en caminatas aleatorias y algoritmos basados en rutas, para los tres modelos de procesamiento diferentes. Esta comparación arrojó luz sobre qué tan bien se ajusta cada modelo a un tipo específico de algoritmo midiendo no sólo su velocidad de recomendación, sino también sus estadísticas de uso de red y uso de memoria. La comparación experimental de modelos de procesamiento también mostró que DPM superó a Pregel y ForkJoin en términos de velocidad recomendación para la mayoría de los algoritmos, manteniendo al mismo tiempo valores aceptables de uso de red y uso de memoria. iii Agradecimientos La presente tesis no se podría haber completado sin el constante apoyo de un conjunto de personas que velaron no solo por la faceta académica, técnica y literaria del trabajo, sino también por aquellas personas que brindaron un soporte anímico indispensable. Por este motivo, humildemente agradezco a las siguientes personas. A mis directoras Daniela Godoy y Silvia Schiaffino, por sus enormes esfuerzos en la creación de esta tesis y por ser una verdadera guía en mis estudios de doctorado. Sus extensas correcciones, críticas y consejos son una de las partes más valiosas de toda esta experiencia. A las autoridades del instituto ISISTAN-CONICET, por estar a disposición constantemente y por las enormes oportunidades brindadas. Especialmente agradezco a Cristian Mateos, por el aporte de su experiencia en sistemas distribuidos, indispensable para avanzar en las etapas más complejas de la propuesta. A mis compañeros, becarios e investigadores, que con el apoyo mutuo generamos un ambiente de trabajo inmejorable, un valor mucho más importante que lugar de trabajo en sí mismo. A mis amigos, por su enorme apoyo moral y constante disponibilidad en los buenos y, sobre todo, en los malos momentos. A mi familia, sin su apoyo incondicional desde los tiempos de mis estudios de grado este trabajo no hubiese existido. A Manu, mi esposa, quien se involucró en una y cada una de las etapas de la creación de esta tesis, dándome un soporte conmovedor en cada decisión tomada. A mi compañera y mi amor, muchas gracias. A todas estas personas, mi agradecimiento Alejandro iv A mi esposa, Manuela v Índice de Contenidos Página Principal i Resúmen ii Agradecimientos iv Dedicación v Índice de Contenidos vi Índice de Figuras xi Índice de Tablas xii Índice de Listados de Código xiii Acrónimos xiv 1 2 Introducción 1 1.1 Motivación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2 Propuesta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Organización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Conceptos Relacionados 10 2.1 Sistemas de Recomendación . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2 Sistemas de Recomendación Basado en Redes Sociales . . . . . . . . . . . . . 13 2.2.1 Redes Sociales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2.2 Recomendación de Amigos . . . . . . . . . . . . . . . . . . . . . . . 14 2.2.3 Recomendación de Followees . . . . . . . . . . . . . . . . . . . . . . 15 2.2.4 Perfilado de Usuarios . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Predicción de Enlaces en Redes Sociales . . . . . . . . . . . . . . . . . . . . . 18 2.3.1 19 2.3 vi Métricas Basadas en Vecinos . . . . . . . . . . . . . . . . . . . . . . . 2.4 3 22 2.3.3 Métricas Basadas en Caminatas Aleatorias (Random Walks) . . . . . . 24 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 32 3.1 Frameworks de Procesamiento de Grafos Distribuido . . . . . . . . . . . . . . 32 3.1.1 Fork-Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.1.2 MapReduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.1.3 Pregel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.1.4 Gather-Apply-Scatter . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3.1.5 Procesamiento Asíncrono . . . . . . . . . . . . . . . . . . . . . . . . 45 3.1.6 Resilient Distributed Datasets . . . . . . . . . . . . . . . . . . . . . . 46 3.1.7 Limitaciones de los Frameworks Actuales . . . . . . . . . . . . . . . . 47 Bases de Datos de Grafos Distribuidas . . . . . . . . . . . . . . . . . . . . . . 49 3.2.1 Tipos de Bases de Datos de Grafos . . . . . . . . . . . . . . . . . . . . 49 3.2.2 Bases de Datos de Grafos Disponibles . . . . . . . . . . . . . . . . . . 50 3.2.3 Limitations of Graph Databases . . . . . . . . . . . . . . . . . . . . . 56 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.3 Graphly 58 4.1 Arquitectura General de Graphly . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.2 Comunicación y Administración de Workers . . . . . . . . . . . . . . . . . . . 61 4.3 Almacén de Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.4 Procesamiento de Grafos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.4.1 Fork-Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 4.4.2 Pregel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 4.4.3 Distributed Partitioned Merge (DPM) . . . . . . . . . . . . . . . . . . 71 4.4.4 Estrategias de Mapeo . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Graphly API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.5.1 API de Recorridos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.5.2 API de Modelos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 4.5.3 GraphRec: Una API de recomendación . . . . . . . . . . . . . . . . . 77 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.5 4.6 5 Path-based metrics . . . . . . . . . . . . . . . . . . . . . . . . . . . . Trabajo Relacionado 3.2 4 2.3.2 Mecanismos de Soporte para Algoritmos Basados en Caminos 81 5.1 Implementación de los Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . 82 5.1.1 Implementación de Algoritmos Basados en Caminos . . . . . . . . . . 82 5.1.1.1 TFR Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 83 5.1.1.2 Algoritmo Katz . . . . . . . . . . . . . . . . . . . . . . . . 88 vii 5.1.1.3 Algoritmo LocalPath . . . . . . . . . . . . . . . . . . . . . 90 5.1.1.4 FriendLink Algorithm . . . . . . . . . . . . . . . . . . . . . 91 Algoritmos Basados en Vecinos . . . . . . . . . . . . . . . . . . . . . 92 5.1.2.1 Common Neighbors . . . . . . . . . . . . . . . . . . . . . . 93 5.1.2.2 Adamic Adar . . . . . . . . . . . . . . . . . . . . . . . . . 94 5.1.2.3 Jaccard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Discusión de las Implementaciones . . . . . . . . . . . . . . . . . . . 97 Configuración Experimental . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 5.2.1 Descripción del Dataset . . . . . . . . . . . . . . . . . . . . . . . . . 98 5.2.2 Selección de Grupos de Test . . . . . . . . . . . . . . . . . . . . . . . 101 5.2.3 Descripción del Clúster . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Resultados Experimentales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 5.3.1 Resultados de Modelos de Procesamiento . . . . . . . . . . . . . . . . 104 5.3.2 Resultados de Estrategias de Mapeo . . . . . . . . . . . . . . . . . . . 117 5.3.3 Discusión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5.1.2 5.1.3 5.2 5.3 5.4 6 Mecanismos de Soporte para Algoritmos Basados en Random Walks 131 6.1 Implementación de Algoritmos Basados en Random Walks . . . . . . . . . . . 131 6.1.1 Implementación de HITS . . . . . . . . . . . . . . . . . . . . . . . . . 132 6.1.2 Implementación de SALSA . . . . . . . . . . . . . . . . . . . . . . . 135 6.1.3 Discusión de la Implementación . . . . . . . . . . . . . . . . . . . . . 137 Resultados Experimentales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 6.2.1 Resultados de Modelos de Procesamiento . . . . . . . . . . . . . . . . 139 6.2.2 Resultados de Estrategias de Mapeo . . . . . . . . . . . . . . . . . . . 147 6.2.3 Discusión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 6.2 6.3 7 Conclusiones 162 7.1 Contribuciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 7.2 Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 7.3 Trabajo Futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 A Bases de Datos NoSQL viii 168 A.1 Conceptos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 A.1.1 El Teorema de CAP . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 A.1.2 Propiedades ACID y BASE . . . . . . . . . . . . . . . . . . . . . . . 172 A.2 Bases de Datos Clave-Valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 A.2.1 Hashing Consistente . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 A.2.2 Virtual Buckets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 A.2.3 Mecanismos Basados en Dynamo . . . . . . . . . . . . . . . . . . . . 178 A.2.4 Discusión de Base de Datos Clave-Valor . . . . . . . . . . . . . . . . . 179 A.3 Bases de Datos Orientadas a Columnas . . . . . . . . . . . . . . . . . . . . . . 183 A.3.1 BigTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 A.3.1.1 SSTable, Tablets y Tables . . . . . . . . . . . . . . . . . . . 184 A.3.1.2 Servidores de Tablets . . . . . . . . . . . . . . . . . . . . . 185 A.3.1.3 MapReduce y BigTable . . . . . . . . . . . . . . . . . . . . 185 A.3.2 Lista de Bases de Datos Orientada a Columnas . . . . . . . . . . . . . 186 A.4 Bases de Datos Orientadas a Documentos . . . . . . . . . . . . . . . . . . . . 189 Bibliografía 195 ix Índice de Figuras 3.1 Un ejemplo de flujo de trabajo en Fork-Join . . . . . . . . . . . . . . . . . . . 36 3.2 Un ejemplo de flujo de trabajo en MapReduce. . . . . . . . . . . . . . . . . . 38 3.3 Ejemplo de cómputo de PageRank utilizando mensajes y agregadores. . . . . . 41 3.4 Ejemplo de cómputo de BSP. . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.5 Ejemplo de etapas y comunicación de Pregel. . . . . . . . . . . . . . . . . . . 43 3.6 Ejemplo de linaje de Resilient Distributed Datasets para el algoritmo PageRank. 47 3.7 Ejemplo de representación de una base de datos de grafos. . . . . . . . . . . . 51 4.1 Vista de capas de la arquitectura de Graphly. . . . . . . . . . . . . . . . . . . . 60 4.2 Pilas UDP y TCP en Graphly. . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 4.3 Un ejemplo de las abstracciones de clúster y workers desplegados en nodos. . . 63 4.4 Flujo de trabajo para la creación de RPCs en Graphly. . . . . . . . . . . . . . . 63 4.5 Componentes que intervienen en una operación getProperty de ejemplo en el almacén de grafos de Graphly. . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.6 El flujo de trabajo de Fork-Join de Graphly. . . . . . . . . . . . . . . . . . . . 67 4.7 El flujo de trabajo de Pregel en Graphly. . . . . . . . . . . . . . . . . . . . . . 70 4.8 Flujo de trabajo del modelo Distributed Partitioned Merge. . . . . . . . . . . . 72 5.1 Ejemplo de recorrido en TFR. . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5.2 Frecuencia de Seguidores y Seguidos ajustados a una ley de potencias con alfa 2.276. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 x 99 Función de complemento acumulado (CCDF) de Seguidos (en azul) y Seguidores (en rojo) alineado a una distribución de ley de potencias con alfa 2.276. . . . . 100 5.4 Resultados experimentales de TFR. . . . . . . . . . . . . . . . . . . . . . . . 107 5.5 Resultados normalizados de TFR con respecto a FJ. . . . . . . . . . . . . . . . 109 5.6 Resultados de Katz. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 5.7 Resultados normalizados de Katz con respecto a FJ.. . . . . . . . . . . . . . . 111 5.8 Resultados de LocalPath. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 5.9 Resultados normalizados de LocalPath con respecto a FJ. . . . . . . . . . . . . 113 5.10 Resultados de FriendLink. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 5.11 Resultados normalizados de FriendLink con respecto a FJ. . . . . . . . . . . . 116 5.12 Resultados de algoritmos basados en vecinos. . . . . . . . . . . . . . . . . . . 118 5.13 Ejemplo de asignación utilizando C RITERIA M APPER. . . . . . . . . . . . . . 119 5.14 TFR per-node memory usage using Fork-Join for user Fol3 . . . . . . . . . . . 121 5.15 Utilización de red por nodo en TFR utilizando FJ para el usuario Fol3 . . . . . 122 5.16 Uso total de memoria en TFR por modelo de procesamiento, para el usuario Fol3 124 5.17 Uso total de red de TFR por modelo de procesamiento para el usuario Fol3 . . . 125 5.18 Resultados de TFR utilizando diferentes estrategias de mapeo para el escenario 1. 127 5.19 Resultados de TFR utilizando diferentes estrategias de mapeo para el escenario 2. 128 6.1 Resultados de HITS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 6.2 Resultados normalizados de HITS con respecto a FJ. . . . . . . . . . . . . . . 143 6.3 Resultados de SALSA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 6.4 Resultados normalizados de SALSA con respecto a FJ. . . . . . . . . . . . . . 146 6.5 Uso de memoria de HITS por nodo para cada estrategia de mapeo. . . . . . . . 148 6.6 Uso de red de HITS por nodo, por estrategia de mapeo. . . . . . . . . . . . . . 149 6.7 Uso de memoria de HITS para cada modelo y estrategia de mapeo. . . . . . . . 152 6.8 Uso de red de HITS para FJ, Pregel y DPM. . . . . . . . . . . . . . . . . . . . 153 6.9 Resultados de HITS para cada estrategia para el escenario 1. . . . . . . . . . . 155 6.10 Resultados de HITS para cada estrategia para el escenario 2. . . . . . . . . . . 157 A.1 Ejemplo de hashing consistente con nodos virtuales. . . . . . . . . . . . . . . . 177 A.2 Ejemplo de Virtual Buckets usando 3 servidores, un vBucket de tamaño 5 y un esquema de replicación 1 : N. . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 A.3 Estructuras SSTable, Tablet y Table. . . . . . . . . . . . . . . . . . . . . . . . 184 A.4 Diagrama operativo de un servidor de Tablet. . . . . . . . . . . . . . . . . . . 185 xi Índice de Tablas 3.1 Comparación de Bases de Datos de Grafos. . . . . . . . . . . . . . . . . . . . 54 4.1 Algoritmos de predicción de enlaces ofrecidos en Graphly. . . . . . . . . . . . 79 5.1 Selección de usuarios objetivo de la recomendación. . . . . . . . . . . . . . . . 102 5.2 Características de hardware del clúster. . . . . . . . . . . . . . . . . . . . . . . 103 5.3 Configuración de algoritmos basasados en caminos. . . . . . . . . . . . . . . . 104 5.4 Tamaño final del subgrafo explorado en la ejecución de cada algorítmo (en millones de vértices). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.1 Tamaños de Subgrafos para HITS y SALSA. . . . . . . . . . . . . . . . . . . . 140 6.2 Tabla de decisión para cada combinación de estrategia y modelo. . . . . . . . . 160 A.1 Bases de datos analizadas agrupadas por categoría . . . . . . . . . . . . . . . . 171 A.2 Agrupamiento de sistemas NoSQL de acuerdo al modelo de datos y propiedades CAP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 A.3 Configuraciones de consistencia eventual. . . . . . . . . . . . . . . . . . . . . 175 A.4 Comparación de bases de datos Clave-Valor. . . . . . . . . . . . . . . . . . . . 182 A.5 Características de las bases de datos orientadas a columnas. . . . . . . . . . . 188 . . . . . . . . . . . 194 A.6 Comparación de bases de datos orientadas a documentos. xii Listados de código 3.1 Ejemplo de PageRank bajo el modelo Pregel. . . . . . . . . . . . . . . . . . . 40 4.1 Ejemplo de conteo de tweets implementado en Graphly. . . . . . . . . . . . . . 67 4.2 Ejemplo de estrategia de mapeo Round Robin . . . . . . . . . . . . . . . . . . 75 4.3 Un ejemplo de recorrido iniciando en el vértice 1000. . . . . . . . . . . . . . . 77 4.4 Pagerank utilizando la API de modelos. . . . . . . . . . . . . . . . . . . . . . 78 5.1 TFR implementada utilizando la API de recorridos. . . . . . . . . . . . . . . . 84 5.2 Implementación en Graphly del algoritmo Count. . . . . . . . . . . . . . . . . 85 5.3 Implementación Pregel del algoritmo TFR. . . . . . . . . . . . . . . . . . . . 87 5.4 Implementación en DPM de Count. . . . . . . . . . . . . . . . . . . . . . . . 87 5.5 Algoritmo Count en FJ utilizando un Beta personalizable. . . . . . . . . . . . . 88 5.6 Implementación en Pregel de Katz. . . . . . . . . . . . . . . . . . . . . . . . . 89 5.7 Implementación en DPM de Katz. . . . . . . . . . . . . . . . . . . . . . . . . 90 5.8 Implementación de Beta de LocalPath. . . . . . . . . . . . . . . . . . . . . . . 90 5.9 Implementación en Pregel de LocalPath. . . . . . . . . . . . . . . . . . . . . . 91 5.10 Implementación de Beta de FriendLink. . . . . . . . . . . . . . . . . . . . . . 91 5.11 Implementación en Pregel de FriendLink. . . . . . . . . . . . . . . . . . . . . 92 5.12 Algoritmo de intersección en FJ. . . . . . . . . . . . . . . . . . . . . . . . . . 93 5.13 Implementación en Pregel de Common Neighbours. . . . . . . . . . . . . . . . 94 5.14 Implementación en FJ de Adamic Adar. . . . . . . . . . . . . . . . . . . . . . 95 5.15 Implementación en Pregel de Adamic Adar. . . . . . . . . . . . . . . . . . . . 95 5.16 Implementación en FJ de Jaccard. . . . . . . . . . . . . . . . . . . . . . . . . 96 5.17 Implementación en Pregel de Jaccard. . . . . . . . . . . . . . . . . . . . . . . 96 6.1 Implementación en Pregel de HITS. . . . . . . . . . . . . . . . . . . . . . . . 133 6.2 Implementación en FJ de HITS. . . . . . . . . . . . . . . . . . . . . . . . . . 134 6.3 Implementación en Pregel de SALSA. . . . . . . . . . . . . . . . . . . . . . . 136 6.4 Implementación del Trabajo FJ de SALSA. . . . . . . . . . . . . . . . . . . . 137 xiii Acrónimos API Application Programming Interface BSP Bulk-Synchronous Parallel CCDF Complemented Cumulative Distribution Function DPM Distributed Partitioned Merge DS Distributed System FJ Fork-Join GFS Google File System HDFS Hadoop File System JVM Java Virtual Machine MP Message Processor MVCC Multiple Version Concurrency Control OS Operating System PR PageRank PPR Personalized PageRank RDD Resilient Distributed Datasets RDF Resource Description Framework RPC Remote Procedure Call RS Recommender System RW Random Walk xiv SN Social Network SNA Social Network Analysis SPOC Subject, Predicate, Object, Context representation SRS Social Recommender System WTF Who-to-Follow xv 1 Introducción E N LOS ÚLTIMOS AÑOS , se ha dedicado considerable atención al diseño y desarrollo de Sis- temas de Recomendación (RS, del inglés Recommender Systems) (Bobadilla et al., 2013) que alivien la sobrecarga de información sobre los usuarios en la Web. Con la aparición de la Web Social, los RSs han ayudado a los usuarios a hacer frente a la abrumadora cantidad de contenido que se intercambia a través de medios de comunicación social, incluyendo mensajes, opiniones, fotos, videos y documentos. De hecho, los SRs se han convertido en una herramienta de vital importancia para hacer frente al crecimiento exponencial de las redes sociales en línea (OSN, del inglés Online Social Networks), mejorando la experiencia del usuario con estos sitios mediante la recomendación de personas, eventos o noticias de interés. Los sistemas de recomendación basados en redes sociales exploran la estructura de la red subyacente al usuario (representada por el grafo de usuarios y sus relaciones) con el objetivo de descubrir nuevos elementos que se resumen, se clasifican y, por último, se presentan en forma de sugerencias. Uno de los problemas de recomendación más destacados en OSN es la sugerencia de amigos, contactos o seguidores; siendo estos últimos roles dependientes de la naturaleza de las relaciones de la red social. Relaciones de amistad en Facebook1 o Foursquare2 , relaciones de seguidores en Twitter3 o Sina Weibo4 , relaciones de confianza en Epinions5 y relaciones de colaboración en LinkedIn6 o GitHub7 , son ejemplos de algunas conexiones que surgieron como consecuencia de la Web Social. La recomendación de personas cumple múltiples propósitos, incluyendo la reducción del esfuerzos de los usuarios en la creación de sus propias redes personales, la mejora de la calidad de 1 Facebook, http://www.facebook.com/ http://foursquare.com/ 3 Twitter, http://www.twitter.com/ 4 Tencent Sina Weibo, http://www.weibo.com/ 5 Epinions, http://www.epinions.com/ 6 LinkedIn, http://www.linkedin.com/ 7 GitHub, http://www.github.com/ 2 Foursquare, 1 of 206 CHAPTER 1. INTRODUCCIÓN la participación de los usuarios con las OSN y contribuye en la expansión de la red. Por ejemplo, se ha informado que el servicio de recomendación "WhoToFollow" de Twitter es responsable de más de una octava parte de todas las nuevas conexiones en la red social y ha sido uno de los principales impulsores en las ganancias de la empresa (Goel et al., 2015). En general, el problema de crear sugerencias a usuarios en una red social se puede interpretar como un problema predicción de enlaces (Liben-Nowell and Kleinberg, 2007) en el cual se trata de predecir relaciones inexistentes o perdidas entre personas de la red. El problema de predicción de enlaces en redes complejas ha llamado mucho la atención en los últimos años debido a su gran potencial para aplicaciones reales en las redes sociales de hoy en día. Los algoritmos más populares utilizan métricas de similitud basadas en la información de los nodos del grafo y en la topología de la red para predecir la existencia de vínculos. Entre los tipos de algoritmo más populares se encuentran los algoritmos basados en vecinos (neighbour-based), basados en caminos (path-based) o basados en caminatas aleatorias (random walk-based) (Armentano et al., 2012; Carullo et al., 2015; Chen et al., 2016; Gupta et al., 2013; Hannon et al., 2011; Papadimitriou et al., 2011). El cómputo de los algoritmos de predicción de enlaces en redes sociales del mundo real plantea retos en cuanto a la escalabilidad del algoritmo de recomendación, ya sea en términos de los recursos necesarios (es decir, memoria RAM, uso de núcleos de CPU) y los requisitos de rendimiento (por ejemplo, para proporcionar recomendaciones en tiempo real). Los usuarios de OSN de hoy, generan enormes cantidades de datos, incluyendo mensajes de texto, fotos, videos, entre otros ítems. Incluso la red social subyacente que conecta a los usuarios y los ítems está en constante evolución y crecimiento. A modo de ejemplo, Facebook tiene 801 millones de usuarios activos diarios que suben más de 500 TB de almacenamiento de datos de Facebook. Del mismo modo, a partir de marzo de 2014, 240 millones de usuarios activos de Twitter se generaron 500 millones de tweets por día. Esta situación impulsó a la industria y la academia a desarrollar nuevas técnicas y herramientas para almacenar y procesar grandes cantidades de datos. En la literatura, el término Big Data (Zikopoulos and Eaton, 2011) fue acuñado para referirse a la gestión de datos a gran escala, incluyendo su análisis y las plataformas de soporte correspondientes. Las OSN son una de las fuentes más importantes de Social Big Data, ya que éstas plataformas permiten a grandes cantidades de individuos interactuar entre sí, proporcionando información acerca de sus preferencias y relaciones(Bello-Orgaz et al., 2016). La mayor parte de los algoritmos de predicción de enlaces, tanto comerciales como aquellos desarrollados en el ámbito académico, se han implementado como aplicaciones en una sola máquina, y en algunos casos, soportando un único hilo de ejecución (Durand et al., 2013; Guo and Lu, 2007; Jing et al., 2014; Rausch et al., 2014; Wang et al., 2014). En consecuencia, estas implementaciones sufren problemas de escalabilidad cuando el grafo social a procesar proviene de OSNs del mundo real, pobladas por miles de usuarios. Incluso el desarrollo del servicio de 2 of 206 CHAPTER 1. INTRODUCCIÓN Twitter WhoToFollow se llevó a cabo en una sola máquina para reducir la complejidad arquitectónica (Gupta et al., 2013), y por ello sus autores admiten limitaciones en la escalabilidad de todo el sistema. Sin embargo, algunas implementaciones de una solo máquina, permiten el procesamiento de conjuntos de datos cada vez más grandes a través del escalado vertical, que consiste en la adición de más recursos, tales como CPU o memoria RAM a un sistema existente. El algoritmo, por lo tanto, puede utilizar más hilos y más memoria para aprovechar el nuevo hardware. Sin embargo, este tipo de escalado es costoso en términos de adquisición de hardware, y ha requerido tradicionalmente el uso de supercomputadoras. Por otra parte, la propia extensibilidad del hardware impone un límite duro en el escalado vertical. El escalado horizontal, por otro lado, consiste en añadir más computadoras a un sistema en red, formando un grupo de computadoras. El escalamiento horizontal introduce un método para escalar soluciones más simple y rentable, pero requiere un software más complejo que soporte un ambiente distribuido. El desarrollo de estos sistemas suele acarrear consigo una serie de problemas que son a menudo ignorados por los recién llegados al área. Dichos problemas suelen presentarse como una serie de falacias que, equivocadamente, los desarrolladores suelen dan como ciertas. Éstas falacias de la computación distribuida (Goff, 2003) se presentan, de forma resumida, a continuación: • La red es fiable: La pérdida de paquetes de información es común entre las máquinas conectadas en red y el diseño del sistema distribuido debe afrontar este hecho. • La latencia es cero: La latencia es uno de los factores más relevantes en la performance en entornos de red. El envío de un paquete a través de una red es muchos órdenes de magnitud más lento que la transferencia de datos en la memoria RAM local. Por ello, los sistemas distribuidos deben evitar hacer varias llamadas distribuidas de tamaño pequeño a menos que sea necesario. Un escenario recurrente en la que se desestima la latencia aparece al utilizar llamadas a procedimiento remoto (RPC), donde la invocación distribuida se enmascara detrás de una simple llamada a función local. El desarrollador debe tener cuidado de no esperar que las llamadas RPC se comporten como llamadas de la memoria local. • El ancho de banda es infinita: Otro aspecto importante del desarrollo distribuido es que, aunque el ancho de banda es cada día mayor, no es infinito, y las aplicaciones debe diseñarse cuidadosamente para evitar la sobrecarga de la red. • El costo del transporte es cero: La conversión a representaciones de bytes, y viceversa, no es una tarea sencilla y barata, y por lo tanto, debe tenerse en cuenta en el diseño de una aplicación distribuida. • La red es homogénea: no todos los equipos del clúster tienen las mismas características de hardware y la aplicación deben ser diseñados con ese concepto en mente. Los desarrolladores en entornos distribuidos no sólo tienen que tener en cuenta los mecanismos para la distribución de los datos de entrada y los resultados, sino que también deben tener en 3 of 206 CHAPTER 1. INTRODUCCIÓN cuenta estas limitaciones conocidas de las redes de computadoras a fin de producir un algoritmo eficiente y robusto. Aquelos enfoques ad-hoc para el desarrollo de algoritmos distribuidos tienen la ventaja de estar especialmente adaptados y ajustados a la tarea en cuestión. Sin embargo, estas soluciones implican generalmente mezclar el código del algoritmo con código de programación distribuida, tal como la gestión de la conexión de red y la codificación de datos, por lo que la puesta en práctica de estos enfoques es muy propensa a errores y difícil de mantener. En general, la adaptación del algoritmo a un framework de procesamiento distribuido existente es mucho más fácil y modificable que el desarrollo de una solución ad-hoc. En el contexto de las redes sociales, la elección más natural para manejar grandes cantidades de datos interconectados y distribuidos son las bases de datos de grafos y los frameworks para el procesamiento de algoritmos basados en grafos. Estos sistemas han adquirido un gran interés por parte de empresas e instituciones académicas que necesitan manejar grandes cantidades de datos interconectados como los datos sociales y los datos geo-espaciales. La cantidad de datos almacenados y consultados por este tipo de aplicaciones hace que las bases de datos tradicionales e incluso las NoSQL (Cattell, 2011; Leavitt, 2010) sean soluciones inviables para hacer frente a los niveles de rendimiento necesarios. Las bases de datos distribuidas para grafos se centran en la representación, almacenamiento y consulta eficiente del grafo, pero por lo general no incluyen características de procesamiento. De hecho, las consultas a menudo se limitan a recorridos sencillos y filtrado de resultados, impidiendo el desarrollo de algoritmos de recomendación más complejos directamente sobre la base de datos. Por otra parte, los frameworks de procesamiento distribuido proporcionan facilidades para desarrollar algoritmos mediante la abstracción de los mecanismos de distribución subyacentes. Estos frameworks suelen imponer un modelo de procesamiento que promueve un uso eficiente de la red subyacente. Un modelo de procesamiento dicta la forma en que los desarrolladores deben escribir sus algoritmos, lo que involucra adaptar el código a las características del modelo. Por ejemplo, en sistemas distribuidos, un modelo de procesamiento popular es MapReduce (Dean and Ghemawat, 2008) en el cual el algoritmo debe ser dividido en dos partes: una función Map y una función Reduce. Algunos algoritmos, especialmente los del tipo divide y conquista, encajan muy bien en este modelo. Sin embargo, los algoritmos iterativos que realizan modificaciones en los mismos datos a través de múltiples pasos son más difíciles de adaptarse a MapReduce, y pueden resultar en una solución ineficiente. Los frameworks de procesamiento de grafos distribuidos actuales tienen sus inconvenientes. Dichos frameworks normalmente cargan los datos de un almacén persistente y luego construyen una representación en memoria del grafo. En clústers donde la memoria RAM es escasa, esta funcionalidad impone un límite duro del tamaño del grafo a ser procesado. Además, muchos algoritmos de grafos requieren estructuras de datos auxiliares en memoria para manejar los resultados intermedios, aumentando aún más la cantidad de memoria necesaria para procesar el 4 of 206 CHAPTER 1. INTRODUCCIÓN grafo. Otra situación que no suele abordarse por frameworks de procesamiento es distribuir el cómputo de acuerdo a las características del clúster, por ejemplo, de acuerdo a la memoria RAM disponible o los núcleos de número de CPU. En relación con al soporte para el diseño de algoritmos, la mayoría de los frameworks suelen proporcionar un único modelo de procesamiento. Sin embargo, los algoritmos de grafos responden a diferentes estilos de programación, como divide y conquista o la programación dinámica, que podría no encajar bien en un modelo dado. Por ello, la selección del modelo impacta sobre la complejidad del código del algoritmo y su posterior mantenimiento. Además, debido a que cada framework implementa su propio modelo, es difícil realizar una comparación justa e imparcial entre los diferentes modelos disponibles. 1.1 Motivación Esta tesis se centra en el problema de soportar el desarrollo de algoritmos distribuidos de predicción de enlaces en redes sociales a gran escala. Aunque el foco principal se encuentra en la recomendación de personas en OSN basadas en la amistad (Corbellini et al., 2012; Tommasel et al., 2015) (e.g., Facebook o Twitter), las técnicas propuestas son aplicables a los grafos sociales subyacentes a otros tipos de redes como OSN de geolocalización (Bao et al., 2015) (por ejemplo, Foursquare) y aquellas basadas en folksonomías (Godoy and Corbellini, 2015) (por ejemplo Flickr). La motivación detrás de esta tesis se puede dividir en diferentes temas, de acuerdo a las problemas abordados. Modelado de algoritmos de grafo Los frameworks de procesamiento actuales para el desarrollo de algoritmos basados en grafos son a menudo diseñados con un único modelo de procesamiento en mente. El soporte de múltiples modelos de procesamiento ayuda al desarrollador a elegir el modelo que se ajuste más naturalmente con el algoritmo que se está desarrollando. Además, la evaluación de más de un modelo puede ayudar a encontrar la alternativa con mejores resultados, con la ventaja de que la comparación se realiza sobre el mismo soporte distribuido (compartiendo, por ejemplo, el soporte de red, particionado de datos, la representación de datos). Adaptación a las características del clúster Los grandes centros de cómputo a menudo poseen hardware con una gran cantidad de memoria RAM y potencia de CPU. La mayoría de los nodos del clúster son idénticos, y si hay diferencias entre los nodos, no es perceptible. En pequeños grupos, sin embargo, los equipos se agregan al clúster en el transcurso de los años y, por tanto, las diferencias en sus características son significativas. Proporcionar herramientas para permitir a los desarrolladores ajustar sus algoritmos a las características actuales de un grupo es vital para el rendimiento de los algoritmos. Por ejem1.1. MOTIVACIÓN 5 of 206 CHAPTER 1. INTRODUCCIÓN plo, si el algoritmo require mucha RAM, ajustar cuidadosamente la distribución del trabajo del algoritmo de acuerdo con las características de memoria RAM de los nodos podrían mejorar su rendimiento y, en algunos casos, en los que la RAM es muy limitada, puede permitir completar la ejecución del algoritmo. Persistencia del Grafo Muchas plataformas de procesamiento no permiten almacenar y escribir datos en soportes persistentes, por lo que la mayor parte del procesamiento se realiza en la memoria RAM. En pequeños clústers, esto puede ser un factor limitante en cuanto a la cantidad de memoria que se puede asignar a las propias necesidades de procesamiento de algoritmos. Una base de datos de grafos persistente es importante en este escenario para dedicar toda la memoria RAM al algoritmo. Si bien los soportes masivos de almacenamiento suelen ser lentos, en la mayoría de los casos, el impacto en el rendimiento se puede reducir mediante el uso de estrategias de almacenamiento en caché. API de Recomendación Una de las principales motivaciones de este trabajo es la necesidad de un framework de recomendación para desarrollar, evaluar y probar algoritmos de recomendación novedosos. Las APIs para el diseño de algoritmos de grafos distribuidos no proporcionan abstracciones para los propósitos de realizar recomendaciones, dejando todo el trabajo a los desarrolladores. Una API de recomendación sobre grafos que permita reutilizar y extender algoritmos existentes es muy importante para la creación de nuevos algoritmos. Facilidad de Uso La mayoría de las plataformas de procesamiento y almacenamiento requieren un esfuerzo sustancial de configuración antes de comenzar a desarrollar algoritmos. Mientras que estas plataformas ofrecen alta disponibilidad y garantías de seguridad, los algoritmos de investigación experimentales no están pensados para su uso "en producción" y, en consecuencia, no necesitan esas garantías. 1.2 Propuesta Esta tesis propone nuevos mecanismos para el desarrollo de algoritmos de recomendación basados en grafos distribuidos y una plataforma, llamada Graphly (Corbellini, 2015; Corbellini et al., 2015a,b), que implementa estos mecanismos. Graphly es un framework de procesamiento distribuido de grafos que proporciona un soporte persistente y soporte a modelos de procesamiento 6 of 206 1.2. PROPUESTA CHAPTER 1. INTRODUCCIÓN de grafos. En su núcleo, Graphly ofrece herramientas de bajo nivel para la distribución y procesamiento de trabajos, además de proporcionar servicios de nivel intermedio, como el descubrimiento de nodos y detección de fallos de ejecución. El soporte de procesamiento distribuido implementado en Graphly consta de dos mecanismos relacionados: modelos de procesamiento y estrategias de asignación. Un modelo de procesamiento proporciona un estilo de programación que el usuario debe seguir y un soporte subyacente que implementa los mecanismos de programación distribuida. Además de proporcionar soporte para múltiples modelos de procesamiento, Graphly introduce estrategias de asignación, un novedoso mecanismo no invasivo que ayuda a personalizar la distribución de las tareas de acuerdo a un criterio definido por el usuario. Las estrategias de mapeo se pueden configurar independientemente de cualquiera de los modelos de procesamiento, y por lo tanto proporcionan un mecanismo transparente que no requiere modificar el código algoritmo original ni el diseño de datos de almacenamiento para la personalización de asignación de tareas. Los aspectos más relevantes de Graphly, que también son los principales aportes de esta tesis, se resumen a continuación: Base de Datos de Grafos La base de datos distribuida integrada en Graphly permite a los algoritmos usar la mayor parte de la memoria principal del clúster para el procesamiento de resultados. En cada nodo donde se ejecuta Graphly, se asigna una parte de la base de datos con el objetivo de almacenar las propiedades y las listas de adyacencia de una sección del grafo. Soporte para múltiples modelos En cuanto a los modelos de procesamiento, Graphly soporta tres modelos de procesamiento de grafo diferentes. Los dos primeros modelos son los conocidos Fork-Join y Pregel. Fork-Join (FJ) (Mateos et al., 2010) ofrece un estilo de programación divide y conquista clásico, en el que el procesamiento de vértices es administrado por un único nodo "padre" encargado de distribuir tareas a los demás nodos y unir los resultados de esas tareas. Aunque Fork-Join es un modelo de procesamiento distribuido genérico, su implementación bajo Graphly ofrece utilidades para el procesamiento de grafos. Pregel (Malewicz et al., 2010), por otro lado, proporciona un estilo de programación basado en vértices y distribuye la unión de los resultados entre todos los nodos. El tercer modelo de procesamiento es una modelo nuevo propuesto en esta tesis, denominado Distributed Partitioned Merge (DPM) (Corbellini et al., 2015a). DPM proporciona un estilo de programación similar a FJ, pero distribuye la unión de los resultados entre todos los nodos del clúster. Además de proporcionar abstracciones de los mecanismos distribuidos, los modelos de procesamiento ayudan a lograr un uso eficiente del clúster mediante la gestión de las invocaciones remotas del usuario y, por lo tanto, garantiza un correcto uso de los recursos de la red. 1.2. PROPUESTA 7 of 206 CHAPTER 1. INTRODUCCIÓN Como se mencionó antes, en un entorno distribuido, la red de computadoras representa un recurso importante que se debe utilizar con cuidado. La implementación de varios algoritmos de predicción de enlaces conocidos se llevaron a cabo en los tres modelos para comparar qué tan bien se ajusta cada modelo al tipo de algoritmo y cómo impacta la elección de un modelo en el rendimiento final. Estrategias de Asignación Las estrategias de asignación (Corbellini et al., 2013) abordan el problema de la adaptar la ejecución distribuida a las características del clúster de computadoras. Estas estrategias pueden ser vistas como una combinación de un esquema de particionado (es decir, una división de los vértices del grafo) y una estrategia de asignación de nodos. La idea principal es asignar listas de vértices de acuerdo a diferentes criterios, tales como la ubicación de los datos del grafo o las capacidades de hardware (por ejemplo, memoria RAM). A través de este mecanismo, Graphly permite al desarrollador configurar la distribución de trabajo en función del entorno de ejecución actual. En la mayoría de los soportes, se trata de ajustar el algoritmo original o la disposición de los datos (de la base de datos) a las preferencias del usuario, lo que implica un esfuerzo adicional o directamente impráctico. Las estrategias de asignación proporcionan una forma no invasiva de personalizar el procesamiento de tareas sin necesidad de modificar el código del algoritmo original ni la disposición de los datos del soporte de almacenamiento. En esencia, estas estrategias proporcionan un puente entre los algoritmos expresados a través de la API de alto nivel y las características del clúster. Graphly soporta dos tipos de estrategias: estrategias estáticas y estrategias dinámicas. Un ejemplo de una estrategia estática es la estrategia que utiliza la ubicación de los datos del grafo para asignar tareas y, por tanto, siempre asignar trabajos a los mismos nodos. Por otro lado, una estrategia que utiliza el estado actual del uso de la RAM para llevar a cabo la asignación de trabajo es un ejemplo de la estrategia dinámica. API provista por Graphly Graphly oculta todas los mecanismos destinados al procesamiento distribuido detrás de dos APIs (Corbellini et al., 2014): Una API de recorridos y una API de modelos. La API de recorridos proporciona una interfaz simple de consulta para acceder a los datos del grafo. Por otra parte, establece la base para el desarrollo de otras APIs, permitiendo consultas compuestas que encadenan resultados de diferentes algoritmos. La API de modelos es compatible con el desarrollo de algoritmos que utilizan los modelos de procesamiento de alto nivel como el Fork-Join, Pregel y el modelo DPM propuesto. 8 of 206 1.2. PROPUESTA CHAPTER 1. INTRODUCCIÓN GraphRec La API de mayor nivel de abstracción en Graphly es un interfaz de recomendación que implementa algoritmos conocidos de recomendación (random-walks, common neighbours, entre otros), y ofrece dichos algoritmos como primitivas para implementar algoritmos más complejos. Construido sobre las APIs de modelos y recorridos, GraphRec ofrece un conjunto de herramientas para el desarrollo de algoritmos de recomendación complejos con el objetivo de fomentar el desarrollo de nuevos algoritmos que se puedan implementar y evaluar sobre grandes conjuntos de datos. 1.3 Organización El resto de esta tesis se organiza de la siguiente manera: • El Capítulo 2 repasa algunos temas de fondo utilizados como base para esta tesis, • El Capítulo 3 explora el trabajo relacionado con respecto a modelos de procesamiento, frameworks y bases de datos, y las APIs de recomendación para grafos, • El Capítulo 4 presenta Graphly, incluyendo su diseño e implementación, • El Capítulo 5 describe los mecanismos de soporte proporcionados por Graphly para el desarrollo de algoritmos predicción de enlaces basados en caminos y basados en la ruta de acceso, junto a la experimentación relacionada al uso de diferentes modelos de procesamiento y estrategias de asignación, • El Capítulo 6 describe los mecanismos de soporte proporcionados por Graphly para el desarrollo de algoritmos basados en caminatas aleatorias, la experimentación que determina qué tan bien cada modelo propuesto se ajusta a cada algoritmo y algunos escenarios donde las estrategias de asignación resultaron útiles, • El Capítulo 7 exhibe algunas conclusiones, entre ellas las ventajas de la plataforma distribuida propuesta para el desarrollo de algoritmos de recomendación sobre redes sociales, sus limitaciones y el trabajo futuro. 1.3. ORGANIZACIÓN 9 of 206 Conceptos Relacionados 2 Los Sistemas de Recomendación (RSs) han atraído una creciente atención en los últimos años debido a la creciente popularidad de la Web y más tarde la Web Social, caracterizado por los sitios de redes sociales que permiten a millones de usuarios comunicarse, intercambiar opiniones y compartir contenido generado por ellos mismos (por ejemplo, fotos, videos y documentos). El uso generalizado e interés en las redes sociales, como Facebook o Twitter, plantean nuevos desafíos a los enfoques tradicionales para la construcción de sistemas de recomendación donde las relaciones sociales tienen un papel destacado. La información acerca de los vínculos sociales y su semántica es explotada por los sistemas de recomendación basados en redes sociales para proporcionar diversos tipos de recomendaciones. Por ejemplo, recomendar lugares para visitar en una red social de viajeros como TripAdvisor1 , mediante el uso de información sobre los lugares visitados por las amistades del usuario; o recomendar gente que un usuario puede estar interesado en seguir en una red social de seguidores como Twitter, mediante la obtención de los intereses a partir de sus mensajes de Twitter o los usuarios que él/ella sigue. Estas técnicas no sólo ayudan a aumentar la conectividad entre los usuarios, sino también a fomentar la adopción y el crecimiento del sistema. Este capítulo presenta los fundamentos teóricos relacionados con los sistemas de recomendación, los sistemas de recomendación basados en redes sociales y el problema de predicción de enlaces como un medio para generar sugerencias sobre personas. La Sección 2.1 introduce brevemente los RSs, los principales enfoques para la construcción de estos sistemas y sus aplicaciones. Los RSs basados en redes sociales se discuten en la Sección 2.2 y se describen varias obras en la literatura en relación al problema de la recomendación de amigos y followees (i.e., usuarios seguidos). Métodos y algoritmos para la predicción de enlaces que se utilizan más adelante en esta tesis se introducen en la Sección 2.3. 1 TripAdvisor, 10 of 206 http://www.tripadvisor.com/ CHAPTER 2. CONCEPTOS RELACIONADOS 2.1 Sistemas de Recomendación Los Sistemas de Recomendación (RSs) abarcan a un conjunto de herramientas y técnicas que proporcionan sugerencias para los artículos más adecuados (productos o servicios) a determinados usuarios (individuos o empresas) por la predicción de interés de un usuario en un elemento de software (Ricci et al., 2010). Una predicción puede basarse en la información relacionada acerca de los elementos, las preferencias de los usuarios y/o las interacciones entre los elementos y los usuarios (Bobadilla et al., 2013). Estas sugerencias pueden ayudar a diversos procesos de toma de decisiones, como qué artículos comprar, qué música escuchar, o que noticias leer. Las recomendaciones suelen ser personalizadas, es decir, diferentes usuarios o grupos de usuarios reciben sugerencias diferentes. Las recomendaciones no personalizadas son más fáciles de generar, pero más genéricas (por ejemplo, sugerir los diez primeros artículos para leer en un sitio Web de un sitio de noticias), y no son normalmente atacadas por la investigación en RSs (Ricci et al., 2010). Por lo general, las sugerencias se presentan a los usuarios en forma de una lista ordenada de ítems. Los sistemas de recomendación hacen predicciones sobre artículos mediante el aprovechamiento de múltiples fuentes de información y, posiblemente, considerando el contexto del usuario o tarea en cuestión (por ejemplo, sugiriendo páginas Web mientras el usuario está navegando, o productos similares al que el usuario está inspeccionando o ya ha comprado). Los sistemas de recomendación se han convertido en un área importante de investigación desde la aparición de los primeros trabajos a mediados de la década de 1990 (Adomavicius and Tuzhilin, 2005). La idea básica de los primeros RSs, tales como la Tapestry (Goldberg et al., 1992), GroupLens (Resnick et al., 1994) y Ringo (Shardanand and Maes, 1995), era la de imitar el proceso de recomendación boca-a-boca humano. En el mundo real, la gente confía en el consejo de amigos, colegas y personas estrechamente relacionadas, y actúan de acuerdo con las opiniones y juicios recogidos. Los RSs han demostrado ser útiles para ayudar a los usuarios a hacer frente a la cantidad posiblemente abrumadora de artículos ofrecidos por un sistema (por ejemplo, un sitio web de venta de libros, tal como Amazon, que contiene miles de libros). El objetivo principal de RSs es aliviar el problema de la sobrecarga de información, sugiriendo a cada usuario nuevos artículos que puedan ser relevantes para la tarea actual del usuario (por ejemplo, páginas web, libros, películas, etc.). En los últimos años, el interés por los RSs se ha incrementado de manera espectacular ya que se han convertido en un elemento esencial y de gran valor comercial para los sitios de Internet más populares como Amazon2 , YouTube3 , Netflix4 , TripAdvisor, y muchos otros. Los enfoques tradicionales para la construcción de sistemas de recomendación se suelen 2 Amazon, http://www.amazon.com/ http://www.youtube.com/ 4 Netflix, http://www.netflix.com/ 3 YouTube, 2.1. SISTEMAS DE RECOMENDACIÓN 11 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS clasificar en tres grandes categorías: el filtrado basado en contenido, filtrado colaborativo y métodos híbridos (Adomavicius and Tuzhilin, 2005): Filtrado Basado En Contenido El usuario recibe recomendaciones de artículos similares a los que el usuario ha preferido en el pasado (Lops et al., 2010). Este enfoque se basa en la intuición de que cada usuario muestra un comportamiento particular bajo un conjunto dado de circunstancias, y que este comportamiento se repite en circunstancias similares. Entonces, el comportamiento de un usuario se predice a partir de su comportamiento en el pasado (por ejemplo, un usuario es probable que visite una página web similar a los que ha visitado antes). Los método basados en el contenido se basan principalmente en la investigación de recuperación de información y filtrado de información. Filtrado Colaborativo El usuario recibe recomendaciones de ítems que personas con gustos y preferencias similares a él han marcado interesantes (Desrosiers and Karypis, 2011). Este enfoque se basa en la intuición de que la gente dentro de un grupo en particular tienden a comportarse de forma similar en circunstancias similares, por lo que el comportamiento de un usuario se predice a partir del comportamiento de otras personas de ideas afines (por ejemplo, un usuario desea un libro que otros usuarios similares han encontrado interesante). Filtrado Híbrido Varios sistemas de recomendación utilizando enfoques híbridos que combinan métodos basados en contenidos y filtrado colaborativo para superar las limitaciones de ambos (e.g. la sobre-especialización en el filtrado basado en contenido causando que el usuario reciba sugerencias muy similares a las que ya ha visto y el arranque en frío de filtrado colaborativo). Los ámbitos de aplicación de los sistemas de recomendación son diversas. Una de las aplicaciones más fructíferas es el comercio electrónico, en el que los RSs sugieren productos (por ejemplo, libros, música, programas de televisión) a los clientes del sitio y proporcionan información para ayudarles a decidir qué productos comprar en sus tiendas en línea. El turismo es también un dominio adecuado para RSs donde los viajeros reciben sugerencias sobre planes para visitar lugares de interés, alojamientos y servicios. De hecho, los sistemas de recomendación móviles sensibles al contexto prometen enriquecer sustancialmente las experiencias turísticas. Los RSs se han convertido en un elemento importante de muchos sistemas basados en la Web, tales como asistentes de navegación y filtrado de información. Otros campos de aplicación incluyen e-learning, sistemas de bibliotecas, desarrollo de software, juegos, salud, entre muchos otros. 12 of 206 2.1. SISTEMAS DE RECOMENDACIÓN CHAPTER 2. CONCEPTOS RELACIONADOS 2.2 Sistemas de Recomendación Basado en Redes Sociales Los sistemas de recomendación dirigidos al ámbito social han atraído gran atención en los últimos años debido a la aparición de la Web Social, que abarca aplicaciones diseñadas para apoyar y fomentar la interacción social. La adopción masiva de aplicaciones sociales, incluidos los sitios de redes sociales (por ejemplo, Facebook, Twitter, Google+ y Foursquare), sistemas de etiquetado colaborativo (e.g. Delicious5 , Flickr6 o CiteULike7 ) y comunidades online (e.g. LinkedIn y GitHub), ha generado un gran volumen de contenido generado por los usuarios, a través de medios de comunicación social heterogéneos. Encontrar contenido relevante, usuarios u otro contenido es una tarea difícil para los enfoques de recomendación existentes. Las relaciones entre usuarios fueron enriquecidas mediante la interacción de las personas con sus familias, amigos y colegas en la Web, y a través de la posibilidad de comunicar y compartir el contenido creado por el usuario (por ejemplo, fotos, videos y blogs). Las relaciones de amistad en Facebook, las relaciones de seguidor/seguido en Twitter y las relaciones de confianza en Epinions, por ejemplo, son diferentes tipos de relaciones entre las personas que aparecen como consecuencia de la Web Social. 2.2.1 Redes Sociales Las redes sociales (SNs, del inglés Social Networks) son estructuras que consisten en vértices que representan a las personas u otras entidades integrados en un contexto social, y ejes que representa la interacción, colaboración, o alguna otra forma de vinculación entre las entidades (Schall, 2015). En los sitios de redes sociales, los usuarios forman una red social en línea (OSN), que proporciona un poderoso medio para compartir, organizar y encontrar contenido y contactos. El núcleo de estos OSN, formado por perfiles personales de usuarios, que suelen contener información de identificación (por ejemplo, nombre y foto), intereses (por ejemplo, grupos de interés a los que suscribieron), y los contactos personales (por ejemplo, la lista de usuarios conectados, normalmente llamado "amistades") (Heidemann et al., 2012). En algunas redes, se establece un vínculo entre dos personas si ambas personas están de acuerdo en tener una relación de amistad. Esto conduce a una red social sin dirección ya que ambas personas comparten una amistad mutua. Facebook, MySpace8 y LinkedIn son ejemplos de redes sociales no dirigidos. En otros sitios de redes sociales, se forma un enlace si un usuario se suscribe para recibir otras actualizaciones de usuario (es decir, publicaciones). Servicios de microblogging como Twitter o Sina Weibo son un ejemplo, así como las redes de colaboración como GitHub, en la que los usuarios se siguen cuando trabajan en proyectos de mutuo interés. 5 Delicious, http://delicious.com/ http://www.flickr.com/ 7 CiteULike, http://www.citeulike.org/ 8 MySpace, http://www.myspace.com/ 6 Flickr, 2.2. SISTEMAS DE RECOMENDACIÓN BASADO EN REDES SOCIALES 13 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS Estas redes sociales dirigidas permiten a los usuarios seguir a otros y que dicha relación no sea recíproca (por ejemplo, las celebridades suelen ser seguidos por muchos usuarios, pero éstas no siguen a sus seguidores). Mientras que el primer tipo de OSN hace énfasis en las amistades, las últimas son las orientadas a la distribución de información. El uso generalizado de las redes sociales generó una expansión explosiva de las OSNs a ritmos sin precedentes. En estas comunidades en línea, se vuelve cada vez engorroso encontrar nuevos contactos y amigos. En respuesta a este problema, muchas plataformas de redes sociales han comenzado a prestar asistencia a sus usuarios para establecer nuevas relaciones sociales mediante recomendaciones (por ejemplo, "WhoToFollow" el servicio en Twitter o el servicio "People You May Know", o PYMK, de Facebook). En las OSNs, las técnicas de formación de enlaces involucran el descubrimiento y el establecimiento de nuevas relaciones y sus aplicaciones incluyen (Schall, 2015): el establecimiento de nuevas relaciones sociales, el soporte a la formación de comunidades de expertos, formación estratégica de equipos de trabajo y la unión de diferentes comunidades en línea. La recomendación de amigos o followees presenta diferentes retos en el diseño de sistemas de recomendación. A continuación se describen estos dos tipos de recomendación. 2.2.2 Recomendación de Amigos La recomendación de amigos apunta sugerir usuarios en los cuales un usuario objetivo puede estar interesado, es decir, se construyen pares de usuarios que tienen interés mutuo. Se han propuesto varios enfoques en la literatura para descubrir amigos. En su mayoría, los enfoques de recomendación de amigos se basan en el análisis del grafo social, explorando el conjunto de personas vinculadas al usuario objetivo con el fin de elaborar recomendaciones. Los usuarios más cercanos en la red social, como amigos de amigos (e.g., la característica PYMK ofrecida por Facebook), o aquellos usuarios con la probabilidad más alta de ser alcanzados en una caminata aleatoria, son los enfoques más comúnmente utilizados. En esta dirección, Liben-Nowell and Kleinberg (2007) analizan la predicción de enlaces en las redes sociales y la comparación de varios métodos basados en la proximidad del vértice desde un punto de vista puramente topológica. El algoritmo de recomendación de amigos de MySpace se basa en el concepto de personas que tal vez conozcas (PYMK) (Moricz et al., 2010), recorriendo el grafo de usuarios con amigos en común. Backstrom and Leskovec (2011) propusieron un método supervisado de recorridos aleatorios con reinicio que combina características de los vértices con características de los ejes para predecir futuros enlaces en Facebook. Este método aprende a sesgar un recorrido aleatorio, similar al de PageRank (ver Sección 2.3.3), de modo que visite determinados vértices (es decir, los ejemplos de entrenamiento positivos) con más frecuencia que los otros vértices. Otro enfoque para abordar el problema consiste en encontrar usuarios afines mediante la evaluación la similitud de sus perfiles. En (Mazhari et al., 2015) se presenta un modelo para medir las similitudes de dos miembros de la red social sobre la base de la información contenida 14 of 206 2.2. SISTEMAS DE RECOMENDACIÓN BASADO EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS en sus perfiles. A diferencia de otros modelos de similitud de perfiles, este método no asigna el mismo peso a los diferentes elementos de los perfiles, sino que un modelo de minería se utiliza para descubrir el grado de influencia de los diferentes factores que afectan la formación de amistades. Xie (2010) diseñó un framework general para la recomendación de amistades mediante el aprovechamiento de diferentes características basadas en perfiles que puede determinar el interés de los usuarios dependiendo de dos dimensiones: contexto (lugar, tiempo) y contenido, así como también la inclusión de conocimiento del dominio para mejorar la calidad de la recomendación. Las propuestas híbridos aprovechan tanto las conexiones en redes sociales, así como también el contenido generado por el usuario y los perfiles. Por ejemplo, Deng et al. (2012) combinan el algoritmo "friend of a friend" (FOAF) y la recomendación basada en contenido utilizando un algoritmo de agrupamiento. Wan et al. (2013) dirigen la recomendación mediante la noción de utilidad de información, que se define como el grado en que un amigo satisface la necesidad de información insatisfecha del usuario de destino. En este enfoque, los mensajes sociales son vistos como objetos y la calificación para cada post se predice mediante el uso de técnicas de filtrado colaborativo (CF). 2.2.3 Recomendación de Followees La recomendación de followees consiste en hacer sugerencias acerca de quién seguir a los usuarios en redes sociales dirigidas. Las plataformas de microblogging son un ejemplo de redes de información o redes híbridas (Romero and Kleinberg, 2010), situada en la intersección entre redes sociales y redes de información. En estas redes, los usuarios pueden seguir a otros usuarios y suscribirse a los contenidos que publican. Sin embargo, la búsqueda de usuarios interesantes puede ser difícil, especialmente para los nuevos usuarios. Se han propuesto varios algoritmos de recomendación de followees en la literatura que explotan la topología de la red, utilizan medidas de similitud de perfiles para recomendar a los usuarios con las preferencias de información similares, o utilizan medidas de popularidad para encontrar buenas fuentes de información. El mecanismo de recomendación de followees más simple se basa en ordenar los usuarios en función de su influencia y sugerir aquellas personas más influyentes. TwitterRank (Weng et al., 2010), una extensión del algoritmo PageRank (ver Sección 2.3.3), trata de encontrar twitteros influyentes teniendo en cuenta la similitud de de tópicos entre los usuarios, así como la estructura de enlaces. TURank (Yamaguchi et al., 2010) considera el grafo social y el flujo de tweets. Garcia and Amatriain (2010) propusieron un método para ponderar la popularidad y la actividad de los enlaces para la clasificación de usuarios. La recomendación de usuarios, sin embargo, no puede basarse exclusivamente en rankings de influencia generales (basados en todo Twitter) ya que las personas que son populares en Twitter pueden no coincidir necesariamente con los intereses del usuario. En su mayoría, las estrategias de recomendación de followees generan recomendaciones mediante el análisis de la estructura de enlaces de la red de seguidores/seguidos. El servicio "Who 2.2. SISTEMAS DE RECOMENDACIÓN BASADO EN REDES SOCIALES 15 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS To Follow" de Twitter, responsable de más de una octava parte de todas las nuevas conexiones en Twitter (Goel et al., 2015), lleva a cabo una exploración del grafo para identificar el "círculo de confianza" del usuario y luego clasificar a los usuarios de dicho círculo (Gupta et al., 2013). Romero and Kleinberg (2010) realizaron investigaciones respecto a "clausuras dirigida", una forma dirigida de cierre triádico (hay una mayor probabilidad de que una amistad – es decir, una díada – se forme entre dos personas si ya tienen un amigo en común – formando, así, una tríada) en redes de atención e información y se encontró que existen comportamientos diferentes en cuanto a la formación de vínculos en subredes diferentes. Armentano et al. (2012) proponen un recorrido de la red sobre la base de hacer una distinción entre los usuarios que actúan como consumidores de información o fuentes de información (Java et al., 2007; Krishnamurthy et al., 2008). Por lo tanto, un consumidor de información sigue a algunos usuarios de Twitter que le interesan y que actúan como fuentes de información. Otras personas que también siguen estas fuentes (es decir, seguidores de los followees del usuario) probablemente compartan algunos intereses con el usuario objetivo y podrían haber descubierto otras fuentes de información relevante sobre los mismos temas. Este último grupo se compone, entonces, de potenciales candidatos para sugerir al usuario como followees a seguir. En (Zhao et al., 2013) un método basado en LDA sobre las relaciones de seguidores/seguidos se utiliza para descubrir las comunidades de usuarios con influencia e intereses similares. Luego, un método de factorización matrices se aplica en cada una de las comunidades para generar recomendaciones más personalizadas. Yu and Qiu (2014) adaptaron el modelo de factorización matrices de RSs tradicionales para ítems, a recomendación de followees y utilizan una regularización estructural para aprovechar la información topológica de la SN y así restringir el modelo. Los métodos dirigidos por la topología de red suelen ignorar los atributos de los individuos, tales como el contenido de los tweets o las características del perfil , y por lo tanto no puede representar en su completitud la preferencia de los usuarios en los sistemas de microblogging. La recomendación de followees no es exclusivo del dominio de microblogging. En el contexto de las redes sociales basados en localización (LBSNs, del inglés Location-Based Social Networks) como Foursquare, se ha propuesto un método de recomendación de followees basado en información geográfica, textual y social (GTS-FR, del inglés Geographic-TextualSocial Based Followee Recommendation)(Ying et al., 2012). GTS-FR tiene en cuenta los movimientos del usuario, mensajes de texto y propiedades sociales para descubrir la relación entre las necesidades de información de los usuarios y la información requerida para generar la recomendación de followee. GitHub es una plataforma de colaboración social en línea que permite a la gente a trabajar en proyectos públicos o privados. En sitios como GitHub, la gente en su mayoría sigue a otras porque éstas últimas trabajan en proyectos interesantes. Schall (2013) presentó un enfoque de recomendación basada en una métrica de autoridad aprovechando el hecho de que en el desarrollo de software comunidades una autoridad es un experto o gurú en un área específica. La autoridad se calcula en base a las acciones realizadas sobre el repositorio (por ejemplo, las ac16 of 206 2.2. SISTEMAS DE RECOMENDACIÓN BASADO EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS tividades de programación, corrección de errores, etc.) y, así, se genera un ranking personalizado sensible al contexto basado en el grado de autoridad . 2.2.4 Perfilado de Usuarios La construcción de perfiles de usuario (i.e. un conjunto de características que representan los intereses del usuario) es una de las estrategias más utilizadas para formular de recomendaciones. En general, los perfiles de usuario se pueden consultar, clasificar y comparar entre sí con el fin de evaluar la similitud entre los intereses de los usuarios. En el sistema de recomendación Twittomender (Hannon et al., 2010, 2011), múltiples estrategias de perfilado se han utilizado de acuerdo a cómo se representar los usuarios: se utilizó un enfoque basado en el contenido, otro de filtrado colaborativo y dos enfoques híbridos. En este sistema, los perfiles de usuario se indexan y un motor de búsqueda se utiliza para recuperar una lista clasificada de los usuarios de Twitter pertinentes basado en un perfil de usuario de destino o en un conjunto específico de términos de consulta. Sun et al. (2009) propusieron un framework de recomendación de microblogging, basado en la difusión, que identifica a un pequeño número de usuarios que juegan el papel de periodistas y que son recomendados a aquellos solicitantes de información en casos de emergencia. Armentano et al. (2013) combinan una búsqueda topológica de los posibles candidatos para la recomendación con la construcción de perfiles basados en contenidos para el ranking de los usuarios de acuerdo a sus preferencias de información. Carullo et al. (2015) presentó un nuevo esquema de sistema de recomendación que trata de encontrar un equilibrio entre la explotación de los vínculos o relaciones ya existentes, aprovechando el cierre triádico, y las afinidades de interés entre los usuarios, teniendo en cuenta la homofilia. ListRec (Rakesh et al., 2014) captura y modela el interés del usuario en base a contenidos, redes y medidas de trendiness, todos combinados utilizando diferentes esquemas y utilizando un algoritmo de regresión para la estimación de parámetros. Rowe et al. (2012) evaluaron un enfoque para predecir seguidores dentro de una red social dirigida aprovechando grafos conceptuales, descubriendo una afinidad de tópicos entre seguidores y followees. Faralli et al. (2015b) propusieron un método de dos pasos. En primer lugar, los usuarios se perfilan y clasifican en comunidades. Luego, la recomendación se plantea como un problema de minería de conjuntos de ítems con el objetivo de obtener reglas de asociación que permitan recomendar no sólo a quién seguir, sin también qué temas seguir. NDCG-LFM (Chen et al., 2016), un esquema de recomendación de los Top-K followees, está destinado a sistemas de microblogging y está basado en un modelo de factor latente que aprovecha la retroalimentación implícita de los usuarios incluyendo tanto el contenido de los tweets así como también la información de relaciones sociales. 2.2. SISTEMAS DE RECOMENDACIÓN BASADO EN REDES SOCIALES 17 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS 2.3 Predicción de Enlaces en Redes Sociales La predicción de enlaces tiene numerosas aplicaciones potenciales, especialmente con la proliferación de las redes sociales a gran escala. Algunos ejemplos son los RSs que ayudan a la gente a encontrar nuevos amigos, colaboradores potenciales o encontrar expertos o co-autores en las redes sociales académicas, entre muchos otros. La recomendación de amigos o seguidores en sistemas como Facebook o Twitter fomentan la formación de nuevos vínculos y favorecen la difusión de información. Las redes sociales pueden ser vistos como los gráficos, donde vértices representan personas y los enlaces representan sus relaciones. Más formalmente, una red social se modela como un grafo dirigido o no dirigido G(V, E) donde V es el conjunto de vértices del grafo que, a su vez, representan personas y E son los ejes entre vértices que indican relaciones entre personas. El grafo se puede representar ya sea visualmente (es decir, de forma tradicional con puntos y flechas) o con una matriz de adyacencia A, donde los vértices se colocan sobre las filas y las columnas, y los números de la matriz indican la existencia de bordes (y posiblemente, el peso de las relaciones). El análisis espectral de la matriz A, por ejemplo, el análisis de sus valores propios, se conoce como teoría espectral de grafos. Considere una red social G(V, E) en un tiempo t particular, donde V y E son conjuntos de vértices y enlaces, respectivamente. La predicción de enlaces apunta a predecir nuevos vínculos o enlaces eliminados entre vértices para un tiempo futuro t 0 (t 0 > t), o links o enlaces no observados, faltantes(Wang et al., 2015). En otras palabras, el objetivo de la predicción de enlaces es predecir si se establecerá un vínculo entre dos usuarios o si falta un enlace en una red observada parcialmente. El último caso es un problema recurrente cuando la red social es una muestra de la red original (Schall, 2015). Otra aplicación es encontrar relaciones ocultas entre las personas, y así, descubrir la red social "real", por ejemplo, encontrar relaciones ocultas entre sujetos de organizaciones criminales. En términos generales, los métodos de predicción de enlaces se pueden clasificar en (Wang et al., 2015): Enfoques basados en la similitud y enfoques basados en el aprendizaje. Los enfoques basados en la similitud calculan las similitudes de pares no conectados de vértices en una red social basándose en métricas de proximidad de los vértices. A cada potencial par de vértices (x, y) se le asigna una puntuación, y, de esta manera, aquellos pares de mayor puntuación tienen más probabilidades de formar un enlace en el futuro. Los enfoques basados en el aprendizaje representan el problema de predicción de enlaces como una tarea de clasificación binaria (Hasan et al., 2006). Cada par de vértices no conectados corresponde a una instancia incluyendo las características de cada vértice involucrado y una etiqueta de clase; la etiqueta es positiva si existe un vínculo potencial y negativa en caso contrario. Las características de los enfoques de aprendizaje se pueden derivar de la propia red social, por ejemplo, a partir de la información textual extraída de los vértices. 18 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS El método más simple para predicción de enlaces es el algoritmo basado en similitud, donde cada par de vértices, x e y, se le asigna un puntaje sxy , definida directamente como la similitud (también llamado "proximidad" en la literatura) entre x e y (Lü et al., 2009). De esta manera, todos los vínculos entre vértices no conectados en un grafo se clasifican de acuerdo a su similitud, lo que indica su probabilidad de existencia. El cálculo de la similitud entre vértices es un proceso no trivial que se puede hacer mediante el uso de las características del vértice y/o la información de la estructura de la red. En general, los algoritmos de predicción de enlaces consideran la vecindad del usuario o recorren la topología de la red (de forma directa e indirecta) para calcular la similitud entre dichos usuarios. Liben-Nowell and Kleinberg (2007) propusieron varias métricas basadas en la topología del grafo, dividiéndolas (en función de sus características) en métricas basadas en vecinos, métricas basadas en rutas, y las métricas basadas en caminatas aleatorias. Las siguientes secciones describen algunos de los algoritmos más populares que pertenecen a cada grupo. 2.3.1 Métricas Basadas en Vecinos Dado un vértice x, Γ (x) denota el conjunto de vecinos de x en el grafo G. Las métricas basadas en vecinos están basadas en la idea de que dos vértices x e y son más propensos a formar un vínculo en el futuro si sus conjuntos de vecinos Γ (x) y Γ (y) coinciden en gran cantidad de vértices (Liben-Nowell and Kleinberg, 2007). Common Neighbors (CN) La métrica más simple de superposición de vecindades corresponde a contar directamente la intersección: sCN xy = |Γ (x) ∩ Γ (y)| (2.1) Esta métrica indica que, si tanto el nodo x como el nodo y están conectados al nodo z, entonces se incrementa la probabilidad de que el nodo x se conectará con el nodo y. Coeficiente de Jaccard El coeficiente de similitud de Jaccard (Jaccard, 1901) normaliza el valor de CN de la siguiente manera: sJaccard = xy |Γ (x) ∩ Γ (y)| |Γ (x) ∪ Γ (y)| (2.2) Esta métrica define la probabilidad de seleccionar un vecino en común de un par de vértices x e y si la dicha selección se realiza de forma aleatoria a partir de la unión de los conjuntos de vecindades de x e y. Los resultados experimentales obtenidos con cuatro redes de colaboración diferentes reportados en (Liben-Nowell and Kleinberg, 2007), mostraron que la performance del coeficiente de Jaccard es peor en comparación a Common Neighbors. 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES 19 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS Common Followers/Followees En redes de seguidores/seguidos tales como Twitter, la superposición de vecindades considerando la direccionalidad de las relaciones lleva a dos métricas diferentes: Common Followees (CFE) y Common Followers (CFR). El conjunto de followees de x se denota como Γout (x), el conjunto de followers de x se expresa como Γin (x), y el grado del vértice x se escribe como kx . CFE mide la superposición de los enlaces salientes de los usuarios (followees o seguidos), lo cual define hasta qué punto dos usuarios siguen el mismo conjunto de usuarios. Si dos usuarios siguen los mismos usuarios, es probable que tengan intereses similares y, por tanto, estén interesado en el mismo tipo de información. Esta métrica es una adaptación del coeficiente de Jaccard y se define formalmente como: sCFE xy = |Γout (x) ∩ Γout (y)| |Γout (x) ∪ Γout (y)| (2.3) Del mismo modo, los CFR mide el solapamiento de enlaces entrantes de los usuarios (followers o seguidores), es decir, la métrica define hasta qué punto dos usuarios son seguidos por las mismas personas, y por lo tanto comparten la misma audiencia. Esta métrica puede ser formalmente definida como: sCFR xy = |Γin (x) ∩ Γin (y)| |Γin (x) ∪ Γin (y)| (2.4) Coeficiente de Sørensen Esta métrica mide el número de vecinos compartidos y penaliza dicho valor de acuerdo a la suma de las vecindades de los vértices involucrados (Sørensen, 1948): S/ orensen sxy = 2 |Γ (x) ∩ Γ (y)| kx + ky (2.5) done kx es el grado del vértice x. Coeficiente de Salton Este coeficiente computa la distancia entre la vecindad de cada usuario representado como vectores binarios (Salton and McGill, 1983). Se puede encontrar en la literatura como "similitud del coseno" y se define formalmente como: sSalton = xy |Γ (x) ∩ Γ (y)| p kx × ky (2.6) Hub Promoted Index (HPI) y Hub Depressed Index (HDI) Las métricas Hub Promoted Index (HPI) y Hub Depressed Index (HDI) miden el número de vecinos comunes y penalizan dicho valor por el tamaño mínimo y el tamaño máximo de vecindad, respectivamente. En este contexto un hub o concentrador es un vértice que concentra muchos ejes (es decir, tiene un conjunto relativamente grande de vecinos) funcionando como un puente para muchos pares de vértices. HPI no tiene en cuenta el grado de un vértice en el factor de penalización, incrementando el valor de 20 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS la métrica para aquellos vértices conectados a un hub. Por el contrario, el HDI penaliza a los vértices que están al lado de un vértice de tipo hub. Los índices pueden ser definidos formalmente como (Ravasz et al., 2002): sHPI xy = |Γ (x) ∩ Γ (y)| min {kx , ky } (2.7) sHDI xy = |Γ (x) ∩ Γ (y)| max {kx , ky } (2.8) Índice de Leicht-Holme-Newman (LHNI) Este índice asigna una alta similitud a pares de vértices que tienen vecinos comunes en relación al número esperado de vértices en lugar de el número máximo (como sucede en CN) (Leicht et al., 2006). = sLHNI xy |Γ (x) ∩ Γ (y)| kx × ky (2.9) Índice Preferential Attachment (PA) Esta métrica es simplemente la multiplicación de grados entre dos vertices x e y (Barabási and Albert, 1999): sPA xy = kx × ky (2.10) El rationale detrás de PA es que la probabilidad de que un nuevo link aparezca entre x e y es proporcional al grado de tanto x como y. PA no requiere información del vecindario de cada vértice, reduciendo su costo computacional. Índice Adamic-Adar (AA) Adamic-Adar refina la métrica CN asignando menos peso a aquellos vecinos que tienen mayor grado, resultando en (Adamic and Adar, 2003): sAA xy = 1 log kz z∈Γ(x)∩Γ(y) ∑ (2.11) Bajo este modelo, los vértices que tienen vecinos comunes con un alto grado (como hubs) son menos propensos a ser similares. El logaritmo inverso penaliza la contribución de los vecinos con un valor de grado grande. Índice Resource Allocation (RA) Esta métrica utiliza el concepto de envío de recursos, de manera que un vértice x puede enviar recursos a un vértice y a través de sus vecinos en común. Asumiendo que cada vértice tiene una unidad de recurso y que dicho valor se distribuye de forma igual entre sus vecinos, la similitud entre x e y se define como la cantidad de recursos que recibe x de y, y viceversa (Zhou et al., 2009): 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES 21 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS sRA xy = 1 k z∈Γ(x)∩Γ(y) z ∑ (2.12) La diferencia entre AA y RA reside en que la contribución de cada vecino a la métrica decae de forma lineal, en lugar de logarítmica. 2.3.2 Path-based metrics Algunas métricas utilizan el conjunto de caminos existentes entre los vértices para evaluar su similitud. Algunos de los indicadores más populares se describen en esta sección. Las métricas basadas en vecinos pueden ser visto como un caso especial, con longitud 2, de las métricas basadas en rutas. Índice Local Path (LP) Este índice (Lü et al., 2009) utiliza la información de las rutas locales con una longitud 2 y longitud 3. A diferencia de CN que sólo utiliza la información de los vecinos más cercanos (longitud 2), LP explota la información adicional de los vecinos de hasta longitud 3 a partir del vértice actual. Esta métrica se define como: sLP = A2 + αA3 (2.13) donde A2 y A3 son matrices de adyacencia para los caminos de longitud 2 y 3 respectivamente, y α es un parámetro libre que le permite penalizar el aporte a la métrica de los caminos de longitud 3. A2 es igual a la cantidad de common neighbours entre cada par de vértices en el grafo. De esta manera, si α = 0, esta métrica es equivalente a CN. Este índice se puede extender también para incluir caminos de mayor longitud. Se ha reportado que el índice LP se comporta mucho mejor que los índices basados en vecindades, tales como RA, AA y CN (Zhou et al., 2009). Índice Katz Esta métrica se basa en combinar todas las rutas existentes entre dos vértices (Katz, 1953). Los caminos están penalizados exponencialmente de manera que los caminos más cortos obtengan mayor peso. El índice Katz se define de la siguiente forma: ∞ 2 2 3 3 l l sKatz xy = ∑ β · pathxy = β A + β A + β A + . . . (2.14) l=1 donde pathlxy es el conjunto de todos los caminos entre x e y con longitud l, y β es el factor de penalización que controla los pesos de los caminos.. Para β > 0 y muy pequeño, Katz se comporta de forma similar a CN, debido a que los caminos de mayor longitud no contribuyen de forma significativa a la similitud final. A pesar de que Katz necesita más información que CN, sigue siendo una medida de similitud local de complejidad relativamente baja en comparación a otras métricas globales y, tanto Katz como LP han reportado resultados mucho mejores que 22 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS CN (Lü et al., 2009). Es importante notar que el valor de β debe ser cuidadosamente seleccionado para que Katz converja. De hecho, debe ser menor que la inversa del mayor autovalor de A, de manera que β l Al con l → ∞ sea 0. FriendLink (FL) Este algoritmo proporciona recomendaciones de amistades recorriendo todos los caminos de hasta cierta longitud (Papadimitriou et al., 2011, 2012). FL supone que las personas en una red social utilizan todos los caminos para conectarse, pero de acuerdo a la longitud del camino. La similitud entre x e y está definido como el conteo de todos los caminos de longitud variable l: pathixy 1 sFL · i xy = ∑ i=2 i − 1 ∏ j=2 (n − j) l donde n es el número de vértices en el grafo, 1 i−1 (2.15) es un factor de penalización de la longitud que sopesa los caminos de acuerdo a su longitud y pathixy es el conjunto de todos los caminos de longitud l desde x hasta y. De forma similar 1 ∏ij=2 (n− j) es un factor de normalización que toma en cuenta todos los posibles caminos de longitud i si el grafo estuviera totalmente conectado. De esta manera, si pathixy es igual a todos los posibles caminos en el grafo de longitud i, el cociente se normaliza a 1. FL ignora todos los caminos de longitud 1 ya que las personas que ya se encuentran conectadas de forma directa se consideran amigas. Twitter Followee Recommender (TFR) Armentano et.al. (Armentano et al., 2011, 2012) propusieron un algoritmo simple basado en caminos para encontrar usuarios en Twitter usando el grafo de seguidores/seguidos en la red social del usuario objetivo. El algoritmo establece la hipótesis de que los usuarios que comparten los mismo seguidos son similares, y de esta manera, los seguidos de un usuario se pueden recomendar a otro. Si A denota la matriz de adyacencia del grafo y representa la relación de "sigue a", (notar que A0 muestra las relaciones de "seguido por"), la matriz de similitud se puede escribir como: sT FR = ( (AA0 ) • T ) A ) • T (2.16) donde T = (1 − A − I) es utilizado como una máscara para filtrar aquellos usuarios que ya están conectados con el usuario objetivo y, además, sirve para filtrar al usuario objetivo en sí mismo. La máscara se aplica 2 veces: en primer lugar cuando se obtienen los seguidores de un seguidor dado, y luego, cuando se obtiene el conjunto de seguidos finales que serán recomendados. 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES 23 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS 2.3.3 Métricas Basadas en Caminatas Aleatorias (Random Walks) Dado un grafo no dirigido G (V, E) con |V | = n, |E| = m un "paso" al azar en G es un movimiento desde un vértice x a un vecino v seleccionado al azar. Una caminata aleatoria es, por tanto, una secuencia de estos pasos aleatorios iniciando el recorrido en un vértice dado. Las caminatas aleatorias se han utilizado en muchos campos, incluyendo la ecología, la economía, la psicología, ciencias de la computación, física, química y biología; para explicar los comportamientos observados de muchos procesos estocásticos en dichos campos. Aunque varios tipos diferentes de caminatas aleatorias son de interés, las caminatas aleatorias por lo general se consideran cadenas de Markov o procesos Markovianos. Tiempo de Conmutación Promedio (ACT) Denotado por m (x, y), el número promedio de pasos requeridos por un caminante aleatorio que inicia su caminata en un vértice x para llegar a un vértice y, el tiempo de conmutación promedio entre x e y es (Lü et al., 2009): n (x, y) = m (x, y) + m (y, x) (2.17) que puede ser obtenido en términos de la pseudoinversa de la matriz Laplaciana, L+ (L = D − A), de la siguiente manera (Fouss et al., 2007; Klein and Randić, 1993): + + + n (x, y) = M lxx + lyy − 2lxy (2.18) + denota la correspondiente celda de L+ . Asumiendo que dos vértices son más donde lxy similares si tienen un promedio de conmutación bajo, entonces la similitud entre x e y puede ser definido como el recíproco de n (x, y) (el factor constante M se quita): sACT xy = 1 + + + lxx + lyy − 2lxy (2.19) Caminatas Aleatorias con Reinicio (RWR, Random Walk With Restart) Considerando a un caminante aleatorio que inicia en el vértice x, que se moverá de forma iterativa a sus vecinos con una probabilidad α y retornar a x con probabilidad 1 − α, y denotado por qxy la probabilidad de que el caminante se encuentre en un vértice y, en el estado estable, es: ~qx = αPT ~qx + (1 − α)~ex (2.20) donde P es la matriz de transición, donde Pxy = 1/kx si x e y están conectados, y 0 en otro caso. De hecho, Px = Ax /kx , lo que significa que la probabilidad de moverse de un vértice x a cualquiera de sus vecinos está distribuido equitativamente. P representa a los ejes salientes del grafo, y por ello, debe ser traspuesta para obtener la probabilidad de alcanzar un vértice dado (cuántos vértices apuntan a dicho vértice). Por ejemplo, si dado un vértice z solo tiene 24 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS ejes salientes, no existe posibilidad de que una caminata al azar termine en z, una situación representada por un vector de ceros en PzT . El factor de reinicio ~ex es un vector de N × 1 donde el x-esimo elemento es igual a 1 y donde los demás valores son 0, lo cual significa que x es el único vértice al cual el caminante puede retornar. Si ~exy = β , el caminante puede “saltar” a cualquier otro vértice y con probabilidad β . Finalmente, la solución a la ecuación 2.20 es: ~qx = (1 − α) I − αPT −1 ~ex (2.21) De esta manera, el índice RWR está definido como la probabilidad de iniciar una caminata desde x, terminando en y, más la probabilidad de realizar el camino inverso: R sRW = qxy + qyx xy (2.22) Random Walk Local (LRW) Dado un caminante aleatorio que inicia en el vértice x, πxy (t) expresa la probabilidad de que este caminante se ubique en el vértice y luego de t pasos. Para medir la similitud entre x e y, un caminante es situado inicialmente en x como un vector inicial de densidad ~πx (0) =~ex . Este vector se transforma en ~πx (t + 1) = PT ~πx (t) para t > 0. El índice LRW en el paso t se define entonces como: sLRW = qx πxy (t) + qy πyx (t) xy (2.23) donde q es la función de configuración inicial. Liu and Lü (2010) aplicaron una forma simple de éste índice, basándose en el grado de cada vértice y con lo cual qx = kx |E| . Random Walk Superpuesto (SRW) Liu and Lü (2010) propusieron el índice SRW, donde el caminante aleatorio inicia de forma continua en el vértice inicial, resultando en una similitud mayor enre el vértice inicial y sus vértices cercanos. SRW se define como: t sSRW xy = t ∑ sLRW xy (π) = ∑ [qx πxy (τ) + qy πyx (τ)] τ=1 τ=1 (2.24) donde t describe pasos realizados por el caminante. SimRank Este índice está definido como el estado estable de la siguiente definición recursiva (Jeh and Widom, 2002): dos vértices son similares siempre y cuando sus vecinos sean similares. Un parámetro γ controla qué tan rápido el peso de los vértices conectados decae en valor a medida que el algoritmo se aleja de los vértices originales: sSimRank =γ· xy ∑z∈Γ(x) ∑z0 ∈Γ(y) sSimRank zz0 kx · ky 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES (2.25) 25 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS donde sxx = 1. SimRank puede ser explicado en términos de pares de usuarios navegando en la web de forma aleatoria: sSimRank determina qué tan pronto estos 2 usuarios se encontrarán en xy la misma página Web o vértice si, individualmente iniciaron en los vértices x e y (e.g., 2 páginas web diferentes), y al azar van navegando a través del grafo de forma inversa. Tiempo de Acceso (Hitting Time) Para dos vértices x e y en el grafo, el tiempo de acceso Hu,v es una medida de similitud definida como el número esperado de pasos requeridos para que una caminata aleatoria alcance y a partir de x. En grafos no dirigidos se puede utilizar una métrica simétrica, tal como el tiempo de conmutación, Cx,y = Hx,y + Hy,x . En la predicción de enlaces, mientras más corto sea el tiempo de acceso más similares serán los vértices y, por tanto, más probable será la formación de enlaces en el futuro. A pesar de que el tiempo de acceso es fácil de calcular utilizando caminatas aleatorias, su alta varianza puede llevar a predicciones de pobre performance (Liben-Nowell and Kleinberg, 2007). El tiempo de acceso es afectado por aquellos vértices que se encuentran alejados y poseen alta probabilidad estacionaria. Por ejemplo, si hay un vértice z lejos de x e y con alta probabilidad estacionaria, esto puede dificultar que una caminata aleatoria escape del vecindario de z. Para prevenir estos comportamientos, se lleva a cabo una caminata aleatoria que reinicia periódicamente la caminata al vértice x con una probabilidad fija α. Otra dificultad radica en que Hx,y es relativamente pequeño si y es un vértice con una alta probabilidad estacionaria πy , sin importar la identidad de x. En estos casos se puede utilizar la versión normalizada del tiempo de acceso: normalized − hitting − time (x, y) = Hx,y · πy + Hx,y · πx (2.26) PageRank PageRank (Página et al., 1999) es una métrica que modela la navegación Web como un paseo aleatorio en el que el internauta selecciona al azar los enlaces a seguir y de vez en cuando salta a una nueva página web para iniciar otro recorrido de la estructura de enlaces de la Web. La Algorithm 2.1 El algoritmo PageRank 1: Po = ne (e es un vector columna de todos 1’s) 2: k = 1 3: 4: 5: repeat Pk = (1 − α) e + αAT Pk−1 k = k+1 6: 7: until kPk − Pk−1 k < ε return Pk 26 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS reputación o prestigio de una página Web es calculada en función de la frecuencia a largo plazo de las visitas de un surfista Web al azar, lo que puede determinarse mediante el cálculo de la distribución en un estado estacionario del proceso estocástico. El peso asignado a cualquier página i dada, se conoce como su PageRank y puede ser visto como una medida de prestigio en redes sociales. El algoritmo de PageRank se basa en el supuesto de que un hipervínculo desde una página que apunta a otra página es un indicador implícito de la autoridad de la página de destino. Así, cuanto más enlaces recibe una página i, más prestigio posee. Al mismo tiempo, una página se vuelve más importante si es apuntado por otras páginas importantes, generando una definición recursiva. Para formular las ideas anteriores, dado el grafo dirigido G = (V, E) el valor de PageRank de la página i, denotado como PR (i), se define como: PR (i) = (1 − α) e + α PR (i) Oj ( j,i)∈E ∑ (2.27) donde O j es el número de links salientes del vértice j. El parámetro α es llamado "factor de reducción", y modela el hecho de que en cada paso el navegante puede saltar a una página Web al azar con probabilidad α, o puede seguir alguno de los links en la página actual con probabilidad (1 − α) e. En otras palabras, el algoritmo es una caminata aleatoria con reinicios al azar sobre G. Si e es todos 1’s, entonces existe igual chance de saltar a cualquier página o vértice en G. Personalizar e permite ajustar el comportamiento del caminante aleatorio. El cómputo de los valores de PageRank sobre páginas Web se realiza, a menudo mediante el método de iteración de potencias, que produce el autovector principal con autovalor 1. El algoritmo está descrito en 2.1, donde P es un vector columna n-dimensional de valores de PageRank, i.e., P = (PR (1) , PR (2) , . . . , PR (n))T sea A la matriz de adyacencia: Ai j = 1 Oj 0 i f (i, j) ∈ E otherwise Típicamente, la distribución inicial de PR (i) es uniforme y el algoritmo itera hasta que los valores de PageRank no cambien, es decir, hasta que converja. En el algoritmo, la iteración finaliza cuando la norma L1 del vector residual es menor que un ε preestablecido. Se debe notar que la norma L1 de un vector es simplemente la suma de todos sus elementos. 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES 27 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS PageRank Personalizado PageRank establece una vista democrática de la importancia de cada página en la Web. Sin embargo, si se personaliza el vector ~e (e.g. dando más peso a algunos vértices), se puede crear una vista personalizada de la importancia relativa de cada vértice (Aggarwal, 2011). De esta manera, usando una densidad de probabilidad de reinicio no uniforme, algunos vértices tendran mayor probabilidad de ser visitados por el caminante aleatorio. Este algoritmo ha sido denominado Rooted PageRank o PageRank Personalizado (PPR) en (Liben-Nowell and Kleinberg, 2007) y es una parte integral (combinado con el algoritmo SALSA descrito en la Sección 2.3.3) del servicio Who to Follow de Twitter. Una caminata aleatoria con reinicio para el vértice v puede ser visto como un PPR donde el vector ~e tiene valor 1 para v y 0 los demás vértices. Algunos autores distinguen ambos casos de uso definiendo PPR(~e), cuando se utiliza un vector personalizado ~e, y PPR(v), cuando ~e tiene el valor 1 sólo para v. HITS Algorithm 2.2 El algoritmo HITS 1: for all u ∈ q B do 1 2: H (u) = |B| q 1 3: A (u) = |B| end for 5: repeat 6: for all v ∈ B do 7: A0 (v) = ∑(u,v)∈N H (u) 4: 9: 10: end for for all u ∈ B do H 0 (u) = ∑(u,v)∈N A (v) 11: 12: end for H = kH10 k H 0 (donde kXk2 es la norma euclídea del vector X) 13: A= 8: 2 14: 1 0 kA0 k2 A until H y A converjan HITS (Kleinberg, 1999) supone un proceso ligeramente más complejo que los algoritmos anteriores, modelando la Web como una composición de dos tipos de páginas Web: hubs y autoridades. La noción de hub expresa la calidad de una página Web como un acceso a recursos útiles (por ejemplo, los directorios Web actúan como buenos hubs), y la noción de autoridad establece la calidad de la página como un recurso en sí. De esta manera, a cada página de la Web se le asignan puntajes de hub y de autoridad. 28 of 206 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES CHAPTER 2. CONCEPTOS RELACIONADOS HITS tiene sus raíces en la noción de relación de refuerzo mutuo entre hubs y autoridades. Un buen hub es una página que apunta a buenas autoridades, mientras que una buena autoridad es una página apuntada por buenos hubs. A la luz de esto, el algoritmo tiene como objetivo la búsqueda de sitios web de autoridad. Ambos resultados, hubs y autoridades, se calculan mediante un algoritmo iterativo que actualiza los resultados de una página basada en las puntuaciones de las páginas de su vecindad inmediata. Este enfoque tiene una relación con PageRank pero realizando dos caminatas aleatorias separadas, uno con transiciones para calcular hubs y una con transiciones para calcular autoridades, en un grafo bipartito compuesto por hubs, de un lado, y autoridades, del otro (Getoor and Diehl, 2005). Las puntuaciones de hub y de autoridad se corresponden a las distribuciones de estado estacionario de los respectivos procesos aleatorios (uno iniciando en el lado izquierdo del grafo, y otro en el derecho). Al contrario de PageRank, HITS es un algoritmo de clasificación que depende de una consulta inicial. Este tipo de algoritmos, clasifican las páginas Web suponiendo que el conjunto de resultados de la consulta inicial tenga un cierto grado de coherencia de tópicos. A continuación, el análisis de enlaces se realiza no en todo el gráfico Web, sino sólo en la vecindad de páginas contenidas en el conjunto de resultados, ya que este vecindario es más probable que contenga enlaces tópicamente pertinentes (Najork, 2007). El algorithm 2.2 detalla el algoritmo HITS (Najork, 2007). Dado como entrada un grafo G (V, E) y un conjunto de resultados de una consulta, denotado como R ⊆ V , HITS computa un grafo de vecinos que consisten en el conjunto base B ⊆ V (incluyendo el conjunto raíz y algunos de sus vecinos) y algunos ejes en E apuntados por B. Para cada vértice u en grafo resultante, HITS computa un puntaje de autoridad A (u), estimando qué tanta autoridad posee u dado el tópico de la consulta, y un puntaje de hub H (u), indicando si u es una buena referencia a varias páginas autoritarias. SALSA SALSA (Stochastic Approach for Link-Structure Analysis) (Lempel and Moran, 2001) combina la idea de una caminata aleatoria en PageRank con el concepto de hub y autoridad de HITS. Dado un grafo G, un grafo bipartito no dirigido H se construye mediante la creación de un subconjunto BA de todos los vértices con un grado de entrada positivo (las potenciales autoridades deben tener al menos un eje entrante), y el subconjunto BH de todos los vértices con grado saliente positivo (los hubs, que deben tener al menos un eje saliente). Los elementos de BA y BH se transforman en vértices de H, el grafo bipartito. Los ejes no dirigidos de H se definen sobre G de la siguiente manera: si G tiene un link de i a j, entonces se agrega un link entre los vértices i de BH y j de BA . El algoritmo se corresponde a dos caminatas aleatorias de 2 pasos sobre el grafo H, una que inicia en BA y otra iniciando en BH . Esto significa que cada paso aleatorio del "lado hub", requiere recorrer un eje saliente y luego un eje entrante para retornar al mismo lado del grafo bipartito. De forma similar, los pasos aleatorios del lado de las autoridades realizan un 2.3. PREDICCIÓN DE ENLACES EN REDES SOCIALES 29 of 206 CHAPTER 2. CONCEPTOS RELACIONADOS Algorithm 2.3 El algoritmo SALSA para el cálculo del valor de hub 1: Let BH be {u ∈ B : out (u) > 0} for all u ∈ B do 2: H (u) = 3: 1 |BH | 0 i f u ∈ BH otherwise end for repeat 6: for all u ∈ BH do 7: H 0 (u) = ∑(u,v)∈N ∑(w,v)∈N 4: 5: H(w) in(v)out(w) end for for all u ∈ BH do H (u) = H 0 (u) 8: 9: 10: end for until H converge 11: 12: recorrido de dos pasos, uno entrante y otro saliente para retornar al mismo lado. Para cada vértice u en el grafo de la vecindad, SALSA calcula el puntaje de autoridad A (u) y el puntaje de hub H (u) utilizando dos algoritmos independientes definidos en 2.3 y 2.4 (Najork, 2007). Algorithm 2.4 El algoritmo SALSA para el cálculo del valor de autoridad 1: Let BA be {u ∈ B : in (u) > 0} 2: 3: for all u ∈ B do A (u) = 1 |BA | 0 i f u ∈ BA otherwise end for repeat 6: for all u ∈ BA do 7: A0 (u) = ∑(v,u)∈N ∑(v,w)∈N 4: 5: 8: 9: 10: 11: 12: 2.4 A(w) out(v)in(w) end for for all u ∈ BA do A (u) = A0 (u) end for until A converge Resumen En este Capítulo se repasaron, brevemente, los principales conceptos referentes a sistemas de recomendación y, más específicamente, aquellos basados en redes sociales. Se describieron 30 of 206 2.4. RESUMEN CHAPTER 2. CONCEPTOS RELACIONADOS trabajos recientes relacionados con recomendación de amistades y followees, mostrando la relevancia de este problema en las redes sociales de hoy en día. Por último, se introdujeron las métricas y los algoritmos de predicción de enlaces que se utilizarán a lo largo de esta tesis. 2.4. RESUMEN 31 of 206 Trabajo Relacionado 3 Este capítulo presenta las obras en dos campos profundamente relacionados con el presente trabajo de tesis. El primer campo de investigación se trata de procesamiento distribuido de grafos, que abarca las técnicas y herramientas que permiten procesar grafos en entornos distribuidos. El segundo campo corresponde a las bases de datos de grafos distribuidas que persisten datos del gráfico en un clúster de computadoras. Las bases de datos de grafos definen estructuras eficientes para la representación de vértices, aristas y propiedades mediante el análisis de patrones de acceso comunes. Este capítulo está organizado de la siguiente forma. En la Sección 3.1 se presentan frameworks para el procesamiento de grafos distribuidos, los modelos de procesamiento en los que se basan. La Sección 3.2 se introducen conceptos y soluciones disponibles relacionadas con las bases de datos de grafos distribuidos que proporcionan soporte para el almacenamiento persistente de dichas estructuras. Las limitaciones y ventajas de ambas soluciones para desarrollar y probar algoritmos de recomendación sobre grandes grafos se destacan al final de ambas secciones. 3.1 Frameworks de Procesamiento de Grafos Distribuido El desarrollo de algoritmos en entornos distribuidos es una tarea que involucra resolver los siguientes problemas: • Distribuir código y datos: para explotar la potencia de cómputo del cluster el desarrollador puede dividir el código y los datos de entrada entre los nodos disponibles. En algunos casos, es importante mantener la localidad de los datos para reducir el uso de la red y, como consecuencia, reducir el tiempo de ejecución del algoritmo. • Comunicación de red: en un entorno distribuido es de vital importancia comunicar procesos de diferentes nodos mediante un protocolo de transferencia de datos. Además de las complicaciones intrínsecas a la programación distribuida, la red surge como un importante cuello de 32 of 206 CHAPTER 3. TRABAJO RELACIONADO botella si no se utiliza con cuidado1 . Una de las principales consideraciones a tener en cuenta es que, aunque el ancho de banda de la red es relativamente alto, la latencia de red es alta, lo cual perjudica las operaciones que requieren datos remotos, en comparación con el acceso de datos local (en el orden de 100 a 1000 veces la latencia de memoria RAM2 ). • Sincronización del algoritmo: Al igual que sucede en las técnicas de procesamiento paralelo, el procesamiento distribuido implica la sincronización de acceso a recursos compartidos, y posiblemente remotos, tales como variables de entrada o resultados intermedios. Por otro lado, la aplicación debe garantizar que el algoritmo se comporte de forma estable, por ejemplo, ordenando la ejecución de las operaciones dependientes en diferentes nodos. • Detección y recuperación de fallas: Los escenarios de falla son muy comunes en clusters de computadoras; algunos nodos dejan de responder debido a un fallo del sistema, un suceso de inactividad temporal o un fallo en la red. Un mecanismo de recuperación de errores se puede considerar para continuar con la ejecución del algoritmo a pesar de perder algunos nodos. En la práctica, para manejar estas tareas, los desarrolladores se basan en los frameworks de procesamiento distribuido que proporcionan abstracciones que aíslan al usuario de la plataforma distribuida subyacente (software y hardware). De hecho, los frameworks distribuidos exponen un modelo de programación que simplifica el desarrollo de algoritmos, mientras que, al mismo tiempo, fomentan la correcta utilización de la plataforma. En este contexto, un modelo de programación puede ser visto como una especificación que el usuario debe seguir con el fin de desarrollar un algoritmo en un framework de procesamiento dado (posiblemente distribuido). Además, un modelo generalmente incluye algunas operaciones para comunicar los resultados de una manera independiente de la plataforma, es decir, sin tener en cuenta cómo y dónde estos resultados se envían. Por ejemplo, el modelo MapReduce (MR) (Dean and Ghemawat, 2008) (Sección 3.1.2) requiere que el usuario divida su algoritmo en dos funciones bien definidas: una función Map, que produce resultados intermedios mediante el procesamiento de los datos de entrada, y una función Reduce, que transforma los resultados intermedio en un resultado final. En las funciones Map y Reduce, MapReduce permite al usuario utilizar una operación llamada emitir para comunicar los resultados del algoritmo a la plataforma (el framework que implementa el modelo), la cual es la encargada de mover y almacenar dichos datos. El procesamiento distribuido de datos a gran escala se aborda generalmente utilizando una arquitectura Shared Nothing, donde el conjunto de datos de entrada se divide usando alguna estrategia de particionado. Esto significa que cada elemento en el conjunto de datos de entrada se puede procesar en un nodo de computación independientemente de otros nodos (no hay memoria compartida entre los nodos que genere que un nodo afecte a otro). En estos sistemas, cada nodo puede contener una o más unidades de procesamiento (por ejemplo se ejecuta en hilos o 1 Falacias de la computación distribuida, http://www.rgoarchitects.com/Files/fallacies.pdf 2 Promedio de latencia de productos de hardware comercial, por año, http://www.eecs.berkeley.edu/~rcs/ research/interactive_latency.html 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 33 of 206 CHAPTER 3. TRABAJO RELACIONADO procesos) llamados workers, que se asignan una parte del conjunto de datos a procesar. Algunos frameworks incluyen workers especiales, llamados Maestros o Coordinadores, que sincronizan la ejecución de los workers. Los algoritmos para grafos presentan nuevos retos para la computación distribuida debido a su naturaleza caótica. En su forma general, los grafos tienen la particularidad de estar conectados de forma arbitraria, lo que significa que un vértice vi puede conectarse a cualquier vértice v j en el grafo. Como consecuencia, un algoritmo que camina de vi a v j (por ejemplo, la recopilación de los tweets, o el cálculo de la puntuación de PageRank), puede abarcar varios nodos del clúster, dependiendo de donde vi y v j se encuentran físicamente. Si vi y v j se encuentran colocalizados, la comunicación de red es nula. Sin embargo, encontrar la mejor manera de dividir los vértices entre los nodos, maximizando la co-localización es un problema NP-completo, por lo que usualmente se utilizan heurísticas para conservar localidad de datos. Otro de los retos en el procesamiento de grafos es el balanceo de tareas. Muchos grafos del mundo real siguen una distribución de ley de potencia, lo que significa que hay muchos vértices bajos conectados que podrían ser procesados muy rápido, y un menor número de vértices altamente conectados, y más lento para procesar. En la literatura se puede encontrar varios frameworks que soportan algoritmos de grafos en clusters de computadoras. Muchos de estos esfuerzos se basan en el conocido modelo Batch Synchrounous Parallel (BSP) por Valiant (1990), que divide la ejecución de un algoritmo en múltiples Superpasos sincronizados por barreras lógicas en las cuales el paso de mensajes se lleva a cabo. A modo de ejemplo, Pregel (Malewicz et al., 2010) es uno de los modelos computacionales basados en BSP más populares para el procesamiento de grafos. Otros modelos de procesamiento distribuido como Fork-Join o MapReduce también se han aplicado al procesamiento de grafos. A pesar de no ser especialmente diseñado para dicha tarea, la simplicidad y amplia popularidad de las implementaciones disponibles, tales como Hadoop3 o GridGain4 , fomentó su uso. Sin embargo, como se discutirá más adelante, estos modelos pueden tener un impacto negativo en el rendimiento de algunos algoritmos de grafos. Esta Sección se organiza de la siguiente manera. Fork-Join y MapReduce se explican en los incisos 3.1.1 y 3.1.2 respectivamente, mientras que Pregel y Gather-Apply-Scatter se explican en los incisos 3.1.3 y 3.1.4 respectivamente. El procesamiento asincrónico de grafos se presenta en la subsección 3.1.5 como una alternativa para la construcción de algunos tipos de algoritmos, especialmente aquellos que obtienen resultados por aproximación. Por último, un modelo más reciente denominado Resilient Distributed Datasets se describe en la subsección 3.1.6. 3 Hadoop Web Page, https://hadoop.apache.org/ Web Page, http://www.gridgain.com/ 4 GridGain 34 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO 3.1.1 Fork-Join La estrategia de programación Divide y Conquista es una de las técnicas más utilizadas en procesamiento paralelo y distribuido. La razón principal radica en que la división del algoritmo y los datos en bloques independientes ayuda a distribuir fácilmente el trabajo en diferente nodos. Una herramienta simple presente en la mayoría de los Sistemas Operativos, se basa en Divide y Conquista para paralelizar el trabajo en diferentes procesos. Una operación denominada fork se encarga de dividir un proceso en procesos hijos que se encargan de realizar una tarea en paralelo. El proceso padre puede esperar por la finalización de sus hijos invocando una operación join y obtener los resultados de las tareas ejecutadas en paralelo. En el contexto de Sistemas Distribuidos, la operación fork se encarga de crear tareas para ser ejecutadas en nodos remotos. Una vez que una tarea hijo finaliza su ejecución, envía los resultados al trabajo padre. Implícitamente, el padre realiza una operación join al esperar que todos sus hijos finalicen el procesamiento y, así, poder unir los diferentes resultados en un resultado final. Este modelo, denominado Fork-Join (FJ) (Mateos et al., 2010) (también conocido como Split and Merge o Split and Reduce en algunos frameworks5 ) es uno de los modelos más simples para el procesamiento distribuido. Desventajas Fork-Join tiene varios inconvenientes con respecto al modelado y el rendimiento algorítmico. El modelo de programación es a menudo muy adecuado para algoritmos de tipo Divide y Conquista, compuestos por un único paso, en el que cual el trabajo se distribuye a través de un clúster y luego sus resultados se combinan. Sin embargo, los algoritmos iterativos que requieren la actualización de un valor durante varias iteraciones sufren de la falta de soporte de FJ a los bucles distribuidos. Una alternativa es proporcionar un bucle, externo a Fork-Join, y pasar el resultado de un trabajo en la iteración i a un trabajo en la iteración i + 1 . Por lo general, la sobrecarga implicada en la combinación de resultados y el envío de los nuevos valores a los nodos para la ejecución de la siguiente iteración es mayor que en otros modelos iterativos. Por otro lado, la operación de unión se realiza generalmente en un solo nodo, resultando naturalmente en un cuello de botella. Sin embargo, en algunas aplicaciones se prefiere la simplicidad de FJ a la complejidad de otros modelos, a pesar de los inconvenientes de rendimiento. Procesamiento de Grafos en Fork-Join Fork-Join es un modelo genérico que permite procesar cualquier algoritmo que pueda ser expresado en términos de dividir el cálculo y fusionar o combinar los resultados de éste cálculo. El desarrollador es libre, entonces, de adaptar sus algoritmos y estructuras de datos. Por lo tanto, 5 For example, GridGain’s TaskSplit, http://www.gridgain.com/api/javadoc/org/gridgain/grid/ compute/GridComputeTaskSplitAdapter.html 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 35 of 206 CHAPTER 3. TRABAJO RELACIONADO Figure 3.1: Un ejemplo de flujo de trabajo en Fork-Join para procesar algoritmos de grafos bajo FJ, los datos del grafo deben ser divididos en diferentes bloques. Por otra parte, cada bloque debe representar una tarea de FJ y ser asignado a un nodo del clúster. A lo largo de esta tesis, el proceso de dividir los datos de entrada en tareas y asignarlas a los nodos, se conoce como mapeo. La pieza de funcionalidad que realiza el mapeo se llama una estrategia de mapeo. Como ejemplo, si el algoritmo utiliza como entrada los vértices el grafo, una estrategia de mapeo simple puede crear tareas utilizando el identificador de cada vértice como clave para dividir el conjunto. Esta función simple puede dividir los vértices de entrada en intervalos de longitud fija (por ejemplo, 100 vértices por tarea), o puede dividir la entrada en N intervalos (por ejemplo, si hay 8 nodos del clúster, la función puede dividir la entrada en 8 tareas, una para cada nodo). Claramente, la estrategia de mapeo puede ser arbitrariamente compleja. La división de tareas puede incluso utilizar factores fuera de la representación del grafo, como la disponibilidad de la memoria de los nodos del clúster o las características de la CPU de dichos nodos. 3.1.2 MapReduce MapReduce (MR) (Dean et al., 2008) se puede ver como una mejora sobre el enfoque FJ, solucionando algunos de sus problemas. Definir un algoritmo bajo el modelo de programación de MR, requiere que el usuario divida el mismo en dos operaciones bien definidas: map y reduce. La operación map es análoga a la función de programación funcional "map", que produce pares de (clave, valor) para un determinado conjunto de datos de entrada. Por ejemplo, considere un algoritmo que cuenta las palabras en un cuerpo de texto. Una función map simple puede contar las palabras en el texto de entrada y producir pares que consisten en (palabra, recuento). La operación reduce es responsable de la fusión de pares producidos por la operación map. Tras el recuento de palabras del ejemplo, si se aplica la operación map para cada párrafo del texto por separado, la operación reduce debería sumar los recuentos de la misma palabra en 36 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO diferentes párrafos para producir el resultado final, que es el número total de las cada palabra en el documento. De esta división en las operaciones map y reduce, se puede deducir que en MR, el cálculo se divide en una etapa map y una etapa de reduce como se muestra en la Figura 3.2. Una estrategia inicial de asignación se utiliza para dividir los datos de entrada en M bloques utilizados como entrada a la etapa mapa. En la práctica, la estrategia de mapeo para la etapa inicial suele ser una estrategia basada en el tamaño, dividiendo los datos de entrada en bloques de tamaño fijo con como 16 MB o 32 MB. Un proceso Master organiza toda la computación MR y es responsable de la asignación de cada uno de los M bloques a los trabajadores disponibles. Luego, los trabajadores aplicar la operación mapa definido por el usuario a sus bloques asignados. En el ejemplo, master asigna el bloque DataM para ser procesado por el Worker0 . Una segunda estrategia de mapeo se utiliza para agrupar la salida de cada operación map y producir R bloques para la etapa de reducir. En el ejemplo de recuento de palabras, si al aplicar map a dos bloques diferentes, éstos producen los pares (casa, 5) y (casa, 1), ambos pares deben reducirse en conjunto para producir el par resultante (casa, 6). Cada resultado producido por la etapa map se registra en el Master, para luego ser consumidos en la etapa reduce. Una vez finalizada la etapa map, el proceso Master asigna los R bloques producidos anteriormente a los trabajadores disponibles con el objetivo de que apliquen la función reduce. Los trabajadores transfieren los resultados producidos por la etapa map a su nodo local y aplican la operación reduce, definida por el usuario. En el ejemplo presentado, el master asigna a Worker0 con la tarea de reducir el bloque r0 . Como se mencionó, este proceso consiste en obtener todos los trozos r0 de los trabajadores disponibles y luego aplicar la función reduce a la lista obtenida. El resultado final de MR consiste en una salida de R sub-resultados producidos por las operaciones reduce. A menudo, la fusión de los R sub-resultados en un único resultado no es necesario, ya que pueden ser usados como entrada a otro trabajo MR o pueden ser leídos por una herramienta externa que manipule los resultados divididos en bloques. Las etapas Map y Reduce se pueden superponer siempre y cuando se mantenga la condición de que la función reduce tenga todos los pares clave-valor de un bloque dado para llevar a cabo la reducción. En situaciones en las que la operación de reducción es asociativa, puede aplicarse incluso antes de que todos los valores para una clave dada estén disponibles. En tal escenario, cuando se encuentran nuevos valores, la operación debe ser ejecutada con los antiguos valores y los nuevos con el fin de producir un resultado final. En la especificación original del framework de Dean and Ghemawat (2008) los datos de entrada, los resultados intermedios y los resultados finales se leen y se escriben en un sistema de archivos distribuido llamado GFS (Google File System) (Ghemawat et al., 2003). GFS proporciona mecanismos de recuperación en caso de escenarios de fallo para que los componentes de MapReduce pueden volver a ejecutar tareas fallidas y continuar procesando el trabajo MR actual. 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 37 of 206 CHAPTER 3. TRABAJO RELACIONADO Figure 3.2: Un ejemplo de flujo de trabajo en MapReduce. La aplicación de MR a procesamiento de grafos requiere la adaptación de los datos del grafo (al igual que en FJ), por ejemplo, mediante el uso del ID del vértice o la etiqueta del vértice para la división inicial. Dependiendo del algoritmo que se ejecuta, para mapear la partición en R bloques (luego de aplicar map) se puede utilizar el ID de vértice u otro identificador extraído del grafo. Algunos estudios han aplicado MapReduce en algoritmos de recomendación de grafos como PageRank personalizado (Bahmani et al., 2011) o SimRank (Cao et al., 2012). Estos estudios reportaron algunos problemas con respecto a los gastos generales de comunicación y E/S de disco impuesta por MapReduce. Sin embargo, algunos frameworks para procesar grafos se han creado sobre MapReduce. GBASE (Kang et al., 2011), por ejemplo, es un framework de procesamiento de grafos distribuido basada en MapReduce que permite procesar la matriz de adyacencia del grafo (sólo su información topológica). Otro ejemplo es Heigen (Kang et al., 2014), un framework basado en MapReduce para el análisis espectral de grafos (el análisis de las propiedades del grafo, basado en el espectro de las matrices que lo definen). Comparación con Fork-Join FJ y MR realizan operaciones similares en los datos de entrada. La operación map es análoga a las tareas en FJ, ambas llevan a cabo el cálculo principal del algoritmo. Sin embargo, en FJ las tareas envían sus resultados al trabajo padre, el cual se encarga de combinarlos. En MR, la operación map emite pares clave-valor que se fusionan en R bloques y luego se reducen. Por lo tanto, las operaciones de join y reduce son similares. Sin embargo, en FJ la operación de unión representa un cuello de botella para toda la computación. Por otro lado, MR evita el cuello de botella FJ mediante el fraccionado de los resultados intermedios en R bloques y distribuyendo la reducción a lo largo del clúster. Aunque, irónicamente, la operación de división presenta una nueva sobrecarga de rendimiento. 38 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO Desventajas MapReduce fue diseñado para procesar conjuntos de datos grandes (que van desde terabytes a petabytes), sin tener en cuenta varios problemas de rendimiento. Se debe notar que la implementación de MapReduce original de Google es de código cerrado y de uso interno a la empresa. Como alternativa libre, Hadoop surgió como una implementación open-source del framework MapReduce (master y workers) y GFS (Google File System). Siguiendo las especificaciones de Dean and Ghemawat (2008), Hadoop lee y escribe los resultados intermedios en HDFS (Sistema de Archivos Hadoop, del inglés Hadoop File System), la implementación de Hadoop de GFS. Esta característica ayuda a recuperarse de situaciones de fallo, pero genera una considerable sobrecarga de E/S de disco en cada nodo. Por otro lado, los trabajadores de MapReduce suelen dividirse en mappers, es decir, los trabajadores que sólo aplican a la función map, y reducers, es decir, los trabajadores que aplican la función de reducir. Con frecuencia, mappers y reducers no se encuentran en los mismos nodos para equilibrar la etapa de mapeo y la de reducción, especialmente en situaciones donde los resultados intermedios pueden reducirse antes de que termine el mapeo. Sin embargo, esto genera una sobrecarga de la comunicación: los reducers deben transferir bloques de datos desde los nodos mapper a través de la red. En particular, los algoritmos iterativos que deben leer y modificar los mismos datos de forma repetida, enfrentan problemas de rendimiento debido a la sobrecarga de comunicación producido por MapReduce. En primer lugar, MapReduce no soporta algoritmos iterativos por lo que el usuario debe programar un bucle externo que trabajos MR. En los algoritmos de grafos iterativos, por ejemplo, la estructura del grafo se envía a través de la red y se escribe en disco en cada iteración entre trabajos de MR. En segundo lugar, incluso si el algoritmo no modifica los datos en una iteración dada, MapReduce debe volver a procesar los datos sin cambios en cada iteración. Esto significa que estos datos se envían a través de la red, se leen y se escriben en el disco solo para que formen parte de la solución final. Algunos algoritmos, tales como Delta-SimRank (Cao et al., 2012), procesan un resultado aproximado del algoritmo y luego procesan mediante MR los deltas (i.e. las diferencias) del resultado inicial para aproximarse al final. En cada iteración se ignoran aquellos valores de delta que son cercanos a cero, reduciendo efectivamente los costos de E/S (de disco y red). Lamentablemente, no todos los algoritmos pueden ser expresados de esta manera. 3.1.3 Pregel Muchos algoritmos iterativos de grafos se pueden describir en términos de las operaciones aplicadas a los vértices del gráfico. Por ejemplo, el algoritmo de PageRank (Page et al., 1999) (Capítulo 2, Sección 2.3.3) aplica la misma operación para cada vértice del grafo. De hecho, la ecuación 2.1, del Capítulo 2 describe implícitamente las operaciones realizadas a cada vér3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 39 of 206 CHAPTER 3. TRABAJO RELACIONADO 1 2 3 4 5 6 7 8 9 10 11 12 public class VertexFunction { void compute ( List messages ){ if ( superstep < 30) { float pr = 0; for ( Message m : message ) pr += m . value (); setValue ( pr * 0.85 + 0.15 / NumberOfVertices ()); sendToNeighbors ( currentvertex . pr_score ); } else halt (); } } Listado de código 3.1: Ejemplo de PageRank bajo el modelo Pregel. tice. El factor AT Pk−1 suma todas las puntuaciones de PageRank de los vértices entrantes (la transpuesta de la matriz de adyacencia A indica los ejes entrantes). Luego, el algoritmo actualiza la puntuación de PR actual de cada vértice utilizando los puntajes sumados de PR y penaliza su valor usando un parámetro α para producir la nueva puntuación. Como consecuencia, la forma matricial puede ser vista como una función, a menudo llamada función de vértice, que se aplica a la totalidad o a un conjunto de vértices en el grafo. Los modelos de programación que requieren que el usuario defina algoritmos a través de funciones de vértices se les conoce comúnmente como un modelo centrados en el vértice y Pregel (Malewicz et al., 2010) es el más representativo de esta categoría. Además de presentar un modelo para el desarrollador, Pregel también especifica un framework para el procesamiento distribuido de grafos. El listado de código 3.1 muestra una posible implementación del algoritmo de PageRank bajo el modelo Pregel. El procedimiento de cálculo del objeto VertexFunction se aplica a cada vértice. En este ejemplo, el vértice recibe las puntuaciones de relaciones públicas de los mensajes entrantes, actualiza su puntuación de relaciones públicas, y envía el resultado a sus vértices vecinos. Por último, en el ejemplo de PageRank, cuando el algoritmo llega a 30 Superpasos, cada vértice llama a la función halt, lo que indica que el cálculo está terminado y, como resultado, termina el algoritmo. En Pregel, este mecanismo de mensajería es muy importante para mantener la localidad de datos: en lugar de obtener datos de otros vértices – posiblemente ubicados en nodos remotos –, cada vértice envía los subresultados del algoritmo (por ejemplo su puntuación PR) a otros vértices. Entonces, cuando se ejecuta un vértice, los actuales resultados de provenientes de otros vértices se presenta como una lista de mensajes. El framework subyacente que soporta el modelo de Pregel se explica a continuación. Mensajes vértice a vértice y agregadores Una función de vértice puede comunicar subresultados utilizando dos mecanismos: mensajería vértice a vértice y agregadores. Como se muestra en el ejemplo de PageRank 3.3, la mensajería 40 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO PR PR Score PR Score PR HaltAggregator PR Score PR Score PR PR Figure 3.3: Ejemplo de cómputo de PageRank utilizando mensajes y agregadores. vértice a vértice permite a cada vértice compartir el estado actual del cómputo con sus vecinos (aunque el mecanismo permite el envío de mensajes a cualquier vértice). Este tipo de comunicación se utiliza para compartir subresultados, por ejemplo la puntuación de PageRank. El segundo mecanismo utilizado para procesar resultados corresponde al de los agregadores. Este mecanismo se utiliza para proporcionar información global (por ejemplo, contadores o estadísticas), gestionar condiciones de corte o mantener resultados compartidos. Por ejemplo, el algoritmo de clustering k-means produce un conjunto de centroides que son globales al grafo y se actualizan en cada superpaso. Los centroides deben estar disponibles para todo el grafo porque todos los vértices deben calcular su distancia a ellos con el fin de actualizar su ubicación. Por lo tanto, el conjunto de centroides es un ejemplo de resultado global que no puede ser procesado usando mensajería vértice a vértice. Para modelar centroides, el desarrollador puede definir un agregador que administre la computación del centroide. La Figura 3.3 representa otro ejemplo del uso de agregadores, que muestra una ejecución del algoritmo de PageRank donde se utilizan ambos mecanismos (vértice a vértice y agregadores). La puntuación de PR se envía a otros vértices utilizando mensajería vértice a vértice, pero el delta total de puntuación de PR (es decir, la diferencia de puntuación entre el superstep anterior y el actual) se combina en un agregador llamado HaltAggregator. En este ejemplo, el HaltAggregator se puede utilizar para detener la ejecución cuando el delta global de las puntuaciones de PR es menor que un determinado ε, es decir, el algoritmo ha convergido. Componentes de Pregel El framework Pregel se compone de dos tipos de componentes en tiempo de ejecución: los workers y un coordinador. Cada worker se le asigna una partición del grafo y es responsable de la aplicación de la función de vértice a la totalidad o parte de los vértices dentro de su partición asignada. El coordinador (análogo al master en MapReduce) es responsable de iniciar y coordinar la ejecución de los workers. 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 41 of 206 CHAPTER 3. TRABAJO RELACIONADO Figure 3.4: Ejemplo de cómputo de BSP. Una de las operaciones implícitas en los modelos Fork-Join y MapReduce es el de realizar la sincronización entre iteraciones. Esto significa que, cuando el algoritmo se ejecuta, se leen los valores actuales y se retornan los nuevos valores, pero nunca se sobreescriben aquellos valores que están siendo leídos. Para organizar la ejecución del algoritmo distribuido, Pregel utiliza una barrera de sincronización lógica que establece los límites de iteración y evita la lectura de valores inconsistentes. Esta técnica es un framework de procesamiento distribuido en sí mismo y se llama BSP (Bulk-Synchronous Parallel) (Valiant, 1990). En BSP, cada iteración del algoritmo se llama un super paso, y se realiza el cómputo entre barreras de sincronización. Cuando un worker termina su cálculo, alcanza una barrera de sincronización y se bloquea hasta que la barrera sea levantada por el Coordinador. BSP también divide la ejecución del worker en dos etapas: procesamiento y envío de mensajes. Durante la fase de procesamiento, los resultados intermedios se computan –y combinan– localmente en cada worker. Durante el envío de mensajes, los workers comunican sus resultados intermedios a sus compañeros. Cuando todos los trabajadores terminan el envío de mensajes, la barrera se levanta y el siguiente superpaso puede comenzar. Un ejemplo de una ejecución BSP se muestra en la Figura 3.4. Flujo de trabajo El usuario puede enviar una función vértice a Pregel a través coordinador. Al recibir la solicitud del usuario, el coordinador instruye a los workers para activar todos los vértices, tal como se muestra en el ejemplo en la Figura 3.5. En este contexto, un vértice se considera activo cuando forma parte del cómputo actual. Después de la fase de inicialización, el primer superpaso puede comenzar y el coordinador comanda a los workers para aplicar la función vértice definida por el usuario sobre los vértices activos. Si un vértice ha completado el procesamiento para el resto del algoritmo, debe desactivarse invocando a la función "halt". Un vértice puede ser activado de nuevo externamente mediante el envío de un mensaje. Cuando un worker termina su etapa de procesamiento, los resultados producidos son compartidos con otros workers para que estén disponibles a nivel local para la próxima iteración. Como se ve en el ejemplo, algunos workers pueden seguir procesando mientras otros están en42 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO Coordinador Coordinador Coordinador Coordinador Activar Vertices Datos de Agregadores Mensajes de Vértice Datos de Agregadores iniciar siguiente superpaso +estado de agregadores W0 W1 W2 W0 W1 W2 W0 W1 W2 W0 W1 W2 D0 D1 D2 D0 D1 D2 D0 D1 D2 D0 D1 D2 Etapa Inicial Etapa de Procesamiento Etapa de Comunicacion/Procesamiento Etapa de Sincronización Superpaso Figure 3.5: Ejemplo de etapas y comunicación de Pregel. viando resultados. Se debe tener en cuenta, también, la diferencia entre los mensajes de vértice a vértice y los datos del agregador. Mientras que los mensajes de vértices implican una comunicación worker a worker, la naturaleza global del agregador requiere fusionar los resultados en una ubicación central, por ejemplo, en el Coordinador. Si los datos del agregador se pueden dividir por alguna clave, la fusión podría ser distribuida entre los workers (Han and Daudjee, 2015). Cuando todos los workers completan el envío de mensajes, el siguiente superpaso puede comenzar. Antes de comenzar el superpaso nuevo, el coordinador envía una copia del estado de los agregadores a los workers. En este nuevo paso, todos los vértices que recibieron un mensaje se consideran activos y, por tanto, están programados para su ejecución. Desventajas El modelo centrado en el vértice y, en particular, los sistemas basados en BSP tienen algunas desventajas. En primer lugar, el modelo restringe la forma en que los algoritmos pueden ser definidos. Diseñar un algoritmo desde el punto de vista del vértice no es una tarea sencilla debido a que los algoritmos de grafos se describen generalmente en términos de su matriz de adyacencia (recordemos el ejemplo PageRank dada anteriormente). El cambio de paradigma es muy propenso a errores y, en muchos casos, requiere la introducción de "ajustes" o "atajos" para compensar las limitaciones del modelo. Algunos ejemplos se presentan en las implementaciones de algunos algoritmos de enlace de predicción propuestos en los Capítulos 5 y 6. Por otro lado, el modelo de procesamiento BSP introduce sus propios problemas. La restricción de que los trabajadores deben llegar a la barrera de la sincronización antes de comenzar el siguiente superpaso limita el rendimiento general al trabajador más lento. Incluso si los trabajadores ejecutan en nodos con hardware idéntico, el procesamiento asignado podría ser desequilibrado. Por ejemplo, en los grafos que siguen una distribución de ley de potencia, es decir, grafos donde hay muchos nodos con grado bajo y algunos nodos con grado alto, el tiempo de ejecución del superpaso dependerá de la forma en que los nodos de grado alto se distribuyen y 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 43 of 206 CHAPTER 3. TRABAJO RELACIONADO el tiempo que se tarda en procesarlos. Frameworks basados en Pregel Pregel es uno de los frameworks más influyentes que implementaron el modelo de programación centrado en el vértice. Muchos frameworks y modelos se basan en las ideas de Pregel. Por ejemplo, GraphX (Xin et al., 2013) es un framework basado en BSP que cubre todo el flujo de trabajo sobre un grafo, es decir, la adquisición de datos, el particionado del grafo y el procesamiento subsiguiente. También proporciona una visualización del grafo en forma de tabla que permite al usuario operaciones de filtrado, asociación y combinación. Otro framework centrado en el vértice, pero de código cerrado, es Trinity (Shao et al., 2012), un framework de procesamiento de grafos creado por Microsoft. Además de proporcionar una implementación basada en BSP, Trinity incluye capacidades de consulta de grafos y pasaje de mensajes a nivel de nodo computacional. Algunos frameworks se originaron en el mundo académico. HipG (Hierarchycal Parallel Graph) (Krepska et al., 2011), por ejemplo, utiliza la noción de sincronizadores para modelar algoritmos y nodos para realizar cálculos centrados en el vértice. Cada sincronizador puede llamar de forma asíncrona a muchos nodos y luego usar una barrera que espera la finalización de la ejecución de los nodos. Los sincronizadores pueden anidar múltiples sincronizadores hijo, construyendo efectivamente una jerarquía de sincronizadores paralelos. Finalmente, varias implementaciones open-source basadas en Pregel se encuentran disponibles públicamente, por ejemplo, Giraph6 , jPregel7 , GoldenOrb8 y Phoebus9 . 3.1.4 Gather-Apply-Scatter Originalmente introducido por PowerGraph (Gonzalez et al., 2012) y GraphLab (Low et al., 2012), el modelo Gather-Apply-Scatter (GAS) se puede ver como una generalización de Pregel. En este caso, el cálculo centrado en el vértice se divide en tres etapas: Gather (Recolectar), Apply (Aplicar) y Scatter (Difundir). La fase Gather, visualizada en la ecuación 3.1, recoge la información sobre el vértice que está siendo procesado, incluyendo la información acerca de sus propiedades, sus ejes y sus vértices adyacentes. Toda esta información se agrega y luego es utilizada como entrada para la fase Apply. Apply, definida en la ecuación 3.2, ejecuta efectivamente el algoritmo del usuario sobre el vértice. Por último, la fase Scatter se muestra en la Ecuación 3.3 modifica el estado de los vértices adyacentes en función de las modificaciones realizadas en los datos del vértice actual y la información de sus vértices adyacentes. 6 Página Web de Apache Giraph, http://giraph.apache.org/ Web de jPregel, http://kowshik.github.com/JPregel/ 8 Página Web de GoldenOrb, http://www.goldenorbos.org/ 9 Página Web de Phoebus, https://github.com/xslogic/phoebus 7 Página 44 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO Gv ← M Gather(Datav , Data(v,u) , Datau ) (3.1) u ε neighbors(v) Datanew ← Apply(Datav , Gv ) v (3.2) Data(v,u) ← Scatter(Datanew v , Data(v,u) , Datau ) (3.3) En las ecuaciones, Datav representa el estado actual y los metadatos relacionados con el vértice v (por ejemplo, su puntaje de PageRank o el delta de dicho puntaje), Data(v,u) representa el estado actual y los metadatos del eje entre v y u, Datanew es el resultado de ejecutar Apply v usando el estado actual de Datav y los resultados Gv recolectados anteriormente. 3.1.5 Procesamiento Asíncrono Algunos modelos están diseñados para ejecutar en un modo de procesamiento asíncrono. Por ejemplo, el modelo GAS puede ser ejecutado mediante un modelo de cálculo BSP o el modelo asíncrono (Gonzalez et al., 2012; Low et al., 2012). La idea detrás del modelo asíncrono es exponer las modificaciones al grafo de inmediato, incluso si otros vértices dependen de aquellos datos que están siendo modificados. Mientras que BSP garantiza que cada paso del algoritmo será ejecutados por separado, el modelo asíncrono relaja esta restricción. Esto significa que para algunos algoritmos el modelo asíncrono no se comportará correctamente porque la información sobre la siguiente etapa se puede leer en el paso actual. Sin embargo, en los algoritmos basados en métodos de aproximación numérica, como PageRank, este modelo puede acelerar la convergencia. Otro ejemplo de un modelo de procesamiento asíncrono es Giraph Unchained (Giraph UC) por Han and Daudjee (2015). Giraph UC es una adaptación de la popular aplicación de código abierto de Pregel, Giraph. Este framework proporciona un modelo basado en Pregel que procesa los mensajes de forma asíncrona, es decir, un vértice puede procesar los mensajes tan pronto como estén disponibles. Algunos frameworks que proporcionan procesamiento asincrónico también proporcionan garantías sobre la secuencialidad, i.e. la capacidad de reproducir los pasos de un programa paralelo en una secuencia. Por ejemplo, si dos vértices adyacentes modifican sus valores al mismo tiempo, el resultado no puede ser reproducido, lo que aumenta la complejidad del diseño de algoritmos y su depuración. Por otra parte, si los dos vértices adyacentes están autorizados a ejecutar, el no determinismo generado puede llevar a algunos algoritmos a diverger y, por lo tanto, no llegar a una solución (Gonzalez et al., 2012). Los frameworks que implementan este modelo, como GraphLab distribuido (Low et al., 2012), proporcionan un mecanismo de sincronización bloqueante para evitar la ejecución o modificación de vértices adyacentes al mismo tiempo. 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 45 of 206 CHAPTER 3. TRABAJO RELACIONADO 3.1.6 Resilient Distributed Datasets Formalmente, los Resilient Distributed Datasets (DDR) (Zaharia et al., 2012) son conjuntos con particiones inmutables que soportan un conjunto de operaciones básicas. Una aplicación popular de RDD es proporcionada por el framework Spark (Zaharia et al., 2012). En Spark, cada RDD es un conjunto de pares (clave, valor) indexados y particionados por clave. Los RDD siguen una estrategia de partición, como en la mayoría de los frameworks, pero añaden una restricción de inmutabilidad, es decir, un RDD no se puede modificar. Para alterar un RDD, un nuevo RDD debe crearse mediante la aplicación de una de las operaciones previstas. Por ejemplo, para aplicar una función dada a todos los valores en un RDD y crear un nuevo RDD, un usuario puede utilizar una operación map y pasar como argumento la transformación que se debe realizar. La secuencia de transformaciones aplicadas a un RDD o conjunto de RDDs, se denomina linaje. El linaje es un Grafo Dirigido Acíclico (DAG) compuesto por operaciones, que permite recuperar el RDD actual en escenarios de fallo. Cuando falla un worker, Spark vuelve a construir el último estado de la partición del RDD asignada al worker mediante la aplicación de las operaciones presentes en el linaje hasta el último estado. Esto sólo puede ocurrir debido a la inmutabilidad de los conjuntos de datos, lo que permite a Spark volver a reproducir las operaciones de RDD pasados. Para algunas operaciones, puede ser imposible mantener todo el linaje de RDD. Por ejemplo, en PageRank, el RDD que mantiene el valor de PR, es decir, el conjunto de pares (clave, PRscore), se transforma en cada paso mediante la unión con la matriz de adyacencia (que es también un RDD) como se muestra en la 3.6. Cada contribución a la puntuación de PR a un vértice por parte de sus vecinos se reduce a un solo valor de PR (mediante la suma de los valores) y luego se penaliza mediante la ecuación clásica de PageRank (Ecuación 2.27). En este ejemplo, debido al hecho de que la puntuación de PR de cada vértice depende de los resultados de los vértices adyacentes, en caso de fallo de un worker, su partición asignada debe ser recalculada usando todas las particiones relacionadas en el linaje. En casos extremos, todo el linaje se recalcula para todas las particiones. Para evitar hacer eso, el usuario puede persistir el RDD de la puntuación PR cada pocas iteraciones del algoritmo y, en caso de fallos, solo recalcular a partir de ese punto. Una de las ventajas de los RDD es el poder descriptivo de su conjunto de operaciones. De hecho, tanto MapReduce como Pregel pueden describirse mediante un conjunto de operaciones sobre RDDs. Por ejemplo, la versión RDD de MapReduce toma un conjunto de datos de entrada y produce un conjunto de datos reducido mediante la aplicación de una operación de map para cada entrada (clave, valor) y después, una operación groupByKey realiza una operación de reducción similar. En su forma más simple, Pregel aplica una operación map en cada vértice para producir un RDD resultante y, después, "envía mensajes" a los vértices vecinos al combinar dicho RDD con el RDD de la matriz de adyacencia (emulando el envío de mensajes). RDD suele ser mucho más rápido que otros frameworks debido a que la mayoría de las 46 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO neighbors pr_score 0 join (set PR score to each neighbor) pr_contribution0 reduce by key (sum) and apply PR map pr_score 1 join pr_contribution1 ... Figure 3.6: Ejemplo de linaje de Resilient Distributed Datasets para el algoritmo PageRank. operaciones son en memoria. Sin embargo, esta ventaja es contrastada por el alto consumo de memoria del framework. En escenarios de poca memoria, los RDDs se pueden escribir en el disco, con un costo de E/S asociado. La adaptación más popular de RDD a procesamiento de grafos es GraphX (Xin et al., 2013). GraphX proporciona una interfaz orientada a grafos sobre Spark y proporciona diferentes RDDs para representar aristas y vértices. La EdgeTable, por ejemplo, almacena todas las aristas en el gráfico. Por otro lado, el RDD VertexDataTable almacena los datos asociados a cada vértice. Para unir ambas tablas, el framework utiliza un RDD llamado VertexMap que une cada vértice a las particiones en EdgeTable que contienen vértices adyacentes (conectados al vértice en cuestión). 3.1.7 Limitaciones de los Frameworks Actuales Debido a que gran parte de los frameworks de procesamiento de grafos deben leer los datos de una fuente determinada para procesar el algoritmo, los requisitos de memoria representan un límite de rendimiento en pequeños clusters. En la mayoría de los casos, una porción del grafo se carga y procesa, pero en otros casos el grafo necesita ser completamente cargado en memoria. Además, cada framework introduce estructuras de datos en memoria que restringen cada vez más los requisitos de memoria. Una de las propuestas de esta tesis es un framework que reduce el consumo de memoria mediante el almacenamiento de los datos del grafo en una base de datos de grafos distribuida, manteniendo solo sub-resultados en memoria. Otro defecto en muchos frameworks se relaciona con las estrategias de particionado. En algunos casos, el particionado de datos de entrada o de resultados intermedios permite reorganizar la información mediante una clave dada (e.g. ordenándolos). En otras situaciones, los datos se reparten de tal manera que la mayor parte de los datos a procesar estén relacionados entre sí. Sin embargo, aunque estas técnicas son útiles, no hay mucho soporte para la asignación a 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO 47 of 206 CHAPTER 3. TRABAJO RELACIONADO trabajadores específicos. Por otra parte, la asignación de particiones a los trabajadores no está relacionado con las características del nodo del trabajador. En clústers heterogéneos, es decir, clústers de ordenadores con diferentes capacidades (memoria principal, velocidad de la CPU, número de núcleos de CPU, capacidad de almacenamiento), la asignación de particiones a los nodos de computación permite distribuir aplicaciones paralelas para maximizar un criterio de desempeño determinado (Kim et al., 2003). En Pregel, por ejemplo, el particionado es estático, una vez que a los trabajadores se les asigna una partición, esto no puede ser modificado en iteraciones posteriores. En frameworks del tipo Fork-Join, como GridGain, el desarrollador debe escribir el código que asigna particiones de tareas, lo cual es engorroso. En MapReduce, los datos se dividen en bloques. Las divisiones utilizan una estrategia de partición que sólo depende de los datos. Las tareas son asignadas a los trabajadores por el Master, en ambas etapas map y reduce. Esta asignación no es fácilmente modificable por los desarrolladores. En esta tesis, se presenta una API para la asignación de particiones a los trabajadores. Cuando el algoritmo de recomendación procesa un conjunto de vértices, una estrategia de mapeo definida por el usuario transforma esos vértices en tareas y distribuye cada tarea en un conjunto de trabajadores. A modo de ejemplo, una estrategia de mapeo basada en ubicación asigna vértices por su ubicación en el soporte de almacenamiento. A diferencia de otros frameworks, este trabajo se centra en el problema de la personalización de la distribución del algoritmo de grafos en grupos heterogéneos. Esto implica proporcionar acceso a la información de los nodos del clúster, tal como el uso de memoria, uso de CPU y tamaño colas de trabajo, y el acceso a la información sobre el soporte de almacenamiento, tales como la ubicación de los datos (por ejemplo, los nodos físicos responsable de los datos de un vértice dado) y la ubicación de los datos en caché. En cuanto a diseño de algoritmos, la mayoría de los frameworks sólo exponen un único modelo de programación. El usuario, a continuación, debe evaluar los diferentes frameworks por separado. Por otra parte, el usuario puede necesitar poner a punto los frameworks considerados para proporcionar una base común para la comparación, lo cual puede ser una tarea abrumadora. Por otro lado, el usuario puede necesitar aprender cuestiones de programación específicos para cada framework seleccionado. En el framework propuesto en esta tesis, se exponen varios modelos de programación y el usuario puede seleccionar uno de ellos. Bajo este framework, el usuario debe escribir el mismo algoritmo con diferentes modelos, pero al utilizar el mismo soporte subyacente, la puesta a punto del framework se aplica igualmente a todos los modelos, lo que facilita la tarea de comparación. 48 of 206 3.1. FRAMEWORKS DE PROCESAMIENTO DE GRAFOS DISTRIBUIDO CHAPTER 3. TRABAJO RELACIONADO 3.2 Bases de Datos de Grafos Distribuidas El diseño de un sistema de almacenamiento y recuperación de datos de grafos consiste en elegir el formato de representación de todos los componentes involucrados (vértices, aristas y propiedades) y un análisis cuidadoso de la forma en que se accederá a estos componentes. Por ejemplo, el enfoque ingenuo de almacenar bordes del grafo en una sola tabla RDBMS (Relational Database Management System) es una forma rápida y sencilla de almacenar y obtener ejes. La tabla de adyacencia resultante puede consistir de dos columnas que representan los vértices involucrados en la definición del eje. Sin embargo, para recorrer el gráfico, es decir, siguiendo un camino de vértices y aristas, la tabla de adyacencia debe ser unida (usando la operación JOIN) con ella misma. En efecto, esto significa que el vértice destino del borde actual debe coincidir con el vértice origen del siguiente eje en la operación de recorrido. En la mayoría de los RDBMS esta operación es muy costosa y produce un impacto negativo en el rendimiento de la operación de recorrido. Por otra parte, si los datos del grafo se distribuyen a través de un clúster de máquinas, mantener la localidad de los datos representa grandes desafíos. Dado el costo de cálculo de un esquema de partición del grafo que maximice la localía de los datos, la mayoría de las bases de datos utilizan una heurística (por ejemplo, la partición por el ID o tag del vértice) o se limitan a mantener la localidad a nivel vértice (se garantiza que los ejes y las propiedades de los vértices estarán en el mismo nodo). Esta sección presenta técnicas y herramientas que permiten, de manera eficiente, almacenar y recuperar un grafo distribuido en un clúster de computadoras. 3.2.1 Tipos de Bases de Datos de Grafos En la literatura de bases de datos de grafos distribuidos, hay al menos dos tipos de alternativas: almacenes RDF (Resource Description Framework) y grafos de propiedades. Los almacenes RDF se originaron con la Web Semántica (Berners-Lee et al., 2001; del Castillo et al., 2010; Erling and Mikhailov, 2010) y la mayoría de ellos se han desarrollado durante años. La especificación RDF proporciona un representación de las relaciones del grafo mediante el uso de ternas < su jeto, predicado, ob jeto >. El sujeto es el vértice origen, el predicado es la etiqueta del eje, y el objeto es el vértice de destino. Por lo general, se añade un contexto para expresar a qué grafo pertenece dicha terna. La representación < su jeto, predicado, ob jeto, contexto > (SPOC) se suele llamar un Quad. Los almacenes RDF generalmente persisten las tuplas SPOC en un almacén de tipo clave-valor, y crean varios índices para soportar diferentes tipos de acceso a la consulta. Por ejemplo, YARS2 (Harth et al., 2007) es una tienda RDF distribuido que crea un índice SPOC y cuatro índices adicionales para apoyar los patrones de acceso alternativas. Blazegraph10 , por otro lado, es una base de datos basada en los conceptos introducidos por YARS2, pero añade un motor de inferencia y una implementación del modelo GAS. Virtuoso (Erling and 10 Página Web de BlazeGraph, https://www.blazegraph.com/product/ 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS 49 of 206 CHAPTER 3. TRABAJO RELACIONADO Mikhailov, 2010) es otro ejemplo de una base de datos madura que soporta el formato RDF y proporciona un mecanismo de inferencia sobre sus tuplas. Los grafos de propiedades son un tipo de almacén de grafos donde ejes y vértices se modelan con un número arbitrario de propiedades, por lo general, en un formato clave-valor. Una técnica común para almacenar un grafo de propiedades es separar los diferentes elementos de un gráfico: listas de adyacencia de cada vértice, datos de los vértices, vértices con ejes de entrada, vértices con ejes de salida, entre otros. Las implementaciones de este tipo de bases de datos son relativamente nuevas y en su mayoría están relacionadas con el movimiento NoSQL, ofreciendo alternativas de almacenamiento que no se basan en el modelo relacional. El apéndice A presenta un estado del arte de tipos de bases de datos NoSQL basados en grafos, entre otras bases de datos (clave-valor, basadas en documentos y basadas en columnas). A modo de ejemplo, Titan 11 es una base de datos de grafos que permite al usuario seleccionar el soporte de almacenamiento de entre una serie de almacenes de datos, incluyendo HBase12 , Cassandra13 , BerkeleyDB (Olson et al., 1999) y Hazelcast14 . Al igual que muchas nuevas bases de datos, Titan implementa la API Blueprints15 , que se conecta con una serie de herramientas ya implementadas para consultar y procesar grafos. Otras bases de datos proporcionan una interfaz de grafos sobre un almacén orientado a documentos (es decir, un almacén de claves-valor, donde los valores tienen un formato conocido pero flexible, tal como XML o JSON), que es el caso de OrientDB 17 . Como último ejemplo, FlockDB18 16 y ArangoDB es un almacén de grafos basado en listas de adyacencia que sólo almacena la estructura del gráfico. Esta base de datos fue desarrollada en Twitter para almacenar las relaciones seguidor/seguido de sus usuarios. 3.2.2 Bases de Datos de Grafos Disponibles Hoy en día, los grafos se utilizan para representar grandes entidades del mundo real (Krepska et al., 2011), tales como mapas y redes sociales. Por ejemplo, OpenStreetMap19 , un repositorio de datos geográficos abierto mantenido por una comunidad de usuarios enorme, llegó a más de 1800 millones de nodos en el 2013. Por otro lado, Twitter ha experimentado un tremendo crecimiento, según lo informado en su declaración de registro del mercado de valores20 , y en la actualidad tiene más de 300 millones de usuarios activos twitteando 500 millones de tweets por día y soporta miles de millones de relaciones de seguidores/seguidos. El amplio interés de alma11 Página Web de Titan, http://thinkaurelius.github.io/titan/ Web de HBase, http://hbase.apache.org/ 13 Página Web de Cassandra, http://cassandra.apache.org/ 14 Página Web de Hazelcast, http://www.hazelcast.com/ 15 Página Web de Blueprints, https://github.com/tinkerpop/blueprints/wiki 16 Página Web de OrientDB, http://orientdb.com/orientdb/ 17 Página Web de ArangoDB, https://www.arangodb.com/ 18 Página Web de FlockDB, https://github.com/twitter/flockdb 19 Página Web de OpenStreetMap, http://www.openstreetmap.org/ 20 http://www.sec.gov/Archives/edgar/data/1418091/000119312513390321/d564001ds1.htm 12 Página 50 of 206 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS CHAPTER 3. TRABAJO RELACIONADO compró B A pró com ró mp co visitó C visitó D visitó A B C D Compró Visitó B A B C,D C Figure 3.7: Ejemplo de representación de una base de datos de grafos. cenar y consultar grandes gráficos ha dado lugar a una amplia gama de bases de datos NoSQL conocidas como orientado a grafos o bases de datos basadas en grafos. Estas bases de datos atacan el problema de almacenar los datos y las relaciones del grafo, permitiendo consultarlo y navegarlo de manera eficiente. De forma similar a lo que sucede con las bases de datos orientadas a documento (Apéndice A), no hay ninguna base de datos de grafos que puede ser utilizado como un "diseño de referencia" (a diferencia de las clave-valor o basadas en columnas). Navegar grafos almacenados en un RDBMS es caro ya que cada movimiento a través de los ejes implica una operación de unión sobre la tabla de adyacencia. Por lo general, las bases de datos de grafos representan los datos y sus relaciones en una forma natural, es decir, usando una estructura que contiene la información del vértice y una lista de punteros a otros vértices. La Figura 3.7 muestra un ejemplo de representación de grafos en la que cada vértice se almacena junto a su lista de adyacencia, es decir, los vértices con los cuales se relaciona. Esta representación está optimizada para consultas de ejes en la dirección saliente. Entre las bases de datos de grafos disponibles se puede encontrar a Neo4J21 , InfiniteGraph22 , InfoGrid23 , Hypergraph (Iordanov, 2010), AllegroGraph (Aasman, 2006) y Blazegraph. Las bases listadas son soluciones de código abierto o bases de datos distribuidas libres, considerando sólo los que prestan algún tipo de mecanismo de persistencia. Las bases analizadas se describen a continuación. Neo4J es un proyecto de código abierto que utiliza índices de Apache Lucene24 para almacenar datos de manera que el acceso a los vértices y las relaciones sea más eficiente. Neo4J también utiliza un mecanismo MVCC con una estrategia read-commited para incrementar la concurrencia de lecturas y escrituras. Estas decisiones permiten el almacenamiento y acceso a millones de vértices en un solo nodo computacional. En Neo4J, el sharding de los vértices entre los nodos se realiza manualmente (por el usuario), utilizando los conocimientos y patrones de acceso específicos del dominio (por ejemplo, acceso por país, URL, etc.). Además, una desfragmentación periódica (reubicación de vértices) uti21 Página Web de Neo4J, http://neo4j.com/ Web de InfiniteGraph, http://www.objectivity.com/products/infinitegraph/ 23 Página Web de InfoGrid, http://infogrid.org/ 24 Página Web de Apache Lucene, https://lucene.apache.org/ 22 Página 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS 51 of 206 CHAPTER 3. TRABAJO RELACIONADO lizando reglas se ha propuesto, pero no implementado. 25 . El acceso a un grafo Neo4J se puede realizar a través de una API de Java o lenguajes de consulta de grafos como SPARQL (Prud’Hommeaux and Seaborne, 2008) o Gremlin26 . SPARQL es un lenguaje que se utiliza para consultar los datos almacenados en formato RDF (Resource Description Framework), un modelo de datos de metadatos originalmente creado por el Consorcio World Wide Web (W3C) para describir los recursos en la Web (es decir, la adición de información semántica). En general, los datos se almacenan como ternas RDF que indican un sujeto, un predicado y un objeto. Intrínsecamente, representan un grafo dirigido y etiquetado: el vértice fuente, el tipo de relación y el vértice destino. Además de una versión gratuita, Neo4J tiene versiones empresariales que añaden monitoreo, respaldo en línea y clustering de alta disponibilidad. El módulo Neo4J que permite definir una estructura de nodos Maestro-Esclavo sólo está disponible en la versión de pago. InfiniteGraph tiene su propio soporte de almacenamiento llamada Objectivity/DB. A diferencia de Neo4J, cuenta con sharding automático utilizando una "ubicación gestionada" para distribuir el grafo en un clúster. La ubicación gestionada permite al usuario definir reglas para realizar el sharding y, por ejemplo, mantener vértices relacionados en la misma ubicación. Por desgracia, la licencia gratuita permite almacenar sólo 1 millón de ejes y vértices. InfoGrid base de datos de grafos que se basa en estructuras conocidas como NetMeshBase, que contienen los vértices del grafo, llamada MeshObjects, y sus relaciones. Infogrid permite persistir la base de datos en un RDBMS como MySQL o PostgreSQL, o el uso de un sistema de archivos distribuido como HDFS o Amazon S3. Si se utiliza un sistema de archivos distribuido como HDFS, se pueden reusar las características de disponibilidad y escalabilidad del sistema. Además, las estructuras NetMeshBase pueden comunicarse entre sí de modo que los grafos se pueden distribuir entre los diferentes grupos. HyperGraphDB introduce un enfoque diferente para la representación de los datos almacenados mediante el uso de hipergrafos. Un hipergrafo define una relación n-aria entre los diferentes vértices de un grafo. Esto reduce el número de conexiones necesarias para conectar los vértices y proporciona una manera más natural de relacionar los nodos en un grafo. Un ejemplo de un hipergrafo es la línea de frontera entre países, donde se pueden añadir nodos como Polonia, Alemania y República Checa. La base de datos sólo requiere una hypergraph que contiene estos vértices para almacenar la relación, mientras que una representación gráfica utiliza tres arcos entre los nodos. Para el almacenamiento, HyperGraphDB se basa en BerkeleyDB (Olson et al., 1999), proporcionando dos capas de abstracción sobre ella: una capa primitiva, que incluye un grafo de las relaciones entre los 25 On sharding graph databases, http://jim.webber.name/2011/02/on-sharding-graph-databases/ Web de Gremlin, https://github.com/tinkerpop/gremlin/wiki 26 Página 52 of 206 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS CHAPTER 3. TRABAJO RELACIONADO vértices, y una capa de modelo, que incluye las relaciones entre las capas primitivas, agregando índices y cachés. Estas abstracciones permiten definir diferentes interpretaciones del grafo, incluyendo RDF, OWL (una extensión de RDF que permite crear ontologías en RDF), una API Java y una API Prolog, entre otros. Blazegraph es una base de datos RDF que escala a un gran número de vértices y aristas. Se basa en un almacenamiento de registros estructurados e índices B+, que se particionan a medida que la cantidad de datos aumenta. Para las configuraciones locales, BlazeGraph puede contener hasta 50 mil millones de vértices o arcos sin sacrificar el rendimiento. Si los vértices se distribuyen, la base de datos proporciona un sencillo mecanismo dinámico de sharding que consiste en particionar índices RDF y distribuirlos a través de diferentes nodos. Además, ofrece la posibilidad de replicar los nodos con el mecanismo maestroesclavo. BlazeGraph ofrece una API para SPARQL y consultas RDF en C++. Esta última es una extensión de RDFS (Resource Description Framework Schema), un conjunto de clases o descripciones para la definición de ontologías en bases de datos RDF, que tiene como objetivo hacer inferencias acerca de los datos almacenados. AllegroGraph es un almacén de tuplas RDF que soporta transacciones ACID y que es comercializada por una empresa llamada Franz Inc., que ofrece una versión gratuita limitada a 3 millones de ternas RDF. Como HyperGraphDB, esta base de datos tiene una amplia gama de métodos de consulta que incluyen: SPARQL, RDFS, OWL, Prolog y APIs nativas para Java, Python, C# entre otros. Además de las bases de datos de la lista, hay otras bases de datos de dominio específico que merecen mención. Uno es FlockDB27 , una base de datos de grafos desarrollado por Twitter. Se trata de una base de datos con un diseño muy simple ya que sólo almacena la lista de adyacencia de los usuarios, es decir, sus seguidos y seguidores. Entre sus características más importantes se puede mencionar sus capacidades de escalado horizontal y la capacidad de realizar sharding automático. 27 Página Web de FlockDB, https://github.com/twitter/flockdb 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS 53 of 206 Persistencia Sharding Lenguaje API Métodos de Consulta Neo4J Índices en Manual Java Java, HTTP + SPARQL (RDF Disco (Apache JSON, y OWL), Java Lucene por bindings in API, Gremlin defecto) Ruby, Clojure, Python, among others InfiniteGraph Objectivity/DB Basado en reglas C++ C++, Java, API para Python and C# recorridos y Predicate Queries 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS InfoGrid MySQL, Manual Java HadoopFS, Java, HTTP + Viewlets, JSON Templates entre otros HypergraphDB 2 capas: HTML, Java Manual Java Java Java API, Primitiva Prolog, OWL, (Datos Crudos) RDF via y Modelo Sesame (relaciones + caching + índices) BlazeGraph Índices Sharding ”Dinámico” (árboles B+) (por rango de claves) Java Java y SPARQL, descubrimiento RDFS++ de servicios utilizando JDNI AllegroGraph Índices Manual Lisp HTTP + JSON SPARQL, y clientes en Prolog, diferentes RDFS++, y una lenguajes API de recorrido de grafos Table 3.1: Comparación de Bases de Datos de Grafos. CHAPTER 3. TRABAJO RELACIONADO 54 of 206 Nombre CHAPTER 3. TRABAJO RELACIONADO Una segunda base de datos a destacar es Graphd (Meyer et al., 2010), el soporte de almacenamiento de FreeBase (Bollacker et al., 2008), una base de datos de colaboración que almacena información sobre las películas, las artes y el deporte, entre otros. Cada tupla de la base puede definir un nodo o una relación entre los nodos. Las tuplas no se sobrescriben: cuando se crea una nueva tupla la tupla modificada se marca como eliminada. Índices invertidos se utilizan para acelerar el acceso, yendo directamente a las posiciones de tuplas en la base de datos. MQL (Metaweb Query Language), un lenguaje de FreeBase análogo a SPARQL, se utiliza para consultar la base de datos. Graphd es un sistema propietario, por lo tanto, no se incluyó en la comparación. Sin embargo, el acceso a la API de consulta de base de datos está disponible en la Web, a través de FreeBase. Por último, en (Sakr et al., 2014) los autores proponen una extensión a SPARQL, llamado G-SPARQL, y un enfoque de almacenamiento híbrido en el que la estructura del grafo y sus atributos se almacenan en una base de datos relacional. Las consultas sobre los atributos del gráfico se ejecutan en la base de datos relacional, mientras que las consultas topológicas se ejecutan sobre una representación en memoria. Esta estrategia evita la pérdida de rendimiento debido a la unión recursiva de las tablas, mientras que se beneficia de la eficiencia en la consulta y el almacenamiento de una base de datos relacional. Sin embargo, los autores no mencionan una variante distribuida del enfoque mencionado. Tabla 3.1 presenta una comparación entre las bases de datos descritas anteriormente: Neo4j, InfiniteGraph, InfoGrid, hypergraph, AllegroGraph y BlazeGraph. Las bases de datos NoSQL gráfico orientada disponibles se analizan y comparan en la Tabla 3.1 a través de las siguientes dimensiones: • Persistencia: Se refiere al método de almacenamiento de datos en los dispositivos no volátiles o persistentes. Varias alternativas son posibles, por ejemplo, índices, archivos, bases de datos y sistemas de archivos distribuidos. Otra alternativa utilizada en algunos casos es mantener los datos en la RAM y hacer periódicamente instantáneas en soportes persistentes (Malarvannan and Ramaswamy, 2010). • Sharding: El particionado de datos o sharding es una técnica para dividir un conjunto de datos en diferentes subgrupos. Cada partición se asigna generalmente a un nodo a fin de distribuir la carga de las operaciones. Existen diferentes maneras de implementar el método de sharding. Un ejemplo sería aplicar una función de hash a los datos a almacenar y dividir el espacio de hashing en múltiples rangos, cada uno representando una partición. Otro ejemplo es el uso de un campo particular del esquema de datos para realizar partición. Una base de datos que soporta la gestión automática del sharding permite desacoplar al desarrollador de los detalles de la topología de la red, incluyendo el soporte para agregar o eliminar nodos de la red. Por lo tanto, el sharding crea la ilusión de un único nodo, mientras que, de hecho, hay un gran conjunto de nodos. En este análisis, la dimensión Sharding indica si la base de datos admite sharding y cómo se puede configurar. Si el sharding no está integrado en la funcionalidad de base de datos, 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS 55 of 206 CHAPTER 3. TRABAJO RELACIONADO el cliente tiene que lidiar con la partición de datos entre nodos. • Lenguaje de Implementación: Describe el lenguaje de programación la base de datos se implementa con. En algunos casos, puede indicar una preferencia de los desarrolladores de base de datos para una tecnología requerida particular. • API: Se refiere al tipo de interfaz de programación utilizado para acceder a la base de datos. En general, las bases de datos NoSQL en la era de la Web permiten el acceso a través del protocolo HTTP. Sin embargo, el acceso a una base de datos utilizando un cliente HTTP es engorroso para el desarrollador y, por ello, es común encontrar clientes nativos en ciertos lenguajes de programación. Esta dimensión enumera los lenguajes de programación que tienen los clientes nativos para la base de datos. Además, se indica el formato de mensaje que se utiliza para añadir o modificar los elementos de la base de datos. • Método de consulta: Se describen los métodos de acceso a la base de datos y se enumeran las diferentes formas de acceder a estos métodos a través de la API. Esta dimensión indica las estrategias o lenguajes de consulta que soporta cada base de datos. 3.2.3 Limitations of Graph Databases Las capacidades de procesamiento de bases de datos de grafos distribuidas se limitan a consultas simples, que consta de recorridos sencillos y operaciones de filtrado. Dado que la mayoría de estas bases de datos se centran en la eficiencia del almacenamiento y la coherencia, es natural que ignoren el aspecto de flexibilidad de procesamiento. Sin embargo, esto impide el desarrollo de algoritmos de recomendación más complejos como los de predicción de enlace, directamente sobre la base de datos. En algunas bases de datos, como Titán, se incorpora un framework MapReduce, aunque el modelo de programación no se ajusta bien a algunos algoritmos de grafos. Por otro lado, la mayoría de las bases de datos de gráficos disponibles no proporcionan sharding. En lugar de ello, algunos de ellos proporcionan un mecanismo de replicación que distribuye los datos de base de datos en un grupo de ordenadores. Esto permite equilibrar operaciones de lectura y escritura entre los nodos replicados, pero implica mantener copias innecesarias de la información que deben mantenerse consistente. La base de datos de grafos desarrollada en esta tesis se basa en un almacén clave-valor distribuido y, los modelos de procesamiento implementadas están todos configurados para utilizar el almacén de grafos propuesto por defecto. Esta decisión elimina la necesidad inicial de particionar los datos del grafo como se requiere por parte de algunos frameworks, incluyendo MapReduce. Sin embargo, algunos modelos pueden beneficiarse más de una representación de almacenamiento que otros. En aras de mantener la simplicidad y teniendo en cuenta el alcance de la propuesta, esta base de datos no implementa algunos de los mecanismo más comunes para la consistencia de los datos y la recuperación de errores tales como transacciones o replicación. 56 of 206 3.2. BASES DE DATOS DE GRAFOS DISTRIBUIDAS CHAPTER 3. TRABAJO RELACIONADO 3.3 Resumen En este capítulo se presentó una breve introducción a los frameworks de procesamiento de grafos y bases de datos distribuidas. Como se mencionó, algunos frameworks están especialmente diseñados para los algoritmos de grafos, mientras que otros son más genérico y se puede adaptar a una representación gráfica dada. Por lo general, los frameworks de procesamiento obtienen los datos iniciales de un soporte persistente. Sin embargo, durante el procesamiento, la mayoría de los frameworks mantienen una representación en memoria del grafo que limita la memoria disponible para otras estructuras de datos, por ejemplo, utilizadas para mantener resultados intermedios. Los frameworks exponen un modelo de programación que facilita el desarrollo de algoritmos y promueve el uso correcto de la plataforma subyacente. Por otro lado, las bases de datos de grafos suelen centrarse en la persistencia eficiente de datos y mantener la coherencia de datos, pero carecen de la capacidad de procesamiento de los frameworks. Por lo general, proporcionan un lenguaje de consulta para obtener datos del grafo, que generalmente se limita sólo a recorridos. En este trabajo, se propuso un framework de procesamiento sobre una base de datos de grafos orientado al desarrollo de algoritmos de recomendación para redes sociales. El framework expone varios modelos de programación que puede consumir datos de la base de datos, lo que reduce los requisitos de memoria, y permite que el framework utilice más recursos para las estructuras de soporte, tales como las estructuras que se encargan de la combinación de los resultados intermedios. Además, proporciona el mecanismo de estrategias de mapeo que le permite particionar los datos de entrada utilizando estadísticas y metadatos de los trabajadores, lo que ayuda a ajustar el procesamiento de las características de cluster y los datos de la base de datos. 3.3. RESUMEN 57 of 206 Graphly 4 Como fue explicado en el Capítulo 3, los frameworks de procesamiento de grafos usualmente cargan datos del disco en memoria para construir una representación del grafo. Esto impone una restricción en la cantidad mínima de memoria RAM necesaria para que el framework procese grafos cada vez más grandes. Aún si el grafo se puede almacenar en memoria, los frameworks utilizan otras estructuras para procesar mensajes y resultados intermedios, incrementando aún más los requerimientos de memoria. Sumado a esto, la mayor parte de los frameworks están diseñados para soportar un modelo específico de programación. Esta característica limita la comparación de los frameworks y sus modelos de programación debido a que cada implementación debe instalarse, configurarse y ajustarse de forma separada. Por el otro lado, las bases de datos de grafos no siempre proveen capacidades genéricas de procesamiento, tal como MapReduce o Pregel. El sistema propuesto en esta tesis, llamado Graphly (Corbellini et al., 2015b), es un framework alternativo que ataca estos problemas. Graphly es un soporte novedoso que aprovecha las ventajas de las bases de datos distribuidas y provee abstracciones para permitir a los usuarios desarrollar algoritmos de recomendación distribuidos bajo diferentes modelos de programación. Este soporte está orientado no solo a facilitar el desarrollo de nuevos algoritmos de recomendación sobre grafos de gran escala, sino también a convertirse en un ambiente de testing y comparación para la investigación y el desarrollo de dichos algoritmos. Una de las características principales de Graphly es el de soportar múltiples modelos de procesamiento de manera que el usuario pueda elegir qué modelo se ajusta mejor al tipo de algoritmo que se está desarrollando (e.g. algoritmos iterativos, como PageRank, o algoritmos basados en recorridos, como Katz) y de esa manera optimizar la performance del algoritmo. Es más, esta característica ayuda a los usuarios a comparar el mismo algoritmo, desarrollado bajo diferentes modelos, bajo la misma infraestructura de comunicación. Esto reduce el overhead de configurar y ajustar dos o más frameworks de forma separada para cada modelo deseado, reduciendo el sesgo de la comparación mediante el uso del mismo soporte de comunicación. Así, 58 of 206 CHAPTER 4. GRAPHLY Graphly se convierte en una opción para el desarrollo y evaluación de algoritmos recomendación experimentales. Como se mostrará en los Capítulos 5 y 6, el modelo elegido para implementar el algoritmo tiene un gran impacto en su rendimiento final y en la legibilidad del código. Otra característica importante de Graphly son las estrategias de mapeo o mapping strategies, un mecanismo para asignar particiones de datos a workers (i.e. un worker es una unidad de computación, tal como un thread o un proceso, que ejecuta tareas en un nodo computacional). Las estrategias de mapeo son una combinación entre un esquema de particionado y una asignación de particiones a workers utilizando sus metadatos. Este enfoque no solo provee esquemas de particionado estándar como round-robin o basados en ubicación, sino que también permite al desarrollador incluir otros esquemas basados en otras métricas. Por ejemplo, una de las estrategias provistas permite mapear vértices a workers de acuerdo a la cantidad de memoria disponible en cada nodo. La falta de memoria en el nodo de un worker dado puede producir un impacto negativo en la performance o incluso causar un fallo debido a insuficiencias de memoria. Bajo este escenario, una estrategia basada en memoria puede producir recomendaciones más rápidas o incluso permitir que el algoritmo complete la ejecución. Así, los usuarios de Graphly pueden elegir la estrategia más adecuada basándose en el algoritmo a ser desarrollado. El presente Capítulo se organiza de la siguiente manera. La Sección 4.1 brinda un panorama general de la arquitectura de Graphly, mientras que las secciones remanentes introducen detalles de cada capa en la arquitectura, comenzando desde la capa de red más inferior en la Sección 4.2, siguiendo con las capas intermedias de almacenamiento de grafos en la Sección 4.3 y de procesamiento de grafos en la Sección 4.4, hasta la capa superior - más amigable al usuario - que provee una API para facilitar la especificación de algoritmos en la Sección 4.5. Finalmente, en la Sección 4.6 se sumarizan las características de Graphly. 4.1 Arquitectura General de Graphly La vista en capas de la arquitectura de Graphly se muestra en la Figura 4.1. En el patrón clásico de capas (Buschmann et al., 1996), cada módulo provee servicios a los módulos de las capas superiores a través de una interfaz. Esta organización permite simplificar el diseño y la implementación de las capas superiores. Además, cada módulo puede ser intercambiado y reemplazado con un módulo nuevo con relativo poco esfuerzo, siempre y cuando se mantengan las interfaces provistas a capas superiores. Las siguientes secciones detallan las capas provistas por Graphly en orden, desde abajo hacia arriba. La capa inferior corresponde con la capa de comunicación y manejo de workers (Sección 4.2). Esta capa implementa la funcionalidad de red para el envío de datos y el código entre los workers y oculta la mayor parte de la funcionalidad detrás de un mecanismo de RPC (Remote Procedure Call). También proporciona una vista del estado actual de los workers a través de una abstracción de clúster. De este modo, el usuario sólo necesita obtener un objeto de 4.1. ARQUITECTURA GENERAL DE GRAPHLY 59 of 206 CHAPTER 4. GRAPHLY Graphly API GraphRec TFR, SALSA, HITS, PageRank, RandomWalk, etc. Traversal API Models API Neighbors, Vertex count, Pregel, Fork-Join, DPM Graph Processing Pregel Fork-Join Jobs and Tasks DPM Vertex Function, Aggregators DPM Tasks Mapping Strategies Location, Memory, Round Robin Graph Storage Store Engine Local Graph Store Consistent Hashing, Store Client LevelDB, RDBMS, etc. Worker Management and Communication RPC Remote invocaction, remote class loading, marshalling Cluster Abstraction Cluster and worker management Networking TCP, UDP, Multicast, Failure Detection, Worker Discovery Figure 4.1: Vista de capas de la arquitectura de Graphly. tipo worker para enviarle un mensaje, sin conocer su dirección de red exacta. Para soportar esta función, esta capa implementa un protocolo de gestión de miembros y un protocolo de detección de fallos para mantener actualizada la vista del clúster. La segunda capa es el almacén de grafos, que distribuye el almacenamiento persistente del grafo del usuario. Esta capa puede ser implementada utilizando un almacenamiento puramente orientado a grafos, similar a Neo4J o puede proporcionar una manera de almacenar la estructura del grafo en una base de datos relacional o un almacén clave-valor. La implementación por defecto se basa en almacén clave-valor distribuido. La tercera capa corresponde a la capa de procesamiento de grafos. Esta capa proporciona tanto las abstracciones necesarias para los diferentes modelos de programación como Pregel o Fork-Join, así como también el soporte distribuido correspondiente para esos modelos. Un tercer modelo, denominado Distributed Partitioned Merge (DPM), se propone en este nivel como otra alternativa para desarrollar algoritmos de grafos. Por último, la capa de API de Graphly es la capa superior que define las interfaces disponibles para el usuario final. Se proporciona un mecanismo de consultas componibles para realizar una cadena de consultas sobre el grafo. Por ejemplo, los usuarios pueden realizar operaciones de recorrido, como el movimiento de un vértice a otro, utilizando la API de recorrido o pueden ejecutar algoritmos más avanzados, como algoritmos Fork-Join o Pregel, utilizando la API de 60 of 206 4.1. ARQUITECTURA GENERAL DE GRAPHLY CHAPTER 4. GRAPHLY Data Sender Fragmenter Acknowledger Ping Failure Detector Bundler UDP Multicast Discoverer UDP MCAST Data Sender Ping Failure Detector TCP Multicast Discoverer UDP MCAST Figure 4.2: Pilas UDP y TCP en Graphly. modelos. La componibilidad de consultas de Graphly permite al usuario mezclar diferentes tipos de operaciones en la misma consulta. Esta capa también implementa primitivas compartidas por muchos algoritmos de recomendación, tales como recorridos aleatorios (random walks), círculo de confianza o vecinos comunes. Todas estas operaciones están disponibles en otra interfaz llamada GraphRec, diseñado para proporcionar algoritmos de recomendación al usuario bajo la misma premisa de componibilidad. Por ejemplo, un usuario puede ejecutar varias operaciones de recorrido y luego ejecutar HITS, SALSA o el algoritmo de Katz sobre los vértices resultantes. 4.2 Comunicación y Administración de Workers Todas las operaciones de red en Graphly se ocultan detrás de una capa de gestión y comunicación de workers (para abreviar, la capa de Comunicación) que proporciona el envío de datos de worker a worker, el descubrimiento y la gestión de los trabajadores, y un mecanismo de llamada a procedimiento remoto (RPC). Esta capa también es responsable de convertir objetos desde y hacia bytes (un proceso conocido como marshalling) y la carga de clases remotas (en caso de que la clase de un objeto enviado por un usuario no se encuentra en el worker). Networking La implementación de esta capa se asemeja a una pila de módulos basados en la abstracción del procesador de mensajes (Message Processor o MP). Cada MP recibe un mensaje, lo procesa y lo envía al siguiente MP. En cada MP, los mensajes se añaden a una cola 1 y se planifica su procesamiento. 1 Para reducir el impacto de la cola en el procesamiento, los mensajes se agregan y se obtienen en lotes. Este enfoque es similar al implementado por el Disruptor Ring Queue (Página Web del Disruptor https: //lmax-exchange.github.io/disruptor/), una cola sincronizada de alta performance usada en escenarios productor-consumidor. 4.2. COMUNICACIÓN Y ADMINISTRACIÓN DE WORKERS 61 of 206 CHAPTER 4. GRAPHLY En Graphly se proveen, por defecto, dos pilas de comunicación, una de ellas basada en el protocolo UDP y otra en TCP. Ambas se muestran en la Figura 4.2. Dichas pilas están diseñadas para ser utilizadas en diferentes escenarios. Por ejemplo, TCP es un protocolo basado en canales de comunicación, utilizado cuando se debe establecer una comunicación confiable entre dos procesos. Por otro lado, UDP está orientado al envío de paquetes no provee ninguna garantía de que, luego de enviar un conjunto de bytes, éstos lleguen a destino. UDP tiene la ventaja de consumir muchos menos recursos de red que TCP debido que no se debe mantener una conexión entre los nodos. De ser necesario, se pueden incluir un conjunto de MPs encima de UDP para poder brindar características similares a TCP, tal como fragmentación de mensajes largos, confirmaciones de recepción y agrupamiento de mensajes pequeños. Toda la comunicación se realiza a través de un MP especial llamado DataSender, que ayuda a enviar una serie de bytes a un worker determinado y, opcionalmente esperar una respuesta, independientemente del protocolo de comunicación subyacente. Además de las abstracciones de red, la capa de comunicación proporciona un protocolo de descubrimiento de workers. Este módulo fue implementado en dos versiones: utilizando multidifusión y utilizando pings. La variante de multidifusión envía mensajes de multidifusión UDP a una dirección de multidifusión dada y espera respuestas de otros workers. El descubrimiento basado pings simplemente envía mensajes UDP a un rango de direcciones definido por el usuario y espera las respuestas. Un protocolo de detección de fallos se utiliza para realizar un seguimiento de la situación de los workers descubiertos. La implementación por defecto de este MP consiste en un protocolo basado en mensajes que envía un ping (es decir, un latido) periódicamente y espera las respuestas. Abstracción del Cluster La comunicación directa, es decir, enviar bytes a una dirección IP y un número de puerto, es incómodo y muy propenso a errores. Como alternativa, la capa de comunicación ofrece una abstracción Worker y otra de Cluster. La clase Worker permite al usuario enviar datos a otros workers que se identifican con una dirección lógica almacenada en un objeto Address, en lugar de un par (ip, puerto). El Cluster agrupa objetos Worker, denotados como {Worker0 ,Worker1 , . . . ,Workern }, como se muestra en la Figura 4.3, y administra la notificaciones de descubrimiento de los workers (cuando los workers notifican su disponibilidad) y las fallas de los workers. Se puede notar en la Figura que tanto el cliente como los workers poseen una vista del cluster (el objeto Cluster, que aparece expandido en el nodo del cliente). Adicionalmente, se puede observar que más de un worker puede ser desplegado en un solo nodo. 62 of 206 4.2. COMUNICACIÓN Y ADMINISTRACIÓN DE WORKERS CHAPTER 4. GRAPHLY Cluster Node1 Cluster Node0 Worker0 Worker1 Worker2 Cluster Cluster Client Node Cluster Graphly Client Cluster Worker Worker Worker Worker 0 1 2 3 Cluster Node2 Worker3 Cluster Figure 4.3: Un ejemplo de las abstracciones de clúster y workers desplegados en nodos. ChatFactory "Chat.java" (Java class or interface) RPC Builder ChatServer ChatBroadcast Server side RPC rpc = graphly.getRPC(); ChatServer server = new ChatServerImpl(); rpc.registerTarget(¨CHAT¨, server); Client side RPC rpc = graphly.getRPC(); ChatFactory factory = ChatFactory.create(rpc,"CHAT"); Chat chat = factory.buildClient(¨worker_0¨); chat.sendChatMessage(user,¨Hello, World¨); Figure 4.4: Flujo de trabajo para la creación de RPCs en Graphly. Llamadas de Procedimiento Remoto En los programas distribuidos, la posibilidad de llamar a métodos de objetos que existen en los workers remotos simplifica enormemente el diseño y la mantenibilidad. Graphly proporciona un framework de llamada a procedimiento remoto (RPC) para realizar fácilmente llamadas remotas a objetos. En la base de este framework se establece la clase RPC, que se encarga de registrar los objetos que son alcanzables mediante RPCs y llevar a cabo las invocaciones remotas. El proceso es sencillo: el trabajador puede utilizar su instancia RPC para llamar a cualquier método de un objeto remoto identificado por un identificador. En la práctica, el identificador es por lo general una constante predefinida por el usuario. Por ejemplo, en el desarrollo de una aplicación de chat, todas las instancias de la clase Chat pueden registrarse ellos mismos utilizando el identificador "CHAT". El framework provee un conjunto de clases de ayuda que permite ocultar las invocaciones remotas y hacerlas parecer como si fuesen invocaciones locales. Estas clases de ayuda generan 3 clases: una fábrica, un cliente y una clase de difusión como se muestra en la Figura 4.4. La clase fábrica crea objetos del tipo cliente y difusión para un objeto y un worker dado. La clase cliente realiza las invocaciones a un worker en particular, mientras que la clase de difusión realiza invocaciones a un conjunto de workers. 4.2. COMUNICACIÓN Y ADMINISTRACIÓN DE WORKERS 63 of 206 CHAPTER 4. GRAPHLY Worker0 getProperty(1000,¨username¨) vertex ID Store Client 1000%4=2 # of Virtual Buckets Assigned Buckets: 0,2 property name Virtual Buckets 0 1 2 3 Graph Store worker 0 worker 1 worker0 worker 1 Local Store Vertices [...,1000,...] Properties ... (1000,¨username¨) ... ¨acorbellini¨ Adjacency 1000 [0,124,254,...] [300, 257, 354,...] IN OUT Figure 4.5: Componentes que intervienen en una operación getProperty de ejemplo en el almacén de grafos de Graphly. 4.3 Almacén de Grafos El soporte de almacenamiento utiliza la representación de grafo de propiedades, donde cada vértice tiene asociado un conjunto de propiedades y de ejes dirigidos y cada eje puede tener sus propias propiedades. El grafo se particiona simplemente utilizando el ID de vértice como clave de particionado. Dado que casi todas las operaciones en el grafo (lecturas o escrituras) implican el uso de un vértice, el ID de vértice ayuda a encontrar el nodo físico que contiene el vértice. En el caso de una operación entre ejes (involucrando dos vértices) el vértice con ID más pequeño que participa en la operación se utiliza como clave. En esencia, este almacén es un almacén clave-valor distribuido donde la clave es el identificador del vértice. De hecho, cada trabajador está a cargo de un conjunto de vértices y almacena los datos de vértice en un almacén de datos local. Por lo tanto, en una operación común, una vez que el trabajador encargado de almacenar es encontrado, se realiza una consulta local. Por ejemplo, si el usuario está buscando la propiedad de un vértice dado, el usuario brinda el ID del vértice y el nombre de la propiedad. El ID se utiliza para encontrar el trabajador remoto y, después, el trabajador utiliza el par (vertexid, propertyname) para encontrar el valor de la propiedad en el almacén local. Una característica importante del almacén es que las listas de adyacencia se duplican. Cada vértice contiene dos tipos de listas: vértices de entrada y vértices de salida. La lista de los vértices de entrada se compone de vértices que tienen un eje que apunta al vértice actual. Por el contrario, la lista de vértices apuntadas por el vértice actual se almacena en una lista de vértices de salida. Esto duplica los bordes, lo que complica su mantenimiento (por ejemplo, para eliminar un eje se deben realizar dos operaciones de borrado), pero ofrece un enorme aumento de rendimiento cuando se recorre el grafo porque todos los vértices adyacentes a un vértice dado están situados en el mismo nodo. La implementación del almacén de grafos en Graphly se basa en diferentes módulos para el 64 of 206 4.3. ALMACÉN DE GRAFOS CHAPTER 4. GRAPHLY guardado y la obtención de datos del grafo, tal y como se muestra en el ejemplo de la Figura 4.5. En primer lugar, una instancia de la clase GraphStore se ejecuta en cada worker y tiene la responsabilidad de almacenar una partición local del grafo. GraphStore mantiene estructuras separadas para las listas de adyacencia, las propiedades del grafo y para los vértices. En su implementación actual, los vértices y las listas de adyacencia son siempre almacenados en disco, mientras que las propiedades pueden ser almacenadas opcionalmente en memoria. El soporte utilizado para el guardado local fue LevelDB2 , un almacén clave-valor multinivel basado en logs que provee relativamente rápido acceso aleatorio (i.e. una forma de acceso muy habitual en grafos). Como fue mencionado anteriormente, el particionado del grafo se hace por ID de vértices. Sumado a esta estrategia, el espacio de claves completo (el rango de todos los posibles identificadores de vértice) se divide en rangos más chicos (llamados Virtual Buckets, ver Sección A.2.2 del Apéndice A). Al inicio, un objeto llamado GraphStoreCoordinator distribuye los rangos de claves a lo largo de los GraphStores disponibles (uno por cada worker). Esta técnica, llamada Consistent Hashing (Karger et al., 1997) (Sección A.2.1 del Apéndice A), permite balancear la redistribución de los datos del grafo asignando solo pequeñas particionas a cada worker. Cuando un nuevo worker se agrega, se le asigna una porción del espacio de claves y en lugar de solicitar las particiones correspondientes de un solo worker, las transferencias se balancean entre todos los workers. La última pieza necesaria para el soporte de almacenamiento de Graphly es el cliente que administra las instancias de GraphStore. Las mayoría de los métodos en el objeto StoreClient utilizan un ID de vértice y luego realizan una invocación RPC a un método específico en un GraphStore remoto. Por ejemplo, el método getProperty realiza la operación mostrada en la Figura 4.5. En primer lugar, se aplica un operación de hashing basada en módulo al ID del vértice para encontrar su Virtual Bucket correspondiente. Debido a que cada Bucket tiene asignado un worker, se realiza una llamada remota a dicho worker. El worker en cuestión encuentra en su almacén local el valor de la propiedad solicitada utilizando el ID del vértice y el nombre de la propiedad, y retorna el valor de dicha propiedad al cliente. 4.4 Procesamiento de Grafos La capacidad de procesamiento de grafo proporcionado por Graphly se pueden dividir en dos mecanismos relacionados: modelos de procesamiento distribuido y las estrategias de mapeo. El objetivo de un modelo de procesamiento es ocultar las cuestiones del framework distribuido al usuario y, al mismo tiempo, fomentar un uso eficiente de los recursos computacionales y de red. Tal como se presenta en el Capítulo 3, Section 3.1, existen varios modelos que se pueden utilizar en el procesamiento de grafos. Los modelos implementados actualmente por Graphly son ForkJoin y Pregel; ambos permiten modelar los enfoques más comúnmente utilizados en el desarrollo 2 Página Web de LevelDB, https://github.com/google/leveldb 4.4. PROCESAMIENTO DE GRAFOS 65 of 206 CHAPTER 4. GRAPHLY de algoritmos de recomendación: recorridos basados en divide y conquista y procesamiento iterativo de grafos. Un tercer modelo, denominado Distributed Partitioned Merge (DPM), se encuentra en un lugar intermedio entre FJ y Pregel, y se propone en esta tesis como una alternativa más eficiente a ambos modelos. Las estrategias de mapeo son una forma no intrusiva para configurar el comportamiento distribuido del procesamiento en un cluster de ordenadores. Este mecanismo utiliza una estrategia de partición para dividir la lista de vértice que se está procesando y luego una estrategia de asignación de particiones a trabajadores. Las estrategias de mapeo se utilizan en toda la capa de procesamiento de grafos para delegar la decisión de dónde (es decir, sobre qué trabajador) una cierta lista de vértices se debe procesar. Los usuarios pueden elegir entre las estrategias disponibles en Graphly, o pueden utilizar sus propias estrategias personalizadas, mediante la extensión del framework. En cualquier caso, los usuarios no tienen que modificar el algoritmo de recomendación que están desarrollando para aplicar una estrategia de mapeo dado. En las siguientes secciones, los modelos de procesamiento distribuido proporcionadas por Graphly se explican en detalle. 4.4.1 Fork-Join El modelo de procesamiento Fork-Join utiliza el concepto de trabajos y tareas para poner brindar un framework distribuido genérico. Bajo este framework, un trabajo puede generar muchas Tareas, distribuirlos entre los trabajadores disponibles y luego –opcionalmente– esperar el resultado del trabajo llevado a cabo por cada Tarea. Adaptar FJ al procesamiento de grafos es simple. La Figura 4.6 muestra el flujo de procesamiento más usual en FJ en Graphly, separado en una etapa de Fork (cuando las tareas se crean y entregan a los workers) y la etapa Join (cuando los resultados de las tareas se unen en el trabajo padre). En primer lugar, los vértices de entrada son particionados utilizando una estrategia de mapeo dando como resultado una lista de pares (Worker, Partition), como se muestra en (1) en la Figura 4.6. En segundo lugar, una Tarea definida por el usuario es creada para cada par (Worker, Partition), como se muestra en (2). Cada {K0 , K1 , ..., KR } emitido por los workers – (3) en la Figura – representa las claves de los resultados intermedios utilizados para identificar unívocamente cada subresultado y su valor. En Graphly, las claves son usualmente IDs de vértice, pero podría ser cualquier clave definida por el usuario (e.g. términos de texto utilizado para calcular frecuencia de términos). Nótese que el rango [0, R] puede difererir del rango de entrada [0, N]. Finalmente, un objeto Trabajo (Job) ejecuta y gestiona los resultados de las tareas especificadas. Para acceder al grafo, cada tarea debe obtener el objeto GraphClient desde el contexto de ejecución de su trabajador asignado. Por último, como completar las tareas de ejecución y devolver resultados, la función Join puede utilizar un combinador definido por el usuario para combinar los subresultados –(4) en la figura– o, si no se especifica un combinador, simplemente coloca los subresultados en una lista agrupados por clave. 66 of 206 4.4. PROCESAMIENTO DE GRAFOS CHAPTER 4. GRAPHLY Figure 4.6: El flujo de trabajo de Fork-Join de Graphly. Un ejemplo de Tarea FJ se muestra en el Listado 4.1. En este ejemplo, el grafo contiene información de usuarios de Twitter y cada usuario posee una propiedad llamada "tweet_count" que representa la cantidad de mensajes publicados en Twitter. Cada tarea definida por el usuario recolecta las cuentas de tweets de los vértices especificados y, mediante una suma, une los resultados en un único resultado global. La unión de los resultados en un solo trabajador genera un cuello de botella tanto en la transferencia de la red como en el rendimiento computacional de los trabajadores. Graphly intenta mitigar el cuello de botella mediante la implementación de soluciones alternativas. Para reducir el impacto de los cuellos de botella de la red, en lugar de enviar el resultado al Trabajo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Result res = graphly . v ( vertices ) . fj () . task ( new Task (){ public void compute ( VertexList vertices ){ for ( long vid : vertices ) for ( String palabra : getProperty ( vid , " palabras " )) emit ( palabra , 1); } }) . combiner ( new Combiner (){ public int combine ( int a , int b ){ return a + b ; }}). run (); System . out . println ( res . get ( " hola " )) Listado de código 4.1: Ejemplo de conteo de tweets implementado en Graphly. 4.4. PROCESAMIENTO DE GRAFOS 67 of 206 CHAPTER 4. GRAPHLY padre, el cluster podría devolver la dirección desde donde el resultado puede ser obtenido. Esto ayuda a obtener los resultados de la tarea sólo cuando el Trabajo puede procesarlos. El cuello de botella de procesamiento es mucho más difícil de mitigar. Una alternativa es dividir el resultado en bloques utilizando un ID y combinar dichos bloques por separado en diferentes hilos, pero esta técnica no siempre es posible aplicarla. Para usar esta alternativa, el usuario debe aceptar que los resultados se presenten en bloques o transformarlos en un resultado final, unificado. Por ejemplo, si el usuario está contando palabras en un grafo de tweets, las palabras pueden estar dispuestos en bloques alfabéticamente (por ejemplo a..e, f..j, etc.), de modo que cada hilo fusiona los resultados de bloques diferentes. Sin embargo, tienen un efecto limitado, dependiendo de las características del nodo que lleva a cabo la operación de combinación. Una de las principales ventajas de FJ es la simplicidad de su modelo de programación de divide y conquista. Como consecuencia de ello, FJ es la elección natural para los recorridos de grafos que recogen datos del almacén de grafos en diferentes fragmentos y combinan los resultados. Por ejemplo, para obtener el vecindario (vértices adyacentes) de un determinado grupo de vértices, FJ puede particionar los vértices de acuerdo a su lugar de almacenamiento (utilizando la estrategia de mapeo por ubicación), recopilar las listas de vecinos obtenidas y finalmente combinar las listas en un vecindario final. Para algoritmos iterativos, sin embargo, FJ sufre de una gran sobrecarga de transferencia en comparación con otros modelos. FJ necesita enviar los datos a procesar a todos los trabajadores en cada iteración. Por ejemplo, en un algoritmo iterativo como SALSA, se debe mantener el valor de autoridad y de concentrador de cada vértice durante el cálculo. En FJ, SALSA se lleva a cabo manteniendo un estado actual de los valores de autorización de los ejes en una tabla de hash. Cuando se inicia el trabajo, FJ divide la tabla en tareas y los asigna a los workers. Entonces, cuando las tareas se llevan a cabo, los resultados actualizados se fusionan en una nueva tabla de autoridad y hub. Este ir y venir de los datos sucede en cada iteración y, por este motivo, el cuello de botella de FJ está involucrado en cada paso, por lo que el proceso completo se hace más lento que otras alternativas. Un problema más sutil que tiene un gran impacto en el rendimiento de FJ cuando se aplica a algoritmos iterativos es el hecho de que los vértices no pueden ser "desactivados". Por ejemplo, incluso si SALSA considera que un vértice no ha cambiado sus valores de autoridad o de concentrador, tiene que enviar los resultados sin cambios al trabajo padre. De lo contrario, debido al hecho de que las tablas de autoridad y de concentrador se vuelven a crear en cada iteración, si se ignoran los resultados sin cambios, éstos no formarían parte del resultado de la iteración actual (y por lo tanto, del resultado final). En consecuencia, a pesar de que algunos vértices convergen en un valor final, sus resultados sin cambios serán enviados a los trabajadores en cada iteración. Como se mencionó en el Capítulo 3, Sección 3.1.2, algunos estudios han atacado el problema adaptando el algoritmo que se está modelando. Por ejemplo, los autores de Delta-SimRank (Cao et al., 2012) procesan un valor inicial del algoritmo SimRank (Jeh and Widom, 2002) para cada 68 of 206 4.4. PROCESAMIENTO DE GRAFOS CHAPTER 4. GRAPHLY vértice y luego aproximan el valor final, sumando (o restando) un delta a los valores iniciales. Así, cuando una actualización es cercana a cero, los autores ignoran la actualización, reduciendo el tráfico de red. 4.4.2 Pregel Graphly proporciona un framework para el modelado de algoritmos de grafos bajo un modelo de procesamiento similar a Pregel (Capítulo 3, Sección 3.1). Bajo este modelo, los algoritmos están diseñados desde el punto de vista del vértice, estableciendo una comunicación con otros vértices a través de mensajes. Una función de vértice se aplica por separado a cada vértice involucrado en el cálculo. A continuación, el vértice procesa los mensajes que le fueron enviados y comunica los resultados a sus vecinos o a cualquier otro vértice en el gráfico. El modelo de procesamiento Pregel proporcionada por Graphly requiere que el usuario implemente la interfaz VertexFunction y utilice la clase PregelClient para comunicarse con el framework. De manera similar a FJ, el usuario debe entregar la lista de vértices a ser procesada. Si el usuario decide activar todos los vértices en el gráfico (muy común en algoritmos como PageRank o K-means) la lista de vértices debe estar vacía y Pregel debe estar configurado para funcionar sobre todo el grafo. Una de las principales diferencias con FJ es que Pregel distribuye la fusión de los resultados a través del clúster utilizando el mecanismo de mensajería de vértice a vértice. Este mecanismo distribuye la carga de procesamiento y de red entre los workers disponibles. Como consecuencia, los resultados se almacenan localmente en cada worker (en el soporte provisto por GraphStore). Una operación adicional es necesaria para recoger los resultados de cada worker aunque, en muchos casos, esto no es necesario ya que los resultados almacenados en cada worker se utilizan como entrada a otro cálculo subsiguiente. La implementación de Pregel subyacente consiste en tres módulos principales, como se muestra en la Figura 4.7: un cliente Pregel (1), un Coordinador (2) y un worker Pregel (3). El coordinador se encarga de gestionar la ejecución de superetapas según lo establecido en BSP. Cada trabajador Pregel ejecuta la función vértice definida por el usuario sobre una partición de vértices. La clase PregelClient es simplemente el punto de acceso al sistema: envía funciones de vértice al Coordinador y espera a que la ejecución finalice. Coordinador Pregel Pregel se basa en el modelo de procesamiento BSP que establece que los trabajadores pueden procesar libremente particiones de datos (vértices en este caso), pero, al finalizar, deben esperar hasta que todos los trabajadores completen su procesamiento. Esta sincronización es conocida en BSP como barreras de sincronización y, en Graphly, es proporcionada por un coordinador. La principal responsabilidad del Coordinador – (2) en la Figura 4.7 – es recibir pedidos de ejecución (una función de vértice y una lista de vértices) de los usuarios, inicializar los workers y 4.4. PROCESAMIENTO DE GRAFOS 69 of 206 CHAPTER 4. GRAPHLY User Input Setup Stage (Initial) Vertex Function Vertex List (opt.) Aggregators (opt.) Msg. Mergers (opt.) VertexPartition0 Coordinator Vertex List Mapping Strategy Vertex Partition0(0-10) ... Vertex PartitionN(n-k, n) (1) (0-10) Aggregators(Local State) Worker1 Aggregators(Global State) Pregel Client VertexPartition1 (2) (11-20) Aggregators(Local State) Processing Stage (from Worker0 perspective) PregelWorker (3) 0 VertexPartition 0 (0-10) (4) Worker0 Coordinator merge aggregators Aggregators(Local State) Aggregators(Global State) updateAggregator Vertex Function Message Mapping Combiner Strategy sendMessage SubResults for Worker V10 SubResult 10 1 V20 SubResult 20 SubResults for Worker2 (5) V21 SubResult 21 V30 SubResult 30 Worker1 Worker 2 Results (for next iteration) (6) V0 SubResult 0 V10 SubResult10 Message Combiner Figure 4.7: El flujo de trabajo de Pregel en Graphly. administrar su ejecución. Inicialmente, el coordinador envía un mensaje de activación a todos los vértices que participan en la primera superetapa. Un vértice se considera activo si ha recibido uno o más mensajes. Naturalmente, cada mensaje se entrega, en primer lugar, al trabajador asignado a la partición del vértice especificado y, luego, al vértice destino. Luego de recibir confirmación de que todos los vértices se encuentran activos y listos para ser procesados, el coordinador entra en un ciclo que termina cuando se alcanza un número de superetapas o cierta condición de corte. Por ejemplo, algoritmos como TFR (Armentano et al., 2011) ejecutan durante una cantidad fija de pasos, mientras que aquellos como PageRank (Page et al., 1999) ejecutan hasta converger. El Coordinador procede a la siguiente superetapa cuando todos los trabajadores notifican que han terminado el cálculo de sus particiones. Encima de dichas notificaciones, los trabajadores también incluyen el valor de sus agregadores. Los agregadores son objetos definidos por el usuario que mantienen una variable global. Debido a que cada agregador se actualiza de forma independiente en cada trabajador, agregadores de diferentes trabajadores deben fusionarse y luego enviarse nuevamente a los trabajadores antes de iniciar la siguiente superetapa. En la 70 of 206 4.4. PROCESAMIENTO DE GRAFOS CHAPTER 4. GRAPHLY implementación actual, los agregadores que realizan una gran cantidad de procesamiento puede suponer un cuello de botella en el sistema. Sin embargo, el particionado de los datos del agregador y la distribución de la operación de fusión ayuda a resolver este problema de rendimiento, aunque no está soportado actualmente por Graphly. Worker Pregel Un Worker Pregel – (3) en la Figura 4.7 – sigue un simple flujo de trabajo que consta de tres etapas: configurar vértices, ejecutar vértices y enviar datos. En la fase de configuración, el trabajador recibe el conjunto inicial de vértices que debe activar, que consiste en colocar un mensaje inicial en cada cola de mensajes de cada vértice. La siguiente etapa, activada por un comando del Coordinador, involucra aplicar la función vértice definida por el usuario - (4) en la figura - para todos los vértices que tienen mensajes en su cola. Por último, todos los mensajes generados por la ejecución son enviados de vuelta a sus correspondientes workers - (5) en la figura. El uso de combinadores de mensajes es vital para mantener controlado el consumo de memoria de los workers. Un combinador es una función que combina todos los mensajes destinados a un vértice, en un mensaje de agregado. Los combinadores son operaciones conmutativas, tales como una suma o una unión de conjuntos, y se aplican al contenido de un mensaje, por ejemplo una puntuación PageRank. El uso de combinadores también tiene un impacto positivo en el consumo de red entre workers. En cualquier momento durante la etapa de procesamiento, los workers Pregel pueden recibir mensajes de otros workers, los cuales se almacenan para la próxima superetapa. Un combinador se puede aplicar para fusionar mensajes de diferentes workers para reducir el consumo de memoria - este proceso se puede ver en (6) en la Figura 4.7. Sin embargo, el enfoque de Pregel de enviar mensajes antes de que todos los workers finalicen la ejecución fuerza a cada worker a mantener dos colas separadas: una para los mensajes entrantes y otra para los mensajes que se están procesando actualmente. Un modo diferente de operación se llevó a cabo en Graphly que sigue el modelo BSP "pura". En el modo de BSP pura, los mensajes se envían solamente después de que la etapa de ejecución se completa en todos los workers. 4.4.3 Distributed Partitioned Merge (DPM) Una de las aportaciones de esta tesis es un nuevo modelo que mitiga el cuello de botella de rendimiento observado en el modelo Fork-Join, aún ofreciendo un estilo de programación basado en FJ. El enfoque MapReduce para evitar el cuello de botella de combinación es la de dividir la salida de cada operación Map en R particiones y asignar cada partición a un worker que aplica la reducción de sub-resultados. Del mismo modo, en Pregel, la salida de cada trabajador se divide de acuerdo con la asignación de particiones de gráficos. 4.4. PROCESAMIENTO DE GRAFOS 71 of 206 CHAPTER 4. GRAPHLY Figure 4.8: Flujo de trabajo del modelo Distributed Partitioned Merge. El modelo propuesto, denominado Distributed Partitioned Merge (DPM), divide la lista de vértice entre los workers cómo FJ - se muestra en (1) en la Figura 4.8-, sino que distribuye la fusión de los resultados a través de la clúster como en los modelos PREGEL o MapReduce se muestra en (2) en la misma figura. En aplicación de gráficos, una DPM de tareas ejecuta una función definida por el usuario que calcula una lista proporcionada de vértices. Cuando se haya completado la tarea, todos los sub-resultados emitidos son enviados a sus trabajadores correspondientes a fusionarse. Así como sucede en el modelo Pregel, DPM mantiene los resultados de la iteración anterior que van a ser utilizados en el procesamiento actual – (3) en la Figura 4.8 – y los resultados de la iteración actual de forma separada – (4) en la misma Figura. Cuando una iteración de DPM finaliza se sobreescriben los resultados anteriores con los de la iteración actual. De forma similar a otros modelos, se provee una lista de vértice como entrada al modelo. Esta lista se particiona en diferentes sub-listas utilizando una estrategia de mapeo y cada partición se asigna a diferentes workers. En DPM, cuando un worker finaliza el envío de resultados a otros workers, se envía la lista de vértices activos, i.e. vértices que fueron emitidos, al trabajo padre – visualizado en (5) en la Figura 4.8. Esto produce un cuello de botella en la unión de vértices activos que es mucho menor que en el modelo FJ, ya que no se deben combinar sub-resultados. Así, el trabajo DPM padre sólo tiene que unir los grupos de vértices en una lista definitiva, que será utilizada para iniciar el cálculo de la siguiente iteración o para recoger resultados en el grafo. 72 of 206 4.4. PROCESAMIENTO DE GRAFOS CHAPTER 4. GRAPHLY 4.4.4 Estrategias de Mapeo A diferencia de las APIs propuestas por otros frameworks y bases de datos, Graphly se centra en el problema de personalizar la distribución del algoritmo en clusters con características heterogéneas. Esto implica proporcionar acceso a los nodos de computación e información del clúster, como el uso de memoria, uso de CPU y el tamaño de las colas de trabajo, y el acceso a la información del soporte de almacenamiento, tales como la ubicación de los datos (por ejemplo, en qué nodo residen los datos de un vértice dado) y la ubicación de datos en caché o replicados. Utilizando esta información, Graphly proporciona un conjunto de estrategias de mapeo predefinidas para cambiar el comportamiento de los algoritmos de la agrupación. Por otra parte, se ha previsto un mecanismo de extensión para una mayor personalización a través de la definición de estrategias ad-hoc. De hecho, el scheduling de trabajos o mapping (Topcuoglu et al., 2002) es un problema ampliamente abordado en sistemas distribuidos. En clusters heterogéneos, es decir, clústers con nodos de diferentes capacidades (e.g. memoria principal, velocidad de la CPU, el número de núcleos de CPU, capacidad de almacenamiento), la asignación de los trabajos a los nodos permite que las aplicaciones paralelas maximicen el rendimiento dado un criterio determinado (Kim et al., 2003). Otra técnica útil para la asignación de trabajo es el robo de trabajos. Si bien la planificación de tareas se centra en la asignación de trabajo a los nodos de cómputo, el robo de trabajos permite a los nodos infrautilizados robar aquellos trabajos aún no ejecutados de otros nodos (Blumofe and Leiserson, 1999). Las condiciones bajo las cuales un nodo puede robar trabajo a otro nodo incluyen eficiencia energética (Rodriguez et al., 2014), orden de los nodos (e.g. formando una jerarquía de nodos (Neary and Cappello, 2005)), proximidad del cluster (Nieuwpoort et al., 2010), latencia (Rosinha et al., 2009) o puramente al azar (Zhang et al., 2006). Actualmente, Graphly soporta estrategias de mapeo que reciben una lista de vértices y brindan como resultado a una lista de particiones que asignadas a trabajadores. Si el clúster se compone de un grupo heterogéneo de nodos de computación (es decir, diferentes tipos de CPU, cantidad de memoria RAM, capacidad de almacenamiento en disco, etc.), el usuario puede decidir cómo se reparte el procesamiento de vértices de acuerdo a las capacidades del nodo de cada trabajador para lograr menores tiempos de recomendación, o reducir el uso de ciertos recursos. Por ejemplo, la reducción de uso de la red puede ser útil en entornos de computación en la nube donde se cobra la comunicación entre nodos. Por otro lado, un algoritmo de uso intensivo de CPU puede necesitar distribuir las tareas de acuerdo con las capacidades de la CPU, mientras que un algoritmo intensivo en uso de memoria puede distribuir tareas en función de la cantidad de memoria RAM en cada nodo. En cualquier caso, el código original algoritmo permanece sin cambios. Por lo tanto, las estrategias de trabajo funcionan efectivamente como una conexión transparente entre el algoritmo, 4.4. PROCESAMIENTO DE GRAFOS 73 of 206 CHAPTER 4. GRAPHLY y la plataforma subyacente. Graphly proporciona un framework de estrategias de mapeo para que los usuarios finales pueden definir sus propias estrategias. Sin embargo, Graphly proporciona un conjunto de estrategias predefinidas para ser utilizado "de fábrica": • Memoria disponible: Esta estrategia utiliza las capacidades de supervisión de los workers para obtener la cantidad de memoria disponible en cada worker y luego divide la lista dada de vértices de acuerdo a dichos valores. Claramente, esta estrategia es dinámica, es decir, se adapta a la situación actual del clúster. • Memoria total: Al igual que en la estrategia de la memoria disponible, la estrategia de memoria total utiliza la cantidad máxima de memoria que un worker puede utilizar para dividir la lista de vértices. Es una estrategia fija que asigna más solicitudes a los workers que tienen más memoria disponible. • Por ubicación: Esta estrategia aprovecha la localidad de los vértices del grafo. Se divide la entrada en diferentes listas de vértices agrupados por su ubicación de almacenamiento, obtenida desde el soporte de almacenamiento. Por ejemplo, sea el worker w1 responsable por a1, a3, a5 y el worker w2 por a2, a4. Se utiliza una estrategia por ubicación para mapear los vértices a1, a2, a5, se dividirán de la siguiente manera: a1, a5 → w1 y a2 → w2. • Round Robin: Esta estrategia simplemente divide la lista dada de vértices por la cantidad de workers disponibles y se asigna una lista secundaria para cada nodo. Esta división igual de peticiones entre nodos hace que esta estrategia más justa en términos de carga de procesamiento. Sin embargo, no se considera ya sea la localización de los datos ni las características del nodo, como la memoria disponible, la CPU o la velocidad de la red física. En la evaluación experimental llevada a cabo en esta tesis, se utilizaron estas cuatro estrategias para mostrar cómo la selección de una estrategia afecta al rendimiento del algoritmo de recomendación y el uso de los recursos del clúster. Para soportar esta funcionalidad, Graphly proporciona una interfaz M APPING S TRATEGY que los usuarios pueden extender para definir sus propias estrategias de mapeo. La única función de esta interfaz es el mapeo de una lista de IDs de vértice a los workers disponibles. Además, se proporciona un objeto de contexto para acceder a la información del clúster y obtener objetos compartidos, como el almacén de grafos. Por ejemplo, la implementación de RoundRobin se muestra en el Listado 4.2. El código presentado obtiene la lista de workers disponibles en el clúster, y asigna los vértices uno por uno a cada worker utilizando un cursor. Como resultado, Round Robin da como salida una asignación equilibrada de particiones para los trabajadores, sin tener en cuenta las características del nodo o de localidad de los datos. Estas estrategias que realizan una división en función de las características de un nodo, hacen uso de la clase MetricMappingStrategy. Esta clase utiliza métricas recopiladas desde el sistema 74 of 206 4.4. PROCESAMIENTO DE GRAFOS CHAPTER 4. GRAPHLY 1 2 3 4 5 6 7 8 9 10 11 12 13 public class RoundRobin extends MappingStrategy { public Map < Worker , VertexList > map ( VertexList vlist , Cluster cluster ){ Map < Worker , VertexList > result = new HashMap (); ArrayList < Worker > workers = cluster . getWorkers (); int cursor = 0; for ( long v : vlist ) { Worker node = workers . get ( cursor ); result . get ( node ). add ( v ); cursor = ( cursor + 1) % workers . size (); } return result ; } } Listado de código 4.2: Ejemplo de estrategia de mapeo Round Robin operativo del nodo y la Máquina Virtual de Java (JVM) donde se ejecuta el trabajador. Las métricas son identificadas por un identificador, por ejemplo, jvm.memory.available identifica la memoria disponible en la máquina virtual. 4.5 Graphly API Graphly presenta toda su infraestructura al usuario a través de una interfaz de programación de aplicaciones (API). Esta API se puede dividir en tres API distintivas: Recorridos, Modelos y GraphRec. La API de recorridos, inspirada en la API de recorridos de Tinkerpop3 , consiste en un conjunto de operaciones siguen un camino en grafo. Específicamente, un recorrido en el grafo es una operación que sigue los enlaces en cierta dirección recopilando información acerca de los ejes o vértices. La API de modelos proporciona acceso a los modelos implementados en Graphly: FJ, Pregel y DPM. La API de modelos está conectado a la API Recorridos, de modo que los resultados de estos algoritmos pueden ser reutilizados por otras operaciones. El tercer lugar se encuentra GraphRec, en la posición más abstracta, que implementa algoritmos de predicción de enlace conocidos. La naturaleza de la API de Graphly permite a GraphRec combinar los resultados de cualquier algoritmo desarrollado en Graphly (por ejemplo, un recorrido, un algoritmo de GraphRec o un algoritmo desarrollado mediante la API de modelos) para construir nuevos algoritmos. Las siguientes secciones proporcionan información sobre estas interfaces. 4.5.1 API de Recorridos La clase raíz de la API Recorridos es la clase T RAVERSAL. Dicha clase representa una serie de operaciones o pasos que recogen información a medida que se atraviesan ejes del grafo. Cada objeto S TEP obtiene información del grafo y produce un resultado que puede ser utilizado por la siguiente operación. La clase de recorrido sirve como una clase de fábrica que crea 3 Página Web de Tinkerpop, http://tinkerpop.incubator.apache.org/ 4.5. GRAPHLY API 75 of 206 CHAPTER 4. GRAPHLY S TEP estándar, tales como E DGE S TEPS, que recogen la adyacencia de un grupo de vértices, o C OUNT S TEPS, que cuentan las veces que un vértice aparece en la adyacencia de un grupo de vértices. Para crear un recorrido, el usuario debe obtener un cliente Graphly y empezar un recorrido con el método v (por vértice). Este método recibe como argumento uno o más vértices como origen del recorrido. El ejemplo que se muestra en el Listado 4.3, navega desde el vértice con ID 1000, se traslada a sus ejes salientes, luego por sus ejes entrantes y, utilizando esa lista, se cuenta el número de vértices salientes, se filtran los vértices [2, 3, 4] y, por último, se obtienen los 10 primeros vértices ordenados por el recuento anterior. Además de las operaciones en el ejemplo, el usuario puede llamar a una de las siguientes operaciones en cualquier orden: • in, out y neighbors: La operación más básica en un recorrido es la obtención de la lista de adyacencia de un vértice o un grupo de vértices. Graphly proporciona tres operaciones de hacerlo: in, out y neighbours. La operación in recupera los vértices entrantes (vértices con ejes que apuntan a los vértices de actuales). La operación out recupera los vértices salientes. Por último, neighbours combina los vértices salientes y entrantes. Cuando cualquiera de estas operaciones se llama, se añade un objeto E DGE S TEP a la lista de recorrido. El E DGE S TEP recibe una lista de vértices y un objeto D IR que indica la dirección de los bordes a obtener. • countIn, countOut, countNeighbors: Una operación recurrente en algoritmos de predicción de enlace es contar caminos en una dirección dada. Por ejemplo, para obtener los vértices con caminos de longitud 2 que apuntan a un vértice x junto con el número de rutas, un usuario puede ejecutar g.v(x).countIn().countIn(). Por lo general, esta operación permite construir un ranking de los vértices utilizando el recuento de los caminos. • f ilter: Esta operación filtra un número de vértices no deseados del resultado. Se utiliza en los algoritmos de predicción de enlace para eliminar vértices que no son parte del resultado. • top: Esta operación obtiene el top N de elementos de un resultado. Por ejemplo, el top N de elementos de una función count (como en countIn) son los N vértices que fueron alcanzados por la mayor cantidad de caminos. • expand: La función de expansión es similar a in, out o neighbors pero mantiene los vértices actuales en el resultado. Por ejemplo, algunos algoritmos como HITS, necesitan expandir el subgrafo inicial en todas direcciones. Para lograr esto en Graphly, el usuario puede escribir g.v(initial).expand(Dir.NEIGHBORS) para agregar todos los vecinos al conjunto initial. • intersect: Esta operación se combina las listas de adyacencia de un grupo dado de vértices. La idea detrás de esta operación es la obtención de una lista común de vecinos compartidos 76 of 206 4.5. GRAPHLY API CHAPTER 4. GRAPHLY 1 2 3 graph . v (1000). out (). in (). countOut () . filter (2 ,3 ,4). top (10) . run (); Listado de código 4.3: Un ejemplo de recorrido iniciando en el vértice 1000. por todos los vértices involucrados. Es una operación muy útil en algoritmos tales como Common Neighbours (Capítulo 2, Sección 2.3). La API de recorridos también permite a los usuarios añadir pasos personalizados utilizando el método customFunction. Un C USTOM F UNCTION realiza una operación genérica en el grafo y devuelve un resultado. Esta flexibilidad permite la inclusión de nuevas funciones, especialmente aquellas relacionadas con el procesamiento de grafos. 4.5.2 API de Modelos La clase C USTOM F UNCTION es una forma sencilla y potente para incluir modelos de procesamiento a la API de Graphly. Sin embargo, representan sólo una parte de la solución para proporcionar una API flexible para acceder a los modelos de procesamiento. La otra parte de la API es C USTOM T RAVERSALS, una clase que decora un recorrido para agregar métodos personalizados. De esta manera, los métodos relacionados con un modelo de procesamiento están expuestos fácilmente para el usuario sin necesidad de modificar la API de recorridos. La API de modelos se compone de tres C USTOM T RAVERSALs que proporcionan la funcionalidad relacionada con cada modelo: el recorrido Pregel, recorrido DPM y recorrido FJ. El recorrido Pregel expone un método vertexFunction que recibe el V ERTEX F UNCTION definido por el usuario. Este método añade un C USTOM S TEP llamado V ERTEX F UNCTION S TEP en el recorrido actual. El V ERTEX F UNCTION S TEP configura el entorno Pregel y, cuando es ejecutado, envía el V ERTEX F UNCTION provisto por el usuario. En la misma línea, el recorrido DPM incluye un método llamado DPM que recibe una tarea DPM. Cuando se ejecuta, este recorrido configura el mecanismo de DPM y envía la función proporcionada por el usuario. Por último, el recorrido FJ proporciona un método f j que recibe una tarea FJ y una función Unir. Un ejemplo de código que ejecuta la función de vértice PageRank se muestra en el listado 4.4. El método as crea una instancia de la clase pasada como parámetro con el recorrido actual como un argumento del constructor. El usuario puede, a continuación, llamar a los métodos que pertenecen a P REGELT RAVERSAL. Para volver a la API de Recorridos, el usuario puede llamar al método asTraversal. 4.5.3 GraphRec: Una API de recomendación GraphRec es una extensión de la API de Recorridos y Modelos que añade soporte para varios algoritmos de predicción de enlace conocidos. La Tabla 4.1 resume los algoritmos ofre4.5. GRAPHLY API 77 of 206 CHAPTER 4. GRAPHLY 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 graph . v () . pregel () . vertexFunction ( new VertexFunction { public void execute ( long vid , MessageList msgs ){ float pr = 1.0/ graphSize (); if ( getSuperstep () >0){ for ( Message m : msgs ) pr += m . getValue (); pr = pr *0.85+0.15/ graphSize (); } setValue ( vid , " pagerank " , pr ); sendToNeighbours ( pr ); } }) . steps (30) . run (); Listado de código 4.4: Pagerank utilizando la API de modelos. cidos por GraphRec y algunas de sus características. GraphRec extiende la API de Graphly usando C USTOM T RAVERSAL para agregar nuevos pasos a un recorrido determinado. Hay dos razones principales para la creación de GraphRec. La primera razón es proporcionar algoritmos de recomendación, que se puede ver como operaciones primitivas, que puede ser compuestos de forma sencilla para crear algoritmos más complejos. Por ejemplo, un método popular para recomendar followees en Twitter es el algoritmo WhoToFollow (Gupta et al., 2013). Este algoritmo ejecuta un algoritmo de PageRank personalizado (Section 2.3.3, Chapter 2), partiendo del vértice objetivo y se aplica el algoritmo SALSA (Section 2.3.3, Chapter 2) para los mejores N vértices ordenados según la puntuación de PageRank. GraphRec permite componer PageRank personalizado y el algoritmo SALSA mediante la ejecución de g.v(target).as(GraphRec. class).personalizedPR().salsa(). La segunda razón para la creación de GraphRec es proporcionar un framework que permita la comparación del rendimiento de un algoritmo dado bajo diferentes modelos de procesamiento. Esta característica de GraphRec ayuda a decidir qué modelo se adapta mejor dado el algoritmo que se está ejecutando, la dimensión del grafo y el entorno de ejecución. 4.6 Resumen Graphly es una plataforma que soporta el desarrollo de algoritmos de recomendación distribuidos en grafos a gran escala. Fue diseñado como una solución ligera con bajos requerimientos de memoria. Para lograr esto, la mayor parte de los datos del grafo se almacenan en el disco usando un almacén de grafos distribuido. Los modelos de procesamiento distribuidos pueden obtener datos del almacén para ejecutar los algoritmos y también pueden almacenar los resultados en el mismo soporte persistente. 78 of 206 4.6. RESUMEN CHAPTER 4. GRAPHLY Algoritmo Tipo PageRank y Personalized PR SALSA HITS Random walk-based Implementaciones Disponibles Pregel Random walk-based Random walk-based Pregel, FJ, DPM Pregel, FJ, DPM TFR Katz Path-based Path-based Pregel, FJ, DPM Pregel, FJ, DPM LocalPath Path-based Pregel, FJ, DPM FriendLink Path-based Pregel, FJ, DPM Common neighbors Adamic Adar Jaccard Neighbor-based Neighbor-based Neighbor-based Pregel, FJ Pregel, FJ Pregel, FJ Parámetros ε (umbral de convergencia) Vertex List, ε Vertex List, ε, Max. expansión de vecinos Target Vertex Target Vertex, β (factor de penalización), Max. Depth Target Vertex, α (factor de penalización) Target Vertex, Max. Depth Vertex List Vertex List Vertex List Table 4.1: Algoritmos de predicción de enlaces ofrecidos en Graphly. Graphly actualmente soporta tres modelos de procesamiento distribuido: FJ, Pregel y DPM. Éstos modelos de procesamiento esconden las cuestiones de distribución al usuario, lo que simplifica la creación de nuevos algoritmos. Además, estos modelos se encuentran implementados sobre el mismo framework de comunicación para facilitar la comparación de los algoritmos con diferentes modelos. Al permitir la comparación y la igualdad de condiciones de las pruebas, Graphly fomentó la creación de un nuevo modelo, el modelo DPM. Todos los modelos de procesamiento dividen el trabajo en todo el clúster de ordenadores, y los modelos de Graphly no son una excepción. De hecho, Graphly introduce estrategias de mapeo: un mecanismo simple para particionar listas de vértices y asignar a cada partición a un worker específico. Como Graphly fue diseñado para funcionar en clústers heterogéneos, proporciona herramientas para la obtención de estadísticas de workers y ajustar la partición en función de las necesidades de los usuarios y de capacidades de memoria, CPU o de red. Las estrategias de mapeo proporcionan a los desarrolladores personalización de la ejecución distribuida sin ensuciar el código del algoritmo con las cuestiones de distribución de código y datos. Graphly expone sus características a través de una API fácil de usar. Esta interfaz incluye una API simple de recorridos para obtener fácilmente los datos del grafo, una API genérica para desarrollar algoritmos personalizados utilizando los modelos de procesamiento compatibles (FJ, Pregel o DPM) y GraphRec, una API que implementa algunos de los algoritmos de predicción de enlace más populares para grafos. Todas estas API se unifican bajo el mismo concepto: el usuario puede componer diferentes algoritmos para crear nuevos algoritmos. La componi4.6. RESUMEN 79 of 206 CHAPTER 4. GRAPHLY bilidad de la API permite ejecutar recorridos simples, modelos de procesamiento y algoritmos pre-construidos, todos mezclados en la misma consulta, impulsando la creación de nuevos algoritmos basados en una composición de otros algoritmos más simples. 80 of 206 4.6. RESUMEN Mecanismos de Soporte para Algoritmos Basados en Caminos 5 Este capítulo aborda el soporte proporcionado por Graphly para algoritmos de predicción de enlaces basados en caminos y basados en vecinos, junto con sus correspondientes implementaciones y su evaluación empírica. Los algoritmos de predicción enlaces suelen considerar la vecindad del usuario o el conjunto de rutas conectadas para calcular la similitud entre dos usuarios dados. El primer grupo de algoritmos puede ser pensado como algoritmos basados en caminos restringido a la profundidad dos. Una vez que se evalúa la similitud, se recomiendan aquellos usuarios altamente similares con los cuales se puede formar un enlace en el futuro. Varios algoritmos basados en caminos y en vecindades se pueden encontrar en la literatura (Lu and Zhou, 2011; Wang et al., 2015) (ver Capítulo 2, Sección 2.3), de los cuales, en esta tesis, se seleccionaron los siguientes con el objetivo de evaluar el soporte proporcionado por Graphly: • Basados en Caminos: Katz, LocalPath, FriendLink y TFR (Twitter Followee Recommender). • Basados en Vecinos: Common Neighbors, Adamic Adar y Jaccard. Los algoritmos seleccionados fueron implementados en el modelo Pregel, el modelo FJ y en el modelo propuesto DPM. La correctitud de los diferentes algoritmos se validó al obtener el top10 de recomendaciones y verificando que sea el mismo para cada versión (FJ, Pregel y DPM), sin tener en cuenta las pequeñas variaciones en el valor de cada puntuación de la clasificación de usuario. Sin embargo, en la mayoría de los casos, las implementaciones de los algoritmos generaron resultados idénticos. Los mecanismos de soporte ofrecidos por Graphly para ambos tipos de algoritmos son presentados y evaluados en el presente capítulo. La Sección 5.1 detalla las implementaciones de algoritmos basados en caminos y en vecinos y discute los problemas que surgen como consecuencia de las características del algoritmo y las adaptaciones necesarias para amoldarse a los 81 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS diferentes modelos de procesamiento. La Sección 5.2 describe el entorno experimental para la realización de la evaluación, incluyendo las características de clúster y el conjunto de datos utilizados. La Sección 5.3 presenta los resultados de la comparación de algoritmos basado en caminos y basados en vecinos bajo diferentes modelos de procesamiento. Además, se presenta un análisis del impacto de las estrategias de mapeo en este tipo de algoritmos y se propuso un par de escenarios en los que las estrategias de mapeo son muy relevantes. Finalmente, la Sección 5.4 ofrece un breve resumen de las técnicas y mecanismos propuestos en este capítulo y un análisis de los resultados obtenidos. 5.1 Implementación de los Algoritmos La implementación de los algoritmos de predicción de enlace basados en caminos se describen en la Subsección 5.1.1 partiendo del algoritmo que implica el recorrido más complejo del grafo, que es TFR (Twitter Followee Recommender), siguiendo con Katz , LocalPath y FriendLink. Posteriormente, la Subsección 5.1.2 muestra CommonNeighbours, Adamic Adar y Jaccard para ilustrar aquellos algoritmos basados en vecinos. 5.1.1 Implementación de Algoritmos Basados en Caminos En esta Sección se detalla la implementación de los algoritmos de predicción de enlace seleccionados en código Java. Las implementaciones que se enumeran a continuación son una versión simplificada del código original, eliminando definiciones de tipos de auxiliares, los comentarios irrelevantes y código que no tienen ningún impacto en la descripción del algoritmo. A pesar de las incompatibilidades intrínsecas de los dos modelos principales, FJ y Pregel, se compararon ambas implementaciones de algoritmos basados en caminos y en vecinos bajo ciertos supuestos. En primer lugar, el soporte de comunicación para cada modelo es el mismo (usando la capa de comunicación de Graphly), que pone los dos frameworks bajo la misma configuración de red. En segundo lugar, cada aplicación realiza las mismas operaciones sobre el grafo (usando el almacén de Graphly), evitando los atajos o las optimizaciones que podrían conducir a una comparación injusta. El primer algoritmo de esta sección corresponde al algoritmo TFR. Debido a la complejidad de sus recorridos, las diferentes implementaciones de TFR ayudan a establecer la mayoría de las estrategias utilizadas para construir otros algoritmos basados en caminos. Es el único algoritmo del grupo basado caminos que requiere filtrar vértices en cada paso, lo que plantea desafíos en el rendimiento y el diseño de la API. 82 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Filtered edge First level edge Second level edge Result level edge Initial vertex Second level vertex Second level and Result vertex Result vertex Figure 5.1: Ejemplo de recorrido en TFR. 5.1.1.1 TFR Algorithm El algoritmo Twitter Followee Recommender (Armentano et al., 2011), especificado en la Sección 2.3.2 del Capítulo 2, realiza un recorrido exploratorio del grafo que rodea a un usuario objetivo, seleccionando usuarios a recomendar. En el contexto de la red social Twitter, un usuario tiene un grupo de seguidores o followers (bordes salientes) y seguidos o followees (bordes entrantes). El algoritmo se puede dividir en dos etapas. En primer lugar, explora la red followee/follower del usuario objetivo (es decir, el usuario que recibe las sugerencias) para seleccionar un conjunto de usuarios potenciales para recomendar. A continuación, los candidatos se filtran y se clasifican de acuerdo a diferentes criterios, como el número de amigos comunes con el usuario de destino o la similitud de sus perfiles basados en contenidos. En esta tesis, el objetivo es proporcionar un soporte distribuido para la exploración de grafos, y por lo tanto, el análisis se centra en la primera etapa del algoritmo. La exploración de la red de followees/followers en este algoritmo se basa en la caracterización de los usuarios de Twitter realizados en varios estudios (Java et al., 2007; Krishnamurthy et al., 2008) y el hecho de que las redes sociales en línea se han convertido fuentes de información en tiempo real y medios de comunicación de difusión, además de fomentar la formación de los lazos sociales (Kwak et al., 2010). Desde un punto de vista centrado en la información, los usuarios se dividen principalmente en dos categorías: fuentes de información y buscadores de información. Los usuarios que se comportan como fuentes de información tienden a acumular un gran número de seguidores, ya que publican información útil o de noticias, mientras que los buscadores de información siguen a varios usuarios para obtener información, pero rara vez publicar un tweet por sí mismos. El rationale de la etapa de recorrido del grafo del algoritmo de TFR se basa en la categorización de los usuarios en buscadores de información o fuentes de información. Por lo tanto, se 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 83 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 graphly . v ( target ). save ( " target " ) . out (). save ( " followees " ) . countIn (). filter ( " followees " , " target " ) . countOut (). filter ( " followees " , " target " ) . top ( n ); Listado de código 5.1: TFR implementada utilizando la API de recorridos. supone que el usuario de destino es un buscador de información que ya ha identificado algunos usuarios interesantes de Twitter en calidad de fuentes de información (es decir, sus seguidores). Otras personas que también siguen a estas personas (es decir, los seguidores de los seguidos del usuario) es probable que compartan algunos intereses con el usuario de destino y podrían haber descubierto otras fuentes de información relevante sobre los mismos temas (es decir, sus seguidos). Este último grupo se compone entonces de los posibles candidatos para ser propuesto al usuario objetivo como futuros usuarios a seguir. En forma matricial, se puede observar que el algoritmo lleva a cabo una serie de recorridos a partir de un usuario de destino u: primero, uno en la dirección OUT (es decir, obtener los seguidores de u), a continuación otro en la dirección IN y, por último, un recorrido final en la dirección OUT . En cada paso, el usuario u y sus followees se quitan de los sub-resultados. Por otra parte, el algoritmo debe contar el número de apariciones de cada vértice con el fin de ordenar aquellos que serán recomendados por el número de caminos que se originan en u. La Figura 5.1 muestra un ejemplo sencillo de un recorrido realizado por TFR. El conjunto inicial (es decir, u y sus seguidos) aparece en rojo y sus vértices se filtran del conjunto de segundo y tercer nivel. vértices de segundo nivel aparecen en azul y se utilizan para encontrar los vértices resultado, que se muestran en verde. Debido al hecho de que los vértices de segundo nivel pueden ser parte del conjunto de resultados, algunos de estos vértices se muestran en verde y azul. Algunos bordes se ignoran porque apuntan al conjunto de partida. Es importante tener en cuenta que los bordes azules no se usan nunca en la etapa final (es decir, el paso que utiliza bordes verdes), ya que siempre apuntan a la configuración inicial. Implementación Fork-Join del Algoritmo TFR TFR se puede dividir en tareas FJ bien definidos, cada uno de los cuales depende de un resultado de una tarea anterior. La primera parte del algoritmo obtiene los vecinos en la dirección OUT , i.e. los seguidores del usuario. La lista followee resultante se pasa luego al algoritmo de recuento que se deben obtener los seguidores de esta lista y agregar las ocurrencias de cada seguidor. Finalmente, el mismo algoritmo se aplica a los seguidores contar, pero contando la aparición de sus seguidores. Es importante señalar que los recuentos anteriores deben ser distribuidos entre los de aquellos que siguen de la última etapa. Por ejemplo, si un usuario con ID 1 aparece 10 veces como follower en el paso 2 y sus followees son2, 3, 4, entonces 2, 3, 4 recibirán un valor de 10 cada uno, significando que hay 10 caminos desde el usuario objetivo hasta los usuarios 2, 3 y 4. Por el otro lado, si el usuario 5 aparece 3 84 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class CountStep implements Step { public TraversalResult exec ( TraversalResult before ) { FJResult res = graphly . fj () . task ( new Task (){ // The count task emits a count for each neighbor . public void compute ( List vertices , TraversalResult previous ){ for ( long vID : vertices ) for ( long neighbor : getGraph (). getNeighbors ( vID )) emit ( neighbor , previous . getCount ( vID )); } }) // The merger simply sums two counts for the same vertex . . merger ( new ResultMerger (){ public Float merge ( Float a , Float b ){ return a + b ; } }) // Execute using the mapping strategy and the previous counts . . run ( mapping_strategy , before ); return new CountResult ( res . value ()); } } Listado de código 5.2: Implementación en Graphly del algoritmo Count. veces y sus followees son 3, 4, 7, la cuenta resultante será 2 → 10, 3 → 13, 4 → 13, 7 → 3. Utilizando la API de Traversals, este acople de cuentas de caminos y filtros se puede expresar como se ve en el Listado 5.1. El código representado muestra cómo la API de Traversals oculta toda la funcionalidad con respecto a la distribución de tareas y el procesamiento de los resultados detrás de una API fácil de usar. Como se ha mencionado en el Capítulo 4, Sección 4.5, la API de recorridos proporciona un DSL (Lenguaje Específico de dominio) para recorrer y procesar el grafo. En este caso, la función Count se utiliza para contar el número de caminos entre el usuario de destino y los usuarios recomendados. En cada paso, el grupo de seguidores y el usuario de destino se eliminan de los sub-resultados. Por último, los mejores N vértices se obtienen y se presentan al usuario como usuarios potenciales para comenzar a seguir. Las funciones que requieren agrupar los resultados del clúster se implementan utilizando el modelo FJ proporcionado por Graphly. En este caso, la función OUT y ambas funciones Count (CountIn y CountOut) se implementan bajo FJ y están integrados en Graphly. No obstante, el usuario puede crear nuevas funciones personalizadas, a través de la API mediante la ampliación de la interfaz CustomStep, como se explicará más adelante en este capítulo. Naturalmente, la operación principal y, también, la que más tiempo consume en el programa del Listado 5.1 es la función Count. La razón es que el conteo debe agregar todas los contadores de rutas para un conjunto de vértices que crecen exponencialmente en cada paso. La 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 85 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS clase CountStep, que implementa la funcionalidad de recuento, se muestra en el Listado 5.2. Cuando se ejecuta, CountStep crea un trabajo FJ mediante la API de modelos. En este caso, la clase CountTask es responsable de distribuir el recuento actual de recorridos entre cada vecino (representado por la operación previous.getCount(vID)). Se debe tener en cuenta que el recuento de inicial es 1. Los sub-resultados emitidos son luego fusionados en la etapa de combinación utilizando una clase Combiner, que suma la cuenta de recorridos por cada vértice. Implementación Pregel del Algoritmo TFR La versión Pregel del algoritmo TFR requiere un cambio paradigmático en términos del diseño de algoritmos. El recuento de los vértices es, ahora, llevado a cabo desde un punto de vista centrado en el vértice, lo que complica algunas de las operaciones que eran simples de realizar en FJ, tales como pasar los resultados de una etapa a la siguiente o el filtrado de vértices. La implementación del algoritmo se muestra en el Listado 5.3. Como se puede ver, el desarrollador debe programar las tres etapas en la misma función utilizando el enfoque de programación centrada en el vértice. Por otra parte, el código de usuario debe utilizar el número de superetapa para decidir qué operación se debe realizar. Por ejemplo, las dos primeras superetapas (paso 0 y 1) marcan los vértices como parte del conjunto de destino (implementados como set("TYPE", "TARGET_SET")), y para el resto de pasos si el vértice es parte del objetivo conjunto (es decir, get("TYPE") == "TARGET_SET"), la función retorna sin realizar ninguna operación, efectivamente filtrando los vértices iniciales. Una vez que los vértices se filtran o se marcan, el recuento de rutas se calcula mediante la suma de los conteos de ruta entrantes. Es importante notar que los vértices en el primer paso envían una longitud de 1. Debido a que el algoritmo alterna la dirección a la que se envía el recuento de rutas, la función isEven(getSuperStep()) ayuda a decidir si se realiza el envío a vértices salientes o entrantes. Dadas las restricciones impuestas por el modelo de programación de Pregel, el código resultante es más difícil de comprender que la alternativa integrada en la API de recorrido, hecha en FJ. Sin embargo, a diferencia del FJ donde el número de caminos se fusiona en un solo nodo, Pregel propaga la cuenta de caminos a lo largo de todo el clúster (utilizando el método send en el código que se muestra en el Listado 5.3, Línea 21) y, como resultado, la fusión de sub-resultados se distribuye. Implementación DPM de TFR Motivado por el problema del cuello de botella identificado en el modelo FJ, DPM tiene un enfoque FJ para distribuir las tareas, pero utilizando un enfoque Pregel (o enfoque de MapReduce) para la distribución de los sub-resultados. En virtud de este nuevo modelo, el algoritmo Count DPM obtiene la longitud de los caminos actuales a partir del grafo en lugar de pasar los resultados de un trabajo a otro, como sucede en FJ. Los recuentos parciales de las rutas se distribuyen y almacenan en todo el clúster, equilibrando la fusión de resultados. El Listado 5.4 muestra la implementación Count DPM, que es un elemento esencial 86 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class TFR implements VertexFunction { public void execute ( long v , MessageList msgs ){ if ( getSuperStep () == 0 || getSuperStep () == 1) set ( " TYPE " , " TARGET_SET " ); else if ( get ( " TYPE " ) == " TARGET_SET " ) return ; float pathCount = 0 f ; if ( getSuperStep () > 0){ for ( Message msg : msgs ) pathCount += msg . value (); if ( getSuperStep () == 3) set ( " RESULT " , pathCount ); } else pathCount = 1 f ; LongSet userList = isEven ( getSuperStep ()) ? getGraph (). out ( v ) : getGraph (). in ( v ); for ( long neighbor : userList ) send ( neighbor , pathCount ); } } public class PregelCount implements Step { public TraversalResult exec ( TraversalResult before ) { PregelResult res = graphly . pregel () . vf ( new TFR ()) . run ( mapping_strategy , before ); return new Preg elTra versal Resul t ( res ); } } Listado de código 5.3: Implementación Pregel del algoritmo TFR. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class DPMCount implements Step { public TraversalResult exec ( TraversalResult before ) { DPMResult res = graphly . dpm () . task ( new DPMTask (){ public void compute ( List vertices ){ for ( long vID : vertices ) for ( long neighbor : getNeighbors ( vID )) emit ( vID , getOrDefault ( vID , 1)); } }) . combiner ( new Combiner (){ public Float combine ( Float a , Float b ){ return a + b ; } }) . run ( mapping_strategy , before ); return new DPMTraversalResult ( res ); } } Listado de código 5.4: Implementación en DPM de Count. 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 87 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class BetaCount implements Step { public TraversalResult execute ( BetaResult prev , Traversal tr ){ int path_length = getCurrentLength (); FJResult res = graphly . fj () . task ( new Task (){ public void compute ( List vertices , BetaResult prev ){ for ( long vID : vertices ) for ( long neighbor : getGraph (). getNeighbors ( vID )) emit ( " PATH " , vID , prev . getCount ( vID )); } }) . merger ( /* sum values */ ) . result_emitter ( new Emitter (){ public void compute ( Long vid , Integer paths , BetaResult prev ){ emit ( " BETA " , vid , prev . getBeta ( vid )+ beta . apply ( path_length )* paths ); } }) . run ( mapping_strategy , before ); return new BetaTraversalResult ( res . value ( " PATH " ) , res . value ( " BETA " )); } } Listado de código 5.5: Algoritmo Count en FJ utilizando un Beta personalizable. para implementar TFR en DPM. En lugar de obtener la cuenta de rutas de una etapa anterior como FJ, estas longitudes se registran en el almacén de grafos y se obtienen utilizando la función get(v) (o getOrDefault). Luego, la longitud de caminos hasta el vértice actual se emite de manera que los recuentos de caminos se distribuyan y se fusionen en todo el clúster. Naturalmente, como se explica en el Capítulo 4, Sección 4.8, los recuentos de rutas distribuidos deben ser almacenados en una memoria auxiliar para evitar lecturas inconsistentes en otros nodos que aún se encuentran procesando rutas. Cuando todos los nodos completan la ejecución, los resultados auxiliares se persisten en el almacén y se utilizan como entrada para el siguiente paso. 5.1.1.2 Algoritmo Katz El índice Katz mide la similitud de los usuarios de acuerdo con el número de caminos que los conecta (véase Capítulo 2, Sección 2.3.2). El n-ésimo paso del algoritmo amortigua todos los caminos de longitud n por la n-ésima potencia de β , efectivamente penalizando rutas largas. Fork-Join Implementation of Katz La implementación de Katz en FJ se basa en una variación de la función Count FJ definido anteriormente en este capítulo (el Listado 5.2). Esta función, denominada BetaCount, permite al usuario especificar un factor de penalización personalizado mediante la ampliación de la interfaz B ETA. En Katz, Beta se define como β n , donde n es la 88 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class KatzPregel implements VertexFunction { public void execute ( long v , MessageList msgs ) { float damped = 0 f ; if ( getSuperStep () > 0) { float katz = getOrDefault ( " RESULT " , 0 f ); for ( Message msg : msgs ) katz += msg . value (); set ( " RESULT " , katz ); damped = sum * beta ; } else damped = beta ; if ( getSuperStep () < lastStep ) for ( long neighbor : g . getAdjacents (v , dir )) send ( neighbor , damped ); } } Listado de código 5.6: Implementación en Pregel de Katz. longitud de la trayectoria actual. Además de la agregación de los recuentos de caminos, BetaCount también agrega los recuentos penalizados, lo que aumenta los requisitos de memoria del algoritmo. Mantener la cuenta de caminos es importante en situaciones donde la función beta no es uniforme a lo largo de las diferentes etapas, como en LocalPath donde se ignoran los primeros recuentos de ruta (o penalizadas con 0). En estos escenarios, por lo tanto, la cuenta de caminos es necesarios para producir la solución correcta. Como se muestra en el Listado 5.5, BetaCount utiliza el mismo enfoque que Count, pero se aplica la función Beta definida por el usuario (que se muestra en la línea de código beta.apply( current_depth)* path_length) y emite las longitudes penalizadas. Las últimas operaciones se llevan a cabo sobre cada resultado, justo después de que se completa la etapa de unión. Pregel Implementation of Katz El enfoque seguido para aplicar el índice Katz bajo el modelo Pregel es, en parte, similar al enfoque FJ. La implementación propuesta envía la longitud del camino actual de un vértice a sus vértices adyacentes, utilizando el mecanismo de mensajería de Pregel para mantener los recuentos de longitud, y los valores de los recuentos son agregados, penalizados y persistidos a través del almacén de grafos. Por lo tanto, al igual que BetaCount en FJ, los requisitos de memoria se duplican en comparación con la aplicación TFR. La implementación actual en GraphRec se muestra en el Listado 5.6. DPM Implementation of Katz La implementación híbrida Katz simplemente incorpora la interfaz B ETA a la función Count DPM. De hecho, todas las implementaciones de B ETA presentados en este trabajo pueden ser reutilizadas tanto para FJ y como para DPM. Por lo tanto, para soportar Katz y otros algoritmos similares, se proporciona una clase DPMB ETAC OUNT, mostrada en el Listado 5.7. 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 89 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class DPMBetaCount implements Step { public TraversalResult execute ( TraversalResult before , Traversal tr ){ int current_depth = tr . getCurrentDepth (); DPMResult res = graphly . dpm () . task ( new DPMTask (){ public void compute ( List vertices ){ for ( long vID : vertices ) for ( long neighbor : getNeighbors ( vID )) emit ( " PATH " , vID , getVertexValue ( vID )); } }) . merger ( /* a + b */ ) . result_emitter ( new Emitter (){ public void compute ( Long vid , Float path_length ){ emit ( " BETA " , vid , beta . apply ( current_depth )* path_length ); } }) . run ( mapping_strategy , before . vertices ()); return new DPMResult ( res . vertices () , " PATH " , " BETA " ); } } Listado de código 5.7: Implementación en DPM de Katz. 1 2 3 4 5 6 7 public class LPBeta implements Beta { public float apply ( int depth ) { if ( depth ==1) return 0 f ; if ( depth == 3) return beta ; return 1 f ; } } Listado de código 5.8: Implementación de Beta de LocalPath. 5.1.1.3 Algoritmo LocalPath La implementación del algoritmo LocalPath toma un enfoque similar al utilizado en Katz. Al igual que TFR, LocalPath restringe la búsqueda a caminos de longitud tres o menos. El algoritmo aplica un B ETA solo a caminos de longitud tres. Implementación de LocalPath en DPM y FJ La implementación de LocalPath bajo FJ y DPM vuelve a utilizar los algoritmos BetaCount y DPMBetaCount respectivamente. Sin embargo, este algoritmo almacena los conteos de longitudes penalizados sólo para caminos de longitud dos y tres. La implementación de B ETA usado para LocalPath bajo FJ y DPM se muestra en el Listado 5.8. Implementación Pregel de LocalPath En este caso, LocalPath sigue la misma estrategia que la implementación de Katz en Pregel: llevar un conteo de rutas que son agregadas para cada 90 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class LocalPath implements VertexFunction { public void execute ( long v , MessageList msgs ){ float adj = 0 f ; if ( getSuperStep () > 0) { for ( Message msg : msgs ) adj += msg . value (); if ( getSuperStep () > 1) { float lp = adj ; if ( getSuperStep () == 3) lp = getOrDefault ( " RESULT " , 0 f ) + alpha * adj ; set ( " RESULT " , lp ); } } else adj = 1 f ; for ( long neighbor : getOugoing ( v )) send ( neighbor , adj ); } } Listado de código 5.9: Implementación en Pregel de LocalPath. 1 2 3 4 5 6 7 8 9 public class FriendLinkBeta implements Beta { public float apply ( int path_length ) { if ( path_length <2) return 0; float prod = 1 f ; for ( int i = 2; i <= path_length ; i ++) prod *= vcount - i ; return (1 f / path_length ) * (1 f / prod ); } } Listado de código 5.10: Implementación de Beta de FriendLink. vértice, luego el resultado del algoritmo es actualizado al valor actual y, por último, los recuentos actuales son enviados a los vértices adyacentes. El Listado 5.9 presenta el código de LocalPath, que es notablemente más complejo de analizar que sus contrapartes en FJ y DPM. 5.1.1.4 FriendLink Algorithm El algoritmo FriendLink penaliza caminos largos de una manera más compleja que los algoritmos anteriores, introduciendo un factor de normalización para mantener los resultados en un intervalo [0, 1]. Sin embargo, las estrategias para resolver el algoritmo son los mismos que antes, solo que aumenta la complejidad de la función β que penaliza los recuentos de ruta. Implementación de FriendLink en FJ y DPM A pesar de la complejidad del cálculo de β , este algoritmo también se puede implementar utilizando los algoritmos BetaCount y GraphBetaCount. La implementación de la interfaz Beta para FriendLink se muestra en el Listado 5.10. 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 91 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class FriendLink implements VertexFunction { public void execute ( long v , MessageList msgs ){ float adj = 0 f ; if ( getSuperStep () > 0) { for ( Message msg : msgs ) adj += msg . value (); if ( getSuperStep () >= 2) { float prod = 1 f ; for ( int i = 2; i <= getSuperStep (); i ++) prod *= vcount - i ; float fl = getOrDefault ( " RESULT " , 0 f ) + (1 / getSuperStep ()) * (1 / prod ) * adj ; set ( " RESULT " , fl ); } } else adj = 1 f ; for ( long neighbor : g . getAdjacents (v , dir )) send ( neighbor , adj ); } } Listado de código 5.11: Implementación en Pregel de FriendLink. Implementación de FriendLink en Pregel El aspecto más importante a considerar en el desarrollo de FriendLink bajo el modelo Pregel, es el hecho de que los sub-resultados deben añadirse al resultado final comenzando en el paso dos y pasos superiores (caminos de longitud dos). Listado 5.11, representa la función vértice de FriendLink. 5.1.2 Algoritmos Basados en Vecinos Mientras que los algoritmos basados en caminos tienen como objetivo de generar recomendaciones para un usuario de destino mediante la clasificación de los usuarios del grafo, los algoritmos basados en los vecinos tienen como objetivo proporcionar una medida de la similitud entre dos o más usuarios mediante el aprovechamiento de la información de su vecindario. Esta métrica da salida un único valor que indica la similitud relativa de los usuarios implicados que, a su vez, permite clasificar a los usuarios por su grado de semejanza. Además, los algoritmos basados en vecinos a menudo operan sólo en la adyacencia de los usuarios y, en este sentido, pueden ser vistos como algoritmos basados en caminos de longitud dos. Estos algoritmos se llevaron a cabo en aquellos modelos que proporcionan algún tipo de agregación de resultados globales, es decir que no están asociados a un vértice específico. FJ soporta de forma natural el agregado de resultado al hacer que las tareas devuelvan un solo valor, que luego se fusionan en el trabajo padre. Pregel proporciona el mecanismo de agregadores que permite a un worker compartir y fusionar un valor agregado con otros workers. DPM, por otra parte, no es compatible con la agregación de resultados simples. En una hipotética implementación, las tareas de DPM pueden devolver un solo valor y entonces el trabajo padre puede combinarlos, lo que resulta en 92 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class IntersectStep implements Step { public TraversalResult exec ( TraversalResult before ) { FJResult res = graphly . fj () . task ( new Task (){ public void compute ( VertexList vertices ){ for ( long vid : vertices ) emit ( getNeighbors ( vid )); } }) . merge ( new Merger (){ public VertexList merge ( VertexList a , VertexList b ){ VertexList res = new VertexList ( a ); for ( long bVertex : b ) if (! a . contains ( bVertex )) res . remove ( bVertex ); return res ; } }). run ( mapping_strategy , before ); return new VertexListResult ( res . value ()); } } Listado de código 5.12: Algoritmo de intersección en FJ. exactamente el mismo mecanismo que el proporcionado por FJ. Así, en los algoritmos basados en los vecinos, la alternativa DPM está ya implementado en FJ. 5.1.2.1 Common Neighbors Common Neighbours es el más simple de los algoritmos basados en vecinos. En primer lugar, el algoritmo recibe un grupo de vértices como entrada y obtiene, para cada uno de ellos, a sus vecinos (es decir, los vértices de entrada y vértices de salida), una operación que es perfectamente paralelizable. En segundo lugar, el algoritmo debe fusionar los vecinos establece mediante el procesamiento de su intersección. El objetivo de las implementaciones de Common Neighbours que se presentan aquí es distribuir la intersección de los vecinos entre los nodos del clúster. En GraphRec, esto se implementa simplemente como: graph.v( user_list ). intersect (Dir . BOTH).size(); Bajo el modelo FJ, cada trabajo procesa la intersección de un subconjunto de los vértices de entrada. Una vez finalizada la intersección distribuida de vecinos, los sub-resultados, es decir, las intersecciones parciales, se interseccionan de nuevo en el nodo de origen para producir el conjunto de vecinos comunes. El Listado 5.12 muestra el código de I NTERSECTION S TEP, la clase utilizada para integrar vecinos comunes a la API de grafos. En esta clase, el C OMBINER configurado realiza una simple intersección entre dos conjuntos que pertenecen al resultado final. A las tareas hijas se les asigna un subconjunto de los vértices de entrada y son responsables de 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 93 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 public class CommonNeighbors implements VertexFunction { public void execute ( long v , MessageList msgs ){ VertexList neighbors = getNeighbors ( v ); getAggregator ( " common_neighbors " ). add ( neighbors ); } } public class IntersectAggregator implements Aggregator { VertexList intersection = new VertexList (); public void add ( VertexList neighbors ) { intersection . intersectWith ( neighbors ); } } Listado de código 5.13: Implementación en Pregel de Common Neighbours. la obtención de los vecindarios. Se debe notar que el método emit no está asociado a ningún vértice ya que los resultados se combinan todos en una sola lista de vértices intersecada. La implementación en Pregel adopta un enfoque similar a la alternativa FJ. Obtiene los vecinos de cada vértice y los inserta en un I NTERSECTIONAGGREGATOR compartido que procesa la intersección de los vecinos. Cuando el algoritmo termina, los I NTERSECTIONAGGREGATORS de todos los nodos se fusionan en un único agregador que contiene los vecinos comunes. En esencia, esta aplicación utiliza la misma estrategia que el enfoque FJ fusionando la intersección en un solo lugar. Sin embargo, en lugar de retornar a los vecinos a un único nodo como en FJ, cada función agrega la vecindad de los vértice al agregador local. El Listado 5.13 muestra la función vértice utilizada para obtener los vecinos de cada vértice y, a continuación, las clase I NTERSECTIONAGGREGATORS utilizada para calcular la intersección. 5.1.2.2 Adamic Adar Este algoritmo extiende Common Neighbours penalizando – de forma logarítmica – la contribución de aquellos vértices que tienen grandes vecindarios. El enfoque en este caso es volver a utilizar el algoritmo de Common Neighbours y extenderlo distribuyendo el cálculo de los tamaños de vecindario. La aplicación FJ vuelve a utilizar la función Intersect presentada antes, como se muestra en el Listado 5.14. La implementación del cálculo de Adamic Adar también se muestra en el mismo Listado. La implementación en Pregel es similar, reutilizando la función de vértices de Common Neighbours presentada anteriormente y utilizando un agregador que combina los resultados utilizando Adamic Adar, como se muestra en el Listado 5.15. 5.1.2.3 Jaccard El algoritmo de Jaccard requiere relativamente más memoria que Common Neighbours debido a que la aplicación debe manejar dos listas de vértices: la unión y la intersección de los vecin94 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 graph . v ( vertices ). intersect ( Dir . BOTH ). customStep ( new AdamicAdar ()); public class AdamicAdarStep implements Step { public TraversalResult exec ( TraversalResult before ) { FJResult res = graphly . fj () . task ( new ValueTask (){ public void compute ( VertexList vertices ){ float count = 0 f ; for ( long v : vertices ) count += 1 / Math . log ( getNeighborhoodSize ( v ))); emit ( count ); } }) . merge ( new ValueMerger (){ public float merge ( float a , float b ){ return a + b ; } }). run ( mapping_strategy , before ); return new ValueResult ( res . value ()); } } Listado de código 5.14: Implementación en FJ de Adamic Adar. 1 2 3 4 5 6 7 8 9 10 graph . v ( vertices ). as ( PregelTraversal . class ) . vertexFunction ( new Com monNe ighbor sPrege l ()) . vertexFunction ( new AdamicAdarPregel ()) . getAggregatorValue ( " ADAMIC " ) public class AdamicAdarPregel implements VertexFunction { public void execute ( long v , MessageList msgs ) throws Exception { getAggregator ( " ADAMIC " ). add (1/ Math . log ( getNeighborhoodSize ( v ))); } } Listado de código 5.15: Implementación en Pregel de Adamic Adar. 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 95 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 tr . intersect ( Dir . BOTH ). customStep ( new AdamicAdar ()); public class JaccardStep implements Step { public TraversalResult exec ( TraversalResult before ) { FJResult res = graphly . fj () . task ( new ValueTask (){ public void compute ( VertexList vertices ){ VertexList intersection = new VertexList (); VertexList union = new VertexList (); for ( long v : vertices ) { VertexList neighbors = getNeighbors (); intersection . intersectWith ( neighbors ); union . addAll ( neighbors ); } emit ( " INTERSECTION " , intersection ); emit ( " UNION " , union ); } }) . merge ( " INTERSECTION " , new ValueMerger (){ public VertexList merge ( VertexList a , VertexList b ){ return a . intersectWith ( b ); } }) . merge ( " UNION " , new ValueMerger (){ public VertexList merge ( VertexList a , VertexList b ){ return a . addAll ( b ); } }) . run ( mapping_strategy , before ); return new ValueResult ( res . get ( " INTERSECTION " ). size () / res . get ( " UNION " ). size ()); } } Listado de código 5.16: Implementación en FJ de Jaccard. 1 2 3 4 5 6 7 8 9 10 11 12 public class JaccardAggregator implements SetAggregator { VertexList inter = new VertexList (); VertexList union = new VertexList (); public float value () { return inter . size () / union . size (); } public void add ( VertexList v ) { intersection . intersectWith ( v ); union . addAll ( v ); } } Listado de código 5.17: Implementación en Pregel de Jaccard. 96 of 206 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS darios. La versión FJ (Listado 5.16) y la versión Pregel son análogos al algoritmo de vecinos comunes con el procesamiento adicional de la unión de los vértices. La implementación Pregel de Jaccard reemplaza el agregador de Common Neighbours con un agregador especial que procesa tanto la unión como la intersección de los vecinos, como se muestra en el Listado 5.16. 5.1.3 Discusión de las Implementaciones El análisis de los problemas que surgen durante la implementación de algoritmos basados en caminos, explicados en la sección anterior, puede ayudar a los desarrolladores a evitar errores comunes e inclinar la decisión de utilizar un modelo u otro dependiendo del tipo particular de algoritmos. Los problemas de rendimiento con respecto a cada combinación de algoritmo y modelo se analizan más adelante en este capítulo. Los algoritmos basados en caminos tienen la particularidad de realizar una pequeña cantidad de pasos de recorrido, combinando caminos cortos, pero generando una gran cantidad de resultados intermedios. En TFR, por ejemplo, hay otra restricción, cada paso de recorrido realiza una operación diferente: la primera etapa construye el subgrafo inicial, el segundo paso cuenta los caminos a los vértices intermedios y filtra el subgrafo inicial, y el paso final devuelve el resultante de vértices clasificados por el recuento de longitudes de caminos y filtrados, nuevamente, por los vértices iniciales. El estilo de programación de DPM y de FJ se adaptan muy bien a este tipo de algoritmos, ya que cada operación se realiza en base a los resultados de la etapa anterior. El estilo centrado en el vértice de Pregel, por el contrario, presenta un nuevo paradigma que pueda perjudicar la legibilidad del código. Aunque el mecanismo de mensajería ayuda al desarrollador a mantener localidad de datos, cada algoritmo basado en la caminos debe ser rediseñado para dar cuenta de esta comunicación de vértice a vértice. Esencialmente, Pregel separa el procesamiento de sub-resultados del cómputo del resultado final. Por ejemplo, en TFR, la agregación de la longitud de los caminos se realiza a través de mensajes en lugar de ser agregada en el almacén de Graphly (como en DPM) o una tabla de resultados (como en FJ). Por lo tanto, el algoritmo debe recoger las longitudes de caminos a partir de los mensajes entrantes y, después, guardar los resultados en el grafo. De hecho, el desarrollador debe resolver estas cuestiones: decidir qué datos serán enviados a los vértices vecinos, cómo los mensajes entrantes son agregados, y la forma en que se guarda el resultado del algoritmo. Por ejemplo, en la mayoría de los algoritmos basados en caminos implementados, los datos enviados contienen la longitud del camino actual, los mensajes entrantes se agregan mediante la adición de ellos y el resultado final se guarda sólo cuando el algoritmo llega a la etapa final. DPM y FJ simplifican el mecanismo de lectura y escritura de los resultados mediante la representación de sub-resultados en el mismo formato que los resultados finales. El algoritmo, a continuación, realiza modificaciones en las sub-resultados actuales y los desarrolladores no están obligados a especificar el modo de representación y comunicación de ellos. Detrás de las 5.1. IMPLEMENTACIÓN DE LOS ALGORITMOS 97 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS escenas, sin embargo, DPM y FJ mantienen los valores antiguos y nuevos para evitar inconsistencias. Los valores antiguos, por lo tanto, desempeñan el papel de los mensajes que se envían en Pregel. Sin embargo, hay otro tema importante respecto del estilo de programación Pregel de algoritmos basados en caminos. Pregel está diseñado para realizar varias iteraciones sobre el conjunto de datos y, a continuación, los algoritmos basados en caminos se ven obligados a ser expresados como si tuvieran un número mayor de iteraciones en lugar de diferentes pasos de recorrido. La alternativa, sería llevar a cabo una sola iteración de Pregel para cada paso del algoritmo, lo que introduce una sobrecarga de la inicialización de la plataforma cada vez. Sin embargo, la versión centrada en el vértice de algoritmos basados en caminos requiere la comprobación acerca de qué Superpaso la plataforma está ejecutando actualmente con el fin de decidir qué paso del algoritmo debe ser calculado. Por ejemplo, en el paso 0 el algoritmo marca el vértice actual (que es el objetivo de la recomendación) e inicializa la longitud de la trayectoria en 1. En el paso 1, el algoritmo marca nuevamente el vértice, pero esta vez se agregan las longitudes de caminos. En el paso 2 y 3, el algoritmo las longitudes de los caminos y filtra los vértices marcados. Además, en el paso 3, que es el paso final, se guardan las longitudes agregados en la plataforma. Claramente, es difícil de expresar los diferentes pasos del algoritmo en una única función de vértice, y aún más difícil de entender y mantener el código resultante. 5.2 Configuración Experimental La presente Sección describe el dataset utilizado para poblar el grafo (Subsección 5.2.1) así como también el conjunto de usuarios utilizados como objetivo de las recomendaciones (Subsección 5.2.2), y los nodos computacionales utilizados para ejecutar los algoritmos (Subsección 5.2.3). 5.2.1 Descripción del Dataset Los experimentos se llevaron a cabo utilizando un dataset de Twitter1 , que contiene la red completa de seguidores/seguidos de julio de 2009, proporcionado por Kwak et al. (2010). El conjunto de datos contiene aproximadamente 1.400 millones de relaciones entre más de 41 millones de usuarios obtenidas mediante la API de Twitter. Este conjunto de datos contiene información topológica sobre toda la red social, es decir, todas las relaciones binarias entre los ID de usuario, pero no incluye los tweets. Esto no es una limitación ya que todos los algoritmos contemplados se basan sólo en las relaciones de los usuarios, en busca de candidatos a seguir en el grafo de Twitter. Debido a que los datos de Twitter ya no están a disposición de los investigadores, este dataset sigue siendo la instantánea más grande de Twitter (Faralli et al., 2015a). En su mayoría, las 1 Dataset 98 of 206 de Twitter 2010, http://an.kaist.ac.kr/traces/WWW2010.html 5.2. CONFIGURACIÓN EXPERIMENTAL CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS (a) (b) Figure 5.2: Frecuencia de Seguidores y Seguidos ajustados a una ley de potencias con alfa 2.276. muestras de este conjunto de datos (es decir subgrafos) se han utilizado ampliamente en la literatura para la evaluación experimental (Valverde-Rebaza and de Andrade Lopes, 2013; Yin et al., 2011). El uso de un grafo de usuarios completo evita el problema de encontrar un subconjunto de usuarios que represente estadísticamente la red social original (Tang et al., 2015; Wang et al., 2011). Por lo tanto, a pesar de que el número de usuarios ha crecido desde el año 2009, el conjunto de datos sirve para el propósito de demostrar la escalabilidad de los algoritmos en un grafo muy grande del mundo real, con usuarios que emergen de las redes sociales en línea. Todo el conjunto de datos ocupa más de 20 gigabytes de espacio almacenados en disco duro en el almacén de Graphly, lo cual es demasiado grande para caber en la memoria de la mayoría de las computadoras de hoy en día. Por otra parte, la mayoría de los frameworks necesitan estructuras adicionales que deben permanecer en la memoria principal ya que se utilizan de forma repetida. En consecuencia, la mayoría de los equipos actuales no pueden mantener tanto la estructura del framework y la estructura del grafo en la memoria principal. Por otra parte, incluso si la cantidad de vértices es relativamente baja, la cantidad de ejes suele ser enorme, lo que impacta directamente en el rendimiento de la mayoría de los algoritmos de grafos que realizan recorridos (o utilizan los ejes de alguna manera). La distribución de los enlaces entrantes y salientes de las redes sociales del mundo real representan un desafío para la distribución eficiente de la computación de grafos en paralelo debido a que la mayoría de los usuarios tienen relativamente pocos vecinos, mientras que un pequeño número de usuarios tiene numerosos vecinos (por ejemplo, las celebridades en una red social). En efecto, la probabilidad de llegar a un vértice con muchos vecinos es bastante alta debido a que estos vértices conectan grandes secciones del grafo. Incluso si el algoritmo empieza a procesar 5.2. CONFIGURACIÓN EXPERIMENTAL 99 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Figure 5.3: Función de complemento acumulado (CCDF) de Seguidos (en azul) y Seguidores (en rojo) alineado a una distribución de ley de potencias con alfa 2.276. un nodo de baja conectividad, pocos ejes necesitan ser recorridos para encontrar un nodo altamente conectado. Predecir el recorrido que el algoritmo va a realizar puede ser imposible, y por lo tanto, equilibrar el procesamiento de vértices altamente y bajamente conectados a lo largo del clúster es muy difícil. Kwak et al. (2010) llevaron a cabo un estudio sobre el grafo completo obtenido, observando algunas propiedades notables de Twitter, como una desviación de la distribución de ley de potencias, un diámetro efectivo corto, y baja reciprocidad de las relaciones, lo que marca una diferencia con las características conocidas de las redes sociales humanas (Newman and Park, 2003). La Figura 5.2 muestra la distribución del número de seguidos (5.2a) y seguidores (5.2b), respectivamente, para los usuarios en el grafo. Tenga en cuenta que una gran cantidad de usuarios sólo tienen 1 seguido (107 usuarios tienen aproximadamente 100 seguidores/seguidos) y sólo una pequeña cantidad de usuarios tiene más de 105 seguidores/seguidos. Como se informó en el estudio, sólo hay 40 usuarios con más de un millón de seguidores, siendo todos ellos celebridades (por ejemplo, Ashton Kutcher, Britney Spears, Shaquille O’Neal) o medios de comunicación (por ejemplo, el Ellen DeGeneres Show, CNN Noticias de última hora, el New York Times, la cebolla). Una línea de distribución de ley de potencias con alfa 2.276 (es decir, x−2,276 , según lo informado por Kwak et al. (2010)) se dibuja junto con la distribución. Como se puede ver, ambas distribuciones siguen una ley de potencia hasta aproximadamente 105 y, después de ese número, las dos distribuciones se desvían de la predicción. Esta distribución de ley de potencia discontinua (es decir, que sigue una distribución de ley de potencia para un cierto rango) pueden ser mejor analizado con una función complementaria de distribución acumulada (CCDF), que se muestra en la Figura 5.3. Una CCDF de una función de ley de potencia se caracterizan por mostrar una línea recta (en negro) en un gráfico log-log. 100 of 206 5.2. CONFIGURACIÓN EXPERIMENTAL CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Observe que la función acumulada se desvía para los seguidos (puntos azules) y seguidores (puntos rojos) aproximadamente en 105 del seguidor. Esto significa que la cantidad de usuarios que tienen más de 105 seguidos disminuye más rápido que la cantidad prevista por la ley de potencias. Por el contrario, la cantidad de usuarios que tienen más de 105 seguidores es más alta que la predicha por la ley de potencias. Por otra parte, la mayoría de las relaciones no son recíprocas, lo que significa que un usuario puede seguir un conjunto de usuarios, pero no todos ellos seguirlo de forma recíproca. Sólo el 22,1% de los ejes son recíprocos (es decir, los usuarios siguen unos a otros) y el 67,6% de los usuarios no son seguidos por ninguno de sus seguidos. 5.2.2 Selección de Grupos de Test Para la evaluación de los algoritmos, se seleccionaron tres grupos de prueba a partir de los usuarios de la base de datos completa, con el objetivo de ilustrar el funcionamiento de las diferentes estrategias para variadas necesidades de los algoritmos y características de los usuarios (por ejemplo, altamente o bajamente conectado). El primer grupo consiste en los 10 primeros usuarios ordenados por cantidad de seguidores, llamados los "Conjunto Followers". Del mismo modo, el segundo conjunto, llamado los "Conjunto de Followees", contiene los 10 primeros usuarios ordenados por cantidad de seguidos, omitiendo aquellos usuarios que pertenecen a los seguidores establecidos. Por último, un grupo de 10 usuarios con una relación de seguidor/seguido entre 0,4 y 0,6, es decir, los usuarios que tienen aproximadamente la misma cantidad de followees y followers, ordenados por los seguidores. Los usuarios se identifican por su posición en las listas ordenadas. Mediante el uso de esta convención, los usuarios en el conjunto de followees se nombran Fee1 , ..., Fee10 , Los usuarios en el conjunto de seguidores se nombran Fol1 , ..., Fol10 y los usuarios en el conjunto de la mitad se nombran Mid1 , ..., Mid10 . La Tabla 5.1a muestra los 10 primeros usuarios del conjunto de seguidores, siendo Ashton Kutcher la persona más seguida en el conjunto de datos. La Tabla 5.1b muestra a los usuarios con la mayor cantidad de seguidos en el conjunto de datos. Este conjunto está conformado en su mayoría con los usuarios que proporcionan algún soporte o ayuda (por ejemplo, @WholeFoods @Starbucks). Por último, el conjunto del medio se muestra en la Tabla 5.1c. El razonamiento detrás de la selección de estos grupos es que el número inicial de enlaces entrantes o salientes puede afectar a los recursos de clúster (memoria RAM, red, CPU) requeridos por un algoritmo de recomendación dado durante la ejecución. De hecho, esta lógica sostiene que cuanto mayor sea el vecindario inicial, más grande serán las secciones del grafo que los algoritmos tendrán que procesar. Por lo tanto, la selección de usuarios con diferentes cantidades de seguidores y seguidos permite probar diferentes escenarios de estrés. La alternativa a esta estrategia es procesar cada algoritmo para los 40M de usuarios en el conjunto de datos y construir un rango de usuarios ordenados por el uso de recursos, lo que es claramente una tarea poco razonable. 5.2. CONFIGURACIÓN EXPERIMENTAL 101 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Twitter ID Nombre de Usuario Seguidos Seguidores Fol1 17461978 @SHAQ 563 1843561 Fol2 19757371 @johncmayer 64 1844499 Fol3 813286 @BarackObama 770155 1882889 Fol4 16190898 @RyanSeacrest 137 1885782 Fol5 783214 @twitter 55 1959708 Fol6 19397785 @Oprah 15 1994926 Fol7 428333 @cnnbrk 18 2450749 Fol8 16409683 @britneyspears 406238 2674874 Fol9 15846407 @TheEllenShow 26 2679639 Fol10 19058681 @aplusk 183 2997469 (a) Top-10 de usuarios por seguidores Fee1 Twitter ID Nombre de Usuario Seguidos Seguidores 14994465 @jimmyeatworld 134788 920556 Fee2 30973 @Starbucks 138045 271215 Fee3 8453452 @GuyKawasaki 140903 157878 Fee4 26784273 @charitywater 143408 705663 Fee5 5380672 @threadless 263317 933726 Fee6 12687952 @BJMendelson 283435 937627 Fee7 14075928 @TheOnion 369569 1380160 Fee8 7040932 @tonyhsieh 407705 1075935 Fee9 15131310 @WholeFoods 498700 1112628 Fee10 14224719 @Number10gov 505613 1105469 (b) Top-10 de usuarios por seguidos, quitando repetidos del grupo de Seguidores. Twitter ID Nombre de Usuario Seguidos Seguidores Mid1 5210841 @ScotMcKay 109279 104813 Mid2 10546442 @RobMcNealy 99184 108477 Mid3 17850012 @Radioblogger 115293 110215 Mid4 15021099 @caseywright 108615 111035 Mid5 14669398 @BradHoward 119531 112462 Mid6 16559157 (closed) 119596 112914 Mid7 14389132 @nansen 123051 114880 Mid8 9720292 @hashtags 99668 117302 Mid9 15947185 @TweetSmarter 107580 128819 Mid10 2557521 @espn 109377 138982 (c) Top-10 de usuarios con aproximadamente la misma cantidad de seguidores y seguidos. Table 5.1: Selección de usuarios objetivo de la recomendación. 102 of 206 5.2. CONFIGURACIÓN EXPERIMENTAL CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS CPU Primer Conjunto (3 nodos) Segundo Conjunto (3 nodos) Tercer Conjunto (2 nodos) AMD Phenom II X6 1055T 2.8 Ghz AMD FX 6100 3.3 Ghz AMD FX 6300 3.5 Ghz # de núcleos 6 6 6 RAM 8 GB 16 GB 16 GB Red 1 Gbit Ethernet 1 Gbit Ethernet 1 Gbit Ethernet Disco Duro 500 GB - 7200 RPM 500 GB - 7200 RPM 500 GB - 7200 RPM Table 5.2: Características de hardware del clúster. 5.2.3 Descripción del Clúster Con respecto a las características de clúster, se utilizó un grupo heterogéneo de 8 nodos divididos en tres conjuntos para ejecutar los experimentos, cada uno con sus propias características de hardware. En la Tabla 5.2 se resumen las características más relevantes de cada conjunto de nodos. En cuanto a las características de software, el sistema operativo instalado en todas las máquinas fue Ubuntu, la versión 14.10, utilizando el núcleo de GNU/Linux versión 3.16. Como Graphly fue desarrollado en Java, cada máquina fue provista con una máquina virtual de Oracle Java HotSpot, soportando Java versión 7. La configuración de Graphly se llevo a cabo de la siguiente manera. Un script de inicialización se ejecuta en cada nodo, iniciando una instancia de servidor de grafos, lo que implicaba la ejecución del Worker Graphly, que a su vez contiene el almacén Graphly, y los componentes de Pregel, FJ y DPM. Uno de los nodos se configuró para arrancar un Coordinador Graphly, que mantiene el protocolo de hashing consistente y la coordinación de Pregel. En DPM y FJ no es necesario un coordinador debido a que el trabajo padre toma ese papel. 5.3 Resultados Experimentales La experimentación reportada en este capítulo tiene como objetivo principal evaluar el impacto de los modelos de procesamiento en el rendimiento de los algoritmos de predicción de enlace basados en caminos. Los modelos FJ y Pregel se comparan junto al modelo DPM propuesto en términos de tiempo de recomendación (es decir, el tiempo requerido para generar una lista de recomendaciones para un usuario objetivo), uso de red y el consumo de memoria. Los resultados experimentales obtenidos con los modelos implementados en Graphly se describen en la subsección 5.3.1. La aplicación de estrategias de mapeo y sus ventajas se presentan en la subsección 5.3.2. 5.3. RESULTADOS EXPERIMENTALES 103 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Algoritmo TFR Katz LocalPath FriendLink Configuración N/D Max. Path Length = 4, β = 0.0001, Edge Direction = OUT β = 0.1, Edge Direction = OUT Max. Path Length = 4, Edge Direction = OUT Table 5.3: Configuración de algoritmos basasados en caminos. 5.3.1 Resultados de Modelos de Procesamiento Los experimentos fueron dirigidos a la comparación del rendimiento de cada modelo en términos de uso de memoria, uso de la red y el tiempo de recomendación. Cada algoritmo se ha configurado deliberadamente para exigir una cantidad significativa de recursos del clúster con el fin de producir resultados comparables del mundo real. La Tabla 5.3 resume la configuración de cada algoritmo para los experimentos descritos. Dada la configuración de los algoritmos y un usuario de prueba, cada algoritmo produce un conjunto resultante de vértices como consecuencia de la exploración del grafo, formando un subgrafo de nodos visitados. Los tamaños de los subgrafos resultantes se resumen en la Tabla 5.4 para obtener una perspectiva del volumen de los datos necesarios para llegar a una lista resultante de recomendaciones para un solo usuario en el grafo (expresado en millones de vértices). Se debe tener en cuenta que para la mayoría de los algoritmos y los usuarios, con unos pocos pasos de recorrido se alcanza casi el número total de vértices en el conjunto de datos, es decir, la red social completa. Aunque el número de vértices es relativamente manejable, el número de aristas que deben procesar los algoritmos crece exponencialmente con el número de vértices. A medida que los algoritmos alcanzan todo el conjunto de datos, la mayoría de los algoritmos de terminan procesando- de forma individual - toda la lista de los 1.400 millones de ejes. Los resultados para cada uno de los algoritmos analizados se presentan a continuación. Resultados de TFR Los resultados experimentales se analizaron inicialmente para el caso TFR, ya que implica el más complejo de recorrido de los algoritmos estudiados. La Figura 5.4 muestra el uso de tiempo de recomendación, uso de la red y la memoria para cada grupo de usuarios objetivo (Seguidores, Seguidos y Mitad) y cada modelo considerado (DPM, FJ y Pregel). DPM presenta una ventaja leve sobre FJ y Pregel en términos de tiempo para hacer una recomendación. En parte, esto podría ser un resultado de la combinación de un modelo de programación adecuado con un mecanismo de fusión eficiente. Entre FJ y Pregel, para la mayoría de los usuarios, Pregel parece comportarse de forma igual o peor que FJ. El análisis de los resultados de uso de la red mostró que FJ fue el modelo menos intensivo en uso de red, seguido de 104 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS TFR Katz LocalPath FriendLink Fol1 24 37 12 38 Fol2 21 32 7 32 Fol3 37 40 35 40 Fol4 24 37 13 37 Fol5 14 21 43 21 Fol6 20 20 35 20 Fol7 14 33 7 33 Fol8 37 40 32 40 Fol9 22 36 12 37 Fol10 24 38 15 39 (a) Grupo de Seguidores. TFR Katz LocalPath Fee1 35 28 Fee2 37 32 Fee3 37 35 Fee4 39 32 Fee5 38 Fee6 36 Fee7 38 34 Fee8 36 34 Fee9 38 35 Fee10 37 34 ~40 32 32 FriendLink ~40 (b) Grupo de Seguidos. TFR Katz LocalPath Mid1 37 Mid2 36 Mid3 37 Mid4 37 Mid5 Mid6 ~38 ~40 37 36 Mid7 37 Mid8 32 Mid9 36 Mid10 32 FriendLink ~40 (c) Grupo Mitad. Table 5.4: Tamaño final del subgrafo explorado en la ejecución de cada algorítmo (en millones de vértices). 5.3. RESULTADOS EXPERIMENTALES 105 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Pregel y DPM en el tercer lugar. Esto era esperado, ya que DPM no sólo distribuye los resultados de todo el grupo, sino también envía la lista de vértices activos a la tarea principal, lo que lo lleva a un consumo mayor de red. En términos de uso de memoria, el claro ganador fue FJ, que presentó los picos más bajos. En esta dimensión, DPM se encuentra en segundo lugar y Pregel fue el modelo más intensivo en uso de memoria. Otro punto de vista de los mismos resultados se muestra en la Figura 5.5. En esta figura, los resultados para cada usuario se normalizaron a un rango [0, 1] con respecto al valor de FJ. En otras palabras, ya que FJ es la elección más natural para la aplicación de este tipo de algoritmos, se consideró como base de referencia para evaluar el rendimiento de Pregel y DPM. En consecuencia, los valores de los modelos Pregel y DPM en el gráfico se deben leer como una proporción de mejora o empeoramiento con respecto a los valores de FJ. Por ejemplo, el tiempo de recomendación para Fol1 (gráfico de barra superior izquierda) es -0.1 para Pregel y -0.2 para DPM, lo que significa que llevan a cabo la recomendación en un 10% y un 20% menos de tiempo que FJ, respectivamente. El uso de este tipo de gráfico facilita la comparación de rendimiento de cada modelo, sin tener en cuenta la escala de los valores. DPM exhibió una diferencia de 10 a 20% menos de tiempo de recomendación para el conjunto de Seguidores, un 10% menos para los Seguidos, y un 5% para el conjunto Mitad. Pregel mostró resultados mixtos con respecto a FJ. Para varios usuarios se comportó igual que FJ, con una diferencia de +/- 2%. Sin embargo, en casos en los que rindió mal las diferencias consistían en aproximadamente 10 a 20% más de tiempo. Para algunos usuarios, sin embargo, Pregel funcionó mejor que FJ, con mejoras de alrededor de 5 a 10%. En cuanto al consumo de red, se presentaron diferencias de alrededor de +10% de uso de la red en Pregel y +20% en DPM. Algunos de los experimentos, especialmente para usuarios con poca cantidad de followees como Fol5 y Fol7 , FJ y Pregel produjo una alta sobrecarga en el uso de la red mientras que DPM produjo 40% menos de tráfico de la red. Los usuarios con pequeña cantidad de seguidos, quienes representan casi todos los usuarios del grupo Seguidores (excepto Fol3 y Fol8 ), presentó un menor uso de memoria en DPM y Pregel con respecto a FJ. Esto está relacionado con la forma en la que TFR explora el grafo: a partir de los de seguidos del usuario objetivo. Como se muestra en la Tabla 5.1a, la mayoría de los usuarios del grupo de Seguidores, no tienen muchos followees, y por lo tanto, generan subgrafos más pequeños (esto se puede ver en Tabla 5.4). Para estos usuarios, la fusión de los resultados de FJ causa una alta sobrecarga, lo que aumenta el uso de memoria en general. Sin embargo, cuando TFR requiere más recursos para calcular una recomendación, FJ presentó una mejor alternativa en relación tanto con la red y el uso de memoria. Esto puede explicarse por el hecho de que, Pregel y DPM están preparados para procesar y distribuir resultados por muchas iteraciones y, por lo tanto, cuando el número de iteraciones es baja como en TFR, la sobrecarga de la división y el almacenamiento de resultados distribuidos es alta. Sin embargo, DPM presentó un menor consumo de memoria que Pregel en casi todos los experimentos, casi llegando a la eficiencia de 106 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Fork Join Pregel Middle DPM Figure 5.4: Resultados experimentales de TFR. 5.3. RESULTADOS EXPERIMENTALES 107 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS uso de memoria de FJ. Katz Results Los resultados experimentales de Katz para cada modelo se muestran en la Figura 5.6. El valor máximo para todas las métricas (tiempo de recomendación, la red y el consumo de memoria) es casi el doble del valor máximo de los resultados TFR, un fenómeno que está relacionado con la diferencia en la profundidad de los caminos recorridos (que se puede ver como pasos en un algoritmo iterativo) configurado para la ejecución Katz (cuatro pasos de Count en comparación con los dos pasos de Count de TFR). Debido a que el algoritmo de Katz procesa los vértices salientes a partir del usuario objetivo, la cantidad inicial de seguidores juega un papel importante en la cantidad total de recursos utilizados. Por lo tanto, las recomendaciones para el conjunto de Seguidores se calculan más rápido que el de los otros dos grupos. En la vista normalizada, que se muestra en la Figura 5.7, se puede ver que FJ proporciona los mejores resultados de uso de red y memoria. En cuanto a uso de red, esta diferencia sube hasta el -30% con respecto a DPM. En uso de la memoria, FJ proporciona hasta -40% menos consumo que DPM y un promedio de uso de 30% menor que Pregel. Sin embargo, la profundidad de las etapas recorridas perjudica el modelo FJ, proporcionando un tiempo de recomendación lento, hasta +20% con respecto al modelo DPM y tiempos casi un +10% más lento que Pregel, que están mejor preparados para varias etapas de ejecución. Resultados de LocalPath LocalPath es el más simple de los algoritmos basados en camino analizados, mostrando los valores de los resultados absolutos más bajos de todas las métricas, como se muestra en la Figura 5.8. La dirección de salida de la exploración conduce a un tiempo de recomendación muy baja y el uso de recursos para el conjunto de Seguidores y también valores reducidos para los Seguidos y Mitad con respecto a los algoritmos anteriores. La comparación normalizada de resultados que se presentan en la Figura 5.9, muestra que FJ es una alternativa mejor que Pregel en términos de tiempo de recomendación, pero casi un 20% más lento que DPM. En cuanto a uso de la red y la memoria, FJ ofrece mucho mejores resultados que los otros modelos, presentando una diferencia de 20% menos consumo de memoria y red. El grupo de Seguidores parecen ser la excepción a la regla, pero cuando se mira en los resultados absolutos, la diferencia entre modelos es más bien baja. Resultados de FriendLink Como se muestra en la Figura 5.10, la ejecución del algoritmo FriendLink exhibe resultados similares a Katz. Al igual que en los otros algoritmos, el grupo de Seguidores muestra el menor uso de recursos. 108 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followees Middle Memory Consumption Network Consumption Recommendation Time Followers Pregel DPM Figure 5.5: Resultados normalizados de TFR con respecto a FJ. 5.3. RESULTADOS EXPERIMENTALES 109 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Fork Join Pregel Middle DPM Figure 5.6: Resultados de Katz. 110 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Pregel Middle DPM Figure 5.7: Resultados normalizados de Katz con respecto a FJ.. 5.3. RESULTADOS EXPERIMENTALES 111 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Fork Join Pregel Middle DPM Figure 5.8: Resultados de LocalPath. 112 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Pregel Middle DPM Figure 5.9: Resultados normalizados de LocalPath con respecto a FJ. 5.3. RESULTADOS EXPERIMENTALES 113 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Fork Join Pregel Middle DPM Figure 5.10: Resultados de FriendLink. 114 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS La comparación normalizada presentada en la Figura 5.11, muestra que DPM y Pregel ejecutan casi un 20% más rápido que FJ, pero requieren casi un 30% más memoria. Al igual que en otros algoritmos, los resultados para el grupo de Seguidores fueron variados con respecto a los Seguidos y Mitad debido a que el tamaño de los subgrafos explorados son de menor magnitud. En cuanto al conjunto de Seguidores, las diferencias de tiempo de recomendación eran mucho más bajos, y en algunos casos, FJ presentan una mejor alternativa a Pregel. DPM, siempre se comportó mejor que FJ en la velocidad de recomendación, a pesar de que utiliza aproximadamente un 20% más memoria. DPM, en particular, fue el modelo más intensivo en uso de red, consumiendo casi un 30% más para todos los usuarios. Prefel, en este sentido, presentó un consumo similar al de FJ. Algoritmos Basados en Caminos Los algoritmos basados vecinos están diseñados para comparar pares de usuarios con el fin de proporcionar una métrica de similitud y generar recomendaciones de acuerdo con dicha puntuación de similitud. Sin embargo, los experimentos con pares de usuarios mostraron que el cálculo de la similitud de los usuarios, incluso entre aquellos bien conectados, prácticamente nada de tiempo y no produjo un uso significativo de recursos. Por lo tanto, en este escenario, la comparación de los modelos es muy difícil porque no se observó ninguna diferencia real en uso de recursos. Para superar este problema, la implementación de los algoritmos basados en vecinos se amplió para apoyar la soportar de grupos de usuarios. Esto significa que cada algoritmo puede recibir como parámetro un grupo de usuarios y calcular su similitud global. De este modo, con esta pequeña modificación, el estrés en el clúster puede elevarse simplemente aumentando el tamaño del grupo a comparar. La forma más natural de seleccionar los grupos de usuarios es la elección de los usuarios de acuerdo con el tamaño de su vecindad. Esta selección ya se llevó a cabo para los algoritmos basados en caminos, que dieron lugar a los grupos de Seguidores, Seguidos y Mitad. En resumen, los experimentos en los algoritmos basados en los vecinos se realizaron en estos tres grupos de usuarios. Por otra parte, los conjuntos originales se ampliaron en dos ocasiones con el fin de aumentar el tamaño del conjunto, y, como consecuencia producir un uso superior de recursos. Los mecanismos de expansión consistieron en la adición de todos los vecinos de cada vértice al conjunto actual. Esta expansión se puede controlar mediante el establecimiento de una cantidad máxima de vecinos para explorar. Por ejemplo, una expansión de un usuario del conjunto Fol consiste en la obtención de los vecinos de los vecinos de cada usuario Foli y su fusión en un grupo final, es decir, Folexpanded = ( S Neighbor(Foli )) S Fol. Foli εFol Los resultados se presentan en la Figura 5.12. Como se mencionó anteriormente, la alternativa DPM de estos algoritmos no se aplicó ya que tenía la misma implementación que la alternativa FJ, y por lo tanto, generó los mismos resultados. Además, la vista normalizada con respecto a FJ no se tuvo en cuenta debido a que las diferencias en los valores absolutos fueron 5.3. RESULTADOS EXPERIMENTALES 115 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Followers Followees Middle Figure 5.11: Resultados normalizados de FriendLink con respecto a FJ. 116 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS más fáciles de leer. La naturaleza de un solo paso de los algoritmos favorece notablemente la alternativa FJ/DPM en la mayoría de los algoritmos. En cuanto a uso de la red, la alternativa FJ/DPM es de dos a tres veces mejor que Pregel. En términos de uso de memoria, FJ/DPM proporciona los mejores resultados, pero en Jaccard la diferencia de rendimiento es más bajo que en otros algoritmos. El tiempo de recomendación proporcionado por FJ/DPM es menor o casi igual a Pregel en la mayoría de las pruebas. 5.3.2 Resultados de Estrategias de Mapeo La segunda parte de los experimentos se relaciona con el uso de estrategias de mapeo que distribuyen procesamiento de vértices de acuerdo con ciertos criterios. La estrategia utilizada hasta ahora fue la estrategia basada en la ubicación, que es la estrategia más rápida disponible en Graphly. El desempeño de la estrategia basada en la ubicación está relacionada con la distribución equilibrada de los vértices en la base de datos de grafos. Otras estrategias pueden ser muy adecuadas para otros escenarios de distribución o características de hardware del clúster que se utiliza. Tal como se presenta en el Capítulo 4, Sección 4.4.4 otras estrategias incorporadas en Graphly son la estrategias de Round Robin (RR), Memoria Máxima (MM) y Memoria Disponible (AM). La estrategia RR fue utilizada como la estrategia de base para la comparación, ya que distribuye uniformemente vértices a procesar entre los trabajadores, pero esta distribución no está alineada a la forma en que los datos se almacena en el cluster. Las estrategias basadas en la memoria son una variación de una estrategia basada en criterios implementado por la clase C RITERIA M APPER. Las estrategias basadas en criterios permiten distribuir los vértices de acuerdo con una métrica del nodo definida por el usuario (por ejemplo, uso de la CPU, la memoria disponible o de otro tipo). A diferencia de RR, la estrategia basada en criterios realiza una asignación inicial de particiones para nodos basados en la estrategia por ubicación, y luego vuelve a asignar parte de los vértices a otros nodos en función del valor actual de la métrica especificada. Por ejemplo, considere los valores de memoria actuales de la configuración del clúster experimental: nodo 1, 2 y 3 tienen 8 GB de RAM y nodos 4, 5, 6, 7 y 8 tienen un 16 GB de RAM. Por lo tanto, la estrategia que utiliza la cantidad máxima de memoria RAM disponible (es decir, la estrategia de Memoria Máxima) se configura como sigue: 1. Los nodos 1, 2 y 3 se les asigna un valor de métrica de 0,5 (la mitad de la cantidad de la RAM máxima) y los nodos 4, 5, 6, 7 y 8 se les asigna un valor de métrica de 1. 2. Un conjunto de "casillas" de tamaño fijo se asigna a cada nodo, por ejemplo, a 100 casillas. Esta operación crea una matriz de N nodos por C casillas, por ejemplo la dimensión de la matriz para el ejemplo sería de 8 x 100. Cada casilla se refiere a un nodo y puede formar una referencia de bucle. Esto último significa que la decisión tomada por la estrategia de ubicación no se modifica. 5.3. RESULTADOS EXPERIMENTALES 117 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Figure 5.12: Resultados de algoritmos basados en vecinos. 118 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 8 buckets 50 buckets Vertex 5 buckets Node 1 Node 1 4 5 6 7 8 2 3 Node 2 Node 2 4 5 6 7 8 1 3 Location-Aware Strategy ... Node 8 Node 8 Figure 5.13: Ejemplo de asignación utilizando C RITERIA M APPER. 3. La asignación de nodos a casillas depende del valor de la métrica. El nodo 1, por ejemplo, tendrá 50 casillas que hacen referencia al nodo 1, y el resto se repartirá entre el otro conjunto de nodos, utilizando también cada valor de la métrica. Por lo tanto, cuando un vértice está dentro de los primeros 50 cubos, la estrategia de reconocimiento de ubicación prevalecerá y el vértice será asignado al nodo 1. De lo contrario, el vértice será reasignado a otro vértice. Resolver donde un vértice debe asignarse requiere dos pasos, como se muestra en la Figura 5.13. La primera etapa busca la ubicación del vértice, y en segundo lugar, el ID de vértice se aplica un hash basado en módulo para encontrar su correspondiente número de casilla. De acuerdo a cómo se asignan los cubos, el vértice se puede enviar al nodo donde se almacena o a otro nodo donde será tratado como un vértice no local. Los datos relativos a un vértice no local deben ser obtenidos de forma remota, introduciendo una alta penalización en cuando recomendación. El comportamiento de cada estrategia de mapeo debe ser analizada a través de sus patrones de uso de memoria y de red. Como caso de estudio para ilustrar este proceso, la versión del FJ del algoritmo TFR para el usuario Fol3 (@BarackObama) fue analizada bajo las diferentes estrategias de mapeo implementadas en Graphly. La Figura 5.14 muestra el uso de la memoria de cada nodo a lo largo de toda la ejecución. En este caso de estudio los nodos 1, 2 y 3 estuvieron equipados con 8 GB de RAM, mientras que el resto de los nodos tiene 16 GB de memoria RAM. El nodo 4 fue asignado como destino del trabajo padre, lo que significa que la combinación de los resultados se realiza en ese nodo y tiene una mayor cantidad de consumo de memoria, como se muestra en la figura. El resto de los nodos exponen diferentes comportamientos de memoria en función de la estrategia. La estrategia por ubicación presenta un uso de memoria más bien equilibrada para cada nodo. Los patrones de uso de memoria en round-robin es bastante caótica. La estrategia de Memoria Máxima termina con un mayor uso de memoria en los nodos que tienen más memoria RAM. La estrategia de Memoria Disponible es una estrategia dinámica que cambia la asignación de vértice en cada paso del algoritmo de acuerdo con la memoria disponible en cada nodo. La estrategia de Memoria Disponible mostró una mejor asignación de memoria que la estrategia de Memoria Máxima, lo que redundó en un uso de memoria en general inferior. Sin embargo, la naturaleza dinámica de Memoria Disponible puede producir grandes picos de uso de la red debido a la reasignación de los vértices. 5.3. RESULTADOS EXPERIMENTALES 119 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS El uso de red acumulado para las diferentes estrategias de mapeo se presentan en la figura 5.15. Los gráficos muestran la cantidad de datos enviados a través de la red de una manera acumulativa. Un valor constante significa que ningún dato se envió en el período. En este sentido, cada estrategia expone un patrón bien definido en los gráficos de líneas. La estrategia por ubicación (Figura 5.15a) mantiene el uso de la red muy baja, y sólo aumenta la cantidad de datos transferidos cuando el paso del algoritmo fusiona resultados y asigna nuevas particiones. El uso de la memoria sigue siendo muy bajo en comparación con otras estrategias, como se muestra en la Figura 5.14a. 120 of 206 5.3. RESULTADOS EXPERIMENTALES 121 of 206 (b) Round Robin (c) Memoria Máxima. (d) Memoria Disponible. Figure 5.14: TFR per-node memory usage using Fork-Join for user Fol3 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 5.3. RESULTADOS EXPERIMENTALES (a) Por ubicación 5.3. RESULTADOS EXPERIMENTALES (b) Round Robin (c) Memoria Máxima (d) Memoria Disponible. Figure 5.15: Utilización de red por nodo en TFR utilizando FJ para el usuario Fol3 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 122 of 206 (a) Por ubicación. CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS La estrategia de Round Robin (Figura 5.15b) la asignación equilibrada de vértices mantiene el uso de la red controlada, pero en constante aumento debido a que cada nodo recibe muchos vértices no locales. El uso de la memoria en Round Robin es caótica, como se ve en la figura 5.14b. La estrategia de Memoria Máxima mantiene las transferencias salientes de la red (Figura 5.15c)) de nodos de memoria de alta en niveles bajos debido a que todos los vértices son locales. Sin embargo, para los nodos de memoria baja, se intercambia el uso de la memoria con el uso de la red, como se puede ver en la Figura 5.14c y la Figura 5.15c, donde los 3 primeros nodos (que tienen 8 GB de RAM) exhiben un alto uso de la red, pero una asignación de memoria baja. La estrategia de Memoria Disponible es similar a la estrategia de memoria máximo pero comienza a reequilibrar los datos más prematuramente, a medida que cada nodo llena la memoria disponible, como se puede observar en la figura 5.14d y la Figura 5.15d. En general, la estrategia de Memoria Disponible produce picos más bajos de memoria que la de Memoria Máxima, pero genera más tráfico de red. Las estrategias de mapeo fueron diseñados para ser utilizadas en diferentes modelos de procesamiento con el fin de comparar su adaptación a diferentes escenarios del clúster. Para analizar el impacto de las estrategias de mapeo de cada modelo, las versiones FJ, Pregel y DPM de TFR se compararon para el usuario Fol3 . Como se muestra en la Figura 5.16, la estrategia por ubicación proporciona un uso intensivo de la memoria, pero el tiempo más bajo de recomendación para cada modelo. La estrategia de Round Robin utiliza una gran cantidad de memoria que crece constantemente cada segundo. Por otra parte, es la segunda estrategia más lenta. La estrategia más lenta es la estrategia de Memoria Máxima, que intercambia la velocidad de recomendación por el uso de memoria. Por último, la estrategia de Memoria Disponible proporciona altos (pero controlados) niveles de uso de memoria, pero tiempos más rápidos de recomendación (que Memoria Máxima). Si se considera el uso de la red bajo los tres modelos, Round Robin transfiere la mayor cantidad de datos, como se muestra en la Figura 5.17. La estrategia por ubicación es la estrategia menos intensiva en red. En el medio, las estrategias de Memoria Disponible y Memoria Máxima transfieren casi la misma cantidad de datos de red, pero con ritmos diferentes: Memoria Disponible transfiere los datos más rápido, ya que procesa TFR más rápido. Usando la información recopilada y analizada a partir de los patrones de red y de uso de memoria, se propusieron un par de escenarios en los que las estrategias pueden ser útiles - o incluso decisivas - para construir una lista de recomendaciones. 5.3. RESULTADOS EXPERIMENTALES 123 of 206 (b) Pregel 5.3. RESULTADOS EXPERIMENTALES (c) DPM Figure 5.16: Uso total de memoria en TFR por modelo de procesamiento, para el usuario Fol3 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 124 of 206 (a) Fork-Join (b) Pregel 125 of 206 (c) DPM Figure 5.17: Uso total de red de TFR por modelo de procesamiento para el usuario Fol3 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS 5.3. RESULTADOS EXPERIMENTALES (a) Fork-Join CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Primer Escenario El primer escenario es un escenario muy desequilibrado donde la mitad de las máquinas tiene 2 GB de RAM y el resto 16 GB de RAM. Sin embargo, el almacenamiento se distribuye por igual entre los nodos, por lo que una estrategia que reconoce la ubicación o una estrategia Round Robin se comporta de forma lenta o ni siquiera puede proporcionar una solución a todos los usuarios debido a errores de memoria insuficiente. Los experimentos se realizaron sobre el conjunto de Seguidores ejecutando TFR bajo FJ, Pregel y DPM. Como se muestra en los resultados en la Figura 5.18 la mayor parte de las pruebas de Round Robin y por ubicación fracasaron. El único modelo que proporcionó una solución en algunos usuarios fue el modelo de DPM. Como era de esperar, la estrategia de Memoria Máxima fue muy lenta pero no falló en cualquiera de las ejecuciones. La alternativa Memoria Disponible proporcionó casi los mismos resultados de rendimiento. Este escenario ilustra cómo la elección de una estrategia de mapeo de acuerdo con las características de clúster es esencial para obtener resultados de recomendación y, además, permite ilustrar la flexibilidad de Graphly, no ofrecida por otros frameworks, para configurar la estrategia bajo un modelo de procesamiento dado. Segundo Escenario Una variación del primer escenario consiste en realizar la fusión de los resultados, por ejemplo, para los modelos FJ y DPM, en un nodo con relativamente poca memoria. Para crear este escenario, un nodo se ha configurado con 4 GB de RAM, 4 con 2 GB de RAM y el resto con 16 GB. Bajo este escenario, la estrategia de memoria disponible debe ser capaz de relocalizar parte de los vértices del nodo de 4 GB mientras el nodo se encuentre utilizando la memoria para combinar los resultados. La Figura 5.19 muestra los resultados de ejecutar TFR bajo el segundo escenario. En este escenario, ambas estrategias Round Robin y por ubicación no pudieron proporcionar resultados, a excepción de dos ejecuciones de DPM. La memoria más baja asignada al nodo principal genera que la mitad de las pruebas de FJ fallen. Tenga en cuenta que DPM y Pregel no se ven afectados por esta situación porque la fusión de resultados se distribuye en todo el clúster. Por último, como se esperaba, la estrategia de Memoria Disponible ayuda a terminar las pruebas de TFR para todos los usuarios en el conjunto de Seguidores. 5.3.3 Discusión Los experimentos con respecto a los modelos de procesamiento aplicados a los algoritmos basados en caminos mostraron que DPM se comporta muy bien en términos de velocidad de recomendación. Sin embargo, para algunos usuarios, especialmente los que exploró porciones muy pequeñas de la gráfica, DPM mostró resultados mixtos. En general, FJ fue el modelo más lento en términos de tiempo de recomendación, seguido de Pregel. 126 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Location Max. Memory Round Robin Fork Join Pregel Available Memory DPM Figure 5.18: Resultados de TFR utilizando diferentes estrategias de mapeo para el escenario 1. 5.3. RESULTADOS EXPERIMENTALES 127 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS Location Round Robin Max. Memory Available Memory Figure 5.19: Resultados de TFR utilizando diferentes estrategias de mapeo para el escenario 2. 128 of 206 5.3. RESULTADOS EXPERIMENTALES CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS En casi todos los experimentos, FJ fue el algoritmo más eficiente en términos de uso de la red. La razón detrás de la eficiencia de FJ es que éste envía sólo un único resultado a la tarea padre que resulta en una compresión de datos más eficiente (cuanto mayor sea la cantidad de datos, más eficaz es la compresión). Por el contrario, Pregel y DPM, distribuyen varios resultados intermedios con particiones a otros workers. Además, DPM exhibió un uso de la red superior a otros modelos, que pueden atribuirse a la adición de la lista de vértices activos distribuidos por el trabajo padre. El algoritmo más eficiente en cuanto a uso de memoria fue FJ, en parte debido a la falta de estructuras adicionales para la gestión de los resultados. En este sentido, DPM presentó resultados diferentes dependiendo del algoritmo. Para Katz y FriendLink, DPM se comporta de manera similar a Pregel, con casi un 30% más de uso de memoria que FJ. Sin embargo, en TFR y LocalPath, proporcionó eficiencia de uso de memoria casi similar a FJ. Curiosamente, DPM heredó de FJ la cero sobrecarga de presentar los resultados al usuario, que puede verse como un uso de memoria casi al estilo FJ en algoritmos con pequeñas cantidades de pasos. Cuando el número de pasos se eleva, sin embargo, la distribución y el almacenamiento de resultados intermedios que DPM tomó prestado de Pregel se tradujo en un uso de memoria similar a Pregel. En la mayoría de los experimentos, Pregel se ubicó como el modelo más intensivo en uso de memoria. En resumen, para esta parte de los experimentos, DPM apareció como el modelo más rápido. Es de notar que en entornos experimentales, por ejemplo, el diferencial en el tiempo de recomendación logrado por DPM para un solo usuario puede reducir significativamente el tiempo total requerido para el cálculo de recomendación para un lote de usuarios. No obstante, en escenarios limitados en términos de red y de memoria, o en situaciones en las que se facturan transferencias de red (como en entornos de nube), la alternativa FJ puede ser una mejor opción que Pregel o DPM. La segunda parte de los experimentos implicó el uso de diferentes estrategias y modelos de mapeo para el cálculo de recomendaciones, utilizando TFR como caso de estudio, en escenarios de clúster de memoria baja. El primero de estos escenarios implicaba una reducción de la memoria de la mitad de los nodos a 2 GB de RAM, mientras que el resto de los nodos fueron asignados con 16 GB, incluyendo el nodo en el que se llevan a cabo fusiones de DPM y FJ. Este escenario fue muy importante para mostrar que la asignación equilibrada del trabajo no siempre es posible. En particular, las estrategias por ubicación y Round Robin sufrieron de errores de falta de memoria y no proporcionaron una recomendación. Sin embargo, los escenarios basados en memoria ayudaron a reasignar vértices que no se podían procesar debido a las limitaciones de memoria. El segundo escenario redujo la cantidad de memoria del nodo de fusión a sólo 4 GB de RAM. Esta restricción perjudica a los modelos, como FJ, que requieren grandes cantidades de memoria RAM en un nodo central. En este escenario, todas las estrategias estáticas fallaron, incluyendo la 5.3. RESULTADOS EXPERIMENTALES 129 of 206 CHAPTER 5. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN CAMINOS estrategia de Memoria Máxima, no pudieron proporcionar recomendaciones para el modelo FJ. Sin embargo, la naturaleza dinámica de la estrategia de Memoria Disponible ayudó a evitar los errores de memoria mediante la reasignación de los vértices que en otros casos fueron asignados al nodo de fusión. 5.4 Resumen En este capítulo se analizó el soporte proporcionado por Graphly para el desarrollo y los algoritmos basados caminos y en vecinos desde dos puntos de vista: las cuestiones de implementación de acuerdo con la adecuación de los algoritmos a los estilos de programación del modelo utilizado, y el rendimiento alcanzado en cada modelo en términos de tiempo de recomendación, uso de memoria y el uso de la red. Por lo tanto, el capítulo proporciona un análisis profundo sobre cómo funcionan los algoritmos con diferentes modelos de procesamiento. Por otra parte, los modelos de procesamiento fueron puestos a prueba bajo diferentes estrategias de mapeo, especialmente en escenarios de baja memoria. 130 of 206 5.4. RESUMEN Mecanismos de Soporte para Algoritmos Basados en Random Walks 6 A pesar de tener los mismos objetivos, la naturaleza recursiva de los algoritmos de Random Walks (RW) es muy diferente a la naturaleza de recorridos de algoritmos basados en caminos. Por lo general, las implementaciones RW aproximan el resultado utilizando el método de iteración de potencia, aplicando cambios en el vector de resultado en cada paso hasta que éste converge, es decir, los resultados dejan de cambiar entre iteraciones. Los mecanismos de soporte ofrecidos por Graphly para los algoritmos basados en RW se presentan y se evalúan en este capítulo. En estas pruebas, se seleccionaron los algoritmos HITS y SALSA por su aplicabilidad a la recomendación de usuarios, siendo SALSA la base del popular servicio de Twitter, Who To Follow (WTF) (Gupta et al., 2013). Por otra parte, estos algoritmos procesan un subgrafo que rodea al objetivo de la recomendación. Otros algoritmos, tales como PageRank, operan al nivel de todo el grafo, produciendo una métrica general para toda la red social. Este capítulo está organizado de la siguiente forma. La Sección 6.1 detalla las implementaciones de HITS y SALSA y discute los problemas en el desarrollo de estos algoritmos en diferentes modelos. La Sección 6.2 presenta los resultados de la ejecución de los algoritmos basados en RW bajo diferentes modelos de procesamiento. Además, al igual que en los algoritmos basados en caminos, se analiza y discute el impacto de las estrategias de mapeo de este tipo de algoritmos. Finalmente, la sección 6.3 ofrece un breve resumen de las técnicas y mecanismos propuestos en el presente capítulo y un análisis de los resultados obtenidos. 6.1 Implementación de Algoritmos Basados en Random Walks Esta sección presenta los detalles de la implementación de los algoritmos HITS y SALSA bajo los modelos FJ, Pregel y DPM. 131 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 6.1.1 Implementación de HITS La implementación de HITS sigue las ecuaciones presentadas en el Capítulo 2, Sección 2.3.3: la puntuación de autoridad de un vértice dado es la suma de las puntuaciones de concentrador de sus vértices entrantes y la puntuación de concentrador es la suma de las autoridades de sus vértices salientes. El algoritmo itera durante una serie de pasos predefinidos para permitir una comparación justa entre los modelos, dejando de lado la verificación de convergencia ya que esto puede dar lugar a diferente número de iteraciones para cada implementación. La descripción de las implementaciones del algoritmo bajo los diferentes modelos se inicia con la implementación en Pregel, que es la más natural y fácil de entender para los algoritmos basados en RW. A continuación, se describen las implementaciones en FJ y DPM, ya que reutilizan los conceptos del enfoque Pregel. Implementación de HITS en Pregel El algoritmo HITS siempre realiza la misma operación (la actualización de las puntuaciones de autoridad y concentrador) para cada iteración y, como consecuencia, su aplicación en Pregel es sencilla. La única consideración especial a tener en cuenta es que tanto el valor de autoridad como de concentrador deben normalizarse en cada iteración. Si no se normalizan, dichos valores podrían crecer de forma descontrolada. Como se muestra en el Listado 6.1, el algoritmo se encuentra duplicado en cada línea, realizando la misma operación para ambas puntuaciones de autoridad y concentrador. El primer paso establece el mismo valor para ambos indicadores. En etapas posteriores, la puntuación de autoridad se actualiza con la suma de los mensajes de concentrador, y la puntuación de concentrador se actualiza con la suma de los mensajes de autoridad. Ambos valores son, entonces, normalizados y persistidos. Por último, las puntuaciones de autoridad y concentrador se envían a los vértices de entrada y salida, respectivamente. Implementación de HITS en FJ y DPM Uno de los principales retos que se plantean en la aplicación de los HITS bajo FJ o DPM, es mantener la localidad de procesamiento. Esto significa que, cuando se procesa el vértice v el algoritmo siempre debe trabajar con datos en relación con el vértice v u otros vértices que se están procesando en el mismo nodo con el fin de mantener la localidad de memoria y de red. En Pregel, este comportamiento está incrustado en el modelo: el usuario debe trabajar sólo con datos relativos al vértice que está siendo actualmente procesado. Un enfoque ingenuo de HITS bajo FJ podría ser añadir las puntuaciones de concentrador de otros vértices – posiblemente remotos – en la puntuación actual de autoridad, perdiendo localidad de red y memoria. Las arquitecturas de computadoras de hoy proporcionan ventajas de rendimiento (por ejemplo, precarga de memoria RAM, almacenamiento en caché de la CPU, 132 of 2066.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class HITSPregel implements VertexFunction { public void execute ( long v , MessageList msg ){ float auth = 0 f ; float hub = 0 f ; if ( getSuperStep () == 0) { auth = 1 f / getGraphSize (); hub = 1 f / getGraphSize (); } else { for ( Message msg : msgs ) if ( msg . isOfType ( " HUB " )) auth += msg . value (); if ( msg . isOfType ( " AUTH " )) hub += msg . value (); auth = auth / getAggregator ( " AUTH_SUM " ); hub = hub / getAggregator ( " HUB_SUM " ); set (v , " AUTH_RESULT " , auth ); set (v , " HUB_RESULT " , hub ); } for ( long vin : getIncoming ( v )) send ( " AUTH " , vin , auth ); for ( long vout : getOutgoing ( v )) send ( " HUB " , vout , hub ); getAggregator ( " AUTH_SUM " ). add ( hub * outgoingSize ()); getAggregator ( " HUB_SUM " ). add ( auth * incomingSize ()); } } Listado de código 6.1: Implementación en Pregel de HITS. 6.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS133 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class HITS implements Step { public TraversalResult execute ( HITSResult prev , Traversal tr ){ FJResult res = graphly . fj () . task ( new Task (){ public void compute ( List vertices , HITSResult prev ){ for ( long v : vertices ) { float hub_v = prev . getHub ( v ); for ( long out : getOutgoing ( v )) emit ( " AUTH " , out , hub_v ); float auth_v = prev . getAuth ( v ); for ( long in : getIncoming ( v )) emit ( " HUB " , in , auth_v ); } } }) . combiner ( /* sum values */ ) . result_emitter ( new Emitter (){ public void compute ( Long vid ){ emit ( " AUTH " , vid , getValue ( " AUTH " , vid )/ getSum ( " AUTH " )); emit ( " HUB " , vid , getValue ( " HUB " , vid )/ getSum ( " HUB " )); } }) . run ( mapping_strategy , prev ); return new HITSResult ( res . value ( " HUB " ) , res . value ( " AUTH " )); } } Listado de código 6.2: Implementación en FJ de HITS. 134 of 2066.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS líneas de caché, entre otros) que favorecen a aquellos programas que mantienen la localidad de memoria, es decir, que acceden a los datos de la memoria situada cerca de la última dirección visitada. Esta es la razón por la cual la lectura lineal de un arreglo de números es mucho más rápido que la lectura al azar. Naturalmente, mantener la localidad de red también es importante debido a la latencia involucrada en todas las envíos por la red. Para evitar este comportamiento nocivo, la ejecución construye una tabla de valores de concentrador y autoridad en cada nodo. Esta tabla es luego fusionada en el nodo de origen, en el caso de FJ, o distribuida a través del clúster, en el caso de DPM. El Listado 6.2 muestra el paso HITS que se ejecuta en cada nodo para la ejecución FJ. La normalización de los valores se realiza después de la fusión de los resultados de todos los nodos en la tarea padre (utilizando el emisor de resultados). La implementación DPM no se muestra debido a su similitud con el enfoque FJ. De hecho, la única diferencia entre las versiones FJ y DPM, es que DPM lee y almacena los valores de autoridad y concentrador en la base de datos. Como consecuencia, los resultados deben ser recogidos del gráfo con el fin de presentarlos al usuario. 6.1.2 Implementación de SALSA SALSA es un algoritmo más complejo en comparación con HITS en términos de diseño. Las puntuaciones de autoridad y de concentrador de un vértice se obtienen al recorrer dos veces la adyacencia del vértice actual y agregando los valores de autoridad y contrentrador de los vértices atravesados. Este comportamiento obliga a la implementación a ser diseñada en diferentes etapas con el fin de mantener la localidad de los datos. Implementación de SALSA en Pregel La implementación de SALSA bajo Pregel requiere dividir el procesamiento en dos partes. La primera parte es ejecutada en todas las iteraciones y consiste en la agregación y la distribución de los puntajes de concentrador y de autoridad entre los vértices adyacentes al vértice actual. Sin embargo, la dirección de los valores distribuidos cambia para cada iteración: en pasos pares las puntuaciones de autoridad van a los vértices de entrada y las puntuaciones de concentrador a los vértices salientes; en pasos impares los valores son distribuidos en la dirección opuesta. El comportamiento en iteraciones pares se corresponde con parte de los algoritmos 2.3 y 2.4, presentado en las ecuaciones 6.1 y 6.2. Como se puede ver, la localidad se puede mantener fácilmente, porque toda la información necesaria para el procesamiento de sub-resultados se relaciona con el vértice w. Aeven (w) = A (w) in (w) (6.1) 6.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS135 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class SALSAPregel implements VertexFunction { public void execute ( long v , MessageList msgs ) { if ( superstep == 0) { auth = 1 f / getGraphSize (); hub = 1 f / getGraphSize (); } else { for ( Message msg : msgs ) if ( msg . isOfType ( " AUTH " )) auth += msg . value (); else hub += msg . value (); if ( isPair ( superstep ())) { set (v , " AUTH_RESULT " , auth ); set (v , " HUB_RESULT " , hub ); } } VertexList auth_dests = isPair ( superstep ()) ? getIncoming ( v ) : getOutgoing ( v ); for ( long inV : auth_dests ) send ( " AUTH " , inV , auth / auth_dests . size ()); VertexList hub_dests = isPair ( superstep ()) ? getOutgoing ( v ) : getIncoming ( v ); for ( long outV : hub_dests ) send ( " HUB " , outV , hub / hub_dests . size ()); } } Listado de código 6.3: Implementación en Pregel de SALSA. Heven (w) = H (w) out (w) (6.2) Por otro lado, cuando se ejecuta una iteración impar, se calculan las ecuaciones 6.3 y 6.4. La localidad de datos todavía se mantiene porque Aeven (w) and Heven (w) son parte de los mensajes que recibe el vértice v. Aodd (v) = Aeven (w) out (v) (v,w)∈N (6.3) Hodd (v) = Heven (w) out (v) (w,v)∈N (6.4) ∑ ∑ La segunda parte de las implementaciones, que sólo se ejecuta en iteraciones pares (excepto en la iteración cero), agrega la suma recibida de las puntuaciones de autoridad y concentrador y almacena los valores agregados, completando de manera efectiva las ecuaciones que se muestran en los algoritmos 2.3 y 2.4 en el Capítulo 2, Sección 2.3.3. La implementación final se muestra en el Listado 6.3. 136 of 2066.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Implementación de SALSA en FJ y DPM La implementación en Pregel establece estrategias para mantener la localidad de los datos y por lo tanto proporciona un rendimiento relativamente bueno. Las implementaciones en FJ y DPM se inspiraron en dichas estrategias y en la estrategia utilizada en la implementación FJ de HITS. Para cada iteración, los valores pares e impares se agregan y se transmiten utilizando una tabla de hash. El Listado 6.4 muestra la correspondiente implementación del paso de SALSA utilizado por la versión FJ de SALSA. El trabajo SALSA, responsable de la distribución de tareas entre los nodos de SALSA, une en cada iteración las puntuaciones de autoridad y de concentrador producidos por las tareas. La versión DPM del algoritmo realiza las mismas operaciones pero distribuye la agregación de los resultados en todo el cluster. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class SALSA implements Step { public TraversalResult execute ( SALSAResult prev , Traversal tr ){ int step = tr . getCurrentStep (); FJResult res = graphly . fj () . task ( new Task (){ public void compute ( List vertices , SALSAResult prev ){ for ( long v : vertices ){ VertexList auth_neighbors = isPair ( step )? getIncoming ( v ) : getOutgoing ( v ); float auth = prev . getAuth ( v )/ auth_neighbors . size (); for ( long w : auth_neighbors ) emit ( " AUTH " , w , auth ); VertexList hub_neighbors = isPair ( step )? getOutgoing ( v ) : getIncoming ( v ); float hub = prev . getHub ( v )/ hub_neighbors . size (); for ( long w : hub_neighbors ) emit ( " HUB " , w , hub ); } } }) . merger ( /* a + b */ ) . run ( mapping_strategy , prev ); return new SALSAResult ( res . value ( " HUB " ) , res . value ( " AUTH " )); } } Listado de código 6.4: Implementación del Trabajo FJ de SALSA. 6.1.3 Discusión de la Implementación El análisis de los problemas de implementación presentados por SALSA y HITS produce una serie de ideas que pueden ayudar a decidir qué modelo es preferible dependiendo de las carac6.1. IMPLEMENTACIÓN DE ALGORITMOS BASADOS EN RANDOM WALKS137 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS terísticas del algoritmo. En cuanto a los modelos FJ y DPM (que comparten el mismo estilo de programación), aunque el código que realiza la actualización de autoridad y concentrador para HITS y SALSA se mantuvo muy simple, el desarrollador debe programar el soporte de repetición externo que pasa los resultados de un trabajo al siguiente. El código adicional podría introducir nuevos errores y su calidad en términos de rendimiento y facilidad de mantenimiento depende de los conocimientos de desarrollador. Una desventaja más sutil de estos modelos se presentan en la sección anterior. La adaptación directa de estos algoritmos a partir de sus ecuaciones originales, produjo una implementación preliminar - e ingenua - que no mantenía la localidad de los datos. Esta implementación naïve produjo una versión muy ineficiente de los algoritmos que requirió un rediseño completo. En Pregel, el modelo está diseñado para ejecutar la misma función vértice muchas veces sobre los vértices activos. El desarrollador sólo necesita implementar la sección del núcleo del algoritmo, es decir, el cálculo de los resultados. Por otra parte, Pregel evita el problema de localidad que apareció en las implementaciones iniciales para los modelos FJ y DPM, mediante la restricción de que los únicos datos que el desarrollador puede leer y modificar son el relacionado con el vértice actual. En una función vértice, el único mecanismo para acceder a los datos que pertenecen a otros vértices es a través de mensajes entrantes y el envío de mensajes. Sin embargo, durante el esfuerzo de implementación de HITS y SALSA bajo Pregel, había dos inconvenientes menores. En primer lugar, el usuario debe discriminar la primera etapa con el fin de establecer los valores iniciales del algoritmo. En segundo lugar, el mecanismo agregador no es muy adecuado para realizar un seguimiento de los valores que se están calculando actualmente, como la sumatoria de puntajes de concentrador y autoridad. En HITS, por ejemplo, este mecanismo se utiliza para normalizar los resultados actuales de autoridad y concentrador. La suma actual de todas las puntuaciones de autoridad y concentrador debe ser calculada antes de este paso. En la propuesta de ejecución, cada vértice se anticipa a su contribución a la suma final de las puntuaciones al multiplicar el valor de la puntuación actual según el número de vértices a donde será enviado. Esto significa que las puntuaciones de autoridad y de concentrador se multiplican por el número de vértices saliente y entrante, respectivamente, y se añaden a un agregador. Una solución alternativa es dividir la normalización y la suma de las puntuaciones. En esta solución, las puntuaciones se agregan en un solo paso y se normalizó en otro, lo que hace que el código HITS más engorroso e ineficiente. SALSA no sufre de este problema debido a que la normalización de los valores se realiza por cada vértice antes de enviar las puntuaciones. 6.2 Resultados Experimentales En esta sección se presentan y discuten los resultados experimentales con respecto a los algoritmos basados en Random Walks. En primer lugar, se describen los experimentos relacionados 138 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS con los modelos de procesamiento y luego se analizan los resultados obtenidos. En segundo lugar, la aplicación de estrategias de mapeo en algoritmos basado en RW se evalúa bajo diferentes escenarios en los cuales las estrategias basadas en memoria podrían ser útiles. 6.2.1 Resultados de Modelos de Procesamiento Al igual que en los algoritmos basados en caminos, el tamaño del subgrafo procesada por los algoritmos SALSA y HITS varía de acuerdo con el usuario. En lugar de construir el subgrafo sobre la marcha, HITS y SALSA lo construyen antes de la ejecución del propio algoritmo. Por ejemplo, HITS se inicia con un subgrafo (en su versión original, el subgrafo es el resultado de una búsqueda de páginas web) que, en la configuración experimental actual está compuesto sólo por el usuario de destino. Naturalmente, este subgrafo de un vértice debe ampliarse a fin de encontrar vértices para recomendar. HITS predefine un mecanismo de "expansión" que encuentra vértices adicionales que rodean el vértice de destino (en la dirección de entrada o salida). Debido a que SALSA sólo ejecuta sobre el subgrafo inicial, que en este caso tiene un tamaño de uno, también se incluyó el mecanismo de expansión pesar de no ser estrictamente parte de la algoritmo original. Para ambos algoritmos, los dos pasos de expansiones se ejecutan en la dirección de entrada y salida, limitado a un número de 10.000 vecinos recogidos por vértice. Por ejemplo, un solo paso de expansión del usuario Fol1 reúne 10.000 usuarios y, a continuación, una segunda expansión reúne hasta 10.000 vecinos para cada uno de los primeros 10.000 usuarios. Como resultado, el subgrafo para Fol1 , por ejemplo, genera aproximadamente 1.2M de usuarios. Los tamaños de cada subgrafo para cada usuario se muestran en la Tabla 6.1. Tal como se presenta en la Tabla, HITS utiliza todo el subgrafo para encontrar las autoridades y los concentradores, mientras que SALSA divide el subgrafo en dos subgrafos: un subgrafo concentrador, el cual contiene los vértices que tienen uno o más vértices salientes, y un subgrafo autoridad, el cual contiene vértices que tienen uno o más vértices entrantes. Curiosamente, el grupo de Seguidores produjo los subgrafos más pequeños. Esto puede explicarse por el tipo de usuarios que pertenecen a este grupo. Por ejemplo, Fol1 tiene 1843561 seguidores y sólo 563 de aquellos que siguen, es decir, una proporción de 1:3200, ó 3200 seguidores para cada followee, y la mayoría de sus seguidores tienen pequeños vecindarios. Esta es una característica de las celebridades, que son seguidos por muchos usuarios pequeños. Por otro lado, el grupo de Seguidos y Mitad tienen listas relativamente más equilibradas de followees y followers. Por ejemplo, Fee1 tiene seguidores 920556 y 134788 de aquellos que siguen, es decir una proporción de 7:1, y Mid1 tiene seguidores 109279 y 104813, es decir una relación casi 1:1. Este tipo de usuarios son generalmente bien conectado con otros usuarios que tienen vecindarios relativamente grandes. El efecto resultante es que los usuarios en el conjunto Mitad y Seguidos generan subgrafos más grandes que los usuarios en el grupo Seguidores. En particular, los usuarios Mitad generan los mayores subgrafos en comparación con los otros dos 6.2. RESULTADOS EXPERIMENTALES 139 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS SALSA HITS Concentrador Autoridad Fol1 1.15M 1.13M 1.1M Fol2 1M 1M 1M Fol3 0.5M 0.5M 0.5M Fol4 0.9M 0.89M 0.9M Fol5 1.57M 1.56M 1.6M Fol6 1.4M 1.4M 1.4M Fol7 1.23M 1.23M 1.2M Fol8 0.71M 0.7M 0.7M Fol9 1.16M 1.14M 1.1M Fol10 1M 0.98M 1M (a) SALSA HITS Concentrador Autoridad Fee1 0.8M 0.8M 0.82M Fee2 2M 2M 2.4M Fee3 2M 2M 2.1M Fee4 1.55M 1.52M 1.58M Fee5 0.25M 0.22M 0.2M Fee6 0.65M 0.63M 0.6M Fee7 1.21M 1.2M 1.2M Fee8 1.52M 1.51M 1.55M Fee9 0.7M 0.7M 0.7M Fee10 0.7M 0.7M 0.7M (b) SALSA HITS Concentrador Autoridad Mid1 2.84M 2.85M 2.89M Mid2 2.62M 2.62M 2.66M Mid3 2.90M 2.90M 2.95M Mid4 2.76M 2.76M 2.81M Mid5 2.45M 2.46M 2.50M Mid6 2.46M 2.46M 2.51M Mid7 2.42M 2.43M 2.47M Mid8 2.50M 2.49M 2.54M Mid9 2.16M 2.17M 2.21M Mid10 1.75M 1.74M 1.78M (c) Table 6.1: Tamaños de Subgrafos para HITS y SALSA. 140 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS conjuntos de vértices. Se debe tener en cuenta que los subgrafos calculadas por HITS y SALSA son mucho menores que los producidos por los algoritmos basados en caminos. La decisión se basó en dos consideraciones experimentales. En primer lugar, los subgrafos pequeños permiten mantener los tiempos de iteración bajo y, por lo tanto, producir experimentos manejables. HITS y SALSA iteran varias veces sobre el mismo subgrafo, leyendo listas de adyacencia y calculando las nuevas puntuaciones de autoridad y concentrador. Los subgrafos más grandes generan tiempos más largos de iteración y, además, para obtener los resultados promedio, cada algoritmo se ejecuta 10 veces, lo que retrasa aún más los experimentos. Para ilustrar este problema, tenga en cuenta el algoritmo de PageRank. Si se utiliza la configuración actual del clúster, una única iteración de PageRank en toda el grafo dura unos 5 minutos, si se toma en cuenta que se realizan 10 iteraciones y 10 repeticiones, esto se traduce en aproximadamente 8 horas de experimentos. La segunda consideración es que los algoritmos de recomendación generalmente restringen sus recomendaciones sobre una pequeña parte del grafo con el fin de proporcionar recomendaciones locales. La ampliación del subgrafo puede perjudicar la precisión del algoritmo mediante la inclusión de más vértices no relevantes. Evaluar el rendimiento de HITS y SALSA bajo diferentes modelos ayuda a probar la hipótesis de que la selección de un modelo apropiado de acuerdo con el tipo de algoritmo podría proporcionar considerables mejoras en el rendimiento. En las siguientes secciones, se presentan los resultados de HITS y SALSA junto con su análisis correspondiente. La configuración del clúster de 8 nodos es la misma que en los experimentos basados en caminos, lo que ayuda a comparar el tiempo de recomendación y la utilización de recursos entre los dos tipos de algoritmos. Resultados de HITS Los experimentos sobre el algoritmo HITS se muestran en la Figura 6.1. Como era de esperar, FJ tuvo un mal desempeño en las tres métricas utilizadas, sobre todo debido a la forma en que los resultados se transfieren hacia y desde un nodo central. Como se ha mencionado en el Capítulo 4, Sección 3.1, el nodo que ejecuta la tarea principal fusiona los resultados de cada tarea de la iteración i, produciendo un conjunto de resultados Ri y, antes de comenzar la iteración i + 1, crea nuevas tareas que procesarán una partición de Ri . Aunque la sobrecarga de la fusión de datos no es muy alta en comparación con el tiempo necesario para calcular funciones sobre el grafo (por ejemplo, el cálculo de las puntuaciones de autoridad y concentrador), la repetición de ésta operación en cada iteración toma un tiempo considerable. Por otra parte, el cuello de botella de la red producida mediante el envío de datos hacia y desde un único nodo también genera un impacto. Aunque tanto DPM y Pregel manejan la fusión de los resultados y de transferencia de datos de manera similar, en la mayoría de las pruebas, DPM fue ligeramente más rápido que Pregel en términos de tiempos de recomendación. Esto se puede explicar por la simplificación de la 6.2. RESULTADOS EXPERIMENTALES 141 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Figure 6.1: Resultados de HITS. 142 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Followees Middle Memory Consumption Network Consumption Recommendation Time Followers Figure 6.2: Resultados normalizados de HITS con respecto a FJ. 6.2. RESULTADOS EXPERIMENTALES 143 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS gestión de resultados en DPM. En Pregel, la función vértice proporciona una lista de mensajes para cada vértice, y cada mensaje contiene un valor, por ejemplo, una puntuación de autoridad. Por otro lado, en DPM los resultados se acceden a través de la API de grafos y se presentan de forma pura, evitando la encapsulación de mensajes empleado en Pregel. Los grupos de Seguidos, Seguidores y Mitad exhibieron los mismos patrones de uso de recursos, pero en diferentes escalas absolutas (ver Figura 6.1). De hecho, los conjuntos de Seguidos y Mitad produjeron los picos más altos de uso de memoria, uso de la red y, el tiempo de recomendación, un comportamiento que se explica por los tamaños de subgrafo procesados para cada grupo de usuarios. La Figura 6.2 muestra la versión normalizada de los resultados con respecto a los valores de FJ. El eje x en y = 0 representa el valor del enfoque FJ, los valores por encima y debajo de este eje se normalizan al valor original en FJ. Por ejemplo, un valor de 0,5 en DPM significa que el valor producido por DPM fue 50% más alta que la alternativa FJ. Desde esta nueva perspectiva, es evidente que con respecto al consumo de red, FJ transfirió más de dos veces la cantidad de datos que otros modelos, lo que también puede explicar su bajo rendimiento en tiempo de recomendación. En este sentido, Pregel fue el claro ganador con el consumo más bajo de la red; sus valores son 70% inferiores a los valores de la versión FJ. El modelo DPM secundó a Pregel en uso de la red, con aproximadamente la mitad del valor de la alternativa FJ. La diferencia entre DPM y Pregel corresponde a la lista de vértices activos que se transfieren entre el trabajo DPM padre y las tareas creadas. Por último, el consumo de memoria para los tres modelos fue muy similar y se puede explicar por los mecanismos utilizados para almacenar sub-resultados. Pregel mantiene una cola de entrada de mensajes que se han programado para su procesamiento en la siguiente iteración y, paralelamente, se mantiene la lista de mensajes que se están procesando actualmente. Del mismo modo, DPM almacena los valores actuales y los resultados anteriores para evitar inconsistencias durante el procesamiento. Cuando se termina una iteración, DPM sustituye a los resultados anteriores con los actuales. FJ utiliza un enfoque bastante similar: mantiene los resultados actuales en el trabajo padre, y luego particiona estos datos entre los trabajadores. Los trabajadores entonces procesar la partición asignada y producen los resultados para la siguiente iteración. Resultados de SALSA Los experimentos en relación con el algoritmo de SALSA se muestran en la Figura 6.3. Es importante notar que, al igual que en HITS, los patrones de ejecución son los mismos para cada modelo. Sin embargo, el estrés sobre el cluster fue mucho mayor que HITS porque la implementación de SALSA requiere de dos iteraciones para completar un solo paso del algoritmo, y por lo tanto, se produce un mayor uso de los recursos. Esto significa que para ejecutar 10 pasos de salsa, el algoritmo debe iterar 20 veces. Los resultados normalizados con respecto a FJ se muestran en la Figura 6.4. Es evidente que, 144 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Followers Followees Middle Figure 6.3: Resultados de SALSA. 6.2. RESULTADOS EXPERIMENTALES 145 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Followees Middle Memory Consumption Network Consumption Recommendation Time Followers Figure 6.4: Resultados normalizados de SALSA con respecto a FJ. 146 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS a excepción del consumo de memoria, Pregel y DPM superaron a FJ para todos los grupos de usuarios. En uso de la memoria, los resultados se mezclan con diferencias de aproximadamente el 10%. En cuanto al uso de la red, DPM presenta un 50% menos de consumo de FJ, y Pregel hasta 70% menos de uso de la red. Por último, cuando se observan los tiempos de recomendación, Pregel muestra diferencias de hasta un 40% menos de tiempo que FJ, mientras que DPM muestra consistentemente una diferencia de hasta la mitad del tiempo de recomendación (entre -0.3 y -0.5). 6.2.2 Resultados de Estrategias de Mapeo Para evaluar experimentalmente el impacto de las estrategias de mapeo, se utilizó el usuario Fol3 (@BarackObama) como objetivo de la recomendación ya que es uno de los usuarios mejor relacionados. Antes de ahondar en el análisis por escenario, es importante analizar el efecto del uso de estrategias de mapeo basadas en algoritmos de RW para cada modelo de procesamiento. 6.2. RESULTADOS EXPERIMENTALES 147 of 206 6.2. RESULTADOS EXPERIMENTALES (c) Memoria Máxima (b) Round Robin (d) Memoria Disponible. Figure 6.5: Uso de memoria de HITS por nodo para cada estrategia de mapeo. CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 148 of 206 (a) Por ubicación. 149 of 206 (c) Memoria Máxima (b) Round Robin (d) Memoria Disponible. Figure 6.6: Uso de red de HITS por nodo, por estrategia de mapeo. CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 6.2. RESULTADOS EXPERIMENTALES (a) Por ubicación. CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS En primer lugar, el análisis de la utilización de recursos para cada nodo del clúster durante la ejecución de HITS revela de qué manera cada estrategia se ocupa de la asignación de tareas y la transferencia de datos. Para simplificar este análisis, se consideró sólo la versión FJ de HITS. La Figura 6.5 muestra el uso de memoria para cada nodo del clúster durante el cálculo de HITS bajo FJ. Observando con cuidado, se puede ver que la estrategia por ubicación (Figura 6.5a) muestra un patrón de arriba a abajo que corresponden con los diferentes pasos (10 pasos) de la ejecución del algoritmo. En el caso de Round Robin (Figura 6.5b), el uso caótico de los recursos oculta el patrón sinusoidal que se ve en la estrategia por ubicación. Las estrategias de Memoria Máxima (Figura 6.5c) y Memoria Disponible (Figura 6.5d) también hacen un uso bastante caótico pero con picos de memoria más pequeños. La vista de uso de la red de la misma ejecución también proporciona información interesante acerca de cada estrategia de mapeo. La estrategia por ubicación (Figura 6.6a) expone un patrón en forma de escalera para el nodo de fusión (nodo 4), que aumenta con cada nuevo paso, producto del envío de los resultados actuales de autoridad y concentrador. Los nodos restantes devuelven los resultados procesados para la partición determinada y, por tanto, las variaciones en los datos enviados son más pequeñas. En Round Robin (Figura 6.6b), los nodos envían datos de vértices uniformemente a lo largo de toda la ejecución, formando una línea recta en el diagrama de puntos. Memoria Máxima (Figura 6.6c) presenta una actividad de red más alta en aquellos nodos que tienen menos memoria RAM. Del mismo modo, la Memoria Disponible (Figura 6.6d) comienza envíando vértices a procesar a los nodos 1, 2 y 3, pero cuando algunos nodos comienzan a utilizar la memoria, se redirige el envío de datos de vértice a otros nodos, tales como el nodo 7, después de t = 50. El segundo análisis respecto a las estrategias de mapeo implica la computación y visualizando del promedio de uso de recursos de cada modelo. La Figura 6.7 presenta el uso de la memoria de las versiones FJ, Pregel y DPM de HITS al calcular una lista de recomendaciones para Fol3 . Los tres modelos exponen un comportamiento similar para cada estrategia, sin embargo, FJ (Figura 6.7a) mostró una mejor adaptación al procesamiento de vértices que no son locales. Curiosamente, en FJ, la estrategia de memoria disponible fue la estrategia más lenta, provocado por la redistribución de los vértices cuando cada nodo utiliza la memoria, cambiando la asignación de particiones. Round Robin fue segundo en tiempo de recomendación, pero con mayor uso de memoria. Round Robin mostró los mismos patrones de uso en Pregel (Figura 6.7b) y DPM (Figura 6.7c). Algunos modelos fueron más fáciles de adaptar al procesamiento no local que otros. En particular, DPM y FJ eran más fáciles de adaptar porque el algoritmo puede acceder a la partición actual y precargar vértices que no son locales. Por ejemplo, la función Count presentada en el Capítulo 5, Sección 5.1.1 solo precarga las listas de adyacencia remotas en la dirección definida por el usuario, lo que ayuda a bajar la cantidad de datos almacenados en caché. Por otra parte, debido a Pregel procesa los vértices uno a uno, es difícil asignar previamente los datos remotos y 150 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS casi imposible saber qué tipo de datos el usuario va a necesitar (listas de adyacencia, propiedades, etc.). En la actualidad, la aplicación de Pregel precarga todos los datos de remotos del vértice actual antes de ejecutar la función de vértice. El soporte de procesamiento no local implementado para Pregel queda todavía por mejorar en términos de tiempo de recomendación, aunque esta característica no era el objetivo principal de las estrategias de mapeo. 6.2. RESULTADOS EXPERIMENTALES 151 of 206 6.2. RESULTADOS EXPERIMENTALES (c) DPM Figure 6.7: Uso de memoria de HITS para cada modelo y estrategia de mapeo. CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 152 of 206 (b) Pregel (a) Fork-Join 6.2. RESULTADOS EXPERIMENTALES 153 of 206 (c) DPM Figure 6.8: Uso de red de HITS para FJ, Pregel y DPM. CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS (b) Pregel (a) Fork-Join CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Figura 6.8 muestra el consumo medio de red para FJ, Pregel y DPM. Como era de esperar, la asignación de grandes cantidades de vértices que no son locales a cada nodo en Round Robin puso la estrategia en la cima de la clasificación de consumo de red. Por el contrario, la estrategia por ubicación es, naturalmente, la estrategia menos intensiva en uso de red. Como se puede ver, Memoria Disponible utiliza más red que la estrategia Memoria Máxima debido a su reasignación dinámica de vértices. Sin embargo, como se mencionó en el capítulo 5, estas estrategias (Memoria Máxima y la Memoria Disponible) utilizan la estrategia por ubicación como base, lo que mantiene la cantidad de vértices que no son locales controlados. A partir del comportamiento exhibido en el análisis, se determinó que los escenarios utilizados para los algoritmos basados en la ruta de acceso (Capítulo 5, sección 5.3.2) pueden ser útiles para demostrar la aplicabilidad de las estrategias de mapeo en algoritmos basados en RW. Los resultados obtenidos para cada escenario se describen a continuación. Primer Escenario El primer escenario, idéntico al establecido para los algoritmos basados en caminos, fue diseñado deliberadamente para ser muy desequilibrado en términos de cantidad de memoria RAM. Cuatro nodos se configuran con un máximo de 2 GB de RAM y los nodos restantes fueron configurados con 16 GB, incluyendo el nodo de fusión (es decir, el nodo 5). Para llevar a cabo este experimento, las implementaciones FJ, Pregel y DPM del algoritmo HITS fueron configurados para ejecutarse utilizando los conjuntos de Seguidores, Seguidos y Mitad definidos en el Capítulo 4, Sección 4.4.4. Como se muestra en los resultados experimentales en la Figura 6.9, en la mayoría de las pruebas de las estrategias basadas en ubicación y Round Robin no se logró proporcionar un resultado debido a errores de falta de memoria. En estas estrategias, los nodos de memoria baja manejan tantos vértices como los nodos de memoria de alta, lo que resulta en el fallo de la ejecución de los primeros. Existen algunas anomalías, sin embargo. Para el usuario Fee4 , la estrategia por ubicación no proporcionó un resultado para todos los modelos, mientras que Round Robin tuvo éxito utilizando los modelos de DPM y Pregel. La singularidad de este caso reside en el hecho de que la estrategia de por ubicación por lo general consume menos memoria que Round Robin (como se muestra en el análisis de la sección anterior). Sin embargo, la anomalía puede explicarse por las longitudes desequilibradas de listas de adyacencia que, para el usuario Fee4 , sólo perjudica a la estrategia por ubicación. Una solución, que no se ha implementado en esta tesis, radica en dividir las listas de adyacencia grandes y procesarlas por secciones (por ejemplo, dividir una lista de adyacencia de 1M vértices en lotes de 10000 vértices). Claramente, el fallo del algoritmo depende también del recolector de basura de la JVM, que puede ser imposible prever en este caso particular. Las alternativas basadas en la memoria exhibieron el mayor tiempo de ejecución, pero aportaron un resultado para la mayoría de usuarios en los grupos de Seguidos. El modelo Pregel, sin 154 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Location Round Robin Max. Memory Available Memory Figure 6.9: Resultados de HITS para cada estrategia para el escenario 1. 6.2. RESULTADOS EXPERIMENTALES 155 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS embargo, no ha emitido un resultado para los usuarios Fee2 , Fee3 y Fee8 para ninguna estrategia. Este comportamiento está relacionado con la presión que los mensajes Pregel imponen en el heap de la JVM. En comparación con los algoritmos basados en caminos, el subgrafo generado por HITS fue más pequeño y, por lo tanto, la tasa de fracaso de las estrategias basadas en la localización y el Round Robin fue menor también. Sin embargo, hubo una clara tendencia en beneficio de la ejecución de estrategias basadas en la memoria sobre las demás. Segundo Escenario El segundo escenario es una ligera variación del primer escenario. En este caso, el nodo que va a ejecutar la tarea principal de DPM y FJ está configurado con un máximo de 4 GB de memoria. Esto significa que el nodo de fusión (en concreto, el nodo 5 del clúster) cuenta con menos memoria para fusionar sub-resultados - en el caso de FJ - o fusionar vértices activos - en el caso de DPM. Este escenario no debería afectar al rendimiento del Coordinador de Pregel ya que no maneja una gran cantidad de datos de agregadores: la implementación HITS propuesta sólo hace un seguimiento de la suma de las puntuaciones de autoridad y concentrador para realizar la normalización. En resumen, la nueva configuración del clúster se llevó a cabo de la siguiente manera: los nodos 1, 2, 3 y 4 se limitan a 2 GB de memoria, el nodo 5 (el nodo de la fusión) fue asignado con 4 GB, y los nodos 6, 7 y 8 fueron equipados con 16 GB de memoria. Como se muestra en la Figura 6.10, este escenario redujo la cantidad de ejecuciones exitosas (es decir, las ejecuciones que no fallan, retornando una lista de recomendaciones), pero sólo para las estrategias basadas por ubicación y Round Robin . Sorprendentemente, Pregel falló consistentemente bajo Round Robin para todos los usuarios, en parte, debido a una memoria global más baja, es decir, 72 GB de RAM en el primer escenario frente al 60 GB de memoria RAM total, en el segundo escenario. Las estrategias de basadas en memoria permanecieron robustas y proporcionaron resultados para todos los usuarios en el conjunto de datos. En este experimento, sin embargo, la estrategia de memoria disponible no pudo entregar un resultado en el caso de Pregel para el usuario Fee2 . Sin embargo, en el segundo escenario, los algoritmos basados en RW no se beneficiaron tanto de las estrategias basadas en la memoria al igual que los algoritmos basados en caminos. Esto es debido al hecho de que la cantidad de resultados manejados por los algoritmos se mantiene constante ya que el tamaño del subgrafo no aumenta con cada iteración. 6.2.3 Discusión La primera parte de los experimentos mostró que Pregel y DPM se comportan muy bien para HITS y SALSA, siendo DPM el de mejor desempeño entre los dos modelos. Por otro lado, FJ tardó casi el doble de la cantidad de tiempo para proporcionar recomendaciones y produjo 156 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS Location Round Robin Max. Memory Available Memory Figure 6.10: Resultados de HITS para cada estrategia para el escenario 2. 6.2. RESULTADOS EXPERIMENTALES 157 of 206 CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS casi el doble de la cantidad de tráfico de red que los otros modelos, reforzando la hipótesis de que la elección correcta del modelo para un determinado tipo de algoritmo es importante para proporcionar recomendaciones rápidas y eficientes. Del análisis de la implementación, surgió que FJ y DPM presentan problemas desde el punto de vista del diseño algorítmico. En estos modelos, el desarrollador es propenso a producir implementaciones que no mantienen la localidad debido a que el acceso al grafo es ilimitado por la API. Por el contrario, el cálculo centrada en el vértice en Pregel obliga al desarrollador a mantener la localidad, limitando el acceso a los datos relacionados con un solo vértice. Además la comunicación con otros vértices es manejado por un mecanismo de mensajería. La segunda parte de los experimentos mostraron que las estrategias de mapeo ayudan a emitir recomendaciones en situaciones adversas, tales como escenarios de poca memoria. Al igual que en los algoritmos basados en caminos, las estrategias basadas en la memoria se comportaron con firmeza incluso en escenarios con poca memoria. Estas estrategias en combinación con FJ o DPM permitió producir con éxito recomendaciones para todos los usuarios en el conjunto de datos de Seguidos. Pregel, sin embargo, sufrió de los requisitos de memoria de su mecanismo de mensajería y no pudo proporcionar recomendaciones para muchos usuarios, incluso utilizando estrategias basadas en la memoria. El análisis global de la combinación de los resultados obtenidos a partir de la experimentación con algoritmos basados en caminos y en RW, puede arrojar alguna luz sobre los criterios que los desarrolladores deben utilizar para seleccionar un modelo a partir del tipo de algoritmo a ser ejecutado, las características del clúster y otras condiciones. De esta manera, la Tabla 6.2 fue diseñada para ayudar a los desarrolladores a decidir cuál es el modelo y la estrategia más adecuada para sus necesidades cuando se utiliza Graphly. Esta tabla se debe leer de la siguiente manera. Cada columna representa un posible escenario o característica que el desarrollador quiere favorecer, agrupados por el tipo de algoritmo que se está desarrollando. Es decir, estas columnas se presentan en el siguiente orden: el tiempo de recomendación (Tiempo), el consumo de memoria (Mem), el consumo de red (Net), la configuración del clúster con memoria baja (Low-Mem), el diseño del algoritmos (Diseño). Las tres primeras características están directamente relacionados con las métricas obtenidas en los resultados experimentales. El escenario Low-Mem se relaciona con los dos escenarios experimentales donde varios nodos del clúster tienen baja cantidad de memoria RAM. Por último, el diseño del algoritmo está relacionado con la facilidad de programación en el modelo de procesamiento dado, y es independiente de la estrategia de mapeo. Por otra parte, cada fila representa una combinación de modelo de procesamiento y estrategia de mapeo. Los desarrolladores pueden elegir un modelo y la estrategia de acuerdo con el escenario o característica seleccionada. Cada celda puede tomar los siguientes valores, de mejor a peor: Muy bueno, Bueno, Regular, Pobre y Muy Pobre. Aunque estos valores son subjetivos, se compara la magnitud relativa de los resultados obtenidos en los experimentos y las observa158 of 206 6.2. RESULTADOS EXPERIMENTALES CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS ciones de la experiencia en la implementación de los algoritmos. Por lo tanto, cada valor de la tabla representa una comparación relativa entre los resultados experimentales en la misma categoría. Por ejemplo, en cuanto a tiempo de recomendación, DPM exhibió los mejores resultados en algoritmos iterativos, que tiene una diferencia considerable con Pregel y una diferencia mucho más grande con FJ. De esta manera, los valores asignados fueron Muy bueno, Bueno y Pobre para DPM, Pregel y FJ, respectivamente. 6.2. RESULTADOS EXPERIMENTALES 159 of 206 FJ Por ubicación Round Robin Memoria Disponible Memoria Máxima Tiempo Algoritmos Iterativos (e.g. RW-based) Mem Net Low-Mem Pobre Regular Regular Pobre Pobre Bueno Pobre Regular 6.2. RESULTADOS EXPERIMENTALES Pregel Por ubicación Round Robin Memoria Disponible Memoria Máxima Bueno Muy Pobre DPM Por ubicación Round Robin Memoria Disponible Memoria Máxima Muy Bueno Muy Pobre Bueno Bueno Regular Regular Regular Muy Pobre Muy Pobre Pobre Regular Muy Pobre Pobre Regular Muy Pobre Muy Pobre Muy Pobre Muy Pobre Bueno Bueno Muy Bueno Average Bueno Bueno Bueno Bueno Bueno Muy Pobre Bueno Bueno Regular Regular Diseño Algoritmos de Recorrido Mem Net Low-mem Tiempo Regular Muy Pobre Muy Pobre Pobre Bueno Muy Pobre Bueno Bueno Bueno Muy Pobre Pobre Pobre Bueno Pobre Muy Pobre Pobre Pobre Pobre Muy Pobre Pobre Pobre Muy Pobre Pobre Pobre Regular Regular Regular Bueno Muy Pobre Muy Pobre Pobre Pobre Pobre Pobre Pobre Pobre Pobre Pobre Table 6.2: Tabla de decisión para cada combinación de estrategia y modelo. Regular Bueno Regular CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 160 of 206 Estrategia de Mapeo Diseño Bueno Bueno Bueno Pobre Bueno Bueno Bueno CHAPTER 6. MECANISMOS DE SOPORTE PARA ALGORITMOS BASADOS EN RANDOM WALKS 6.3 Resumen En este capítulo, se mostró que los algoritmos basados en RW, tales como HITS o SALSA, actúan de forma diferente de acuerdo con el modelo de procesamiento elegido. De hecho, DPM y Pregel mostraron los mejores resultados para este tipo de algoritmos. En particular, DPM se destacó en términos de velocidad recomendación pero con dificultades para adaptarse al tipo de algoritmo debido a su estilo de programación similar a FJ. El Capítulo también resume una comparación de la aptitud de los modelos proporcionando una tabla de decisión para ayudar a los desarrolladores a elegir el modelo más apropiado bajo diferentes condiciones del clúster y determinados tipos de algoritmos. 6.3. RESUMEN 161 of 206 7 Conclusiones En esta tesis se propusieron nuevos mecanismos y técnicas para el desarrollo de algoritmos de predicción de enlace distribuidos como componente central de los sistemas de recomendación en redes sociales a gran escala. El incesante aumento del tamaño de tales redes demanda modelos de procesamiento distribuidos capaces de hacer frente a las grandes cantidades de datos sociales involucrados. Como resultado de esta investigación, un framework, llamado Graphly, fue desarrollado para dar soporte a los mecanismos propuestos y ayudar al usuario en la creación de algoritmos de recomendación complejos en redes sociales. Graphly fue diseñado para proporcionar diferentes estilos de programación a través de los modelos de procesamiento con el fin de soportar de manera eficiente múltiples tipos de algoritmos (por ejemplo, de recorrido o iterativos). Tal como se presenta en el Capítulo 4, el marco propuesto es compatible con tres modelos de procesamiento distribuido: FJ, Pregel y DPM. FJ fue adaptado para el procesamiento de grafos e integrado en Graphly a través del uso de la abstracción de Tareas y Trabajo. Pregel, por el contrario, requiere la creación de la abstracción Función Vértice, y la ejecución de un coordinador, que lleva a cabo el control de la ejecución BSP y los workers Pregel, que se encargan del procesamiento de vértices y la mensajería de resultados. Por último, el modelo Distributed Partitioned Merge (DPM) que se propone en esta tesis proporciona un punto medio entre estos dos modelos mezclando la sencillez del estilo de programación FJ, y la eficiencia de fusión distribuida y la activación de vértices de Pregel. Desde el punto de vista del usuario, Graphly se ocupa de las cuestiones de programación distribuida, como la distribución o código, y las esconde detrás un conjunto de APIs. En primer lugar, una API de grafos permite la consulta de información del almacén Graphly sin tener en cuenta su ubicación en el clúster. En segundo lugar, una API de recorrido ayuda a realizar recorridos simples como caminar a través del grafo en una dirección dada, contando la cantidad de aristas que participan en un recorrido, o filtrando vértices de los resultados. La tercer API es la API modelos, que proporciona acceso a los tres modelos de procesamiento implementados. Por último, una cuarta API, llamada GraphRec, permite al usuario ejecutar y reutilizar un conjunto 162 of 206 CHAPTER 7. CONCLUSIONES de algoritmos conocidos de predicción de enlace como si fueran primitivas. Este nuevo enfoque fomenta la creación de nuevos algoritmos de recomendación mediante la reutilización de los algoritmos existentes y su composición. Por último, el mecanismo de estrategias de mapeo introducido por Graphly es una forma de personalizar la ejecución distribuida del algoritmo, sin tocar una sola línea de código del mismo. La estrategia, definida por el usuario, decide cómo se reparten los vértices y donde se asigna cada partición. Un conjunto de estrategias integradas son proporcionados por Graphly, utilizando por defecto la estrategia por ubicación. La evaluación experimental llevado a cabo en esta tesis tuvo como objetivo evaluar las ventajas y desventajas de los mecanismos de soporte propuestos para los diferentes algoritmos de predicción de enlace y las características del clúster subyacente. Los experimentos mostraron que, en función del tipo de algoritmos siendo desarrollado, un modelo de procesamiento puede ser más o menos adecuado. De hecho, se ha exhibido que los algoritmos basados en la trayectoria con recorridos cortos, tales como TFR y LocalPath, y los algoritmos basados en vecinos, se comportaron mejor en FJ o DPM que en Pregel. Sin embargo, en los algoritmos, como Katz o FriendLink donde la profundidad del recorrido fue mayor, Pregel y DPM superaron en gran medida a FJ. En estos casos FJ introdujo demasiada sobrecarga en la distribución y la fusión de los resultados. Esto fue confirmado en la evaluación de algoritmos basados en RW (HITS y SALSA), donde se ejecutaron varias iteraciones para aproximar las puntuaciones de autoridad y concentrador. FJ se comportó pobremente en estos algoritmos iterativos, introduciendo una enorme sobrecarga en consumo de red y tiempo de unión de resultados. Para ambos tipos de algoritmos DPM exhibió una velocidad notable en comparación con Pregel y FJ, sin comprometer el uso de memoria. De hecho, en varios experimentos, proporcionó casi la eficiencia de la memoria de FJ. En los algoritmos basados en RW, DPM también exhibió uso de red mucho más bajo que FJ, aunque un poco más alto que Pregel. Para algoritmos basados en caminos, sin embargo, fue el modelo más intensivo en uso de red. Las estrategias de mapeo se encargan de la asignación personalizada de cómputo a los nodos. El objetivo principal de estas estrategias es ajustar la asignación de particiones de acuerdo a las características de clúster. Para demostrar su utilidad, se propusieron dos escenarios para poner a prueba las estrategias de mapeo que ofrece Graphly: un escenario muy desequilibrado donde la mitad del grupo tenía 2 GB de RAM y el resto 16 GB, y un segundo escenario en el que uno de los nodos de 16 GB en el primer escenario se redujo a 4 GB y fue configurado como el nodo fusión para los modelos DPM y FJ. Naturalmente, el objetivo era reequilibrar el cálculo de los vértices a los nodos con más memoria, en lugar de proporcionar una asignación equitativa de particiones. En ambos escenarios para todo tipo de algoritmos, las estrategias por ubicación y Round Robin no emitieron ningún resultado para la mayoría de usuarios de prueba, debido a errores de falta de memoria. Este fue un comportamiento esperado, ya que el primero se basa en la estrategia de distribución - equilibrada - de la base de datos de grafos y el segundo asigna 163 of 206 CHAPTER 7. CONCLUSIONES vértices nodo a nodo sin tomar en cuenta otra métrica. Por otro lado, ambas estrategias basadas en memoria lograron proporcionar una recomendación, aunque con una penalización de tiempo importante. Esto demostró que en escenarios de baja memoria es fundamental proporcionar un mecanismo para reequilibrar la ejecución de vértices y Graphly proporciona el soporte para elegir la mejor estrategia de mapeo sin alterar el código de algoritmo. Los modelos que fusionan los resultados en un nodo central, como FJ, pueden beneficiarse con una estrategia dinámica tal como la estrategia de la Memoria Disponible. Como se muestra en los experimentos basados en caminos, la mayoría de las ejecuciones FJ en el segundo escenario fallaron, excepto cuando se utiliza la estrategia de Memoria Disponible. Para algoritmos basados en RW, sin embargo, HITS no mostró ninguna mejora en la tasa de fracaso entre las estrategias Memoria Máxima y Memoria Disponible. 7.1 Contribuciones Esta tesis se centró en el problema de soportar la ejecución eficiente de algoritmos de predicción de enlace en entornos distribuidos. En particular, uno de los principales objetivos fue el de proporcionar un framework que implemente diferentes modelos de procesamiento con el fin de ejecutar de manera eficiente diferentes tipos de algoritmos y compararlos bajo la misma plataforma. El otro objetivo principal era proporcionar un mecanismo que permitiera controlar la computación distribuida dependiendo de las características de clúster y otras condiciones definidas por el usuario, sin necesidad de modificar los algoritmos ya creados. Resumiendo, las mayores contribuciones de esta tesis son: • Un nuevo modelo de procesamiento, denominado Distributed Partitioned Merge que ofrece un estilo de programación FJ, sin dejar de ser adecuado para los algoritmos iterativos como el modelo orientado a grafos, Pregel. Las tareas de DPM distribuyen la combinación de los resultados por el clúster y devuelven la lista de vértices que se modificaron durante el cálculo. De este modo, DPM elimina el uso de un nodo coordinador y simplifica la gestión de los vértices activos. En los experimentos propuestos, DPM realiza recomendaciones más rápido que otros modelos sin importar el tipo de algoritmo, con una pequeña penalización en la memoria y el uso de la red con respecto a FJ. En algunos experimentos, la eficiencia de DPM en términos de red y el uso de memoria era igual a la conseguida por el modelo FJ. • Un mecanismo, llamado Mapping Strategies, que permite personalizar la ejecución de un algoritmo de recomendación, sin ensuciar el código con las cuestiones de programación distribuida. Este mecanismo puede resultar crítico para ciertos escenarios tales como los escenarios de poca memoria. • Un framework, llamado Graphly, para el desarrollo de algoritmos basados en el grafos 164 of 206 7.1. CONTRIBUCIONES CHAPTER 7. CONCLUSIONES distribuidos, especialmente diseñado para fomentar la creación de algoritmos de recomendación para redes sociales en línea a gran escala. En particular, Graphly se centró en soportar los algoritmos de predicción de enlace utilizados para recomendar a los usuarios en redes de amistad o seguidor/seguido. El framework proporciona autoconfiguración, auto-descubrimiento de nodos y soporte para diferentes modelos de procesamiento y estrategias de mapeo. Por otra parte, Graphly simplifica la evaluación de diferentes modelos de procesamiento proporcionando una plataforma unificada que ayuda a aumentar la equidad de la comparación. En otros casos, varios frameworks que implementan un modelo de procesamiento particular deben ser instalados y configurados de forma independiente, introduciendo una gran cantidad de configuraciones alternativas y complicando la comparación. Además, las estrategias de mapeo están implementadas de forma independientemente del modelo de procesamiento elegido por el desarrollador. Como consecuencia de ello, la misma implementación de un algoritmo puede ser ejecutado utilizando diferentes estrategias sin modificar el código. • Una API, llamada GraphRec, para la ejecución y composición de algoritmos de recomendación bien conocidos, tales como SALSA, HITS, Katz, entre otros. Cada uno de estos algoritmos se implementa con diferentes modelos de procesamiento y por lo tanto, podría ser utilizado como referencia a portar algoritmos similares a Graphly. La verdadera ventaja reside en el hecho de que estas implementaciones se proporcionan como primitivas que pueden usarse para desarrollar nuevos algoritmos de recomendación. El desarrollador puede elegir un modelo particular para un determinado algoritmo de acuerdo con el análisis realizado anteriormente en esta tesis. Por ejemplo, si se requiere un tiempo rápido para recomendación, cualquier implementación de DPM sería preferible. • Una comparación de modelo que proporciona información de qué tan bien los modelos se adaptan a determinados tipos de algoritmos y condiciones del clúster. Esta comparación es útil para decidir qué modelo de procesamiento es mejor para los algoritmos implementados o nuevos que se están desarrollando. Por ejemplo, se observó que los algoritmos basados en caminos realizan recomendaciones más rápidas en DPM y FJ cuando la profundidad del recorrido se mantiene baja, como en TFR o vecinos comunes, pero cuando aumenta la profundidad del recorrido, FJ es superado por otros modelos. Por otro lado, si la reducción de uso de la red es la máxima prioridad, se encontró que FJ se comporta muy bien para los algoritmos basados en caminos, pero no tan bien para los algoritmos basados en RW. 7.2 Limitaciones El framework y los mecanismos propuestos tienen algunas limitaciones, siendo las siguientes las más relevantes: 7.2. LIMITACIONES 165 of 206 CHAPTER 7. CONCLUSIONES • El soporte algorítmico actual se limita a los algoritmos de predicción de enlace en grafos. Aunque otros algoritmos que usan la topología del grafo se pueden desarrollar fácilmente, los algoritmos que utilizan las propiedades de eje o procesamiento más complejos, tales como procesamiento de texto, no se admiten actualmente. Por ejemplo, el filtrado colaborativo o la detección de comunidades, que son métodos comunes que se utilizan para la construcción de sistemas de recomendación no son compatibles. • La modificación de la estructura del grafo durante la ejecución de los algoritmos está permitido, pero no probado ni está soportado. Esta función es útil, por ejemplo, en algoritmos adaptativos de recomendación (Desikan et al., 2005; Yu et al., 2014) que generan sugerencias medida que evoluciona el grafo, lo cual incluye la adición o eliminación de vértices, propiedades o ejes. • El framework no está diseñado para soportar las características empresariales, tales como recuperación de errores, replicación, mitigación de fallas, y así sucesivamente. Además, el estado actual de la aplicación no es compatible con puntos de control, lo que ayuda a continuar tareas de larga duración. • El modelo DPM tiene sus propias limitaciones en cuanto al tamaño de los datos que puede procesar. Ya que combina los vértices activos en un nodo central, el impacto de esa combinación puede reducir su capacidad de escala, aunque esto todavía tiene que ser probado, por ejemplo, en grafos con miles de millones de vértices. No obstante, DPM tiene requisitos más bajos en el nodo de fusión que FJ. Pregel, por otra parte, distribuye las particiones entre los trabajadores y no tiene un componente de fusión central. Sin embargo, las abstracciones de mensajería utilizadas por Pregel reducen el rendimiento general del algoritmo, poniéndolo detrás de DPM y su estilo de programación más sencilla. 7.3 Trabajo Futuro Graphly y los mecanismos de soporte propuestos en esta tesis dan lugar a todo un espectro de alternativas de investigación que merecen atención, algunos de ellos son: • Soporte para nuevos algoritmos: los algoritmos que requieren diferentes patrones de acceso, tales como algoritmos de clustering (por ejemplo, K-means) o algoritmos de detección de comunidades (por ejemplo, Newman-Girvan), pueden requerir nuevos modelos que les den soporte o modificaciones a los ya existentes. Además, los algoritmos de recomendación en el contexto de las redes sociales multidimensionales, como las redes sociales basadas en localización y Folksonomías (Godoy and Corbellini, 2015), puede requerir un nuevo soporte de modelos y estructuras asociadas. 166 of 206 7.3. TRABAJO FUTURO CHAPTER 7. CONCLUSIONES • Mejora de la evaluación: Nuevos mecanismos de evaluación necesitan ser establecidos para la comparación de algoritmos de grafos en diferentes frameworks. En la actualidad, debido al hecho de que la mayoría de estos marcos realizan la mayor parte de su procesamiento en el disco (Hadoop y Giraph), o por el contrario, almacenar tanto grafo y los resultados en memoria (Spark), la comparación sería relativamente injusta. • Características de soporte adicionales: En la actualidad, Graphly utiliza sólo las listas de adyacencia del grafo para emitir recomendaciones. Sin embargo, la mayoría de los algoritmos mejoran la recomendación topológica con información textual o de otro tipo de datos, asociado a cada vértice, ya sea mediante la construcción de un modelo de usuario, o procesando el texto sobre la marcha. Por ejemplo, los algoritmos basados en contenidos que explotan el texto de los mensajes sociales (por ejemplo, los tweets) para conocer los perfiles de usuario, se han utilizado para generar recomendaciones a usuarios de Twitter (Tommasel et al., 2015). El procesamiento de este tipo de información requiere más recursos del clúster, y, posiblemente, originaría nuevos mecanismos para soportarlo. 7.3. TRABAJO FUTURO 167 of 206 A Bases de Datos NoSQL Las bases de datos relacionales o RDBMS (Sistemas de Gestión de Bases de Datos Relacionales) se han utilizado desde los años 70 y, como tales, pueden considerarse una tecnología madura para almacenar datos y sus relaciones. Sin embargo, los problemas de almacenamiento en sistemas orientados a la Web alcanzaron los límites de las bases de datos relacionales, obligando a los investigadores y las empresas a investigar formas no tradicionales de almacenamiento de datos (Stonebraker and Cattell, 2011). Los datos generados por los usuarios de hoy pueden escalar a terabytes por día y deben estar a disposición de millones de usuarios en todo el mundo bajo los requisitos de baja latencia. El aumento de la capacidad de almacenamiento de cualquier nodo computacional significa la adición de más memoria RAM o más espacio en disco bajo las restricciones del hardware subyacente. Al llegar a un límite de almacenamiento de nodo, no hay otra alternativa que la distribución de los datos entre los diferentes nodos. Por lo general, los sistemas RDBMS no están diseñados para ser distribuidos fácilmente, y por lo tanto la complejidad de añadir nuevos nodos para equilibrar los datos es alta (Leavitt, 2010). Además, el rendimiento de base de datos a menudo disminuye significativamente dado que las uniones y transacciones son costosas en entornos distribuidos (Cattell, 2011; Orend, 2010). Con todo, ésto no significa que los RDBMS sean obsoletos, sino que han sido diseñados con otros requisitos en mente y funcionan bien cuando no se requiere una alta escalabilidad. Precisamente, las bases de datos NoSQL han surgido como alternativas de almacenamiento, no basados en modelos relacionales, para hacer frente a los problemas mencionados. El término “NoSQL” fue acuñado por Carlo Strozzi en 1998 para referirse a las bases de datos de código abierto llamado NoSQL, que carecen de una interfaz SQL (Strozzi, 1998). En 2009, el término resurgió gracias a Eric Evans en el contexto de un evento sobre bases de datos distribuidas1 Desde entonces, algunos investigadores (James and Cooper, 2009; Jeffery, 2009) han señalado 1 NoSQL Meetup 2009, http://nosql.eventbrite.com/ 168 of 206 APPENDIX A. BASES DE DATOS NOSQL que los nuevos paradigmas de gestión de la información como Internet de las Cosas necesitarían cambios radicales en la forma en la que se almacenan los datos. En este contexto, las bases de datos tradicionales no pueden hacer frente a la generación de grandes cantidades de información desde diferentes dispositivos, incluyendo la información del GPS, RFID, las direcciones IP, identificadores únicos, datos y metadatos sobre los dispositivos, datos de sensores y datos históricos. En general, las bases de datos NoSQL son no estructuradas, es decir, no tienen un esquema fijo y su interfaz de uso es generalmente simple, permitiendo a los desarrolladores empezar a usarlas rápidamente. Además, estas bases de datos generalmente evitan uniones en el nivel de almacenamiento de datos, ya que este tipo de operación es a menudo costosa, dejando la tarea de unión de los datos a cada aplicación. El desarrollador debe decidir si realizar uniones a nivel de aplicación o, en su defecto, desnormalizar datos. En el primer caso (unión manual de datos), la operación puede implicar la recopilación de datos de varios nodos físicos en base a una serie criterios y luego la unión de los datos recogidos. Este enfoque requiere más esfuerzo de desarrollo, pero hay marcos y lenguajes que alivian esta tarea (Dean and Ghemawat, 2008; Malewicz et al., 2010). En cambio, si se elige la desnormalización, múltiples atributos de datos pueden ser replicados en diferentes estructuras de almacenamiento. Por ejemplo, supongamos un sistema para almacenar fotos de los usuarios. Para optimizar las consultas para las fotos que pertenecen a los usuarios de una determinada nacionalidad, el campo Nacionalidad puede ser replicado en las estructuras de datos de Foto y Usuario. Naturalmente, este abordaje conlleva consideraciones especiales con respecto a las actualizaciones del campo Nacionalidad, ya que podrían producirse inconsistencias entre las estructuras de datos de Foto y de Usuario. Muchas bases de datos NoSQL admiten la distribución de datos por diseño, lo que aumenta su capacidad por medio de la adición de nodos a la infraestructura, una propiedad también conocido como escalabilidad horizontal. En la mayoría de las implementaciones, los requisitos de hardware de los nodos individuales no debe exceder los de una computadora personal tradicional con el fin de reducir los costos de construcción de tales sistemas y también para facilitar la sustitución de los nodos defectuosos. Las bases de datos NoSQL se pueden dividir en varias categorías según la clasificación propuesta en (Cattell, 2011; Hecht and Jablonski, 2011; Leavitt, 2010; Tudorica and Bucur, 2011), cada una prescribiendo un determinado modelo para los datos almacenados: • Clave-Valor: estas bases de datos permiten almacenar datos arbitrarios bajo una clave. Funcionan de manera similar a una tabla de hash convencional, pero distribuyendo las claves (y valores) entre un conjunto de nodos físicos. • Orientadas a Familias de Columnas: en lugar de guardar los datos de la fila (como en las bases de datos relacionales), este tipo de bases de datos almacenan los datos por columna. Por lo tanto, algunas filas pueden no contener parte de las columnas, lo que ofrece flexi169 of 206 APPENDIX A. BASES DE DATOS NOSQL bilidad en la definición de datos y permite aplicar algoritmos de compresión de datos por columna. Por otra parte, las columnas que no se consultan a menudo juntas pueden ser distribuidos a través de diferentes nodos. • Orientadas a Documentos: un documento es una serie de campos con atributos, por ejemplo: name = "John", lastname = "Smith" es un documento con 2 campos. La mayoría de las bases de datos de almacenamiento de documentos permite el almacenamiento de documentos en formatos semi-estructurados como XML (Bray et al., 1997) (eXtensible Markup Language), JSON (Crockford, 2006) (JavaScript Object Notation) o BSON (Membrey et al., 2010) (Binary JSON). Funcionan de manera similar a las bases de datos clavevalor pero, en este caso, la clave es siempre el ID de un documento y el valor es un documento con una estructura conocida. Por otra parte, algunos autores también conciben las bases de datos Orientadas a Grafos, que se han descrito en el Capítulo 3.2, como una cuarta categoría de las bases de datos NoSQL (Hecht and Jablonski, 2011; Tudorica and Bucur, 2011). Las siguientes secciones presentan y discuten, a grandes rasgos, las bases de datos más importantes en cada una de las categorías descritas anteriormente. La Tabla A.1 enumera las bases de datos analizadas, agrupadas por categoría. Vale la pena señalar que hay una minoría de las bases de datos híbridas que permiten almacenar más de un modelo de datos. Ejemplos de bases de datos multi-modelo son OpenLink Virtuoso (Erling and Mikhailov, 2010), OrientDB2 y Aerospike3 . Sin embargo, no se van a discutir estos esfuerzos en una sección separada ya que los mecanismos de apoyo a los diferentes modelos no difieren conceptualmente de los ofrecidos por las bases de datos de modelo único. Este apéndice está organizado de la siguiente manera. La Sección A.1 describe algunos conceptos preliminares que necesitan ser explicados antes de comenzar con la descripción y el análisis de las bases de datos disponibles en el mercado. La Sección A.2 introduce las bases de datos Clave-Valor. La Sección A.3 presenta las bases de datos Orientadas a Familias de Columnas. Las bases Orientadas a Documentos se describen en la Sección A.4. A.1 Conceptos Esta sección cubre los conceptos básicos relacionados con las bases de datos NoSQL necesarias para comprender plenamente el dominio. 2 OrientDB 3 Aerospike 170 of 206 Web Page, http://orientdb.com/orientdb/ Web Page, http://www.aerospike.com/ A.1. CONCEPTOS APPENDIX A. BASES DE DATOS NOSQL Categoría Clave-Valor (Sección A.2) Orientadas a Columnas (Sección A.3) Orientadas a Documentos (Sección A.4) Orientadas a Grafos (Capítulo 3, Sección 3.2) Bases de datos NoSQL analizadas Hazelcasta Redisb Couchbasec Riakd Voldemorte Infinispan (Marchioni, 2012) HBase (George, 2011) Hypertablef Cassandra (Lakshman and Malik, 2010) CouchDB (Lennon, 2009) MongoDB (Chodorow and Dirolf, 2010) RavenDBg Neo4J InfiniteGraph InfoGrid HypergraphDB AllegroGraph BlazeGraph a Hazelcast Web Page, https://hazelcast.com/ Web Page, http://redis.io/ c Couchbase Web Page, http://www.couchbase.com/ d Riak Web Page, http://basho.com/products/riak-kv/ e Voldemort Web Page, http://www.project-voldemort.com/voldemort/ f Hypertable Web Page, http://hypertable.org/ g RavenDB Web Page, http://ravendb.net/ b Redis Table A.1: Bases de datos analizadas agrupadas por categoría A.1.1 El Teorema de CAP El teorema de CAP, o teorema de Brewer (Gilbert and Lynch, 2002), afirma que es imposible garantizar simultáneamente las siguientes propiedades en un sistema distribuido: • Consistencia (Consistency): si se cumple este atributo, se garantiza que una vez que los datos se escriben están disponibles y actualizados para cada usuario que utiliza el sistema. • Disponibilidad (Availability): esta propiedad se refiere a ofrecer el servicio de forma ininterrumpida y sin degradación dentro de un determinado porcentaje de tiempo. • Tolerancia a Particiones (Partition Tolerance): si el sistema cumple esta propiedad, una operación se puede completar incluso cuando falla alguna parte de la red. En 2000, Eric Brewer conjeturó que en cualquier momento dado en el tiempo sólo dos de las tres características mencionadas se pueden garantizar. Esto significa que sólo se pueden crear sistemas que consigan las siguientes combinaciones: AP (Availability-Partition Tolerance), CP A.1. CONCEPTOS 171 of 206 APPENDIX A. BASES DE DATOS NOSQL Modelo de datos Clave-Valor (Sección A.2) AP Riak, Infinispan, Redis, Voldemort, Hazelcast Orientadas a Columnas (Sección A.3) Orientadas a Documentos (Sección A.4) Orientadas a Grafos (Capítulo 3, Sección 3.2) Cassandra CP AC Infinispan, Infinispan Membase/CouchBase, BerkeleyDB, GT.M HBase, Hypertable - MongoDB, RavenDB , CouchDB MongoDB - Neo4J, HypergraphDB, BlazeGraph, AllegroGraph, InfoGrid, InfiniteGraph InfiniteGraph - Table A.2: Agrupamiento de sistemas NoSQL de acuerdo al modelo de datos y propiedades CAP. (Consistency-Partition Tolerance) o AC (Availability-Consistency). La Tabla A.2 resume las bases de datos NoSQL revisadas en esta tesis organizadas de acuerdo con el modelo de datos compatible. Dentro de cada grupo, las bases de datos se agrupan adicionalmente de acuerdo con las características del teorema de CAP que exhiben. Como se ilustra, la mayoría de las bases de datos de la encuesta caen en los grupos “AP” o “CP”. Esto es porque renunciar a “P” (Tolerancia a particiones) en un sistema distribuido significa asumir que la red subyacente nunca perderá paquetes ni se desconectará, lo cual no es factible. Hay algunas excepciones a esta regla, dadas por bases de datos NoSQL (por ejemplo, Infinispan (Marchioni, 2012)) que son capaces de relajar “P” mientras que proporcionan “A” y “C”. Debido a que algunas bases de datos, como Infinispan y MongoDB, se puede configurar para proporcionar garantía de consistencia completa (sacrificando alguna disponibilidad) o consistencia eventual (proveyendo alta disponibilidad), aparecen en ambas columnas AP y CP. A.1.2 Propiedades ACID y BASE En 1970, Jim Gray propuso el concepto de transacción (Gray and Reuter, 1992), una unidad de trabajo en un sistema de base de datos que contiene un conjunto de operaciones. Para que una transacción se comporte de una manera segura debe exhibir cuatro propiedades principales: atomicidad (atomicity), consistencia (consistency), aislamiento (isolation) y durabilidad (durability). Estas propiedades, conocidas como ACID, aumentan la complejidad del diseño de los sistemas de base de datos y aún más en las bases de datos distribuidas, que diseminan datos en varias particiones a través de una red informática. Esta característica, sin embargo, simplifica 172 of 206 A.1. CONCEPTOS APPENDIX A. BASES DE DATOS NOSQL el trabajo de los desarrolladores mediante la garantía de que cada operación dejará la base de datos en un estado consistente. En este contexto, las operaciones son susceptibles a los fallos y retrasos de la propia red, por lo que se deben tomar precauciones para garantizar el éxito de una transacción. Los RDBMS distribuidos permiten, desde hace algún tiempo, realizar transacciones utilizando protocolos específicos para mantener la consistencia de los datos entre las particiones. Uno de los protocolos más utilizados para este propósito es 2PC (Two-phase commit), que ha sido fundamental en la ejecución de operaciones en entornos distribuidos. La aplicación de este protocolo se ha extendido incluso al ámbito de los Servicios Web, que permite transacciones en arquitecturas REST (REpresentational State Transfer) que de lo contrario no serían posibles (da Silva Maciel and Hirata, 2010). El protocolo 2PC consta de dos partes principales: 1. Una etapa en la que un componente coordinador pide a las bases de datos implicadas en la transacción hacer una operación de pre-commit. Si todas las bases de datos puede cumplir la operación, se lleva a cabo el escenario 2. 2. El coordinador pide a las bases de datos realizar una operación commit. Si alguna de las bases de datos rechaza el commit, se realiza un rollback. De acuerdo con el teorema CAP el uso de un protocolo como 2PC impacta negativamente en la disponibilidad del sistema. Con el fin de medir el grado de este impacto, una operación de disponibilidad se puede calcular como el producto de la disponibilidad individual de los componentes involucrados en dicha operación. Por ejemplo, si cada partición de base de datos tiene un 99,9% de disponibilidad, es decir, se les permiten 43 minutos fuera de servicio por mes, un commit usando 2PC sobre 2 particiones reduce la disponibilidad a 99,8%, que se traduce a 86 minutos al mes fuera de servicio (Pritchett, 2008). Además, 2PC es un protocolo de bloqueo, lo que significa que las bases de datos implicadas en una transacción no se pueden utilizar en paralelo mientras que un commit está en curso. Esto aumenta la latencia del sistema cuando el número de transacciones que ocurren crece. Debido a esto, muchos enfoques de bases de datos NoSQL decidieron relajar las restricciones de consistencia. Estos enfoques se conocen como BASE (Basically Available, Soft State, Eventually Consistent) (Pritchett, 2008). La idea detrás de los sistemas implementando este concepto es permitir fallos parciales en lugar de un fallo del sistema completo, lo que conduce a una percepción de una mayor disponibilidad del sistema. El diseño de los sistemas BASE, y en particular las bases de datos NoSQL BASE, permite que se realicen ciertas operaciones dejando las réplicas (es decir, copias de los datos) en un estado inconsistente. Precisamente, esto se conoce como Soft-State, en contraste con sistemas Hard-State, como las bases de datos transaccionales a los que no se les permite inconsistencias. Una inconsistencia en un sistema necesita ser resuelta sobre la base de criterios que aseguran A.1. CONCEPTOS 173 of 206 APPENDIX A. BASES DE DATOS NOSQL volver a un estado consistente. Por ejemplo, la base de datos NoSQL Cassandra (Lakshman and Malik, 2010) implementa las siguientes políticas de actualización de alto nivel: • Read-repair: las inconsistencias se corrigen durante la lectura de datos. Esto significa que la escritura podría dejar algunas inconsistencias detrás, que sólo se resolverán después de una operación de lectura. Por lo tanto, el componente coordinador que consulta las réplicas es responsable de actualizar esas réplicas que tienen datos obsoletos, ralentizando la operación de lectura. Vale la pena notar que los conflictos se resuelven solamente para los datos que intervienen en la operación de lectura. • Write-repair: la corrección de una inconsistencia se produce durante la escritura, lo que frena la operación. Como Read-repair, cuando se encuentra una inconsistencia mientras se escriben nuevos datos, el sistema decide qué información correcta deben tener las réplicas y las réplicas obsoletas se sincronizan. • Asynchronous-repair: la corrección no es ni parte de la lectura ni de la escritura. La sincronización puede dispararse por el tiempo transcurrido desde la última sincronización, la cantidad de escrituras o cualquier otro evento que pueda indicar que la base de datos no está actualizada. Además de la consistencia de las lecturas y escrituras, en los sistemas de almacenamiento distribuidos surge el concepto de durabilidad, que es la capacidad de un sistema dado de persistir los datos, incluso en presencia de fallos. Esto provoca que los datos se escriban en un número de dispositivos de memoria no volátil antes de informar el éxito de una operación a un cliente. En los sistemas eventualmente consistentes existen mecanismos para calibrar la durabilidad del sistema y su consistencia (Vogels, 2009). Por ejemplo, sea N el número de nodos en los que una clave está replicada, W el número de nodos necesarios para considerar un escritura un éxito y R el número de nodos en los que se realiza una lectura. La Tabla A.3 muestra diferentes configuraciones de W y R, así como el resultado de aplicar este tipo de configuraciones. Cada valor se refiere al número de réplicas necesarias para confirmar una operación exitosa. Para brindar la denominada Consistencia Fuerte (Strong Consistency) se alcanza al cumplir W + R > N, es decir, el conjunto de escrituras y lecturas se superpone de manera que una de las lecturas siempre obtiene la versión más reciente de una pieza de datos. Por lo general, RDBMs tienen W = N, es decir, todas las réplicas se conservan y R = 1, ya que cualquier lectura devolverá datos hasta a la fecha. La Consistencia Débil (Weak Consistency) tiene lugar cuando W + R ≤ N, en el que las lecturas pueden obtener datos actualizados. La Consistencia Eventual (Eventual Consistency) es un caso especial de consistencia débil en el que hay garantías de que si una pieza de datos se escriben en el sistema, con el tiempo llegará a todas las réplicas. Esto dependerá de la latencia de la red, la cantidad de réplicas y la carga del sistema, entre otros factores. 174 of 206 A.1. CONCEPTOS APPENDIX A. BASES DE DATOS NOSQL Réplicas involucradas Writing (W) Reading (R) 0 No se espera confirmación de ningún N/D nodo (puede fallar) 1 M, con M < N (Quorum) Una única confirmación es suficiente La lectura se realiza desde una única (optimizada para escrituras) réplica (optimizada para lectura) Se espera las confirmaciones de varias La lectura se realiza desde un conjunto réplicas de réplicas (conflictos en el cliente necesitan ser resueltos) N (todos los nodos) Se espera las confirmaciones de todas La lectura se realiza desde todas las las réplicas (reduce disponibilidad, réplicas incrementando la latencia de pero incrementa la durabilidad) lectura Table A.3: Configuraciones de consistencia eventual. Si las operaciones de escritura necesitan ser más rápidas, se pueden realizar sobre un único o un conjunto de nodos con la desventaja de menor durabilidad. Si W = 0, el cliente percibe una escritura más rápida, pero la durabilidad más baja posible ya que no hay confirmación de que la escritura fue exitosa. En el caso de W = 1, es suficiente con que un solo nodo persista la escritura para devolver al cliente, mejorando así la durabilidad en comparación con W = 0. De la misma manera es posible optimizar la lectura de datos. La configuración R = 0 no es una opción, ya que la misma operación de lectura confirma. Para alcanzar el rendimiento óptimo en la lectura, se puede usar R = 1. En algunas situaciones (por ejemplo, si se usa Read-repair), podría ser necesario leer desde todos los nodos, esto es R = N, y luego fusionar las diferentes versiones de los datos, lo que frena la mencionada operación. Un esquema intermedio para la escritura o lectura es el de quórum, en el que la operación (lectura o escritura) se realiza sobre un subconjunto de nodos. Con frecuencia, el valor utilizado para el quórum es de N/2 + 1, tal que 2 escrituras o lecturas subsecuentes comparten al menos un nodo. A.2 Bases de Datos Clave-Valor Las bases de datos que pertenecen a este grupo son, en esencia, tablas de hash distribuidas que proporcionan al menos dos operaciones: get(key) y put(key, value). Una base de datos ClaveValor mapea los ítems de datos a un espacio de claves que se utiliza tanto para la asignación de pares clave/valor a las computadoras como para localizar de manera eficiente un valor dada una clave. Estas bases de datos están diseñados para escalar a terabytes o incluso petabytes, así como para soportar millones de operaciones simultáneas agregando horizontalmente computadoras. Las siguientes secciones enumeran algunas de las técnicas utilizadas en las bases de datos Clave-Valor. En la Sección A.2.1 se introduce el concepto de hashing consistente (Consistent Hashing), un mecanismo utilizado con frecuencia para distribuir claves entre los nodos. En la Sección A.2.2 describimos Virtual Buckets, un mecanismo alternativo utilizado para distribuir A.2. BASES DE DATOS CLAVE-VALOR 175 of 206 APPENDIX A. BASES DE DATOS NOSQL las claves entre los nodos. En la Sección A.2.3, se describe un conjunto de técnicas utilizadas por Dynamo (DeCandia et al., 2007), una base Clave-Valor creada por Amazon que influyó en varias otras bases de datos. En la Sección A.2.4 se describen algunas de las bases de datos Clave-Valor más notorias disponibles. A.2.1 Hashing Consistente Las bases de datos Clave-Valor suelen asignar pares clave/valor mediante la aplicación de una función de hash para la clave y usando el resultado para obtener un equipo específico de la red física donde se almacena finalmente el valor. La distribución de claves utilizando un mecanismo de asignación de hash estándar (es decir, en base a la cantidad de equipos de la red) es sensible a la falla de los nodos, es decir, si uno de los nodos no está disponible, todos sus pares clave/valor necesita ser reasignado debido al cambio de tamaño de la red. Varias bases de datos aprovechan el concepto de Consistent Hashing (Karger et al., 1997) para hacer frente a esta situación. El hashing consistente modela un espacio de clave de tamaño K como un anillo, donde cada uno de los N nodos maneja una serie de claves contiguas. En su forma más simple, el hashing consistente asigna rangos de K/N claves de nodos, aunque los rangos pueden variar en función de las características de cada nodo. Si uno de los nodos en el anillo falla, las claves que pertenecen a tal nodo debe rebalancearse, poniéndolos en el siguiente nodo físico. Utilizando este esquema, la replicación de claves se puede realizar en los R nodos siguientes de cada nodo. El problema de usar nodos físicos para dividir el espacio de clave es que los cambios sucesivos en la red, tales como el fracaso o la adición de nuevos nodos pueden desequilibrar la distribución de claves entre los nodos. Este problema se acentúa aún más cuando la red tiene hardware heterogéneo, por ejemplo, si un nodo está sirviendo como failover de un nodo con mayor capacidad. Una mejora con respecto a este esquema de particionamiento es introduciendo nodos virtuales. Cada nodo físico puede ser responsable de uno o más nodos virtuales. Por lo tanto, cuando falla un nodo físico, sus nodos virtuales se asignan de manera uniforme a otros nodos físicos, balanceando la distribución de claves. Por otra parte, cuando se añade un nuevo nodo físico, se le asigna un conjunto de nodos virtuales, y por lo tanto, puede recibir rangos de claves de otros nodos físicos diferentes. La Figura A.1 muestra un ejemplo del uso de la distribución de nodos virtuales. Los nodos virtuales A, C y M se almacenan en el nodo físico 1, los nodos virtuales B, D y G en el nodo físico 2 y el nodo virtual E en el nodo físico 3. En este ejemplo, el nodo virtual A es responsable de almacenar las claves en el rango de (G, A]. Además, el nodo virtual A es responsable de la replicación de datos sobre las teclas en el rango precedente N − 1. Si N es igual a 2, A sería responsable de la replicación de las claves en el rango (F, G]. El resto de los nodos virtuales se comportan de manera similar. Si el nodo físico 2 falla, el rango de llaves (F, G] se vuelven parte del nodo virtual A, el rango (A, B] se mueve al nodo virtual C y el rango (C, D] al nodo virtual E. 176 of 206 A.2. BASES DE DATOS CLAVE-VALOR APPENDIX A. BASES DE DATOS NOSQL A G B Key Space C F E D Node 1: A, C, F Node 2: B, D, G Node 3: E Figure A.1: Ejemplo de hashing consistente con nodos virtuales. A continuación, el conjunto de claves se distribuye entre los nodos físicos 1 y 3. A.2.2 Virtual Buckets Como el hashing consistente, Virtual Buckets o vBuckets virtual es una técnica introducida por Couchbase para superar el problema de la redistribución de claves cuando un nodo falla o se añade un nuevo nodo. Al igual que en el hashing consistente, vBuckets proporcionan un nivel de indirección entre las llaves y las direcciones de los nodos. El objetivo de vBuckets es dividir el espacio de claves en una cantidad fija de vBuckets (por ejemplo, 4096) y mapear cada vBucket a un nodo. Desde una perspectiva de nodo, un vBucket puede estar en uno de tres estados: • Disponible: el nodo actual contiene los datos sobre el vBucket. • Réplica: el nodo actual sólo puede recibir solicitudes de réplica para el vBucket actual. • Muerto: el nodo no puede recibir solicitudes del vBucket. Desde la perspectiva del cliente, sólo un nodo puede servir las peticiones de un vBucket dado. Como resultado, los vBuckets disponibles se pueden replicar en otros nodos utilizando los vBuckets correspondientes marcados como muertos. De esta forma, la replicación se puede configurar en un 1 : N o una configuración en cadena. En el primer caso, cada vBucket se replica a N nodos. En el segundo, en una configuración encadenada, un vBucket replica a otro nodo, y a su vez, el vBucket replicado tiene una réplica en un tercer nodo. A.2. BASES DE DATOS CLAVE-VALOR 177 of 206 APPENDIX A. BASES DE DATOS NOSQL Node 1 Node 2 Node 3 A R A R R R A R R A R R R A R vBucket 1 vBucket 2 vBucket 3 vBucket 4 vBucket 5 Figure A.2: Ejemplo de Virtual Buckets usando 3 servidores, un vBucket de tamaño 5 y un esquema de replicación 1 : N. La Figura A.2 muestra un posible escenario de vBuckets donde la cantidad de vBuckets es 5 y el esquema de replicación es de 1 : N. Los vBuckets marcados como “A” son vBuckets disponibles, mientras que vBuckets marcados como “R” son réplicas. A.2.3 Mecanismos Basados en Dynamo Una de las bases de datos más influyentes en el desarrollo de bases de datos Clave-Valor altamente escalables es Dynamo (DeCandia et al., 2007) de Amazon. Dynamo fue diseñada para apoyar el servicio de gestión del carrito de compras y el servicio de administración de sesiones de Amazon, cada una manipulando decenas de millones de solicitudes. Esta base de datos resultó ser un sistema de alta disponibilidad, además de cumplir con los fuertes requisitos de latencia (DeCandia et al., 2007). Entonces, Dynamo ofrece mecanismos de almacenamiento de datos y de acceso que representan la inspiración de muchas bases de datos Clave-Valor existentes. Debajo se introducen las técnicas más importantes que intervienen en la ejecución de Dynamo: Vector Clocks Dynamo proporciona consistencia eventual, lo que permite lograr una alta disponibilidad. Las inconsistencias se resuelven durante la lectura (read-repair), lo que implica que una escritura puede volver al cliente antes de la escritura real se haya extendido a todas las réplicas. Los diferentes valores se unifican utilizando un esquema de control de versiones conocido como Vector Clocks (Baldoni and Klusch, 2002). Un vector clock es una estructura que contiene una lista de pares (nodo, contador). Un vector clock se asocia con todas las versiones de cada par clave/valor. Este esquema de control de versiones permite a los nodos descartar las viejas versiones de un mismo objeto (si todos los contadores son menos o igual que los contadores actuales), o conciliar versiones conflictivas. Este mecanismo de la conciliación puede ser automático, por ejemplo, diferentes versiones de un carrito de compras se pueden combinar añadiendo todos los artículos en un carro único, incluyendo los elementos eliminados por el 178 of 206 A.2. BASES DE DATOS CLAVE-VALOR APPENDIX A. BASES DE DATOS NOSQL usuario. Sloppy Quorum y Hinted Handoff Sloppy Quorum es una técnica de quórum que escribe o lee un elemento sobre los primeros N nodos disponibles de una lista de preferencia cuando las réplicas del nodo no están disponibles. A continuación, algunas copias de los datos a ser escritos se pueden encontrar en los nodos que no son réplicas de estos datos. Cuando se produce esta situación, el nodo recibe, junto con los datos, una pista sobre el propietario de la copia. Este mecanismo, conocido como Hinted Handoff, junto con Sloppy Quorum, permite al cliente volver lo antes posible, sin esperar a persistir datos en todas las réplicas. Árboles de Merkle Para fallas prolongadas en las que las copias hinted no pueden volver a la réplica original, elementos de las réplicas restantes deben ser re-sincronizados al detectar qué claves son obsoletas. Comparar las claves una por una de acuerdo a su valor de hash puede tardar mucho tiempo y consumir mucho ancho de banda. Dynamo utiliza una estructura de árbol conocido como Árbol de Merkle (Merkle, 2006) donde cada nodo representa un valor de hash, calculado a partir de sus hijos, que a su vez también son valores de hash. Las hojas del árbol son los valores de hash calculados usando las claves almacenadas. Esto permite una comparación rápida de los juegos de claves. Sin embargo, la actualización de un rango de claves cuando falla un nodo puede ser costoso. Dynamo implementa todos los conceptos descritos anteriormente para crear un sistema altamente escalable y disponible. Sin embargo, es un sistema patentado por Amazon y sólo se puede acceder a través de los servicios prestados por la empresa. Hay, sin embargo, varias implementaciones de código abierto de Dynamo y otras bases de datos de Clave-Valor que se pueden instalar en una red. La siguiente sección resume algunas de las bases de datos pertinentes en esta línea. A.2.4 Discusión de Base de Datos Clave-Valor La Tabla A.4 resume varias bases de datos Clave-Valor relevantes que soportan el almacenamiento persistente y la distribución. Otras bases de datos tales como Kyoto Gabinete4 , LevelDB, Memcached5 , BerkeleyDB (Olson et al., 1999) y Scalaris (Schutt et al., 2008) fueron excluidos de esta revisión, ya que no cumplen con estos requisitos. Las bases de datos listadas son Riak, Infinispan, Hazelcast, Redis, CouchBase and Voldemort. En el momento de escribir este trabajo, todas estas bases de datos estaban bajo desarrollo activo y siendo muy empleadas por alguna comunidad de usuarios. Esto significa que cada base de datos está soportada por un grupo de desarrolladores liberando actualizaciones periódicas, corrigiendo errores e incorporando nuevas funcionalidades. Dado que la adopción de una base de datos activa para un nuevo proyecto asegura la existencia de la documentación y la ayuda 4 Kyoto Cabinet Web Page, http://fallabs.com/kyotocabinet/ Web Page, http://memcached.org/ 5 Memcached A.2. BASES DE DATOS CLAVE-VALOR 179 of 206 APPENDIX A. BASES DE DATOS NOSQL de los responsables del software de base de datos, las bases de datos persistentes y distribuidas cuyo desarrollo ha sido abandonado no se incluyeron en la comparación. Las bases de datos Clave-Valor analizadas se describen a continuación: Riak y Voldemort Entre las bases de datos de la lista, las que están más relacionadas con Dynamo son Riak y Voldemort ya que son implementaciones directas de la especificación asociada de Amazon. Por lo tanto, utilizan hashing consistente para la partición y replicación, y proporcionan consistencia eventual basada en la read-repair. Redis Redis se distingue por proporcionar estructuras más complejas, tales como listas, tablas de hash, conjuntos y conjuntos ordenados para la representación de valores. Esta funcionalidad hace a Redis muy similar a las bases orientadas a documentos que se describen en la Sección A.4. Sin embargo, en Redis, claves diferentes pueden tener diferentes tipos de valores, es decir, una clave puede referirse a una lista y la otra clave se puede referir a un conjunto. En las bases de datos orientada a documentos, todos los valores son documentos de un mismo esquema. Una limitación de Redis es que el sharding debe realizarlo la aplicación cliente, lo que implica que el cliente debe conocer la topología de la red para distribuir las claves entre los nodos. Infinispan Infinispan, antes conocida como JBoss Cache, nació como una herramienta de apoyo para ampliar las aplicaciones Web y lograr la tolerancia a fallos en el conocido JBoss Application Server. En particular, JBoss Cache se utiliza para replicar y sincronizar el estado de una sesión entre los servidores de un cluster de servidores JBoss. La principal diferencia con otras bases de datos es que Infinispan tradicionalmente se ha inclinado hacia la consistencia y la disponibilidad, sacrificando la tolerancia a particiones. Hazelcast Hazelcast se diferencia del resto de las bases de datos Clave-Valor revisadas por su capacidad para integrarse con facilidad y sin problemas con los programas Java no distribuidos existentes. Para lograr esto, Hazelcast proporciona implementaciones distribuidas de las estructuras de datos Java típicas como Lista, Vector, Set y Hashtable. Luego, utilizar Hazelcast en un programa Java requiere la sustitución de importaciones, y luego afinar varios parámetros como nodos pertenecientes al cluster, modo de replicación, estructuras de datos distribuidas utilizadas, etc. Hazelcast no proporciona almacenamiento persistente por defecto, pero permite a los desarrolladores definir su soporte de almacenamiento propio, que puede ser persistente. Couchbase Couchbase utiliza el mecanismo de vBuckets para distribuir y replicar datos entre servidores. La consistencia de escritura es inmediata porque la escritura y la lectura siempre se llevan a cabo en el nodo principal de la clave (que tiene el único vBucket disponible). De este modo, el cliente siempre obtiene el último valor escrito. Una de las características más atractivas 180 of 206 A.2. BASES DE DATOS CLAVE-VALOR APPENDIX A. BASES DE DATOS NOSQL de Couchbase es su simplicidad de configuración. Una vez instalada en los nodos de la red se puede configurar a través de una interfaz Web amigable. En el lado negativo, Couchbase requiere reajuste manual de las claves cuando un servidor no funciona y necesita ser removido del cluster. El rebalanceo de claves es una operación costosa que depende de la cantidad de claves que maneja el servidor eliminado. Algunas bases de datos Clave-Valor mantienen un subconjunto de pares clave/valor almacenados en memoria RAM para mejorar el rendimiento de las consultas. De las bases de datos analizados en esta revisión, Hazelcast, Membase, Redis y Riak utilizan esta estrategia. Sin embargo, esta decisión tiene un costo: mientras el número de claves aumenta, aumenta el uso de memoria RAM. Riak y Membase siempre mantienen las claves en la memoria, mientras que los valores se eliminan de la memoria si se necesita espacio para las nuevas claves. Hazelcast y Redis mantienen todos los pares clave/valor en memoria y eventualmente los persisten en el disco. En todos los casos, las nuevas solicitudes para agregar claves son rechazadas cuando la memoria RAM se queda sin espacio. Por esta razón, es necesario tener en cuenta si el número de claves a ser almacenadas va a ser superior a la cantidad de RAM en la red y, si este es el caso, elegir otra alternativa o aumentar el tamaño de la red. Otra característica a tener en cuenta en la elección de una base de datos es la durabilidad de datos esperada. El nivel de durabilidad debe decidirse de acuerdo con la importancia de los datos almacenados en la red, que a veces se puede configurar. Redis es un caso de durabilidad configurable. Por defecto, Redis ofrece la posibilidad de hacer instantáneas de datos en memoria a intervalos de tiempo. Si se produce un fallo durante dicho intervalo, se pierden los datos actuales del nodo. Por esta razón, la base de datos ofrece a hacer escrituras más frecuentes en el disco en un archivo que sólo es compatible con appends, un concepto similar a un registro en un sistema de archivos de log estructurado. Este tipo de archivos se utiliza a menudo cuando se necesita un alto rendimiento en las escrituras. El método de consulta varía de base de datos a base de datos, pero la operación Get (es decir, obtener un valor para clave) está siempre presente. Algunos métodos de consulta alternativas son dignos de mención. Por ejemplo, Riak proporciona un método de consulta gráfico llamado Link Walking. Este método consiste en la creación de relaciones entre las claves y el etiquetado de cada relación. Por ejemplo, si existe una relación etiquetada “amigo” entre una clave denominada “Marcos” y todas las claves de sus amigos, se puede consultar en Riak con la etiqueta “amigo” para obtener todos los amigos de Mark. Otras bases de datos proporcionan métodos de consulta alternativas como Cursors (una estructura muy conocida en RDBMS), XQuery (un lenguaje de consulta XML) e incluso MapReduce (Sección A.3.1.3). Algunas bases de datos también permiten al usuario realizar bulk gets, es decir, obtener los valores de varias claves en una sola operación, resultando en una considerable mejora de rendimiento y ahorro en la comunicación de red. A.2. BASES DE DATOS CLAVE-VALOR 181 of 206 Persistencia Replicación Sharding Consistencia Lenguage de API Imple- Método de Consulta mentación Riak Bitcask (log-structured store), Anillo Consistent Consistencia LevelDB, In-Memory y (siguienteN − Hashing Eventual Multi-backend (diferentes 1) Erlang bases para diferentes clavess) PBC Get, (Protocol MapRe- Buffer duce, Link Client), Walking HTTP, Java, Erlang, C++, PHP, Ruby, Python Infinispan Simple File Storage, Anillo Consistent Consistencia BerkeleyDB, JDBM, JDBC (siguienteN − Hashing Fuerte o MapRe- Eventual duce, 1) Java HTTP, Java Get, A.2. BASES DE DATOS CLAVE-VALOR others. Hazelcast User-defined MapStore, que Anillo Consistent Consistencia puede ser persistente (siguienteN − Hashing Fuerte Java 1) HTTP, Get, Java, C# MapRe- and any duce Memcache client Redis Snapshots en tiempos Master-Slave No (a cargo de Consistencia especificados de intervalos por (se pueden la aplicación) Eventual defecto o un archivo formar cadenas Append-only. Ambos se de Slaves) C Java, C, Get (also C#, Ruby, depends on Perl, Scala the value structure) pueden combinar. Membase/ SQLLite or CouchDB CouchBase Voldemort vBuckets 1 : N vBuckets Replication Consistencia C/C++, Erlang Java, C, C# Get Java Java, Get Fuerte BerkeleyDB, In-Memory, Anillo Consistent Consistencia MySQL (siguiente Hashing Eventual N − 1) Table A.4: Comparación de bases de datos Clave-Valor. Python APPENDIX A. BASES DE DATOS NOSQL 182 of 206 Nombre APPENDIX A. BASES DE DATOS NOSQL A.3 Bases de Datos Orientadas a Columnas Las bases de datos orientadas a columnas o familias de columnas (Wide Column) almacenan los datos por columnas y no imponen un esquema rígido para los datos del usuario. Esto significa que algunas filas pueden o no tener columnas de un tipo determinado. Además, dado que los datos almacenados por columna tienen el mismo tipo de datos, algoritmos de compresión puede ser usado para disminuir el espacio requerido. También es posible hacer particionamiento funcional por columna de manera que las columnas que se utilizan frecuentemente se coloquen en la misma ubicación física. La mayoría de las bases de datos de esta categoría están inspirados en BigTable (Chang et al., 2008), una base de datos ordenada, multidimensional, dispersa, distribuida y persistente, que fue creada por Google para almacenar datos en el orden de petabytes. Una breve descripción de las características más importantes de BigTable y cómo logra sus objetivos se da en la siguiente sección. A diferencia de las bases de datos Clave-Valor, todas las bases de datos orientadas a columnas que figuran en esta sección se basan en los esquemas de datos o mecanismos de BigTable. Esta falta de diversidad se puede explicar por el hecho de que este tipo de bases de datos tiene un objetivo muy específico: almacenar terabytes de tuplas con columnas arbitrarias en un entorno distribuido. A.3.1 BigTable BigTable (Chang et al., 2008) fue desarrollada con el fin de dar cabida a la información de varios servicios de Google: Google Earth, Google Maps y Blogger, entre otros. Estas aplicaciones utilizan BigTable para diferentes propósitos, desde un alto rendimiento de procesamiento de trabajo por lotes hasta aprovisionamiento de datos para el usuario final teniendo en cuenta las limitaciones de latencia de datos. BigTable no proporciona un modelo relacional, lo que permite a la aplicación cliente tener un control completo sobre el formato de datos y su disposición. En BigTable, todos los datos son matrices de bytes indexados por columnas y filas, cuyos nombres pueden ser cadenas arbitrarias. Además, se añade una dimensión de timestamp a cada tabla para almacenar diferentes versiones de los datos, por ejemplo, el texto de una página Web. Por otra parte, las columnas se agrupan en conjuntos llamados familias de columnas. Por ejemplo, la familia de la columna curso puede tener las columnas Biología y Matemática, que se representan como curso:Biología y curso:Matemática. Las familias de columnas suelen tener el mismo tipo de datos, con el objetivo de ser comprimidos. Por otra parte, el acceso a memoria y disco se optimiza y controla de acuerdo a las familias de columnas. A.3. BASES DE DATOS ORIENTADAS A COLUMNAS 183 of 206 APPENDIX A. BASES DE DATOS NOSQL Table Tablet (Range Aaa-Car) SSTable Block 64K Block 64K Lookup Index ... ... Figure A.3: Estructuras SSTable, Tablet y Table. A.3.1.1 SSTable, Tablets y Tables BigTable trabaja sobre el sistema de archivos distribuido GFS (Google File System) (Ghemawat et al., 2003) y tiene tres tipos de estructuras de almacenamiento: SSTables, Tablets y Tables, que se muestran en la Figura A.3. SSTable es la estructura más básica, que ofrece un mapa de clave/valor ordenada de cadenas de bytes. Este bloque básico consiste en una secuencia de bloques (por lo general de 64 KB) y un índice de búsqueda para determinar qué bloque es un dato determinado, evitando la carga innecesaria de los otros bloques en memoria y la disminución de operaciones de disco. Cada SSTable es inmutable, por lo que no se necesita el control de concurrencia para la lectura. Se requiere un recolector de basura para liberar las SSTables eliminados. Un conjunto de SSTables se llama Tablet. Una Tablet es una estructura que agrupa una gama de claves y representa una unidad de distribución para equilibrar la carga. Cada tabla se compone de varias Tablets y, a medida que la tabla crece, se divide en más Tablets. Las sub-Tablets a menudo tienen un tamaño fijo de 100 a 200 MB. La ubicación de cada Tablet se almacena en los nodos de la red usando una estructura de árbol de tres niveles, como un árbol B+. La raíz del árbol es una Tablet especial llamada Root Tablet. Las hojas del árbol se llaman Metadata Tablets y son responsables de almacenar la ubicación de las Tables de usuario. Chubby (Burrows, 2006), un servicio de bloqueo distribuido, se utiliza para encontrar y acceder a cada Tablet de usuario. Chubby mantiene la ubicación de la Root Tablet, la información sobre el esquema de base de datos (las familias de las columnas y tablas) y listas de control de acceso. Además, sincroniza y detecta nodos Tablets (a.k.a. servidores) que almacenan Tablets. Un servidor maestro es el encargado de asignar las Tablets a los servidores Tablet. El servidor maestro supervisa la adición y expiración de los servidores de Tablet, equilibra la carga de tales servidores y lleva a cabo la recolección de basura de los archivos almacenados en el GFS. También supervisa los cambios en el esquema, es decir, el agregado de nuevas familias de columnas y Tables. 184 of 206 A.3. BASES DE DATOS ORIENTADAS A COLUMNAS APPENDIX A. BASES DE DATOS NOSQL Memtable read operation RAM GFS Commit log write operation SSTable SSTable SSTable Figure A.4: Diagrama operativo de un servidor de Tablet. A.3.1.2 Servidores de Tablets La Figura A.4 representa cómo se almacena una Tablet en un servidor de Tablets. Los cambios realizados en las Tablets pertenecientes a un servidor se almacenan en un registro Commit que guarda los registros para rehacer operaciones de commit en el caso de que el servidor de Tablets se caiga. Los registros más recientes se guardan en memoria en un buffer conocido como Memtable. Para obtener una Tablet el servidor lee desde una tabla llamada METADATA que contiene la lista de SSTables que forman una Tablet y un conjunto de punteros a los llamados puntos de redo. El servidor entonces aplica los cambios realizados a partir de los puntos de redo para reconstruir la memtable. Por último, para leer de una Tablet, el servidor de Tablets forma una vista combinada del conjunto de SSTables y la memtable. Para las operaciones de escritura, después de verificar que la operación está bien formada y que el usuario está autorizado (a través Chubby), una mutación válida (escribir, actualizar o eliminar) se registra en el Commit. Grupos de commits se utilizan para mejorar el rendimiento de pequeñas mutaciones. Después de hacer el commit, su contenido se inserta en la memtable. Si se sobrepasa un cierto límite de la memtable, se crea una nueva memtable y la memtable anterior se transforma en una SSTable. Para las operaciones de lectura, la buena formación y autorización también se comprueban, después de lo cual se le presenta al usuario una vista conjunta de la secuencia de SSTables y la memtable. Por lo tanto, las últimas actualizaciones se muestran al usuario sin mantener las últimas SSTables en disco. A.3.1.3 MapReduce y BigTable BigTable (y muchas otras bases de datos) soporta pasar datos a map jobs y almacenar datos de reduce jobs mediante la definición de contenedores de entrada y salida de MapReduce (Capítulo 3, Sección 3.1). De esta manera, los trabajos de MapReduce permiten consultar y transformar los A.3. BASES DE DATOS ORIENTADAS A COLUMNAS 185 of 206 APPENDIX A. BASES DE DATOS NOSQL datos almacenados en BigTable en paralelo, con la condición de que las consultas se puedan expresar en este paradigma. A.3.2 Lista de Bases de Datos Orientada a Columnas BigTable es un sistema utilizado internamente por Google, es decir, la comunidad no tiene acceso a su código fuente o ejecutables. Sin embargo, varias alternativas de código abierto que ofrecen servicios similares se desarrollaron en base a las publicaciones académicas realizadas por la empresa. La Tabla A.5 resume estas alternativas. La tabla compara HBase (George, 2011), Hypertable y Cassandra (Lakshman and Malik, 2010). La siguiente es una descripción de estas bases de datos: HBase y Hypertable HBase pertenece a Apache Software Foundation y se basa directamente en BigTable. El soporte de almacenamiento es HDFS (Hadoop Distributed File System) (Shvachko et al., 2010), que a su vez se basa en GFS. Del mismo modo, Hypertable también se basa en HDFS para el almacenamiento y la replicación. Ambas bases de datos permiten consultar la base de datos utilizando Hadoop MapReduce (Shvachko et al., 2010), una implementación de código abierto de Google MapReduce. Además, las consultas se realizan a través de lenguajes similares a Sawzall, tales como Pig (Gates et al., 2009) y Colmena (Thusoo et al., 2009). Las consultas también se pueden combinar con un sistema de scheduler de workflows como Apache Oozie (Islam et al., 2012), el cual permite la creación de DAGs (Grafos acíclicos dirigidos) de trabajos que obtienen datos de HDFS. Como desventaja, Hypertable o HBase, ambos basados en HDFS, tienen un único punto de fallo: el componente NameNode. Este componente es Master Server que administra el espacio de nombres del sistema de archivos y controla el acceso de los clientes. El inconveniente es que este componente es único para todo el sistema de archivos. La replicación del NameNode se puede hacer mediante cualquier software que puede copiar todas las escrituras a disco a un nodo espejo. Un ejemplo de este tipo de software es DRBD (Distributed Replicated Block Device), un sistema de reflejo distribuido análogo a RAID-1 array (Ellenberg, 2007). Cassandra Cassandra, que se mudó recientemente a la Apache Software Foundation, utiliza columnas y columnas familias para modelar los datos, pero se basa en técnicas de Dynamo para administrar el almacenamiento y replicación, como Consistent Hashing, Read-Repair, Vector Clocks, Gossip Protocol , entre otros mecanismos. A diferencia de HBase o Hypertable, Cassandra utiliza una arquitectura peer-to-peer basada, esencialmente, en el anillo de hashing consistente de nodos. Por lo tanto, Cassandra no expone un único punto de fallo, pero con el inconveniente de complicar la implementación del sistema. 186 of 206 A.3. BASES DE DATOS ORIENTADAS A COLUMNAS APPENDIX A. BASES DE DATOS NOSQL Su arquitectura en forma de anillo distribuye claves de acuerdo a una estrategia de partición. De hecho, Cassandra ofrece dos esquemas de particionamiento: Order Preserving Partitioning y Random Partitioning. Order Preserving Partitioning distribuye claves en el anillo, preservando su orden. Esto permite llevar a cabo de manera eficiente consultas de rango, es decir, obtener claves consecutivas. Sin embargo, este esquema de particionado tiende a desequilibrar la carga entre nodos, por ejemplo, las operaciones de escritura frecuentes en un rango de teclas puede caer en el mismo nodo. Este problema se traduce en una sobrecarga para tratar de distribuir los rangos de claves de acuerdo a sus patrones de acceso. Random Partitioning ayuda a equilibrar rangos de teclado, pero pierde el impulso de rendimiento de las consultas por rango. Para consultar Cassandra, un usuario puede utilizar un lenguaje de consulta SQL-Like llamado CQL (Cassandra Query Language) y Hadoop MapReduce para el procesamiento de trabajos distribuido. Es notable el reducido número de bases de datos de orientadas a columnas disponibles con respecto a otros tipos de bases de datos NoSQL. En principio, esto se puede atribuir a dos razones. En primer lugar, la complejidad en el desarrollo de dichas bases de datos es considerablemente alto. Considerando Bigtable, por ejemplo, se requiere un medio de almacenamiento como GFS, un servidor de bloqueo distribuido como Chubby y un servidor de Tables similar al Master Server. En segundo lugar, el dominio de aplicación de las bases de datos de orientadas a columnas se limita a problemas concretos: los datos que se almacenen necesitan ser estructurados y potencialmente alcanzar el orden de petabytes, pero la búsqueda sólo se puede hacer a través de la clave primaria, es decir, el ID de la fila. Después, las filas resultantes pueden ser filtradas por columna. Sin embargo, las consultas sobre determinadas columnas como clave principal no son factibles ya que esto implicaría tener un índice de todo el conjunto de datos o recorrerlo. A.3. BASES DE DATOS ORIENTADAS A COLUMNAS 187 of 206 Persistencia Replicación Sharding Consistencia Lenguage de API Imple- Método de Consulta mentación HBase HDFS Replicación Por rangos Consistencia HDFS de clave Fuerte Java Java, HTTP Hadoop + JSON, MapReduce, Avro, Pig, Hive Thrift (Slee et al., 2007) A.3. BASES DE DATOS ORIENTADAS A COLUMNAS Hypertable HDFS por Replicación Por rangos Consistencia defecto HDFS de clave Fuerte C++ Thrift HQL (Hypertable (otros Query soportes Language), disponibles) Hadoop MapReduce, Hive, Pig Cassandra Formato Anillo Consistent Consistencia propietario (siguiente Hashing Eventual Java Thrift N-1) CQL (Cassandra Query Language), Hadoop MapReduce, Pig, Hive Table A.5: Características de las bases de datos orientadas a columnas. APPENDIX A. BASES DE DATOS NOSQL 188 of 206 Nombre APPENDIX A. BASES DE DATOS NOSQL A.4 Bases de Datos Orientadas a Documentos Las bases de datos basadas orientadas a documentos pueden ser vistas como bases de datos de Clave-Valor donde cada valor tiene una estructura conocida, es decir, un documento. En contraste con las orientadas a columnas y las Clave-Valor, no hay un diseño de referencia para bases de datos orientadas a documentos (como BigTable o Dynamo), lo que se refleja en la diversidad de técnicas y tecnologías aplicadas por los proveedores de bases de datos. En este contexto, los documentos se entienden como tipos de datos semi-estructurados, es decir, no están totalmente estructurados como las tablas de una base de datos relacional, pero los nuevos campos se pueden añadir a la estructura de cada documento de acuerdo con ciertas reglas. Estas reglas se especifican en el formato estándar o codificación de los documentos almacenados. Algunos formatos de documentos populares son XML, JSON y BSON. Al igual que las bases de datos orientadas a columnas, las orientadas a documentos son sin esquema (schemaless), es decir, que no tienen un esquema de datos predefinidos al cual ajustarse. Entonces, el número y tipo de campos en los documentos en la misma base de datos pueden ser diferentes. Dado que la base de datos conoce el tipo de datos almacenados, las operaciones que no están disponibles en bases de datos Clave-Valor tradicionales se hacen posibles en bases de datos orientados a documentos. Entre estas operaciones podemos mencionar añadir y quitar campos de valor, modificar ciertos campos y consultar la base de datos de campos. Naturalmente, si una base de datos de Clave-Valor se utiliza para almacenar documentos, la adición, supresión y modificación de los campos implica la sustitución de todo el documento por un nuevo documento. Por el contrario, en una base de datos orientada a documentos se pueden realizar directamente las modificaciones al campo. En una base de datos de Clave-Valor, las consultas se realizan al proporcionar una o más claves como entrada. En las bases de datos orientadas a documentos a las consultas se pueden hacer sobre cualquier campo utilizando patrones. Entonces, rangos, operadores lógicos, comodines, y más, se pueden usar en las consultas. El inconveniente es que para cada tipo de consulta un nuevo índice tiene que ser creado, porque las bases de datos orientadas a documentos indexan elementos de acuerdo al identificador de documento. Una base de datos orientada a documentos es útil cuando el número de campos no puede ser plenamente decidido a la hora del diseño de la aplicación. Por ejemplo, en un sistema de gestión de imágenes, un documento podría escribirse en formato JSON de la siguiente manera: { route : / usr / images / img . png , owner : { name : Alejandro surname : Corbellini }, A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS 189 of 206 APPENDIX A. BASES DE DATOS NOSQL tags : [ sea , beach ] } Nuevas características se pueden añadir a medida que el sistema evoluciona. Por ejemplo, cuando se actualiza el documento anterior con la capacidad para acceder al propietario de la página, una checksum de la imagen y las calificaciones del usuario, el documento mencionado sería: { route : / usr / images / img . png , owner : { name : Alejandro surname : Corbellini web : www . alejandrocorbellini . com . ar }, tags : [ sea , beach ] , md5 : 123456789 abcdef123456789abcdef12 , ratings : [ { user : John Doe comment : Very good ! rating : 4 } ] } Nuevas tablas deben crearse para lograr el mismo objetivo en una base de datos relacional, que puede llevar a uniones entre tablas que contiene numerosas filas o modificar el esquema de tabla existente, actualizando todas las filas de la base de datos. En la Tabla A.6 se resumen las bases de datos orientadas a documento NoSQL más representativas actualmente disponibles: CouchDB (Lennon, 2009), MongoDB (Chodorow and Dirolf, 2010), Terrastore y RavenDB. A continuación se describen cada una de ellas: CouchDB CouchDB es una base de datos mantenida por la Fundación Apache y apoyada principalmente por dos empresas: Cloudant y Couchbase. Esta base de datos utiliza Multiple Version Concurrency Control (MVCC) (Bernstein and Goodman, 1981) para proporcionar acceso simultáneo a los documentos almacenados, un mecanismo que permite a varias versiones de un documento que coexisten en la base de datos (similar al concepto de branch en un sistema de control de versiones, Version Control System o VCS). Cada usuario que está editando un documento recibe una instantánea del documento actual y después de trabajar en él, se guarda una versión con el timestamp más reciente. Las versiones anteriores no se eliminan de modo que los lectores puedan seguir accediendo a ellos. Cuando un lector quiere acceder al documento, 190 of 206 A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS APPENDIX A. BASES DE DATOS NOSQL la base de datos resuelve cuál es la versión más nueva utilizando timestamps. Esta flexibilidad viene con un costo extra de espacio de almacenamiento y tiene la desventaja de que los conflictos entre versiones podrían surgir entre documentos. El último tema se suele resolver alertando al cliente que está tratando de escribir una versión en conflicto, al igual que lo haría un VCS. A diferencia de un VCS, la base de datos debe garantizar que los documentos obsoletos se limpian periódicamente, es decir, aquellos que no están en uso y corresponden a las versiones anteriores. CouchDB proporciona transacciones ACID por documento serializando operaciones realizadas por los clientes y nunca sobrescribiendo documentos en el disco. La replicación sigue el modelo Master-Master, es decir, las réplicas también sirven las peticiones de los clientes, tanto para escritura como para lectura. El objetivo es que los nodos de servidor puedan ser distribuidos entre las diferentes redes y los clientes puedan escribir o leer desde los servidores más cercanos. Las actualizaciones entre réplicas son bidireccionales y, si hay fallos en la red, la sincronización espera a que la conectividad sea restablecida. Este enfoque puede resultar en clientes leyendo documentos antiguos de réplicas que no han recibido las actualizaciones todavía. Para consultar los documentos, CouchDB utiliza el concepto de puntos de vista, que se tomó prestado de RDBMS. Estas estructuras se definen en JavaScript y visualiza contenidos estructurados recogidos de los documentos. Una vista realiza una operación equivalente a la función de map de MapReduce, pero no se lleva a cabo de una manera distribuida. Hay extensiones, sin embargo, que permiten usar CouchDB en un cluster de computadoras, como BigCouch6 , Salón 7 y Pillow (Holt, 2011). Además, algunas de estas extensiones proporcionan una técnica automática de sharding tales como Consistent Hashing (Sección A.2.1). MongoDB MongoDB es una base de datos libre orientada a documentos que se ejecuta en una amplia gama de plataformas. Los documentos en MongoDB están codificados en BSON, una versión binaria JSON. BSON ofrece lectura más rápida y requiere menos espacio que JSON. Para lograr el anterior objetivo, BSON utiliza prefijos que indican el tamaño de cada elemento y su posición. Sin embargo, los documentos BSON tienen un límite de espacio de hasta 16 MB, aunque archivos de más de 16 MB se puede almacenar en GridFS (Bhardwaj and Sinha, 2006), un sistema de archivos distribuido diseñado especialmente para archivos de gran tamaño. Respecto del sharding de datos MongoDB integra la funcionalidad para la distribución de datos y consultas a través de los diferentes nodos. Para este propósito, la base de datos utiliza un router para las consultas, llamado Mongo, que distribuye uniformemente consultas a los nodos para equilibrar la carga del cluster. Para consultas más simples, MongoDB proporciona un find() API que recibe un documento BSON como parámetro y resalta aquellos documentos que coinciden con los campos correspondientes. Entonces, estos documentos se recorren mediante un cursor que visita cada documento que coincide con la consulta como en un RDBMS. Para consultas 6 BigCouch 7 Lounge Web Page, http://bigcouch.cloudant.com/ Web Page, http://tilgovi.github.io/couchdb-lounge/ A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS 191 of 206 APPENDIX A. BASES DE DATOS NOSQL más avanzadas, que requieren agrupar los datos pertenecientes a varios documentos, MongoDB puede ejecutar trabajos de MapReduce. La replicación en MongoDB se puede lograr a través del esquema clásico Master-Slave, sino que también introduce una alternativa conocida como Replica Sets. Al igual que en un esquema Master-Slave, Replica Sets permiten a los nodos replicados agruparse, ofreciendo también recuperación automática a fallas. Uno de los nodos en el conjunto es conocido como el nodo principal y los restantes son nodos secundarios. Opcionalmente, la lectura se puede realizar a partir de los nodos secundarios equilibrando la carga sobre los Replica Sets, pero reduciendo el nivel de consistencia con respecto al nodo primario. El objetivo de los Replica Sets es mejorar el esquema Master-Slave llano, facilitando el mantenimiento del cluster. MongoDB ofrece operaciones atómicas por documento que significa que, cuando un documento se actualiza utilizando operaciones atómicas, la base de datos asegura que la operación tendrá éxito o fallará sin dejar inconsistencias. A diferencia de CouchDB, MongoDB no ofrece MVCC, mediante el cual las lecturas pueden ser bloqueadas hasta que se completen las operaciones atómicas. Terrastore Otra alternativa para el almacenamiento de documentos de una manera distribuida es Terrastore. Esta base de datos se basa en Terracotta (Terracotta et al., 2008), un framework de aplicaciones distribuidas basado en Java. Los documentos deben seguir la notación JSON y pueden accederse directamente tanto a través de HTTP o clientes específicos en Java, Clojure y Scala, entre otros. Como MongoDB, Terrastore ha integrado el soporte a sharding. Terracota replica los datos utilizando un enfoque Master-Slave, donde los esclavos se mantienen en hot-standby, es decir, pueden sustituir el maestro en cualquier momento si se produce un error. Las operaciones de Terracota son consistentes a nivel de documento y la concurrencia se maneja con la estrategia read-commit. Los write-locks se utilizan a lo largo de una transacción de escritura, pero las lecturas solamente se bloquean para cada consulta o SELECT permitiendo separadamente alternar operaciones de lectura y escritura. Como resultado de esta estrategia, puede ser posible que durante una transacción de una lectura devuelve un valor, se modifica el documento y luego una lectura idéntica dentro de la transacción devuelve un valor diferente. RavenDB RavenDB es una base de datos de documentos alternativa desarrollada para la plataforma .Net. Aunque implementada en C #, sino que también proporciona una interfaz HTTP para acceder a la base de datos de otros idiomas. Las transacciones ACID son soportadas, pero RavenDB se basa en un esquema de transacciones optimista para evitar el uso extensivo de locks. La consulta en RavenDB es compatible a través de LINQ, un lenguaje de consulta desarrollado por Microsoft con una sintaxis similar a SQL. En las consultas en LINQ se pueden definir campos libres que se pueden pasar como parámetros por parte del usuario, filtrando los documentos 192 of 206 A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS APPENDIX A. BASES DE DATOS NOSQL indexados. Una característica que diferencia RavenDB de otras bases de datos orientados a documentos es el mecanismo para configurar el sharding de documentos. Aunque el soporte al sharding está integrado, no es automático. El cliente de la base de datos debe definir los fragmentos y estrategias para distribuir los documentos a través de los diferentes nodos de la red. A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS 193 of 206 Persistencia Replicación Sharding Consistencia Leng. API Método de Consuta Impl. CouchDB CouchDB Storage Master-Master. Engine (B-Tree) MongoDB A.4. BASES DE DATOS ORIENTADAS A DOCUMENTOS Terrastore HTTP + JSON, y Vistas usando extensiones a No, pero hay Consistencia Eventual Erlang clientes para JavaScript + CouchDB que diferentes lenguages MapReduce permiten sharding (incluyendo Java) Objetos BSON o Replica Sets (sets de Por campo, que puede Consistencia estricta C++ Mongo Wire Protocol Queries per field, GridFS para archivos Master-Slaves) o ser cualquier campo por defecto pero se + BSON, HTTP + Cursors and grandes simplemente en la colección de puede relajar a JSON, and clients for MapReduce Master-Slave documentos Consistencia Eventual Soporte de Master-Slave con N Consistent Hashing Consistencia Eventual most languages Java HTTP + JSON, y Consultas almacenamiento réplica en clientes para algunos condicionales, Terrastore hot-standby. lenguajes (Java, consultas por rango, Clojure (Hickey, Predicates, 2008), MapReduce Scala (Odersky et al., 2004)) RavenDB Microsoft’s ESE Master-Slave sobre Permite al usuario (Extensible Storage N-réplica. definir una función de Engine) Consistencia Eventual C# HTTP + JSON, .Net sharding basada en los campos de los documentos Table A.6: Comparación de bases de datos orientadas a documentos. LINQ APPENDIX A. BASES DE DATOS NOSQL 194 of 206 Nombre Bibliografía Aasman, J. (2006). Allegro graph: RDF triple database. Technical report, Technical Report 1, Franz Incorporated. Adamic, L. A. and Adar, E. (2003). Friends and neighbors on the Web. Social Networks, 25(3):211–230. Adomavicius, G. and Tuzhilin, A. (2005). Toward the next generation of recommender systems: A survey of the state-of-the-art and possible extensions. IEEE Transactions on Knowledge and Data Engineering, 17(6):734–749. Aggarwal, C. C., editor (2011). Social Network Data Analytics. Springer. Armentano, M., Godoy, D., and Amandi, A. (2011). Towards a followee recommender system for information seeking users in Twitter. In Proceedings of the International Workshop on Semantic Adaptive Social Web (SASWeb’11), volume 730 of CEUR Workshop Proceedings, Girona, Spain. Armentano, M., Godoy, D., and Amandi, A. (2013). Followee recommendation in Twitter based on text analysis of micro-blogging activity. Information Systems, 38(8):1116–1127. Armentano, M. G., Godoy, D., and Amandi, A. (2012). Topology-based recommendation of users in micro-blogging communities. Journal of Computer Science and Technology, 27(3):624–634. Backstrom, L. and Leskovec, J. (2011). Supervised random walks: Predicting and recommending links in social networks. In Proceedings of the 4th ACM International Conference on Web Search and Data Mining (WSDM ’11), pages 635–644, Hong Kong, China. Bahmani, B., Chakrabarti, K., and Xin, D. (2011). Fast personalized PageRank on MapReduce. In Proceedings of the 2011 ACM SIGMOD International Conference on Management of Data (SIGMOD ’11), pages 973–984, Athens, Greece. ACM. Baldoni, R. and Klusch, M. (2002). Fundamentals of distributed computing: A practical tour of vector clock systems. IEEE Distributed Systems Online, 3(2). Bao, J., Zheng, Y., Wilkie, D., and Mokbel, M. (2015). Recommendations in location-based social networks: A survey. Geoinformatica, 19(3):525–565. Barabási, A.-L. and Albert, R. (1999). Emergence of scaling in random networks. Science, 286(5439):509–512. 195 of 206 BIBLIOGRAFÍA Bello-Orgaz, G., Jung, J. J., and Camacho, D. (2016). Social big data: Recent achievements and new challenges. Information Fusion, 28:45–59. Berners-Lee, T., Hendler, J., and Lassila, O. (2001). The Semantic Web. Scientific American, 284(5):28–37. Bernstein, P. A. and Goodman, N. (1981). Concurrency control in distributed database systems. ACM Computing Surveys, 13(2):185–221. Bhardwaj, D. and Sinha, M. K. (2006). GridFS: Highly scalable I/O solution for clusters and computational grids. International Journal of Computational Science and Engineering, 2(5):287–291. Blumofe, R. D. and Leiserson, C. E. (1999). Scheduling multithreaded computations by work stealing. Journal of the ACM, 46(5):720–748. Bobadilla, J., Ortega, F., Hernando, A., Abraham, and Gutiérrez (2013). Recommender systems survey. Knowledge Based Systems, 46:109–132. Bollacker, K., Evans, C., Paritosh, P., Sturge, T., and Taylor, J. (2008). Freebase: A collaboratively created graph database for structuring human knowledge. In Proceedings of the 2008 ACM SIGMOD International Conference on Management of Data (SIGMOD ’08), pages 1247–1250, Vancouver, Canada. ACM. Bray, T., Paoli, J., Sperberg-McQueen, C. M., Maler, E., and Yergeau, F. (1997). Extensible markup language (XML). World Wide Web Journal, 2(4):27–66. Burrows, M. (2006). The Chubby lock service for loosely-coupled distributed systems. In Proceedings of the 7th Symposium on Operating Systems Design and Implementation (OSDI ’06), pages 335–350, Seattle, WA, USA. Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P., and Stal, M. (1996). Pattern-oriented software architecture: A system of patterns. John Wiley and Sons. Cao, L., Cho, B., Kim, H. D., Li, Z., Tsai, M.-H., and Gupta, I. (2012). Delta-SimRank computing on MapReduce. In Proceedings of the 1st International Workshop on Big Data, Streams and Heterogeneous Source Mining: Algorithms, Systems, Programming Models and Applications (BigMine ’12), pages 28–35, Beijing, China. ACM. Carullo, G., Castiglione, A., Santis, A. D., and Palmieri, F. (2015). A triadic closure and homophily-based recommendation system for online social networks. World Wide Web, 18(6):1579–1601. Cattell, R. (2011). Scalable SQL and NoSQL data stores. ACM SIGMOD Record, 39(4):12–27. Chang, F., Dean, J., Ghemawat, S., Hsieh, W. C., Wallach, D. A., Burrows, M., Chandra, T., Fikes, A., and Gruber, R. E. (2008). Bigtable: A distributed storage system for structured data. ACM Transactions on Computer Systems, 26(2):1–26. Chen, H., Cui, X., and Jin, H. (2016). Top-k followee recommendation over microblogging systems by exploiting diverse information sources. Future Generation Computer Systems, 55:534–543. 196 of 206 BIBLIOGRAFÍA BIBLIOGRAFÍA Chodorow, K. and Dirolf, M. (2010). MongoDB: The definitive guide. O’Reilly Media. Corbellini, A. (2015). A distributed platform to ease the development of recommendation algorithms on large-scale graphs. In Proceedings of the 24th International Conference on Artificial Intelligence, Doctoral Consortium, pages 4353–4354. AAAI Press. Corbellini, A., Diaz, C. M., Godoy, D., Zunino, A., and Schiaffino, S. (2015a). An evaluation of distributed processing models for random walk-based link prediction algorithms over social big data. In 4th World Conference on Information Systems and Technologies, Recife, Brazil. Corbellini, A., Godoy, D., Diaz, C. M., Schiaffino, S., and Zunino, A. (2013). Supporting the efficient exploration of large-scale social networks for recommendation. In Proceedings of the II Brazilian Workshop on Social Network Analysis and Mining (BraSNAM 2013), pages 1469–1474, Maceió, AL, Brazil. Corbellini, A., Godoy, D., Mateos, C., Zunino, A., and Schiaffino, S. (2014). A programming interface and platform support for developing recommendation algorithms on large-scale social networks. In Proceedings of the 20th International Conference on Collaboration and Technology (CRIWG 2014), volume 8658 of LNCS, pages 67–74. Springer, Santiago, Chile. Corbellini, A., Godoy, D., and Schiaffino, S. (2012). Can your friends help you to find interesting multimedia content on web 2.0? In Advances in New Technologies, Interactive Interfaces and Communicability, pages 253–261. Springer. Corbellini, A., Mateos, C., Godoy, D., Zunino, A., and Schiaffino, S. (2015b). An architecture and platform for developing distributed recommendation algorithms on large-scale social networks. Journal of Information Science, 41(5):686–704. Crockford, D. (2006). JSON: The fat-free alternative to XML. In Proceedings of XML 2006, volume 2006. da Silva Maciel, L. A. H. and Hirata, C. M. (2010). A timestamp-based two phase commit protocol for Web services using REST architectural style. Journal of Web Engineering, 9(3):266– 282. Dean, J. and Ghemawat, S. (2008). MapReduce: Simplified data processing on large clusters. Communications of the ACM, 51(1):107–113. DeCandia, G., Hastorun, D., Jampani, M., Kakulapati, G., Lakshman, A., Pilchin, A., Sivasubramanian, S., Vosshall, P., and Vogels, W. (2007). Dynamo: Amazon’s highly available key-value store. ACM SIGOPS Operating Systems Review, 41(6):205–220. del Castillo, J. M. M., Peis, E., Ruiz, A. A., and Herrera-Viedma, E. (2010). Recommending biomedical resources: A fuzzy linguistic approach based on Semantic Web. International Journal of Intelligent Systems, 25(12):1143–1157. Deng, Z., He, B., Yu, C., and Chen, Y. (2012). Personalized friend recommendation in social network based on clustering method. In Proceedings of the 6th International Symposium on Intelligence Computation and Applications (ISICA 2012), pages 84–91, Wuhan, China. BIBLIOGRAFÍA 197 of 206 BIBLIOGRAFÍA Desikan, P., Pathak, N., Srivastava, J., and Kumar, V. (2005). Incremental page rank computation on evolving graphs. In Special interest tracks and posters of the 14th International Conference on World Wide Web, pages 1094–1095. ACM. Desrosiers, C. and Karypis, G. (2011). Recommender Systems Handbook, chapter A Comprehensive Survey of Neighborhood-based Recommendation Methods, pages 107–144. Springer. Durand, G., Belacel, N., and LaPlante, F. (2013). Graph theory based model for learning path recommendation. Information Sciences, 251:10–21. Ellenberg, L. (2007). DRBD 8.0.x and beyond: Shared-disk semantics on a shared-nothing cluster. LinuxConf Europe. Erling, O. and Mikhailov, I. (2010). Virtuoso: RDF support in a native RDBMS. In Semantic Web Information Management, pages 501–519. Springer. Faralli, S., Stilo, G., and Velardi, P. (2015a). Large scale homophily analysis in twitter using a twixonomy. In Proceedings of the 24th International Conference on Artificial Intelligence (IJCAI 2015), pages 2334–2340, Buenos Aires, Argentina. AAAI Press. Faralli, S., Stilo, G., and Velardi, P. (2015b). Recommendation of microblog users based on hierarchical interest profiles. Social Network Analysis and Mining, 5(1):1–23. Fouss, F., Pirotte, A., Renders, J.-M., and Saerens, M. (2007). Random-walk computation of similarities between nodes of a graph with application to collaborative recommendation. IEEE Transactions on Knowledge and Data Engineering, 19(3):355–369. Garcia, R. and Amatriain, X. (2010). Weighted content based methods for recommending connections in online social networks. In Proceedings of the 2nd ACM Workshop on Recommender Systems and the Social Web, pages 68–71, Barcelona, Spain. Gates, A. F., Natkovich, O., Chopra, S., Kamath, P., Narayanamurthy, S. M., Olston, C., Reed, B., Srinivasan, S., and Srivastava, U. (2009). Building a high-level dataflow system on top of Map-Reduce: The Pig experience. Proceedings of the VLDB Endowment, 2(2):1414–1425. George, L. (2011). HBase: The Definitive Guide. O’Reilly Media, Inc. Getoor, L. and Diehl, C. P. (2005). Link mining: A survey. ACM SIGKDD Explorations Newsletter, 7(2):3–12. Ghemawat, S., Gobioff, H., and Leung, S.-T. (2003). The Google file system. In Proceedings of the 9th ACM Symposium on Operating Systems Principles (SOSP ’03), volume 37, pages 29–43, Bolton Landing, NY, USA. Gilbert, S. and Lynch, N. (2002). Brewer’s conjecture and the feasibility of consistent, available, partition-tolerant web services. SIGACT News, 33(2):51–59. Godoy, D. and Corbellini, A. (2015). Folksonomy-based recommender systems: A state-of-theart review. International Journal of Intelligent Systems. In press. Goel, A., Gupta, P., Sirois, J., Wang, D., Sharma, A., and Gurumurthy, S. (2015). The Who-ToFollow system at Twitter: Strategy, algorithms, and revenue impact. Interfaces, 45(1):98–107. 198 of 206 BIBLIOGRAFÍA BIBLIOGRAFÍA Goff, M. (2003). Network distributed computing: fitscapes and fallacies. Prentice Hall Professional Technical Reference. Goldberg, D., Nichols, D., Oki, B. M., and Terry, D. (1992). Using collaborative filtering to weave an information tapestry. Communications of the ACM, 35(12):61–70. Gonzalez, J. E., Low, Y., Gu, H., Bickson, D., and Guestrin, C. (2012). PowerGraph: Distributed graph-parallel computation on natural graphs. In Proceedings of the 10th USENIX conference on Operating Systems Design and Implementation (OSDI’12), pages 17–30, Hollywood, CA, USA. Gray, J. and Reuter, A. (1992). Transaction Processing: Concepts and Techniques. Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 1st edition. Guo, X. and Lu, J. (2007). Intelligent e-government services with personalized recommendation techniques. International Journal of Intelligent Systems, 22(5):401–417. Gupta, P., Goel, A., Lin, J., Sharma, A., Wang, D., and Zadeh, R. (2013). WTF: The who to follow service at Twitter. In Proceedings of the 22th International World Wide Web Conference (WWW 2013), pages 505–514, Rio de Janeiro, Brazil. Han, M. and Daudjee, K. (2015). Giraph unchained: Barrierless asynchronous parallel execution in Pregel-like graph processing systems. Proceedings of the VLDB Endowment, 8(9):950–961. Hannon, J., Bennett, M., and Smyth, B. (2010). Recommending Twitter users to follow using content and collaborative filtering approaches. In Proceedings of the Fourth ACM Conference on Recommender Systems (RecSys ’10), pages 199–206, Barcelona, Spain. Hannon, J., McCarthy, K., and Smyth, B. (2011). Finding useful users on twitter: Twittomender the followee recommender. In Advances in Information Retrieval, volume 6611 of LNCS, pages 784–787. Springer. Harth, A., Umbrich, J., Hogan, A., and Decker, S. (2007). YARS2: A federated repository for querying graph structured data from the Web. In The Semantic Web, volume 4825, pages 211–224. Springer. Hasan, M. A., Chaoji, V., Salem, S., and Zaki, M. (2006). Link prediction using supervised learning. In Proceedings of SDM’06 Workshop on Link Analysis, Counter terrorism and Security, Bethesda, USA. Hecht, R. and Jablonski, S. (2011). NoSQL evaluation: A use case oriented survey. In IEEE International Conference on Cloud and Service Computing (CSC 2011), pages 336–341, Hong Kong, China. Heidemann, J., Klier, M., and Probst, F. (2012). Online social networks: A survey of a global phenomenon. Computer Networks, 56(18):3866–3878. Hickey, R. (2008). The Clojure programming language. In Proceedings of the 2008 Symposium on Dynamic Languages (DLS ’08), pages 1:1–1:1, Paphos, Cyprus. Holt, B. (2011). Scaling CouchDB. Oreilly & Associates Inc. BIBLIOGRAFÍA 199 of 206 BIBLIOGRAFÍA Iordanov, B. (2010). HyperGraphDB: A generalized graph database. In Web-Age Information Management, volume 6185 of LNCS, pages 25–36. Springer. Islam, M., Huang, A. K., Battisha, M., Chiang, M., Srinivasan, S., Peters, C., Neumann, A., and Abdelnur, A. (2012). Oozie: Towards a scalable workflow management system for Hadoop. In Proceedings of the 1st ACM SIGMOD Workshop on Scalable Workflow Execution Engines and Technologies (SWEET ’12), pages 4:1–4:10, Scottsdale, AZ, USA. ACM. Jaccard, P. (1901). Etude comparative de la distribution florale dans une portion des alpes et des jura. Bulletin de la Societe Vaudoise des Science Naturelles, 37(142):547–579. James, A. and Cooper, J. (2009). Challenges for database management in the Internet of Things. IETE Technical Review, 26(5):320–329. Java, A., Song, X., Finin, T., and Tseng, B. (2007). Why we Twitter: Understanding microblogging usage and communities. In Proceedings of the 9th WebKDD and 1st SNA-KDD 2007 Workshop on Web Mining and Social Network Analysis (WebKDD/SNA-KDD ’07), pages 56– 65, San Jose, CA, USA. Jeffery, K. (2009). The Internet of Things: The death of a traditional database? IETE Technical Review, 26(5):313–319. Jeh, G. and Widom, J. (2002). SimRank: A measure of structural-context similarity. In Proceedings of the Eighth ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (KDD’02), pages 538–543, Edmonton, AB, Canada. Jing, Y., Zhang, X., Wu, L., Wang, J., Feng, Z., and Wang, D. (2014). Recommendation on Flickr by combining community user ratings and item importance. In Proceedings of the IEEE International Conference on Multimedia and Expo (ICME 2014), pages 1–6, Chengdu, China. Kang, U., Meeder, B., Papalexakis, E. E., and Faloutsos, C. (2014). Heigen: Spectral analysis for billion-scale graphs. IEEE Transactions on Knowledge and Data Engineering, 26(2):350– 362. Kang, U., Tong, H., Sun, J., Lin, C.-Y., and Faloutsos, C. (2011). GBASE: A scalable and general graph management system. In Proceedings of the 17th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (KDD’11), pages 1091–1099. ACM. Karger, D., Lehman, E., Leighton, T., Panigrahy, R., Levine, M., and Lewin, D. (1997). Consistent hashing and random trees: Distributed caching protocols for relieving hot spots on the World Wide Web. In Proceedings of the 29th Annual ACM Symposium on Theory of Computing (STOC ’97), pages 654–663, El Paso, TX, USA. Katz, L. (1953). A new status index derived from sociometric analysis. Psychmetrika, 18(1):39– 43. Kim, J.-K., Shivle, S., Siegel, H. J., Maciejewski, A. A., Braun, T. D., Schneider, M., Tideman, S., Chitta, R., Dilmaghani, R. B., Joshi, R., Kaul, A., Sharma, A., Sripada, S., Vangari, P., and Yellampalli, S. S. (2003). Dynamic mapping in a heterogeneous environment with tasks 200 of 206 BIBLIOGRAFÍA BIBLIOGRAFÍA having priorities and multiple deadlines. In Proceedings of the International Parallel and Distributed Processing Symposium (IPDPS’03), Nice, France. Klein, D. J. and Randić, M. (1993). Resistance distance. Journal of Mathematical Chemistry, 12(1):81–95. Kleinberg, J. M. (1999). Authoritative sources in a hyperlinked environment. Journal of the ACM, 46(5):604–632. Krepska, E., Kielmann, T., Fokkink, W., and Bal, H. (2011). HipG: Parallel processing of largescale graphs. ACM SIGOPS Operating Systems Review, 45(2):3–13. Krishnamurthy, B., Gill, P., and Arlitt, M. (2008). A few chirps about Twitter. In Proceedings of the 1st Workshop on Online Social Networks (WOSP’08), pages 19–24, Seattle, WA, USA. Kwak, H., Lee, C., Park, H., and Moon, S. (2010). What is Twitter, a social network or a news media? In Proceedings of the 19th International Conference on World Wide Web (WWW’10), pages 591–600, Raleigh, NC, USA. Lakshman, A. and Malik, P. (2010). Cassandra: A decentralized structured storage system. ACM SIGOPS Operating Systems Review, 44(2):35–40. Leavitt, N. (2010). Will NoSQL databases live up to their promise? Computer, 43(2):12–14. Leicht, E. A., Holme, P., and Newman, M. E. J. (2006). Vertex similarity in networks. Physical Review E, 73(2):026120. Lempel, R. and Moran, S. (2001). SALSA: The stochastic approach for link-structure analysis. ACM Transactions on Information Systems, 19(2):131–160. Lennon, J. (2009). Introduction to CouchDB. In Beginning CouchDB, pages 3–9. Springer. Liben-Nowell, D. and Kleinberg, J. (2007). The link-prediction problem for social networks. Journal of the American Society for Information Science and Technology, 58(7):1019–1031. Liu, W. and Lü, L. (2010). Link prediction based on local random walk. Europhysics Letters, 89(5):58007. Lops, P., de Gemmis, M., and Semeraro, G. (2010). Recommender Systems Handbook, chapter Content-based Recommender Systems: State of the Art and Trends, pages 73–105. Springer. Low, Y., Bickson, D., Gonzalez, J., Guestrin, C., Kyrola, A., and Hellerstein, J. M. (2012). Distributed GraphLab: A framework for machine learning and data mining in the cloud. Proceedings of the VLDB Endowment, 5(8):716–727. Lü, L., Jin, C.-H., and Zhou, T. (2009). Similarity index based on local paths for link prediction of complex networks. Physical Review E, 80(4):046122. Lu, L. and Zhou, T. (2011). Link prediction in complex networks: A survey. Physica A: Statistical Mechanics and its Applications, 390(6):1150–1170. BIBLIOGRAFÍA 201 of 206 BIBLIOGRAFÍA Malarvannan, M. and Ramaswamy, S. (2010). Rapid scalability of complex and dynamic Webbased systems: Challenges and recent approaches to mitigation. In Proceedings of the 5th International Conference on System of Systems Engineering (SoSE 2010), pages 1–6. Malewicz, G., Austern, M. H., Bik, A. J. C., Dehnert, J. C., Horn, I., Leiser, N., and Czajkowski, G. (2010). Pregel: A system for large-scale graph processing. In Proceedings of the 2010 International Conference on Management of Data (SIGMOD ’10), pages 135–146, Indianapolis, IN, USA. Marchioni, F. (2012). Infinispan Data Grid Platform. Packt Pub Limited. Mateos, C., Zunino, A., and Campo, M. (2010). An approach for non-intrusively adding malleable fork/join parallelism into ordinary JavaBean compliant applications. Computer Languages, Systems & Structures, 36(3):288–315. Mazhari, S., Fakhrahmad, S. M., and Sadeghbeygi, H. (2015). A user-profile-based friendship recommendation solution in social networks. Journal of Information Science, 41(3):284–295. Membrey, P., Plugge, E., and Hawkins, T. (2010). The Definitive Guide to MongoDB: The NoSQL database for cloud and desktop computing. Springer. Merkle, R. (2006). A digital signature based on a conventional encryption function. In Pomerance, C., editor, Advances in Cryptology (CRYPTO ’87), volume 293 of LNCS, pages 369–378. Springer. Meyer, S. M., Degener, J., Giannandrea, J., and Michener, B. (2010). Optimizing schemalast tuple-store queries in Graphd. In Proceedings of the 2010 International Conference on Management of Data (SIGMOD ’10), pages 1047–1056, Indianapolis, IN, USA. Moricz, M., Dosbayev, Y., and Berlyant, M. (2010). PYMK: Friend recommendation at Myspace. In Proceedings of the 2010 ACM SIGMOD International Conference on Management of Data (SIGMOD ’10), pages 999–1002, Indianapolis, IN, USA. Najork, M. a. (2007). Comparing the effectiveness of HITS and SALSA. In Proceedings of the 16th ACM Conference on Conference on Information and Knowledge Management (CIKM ’07), pages 157–164, Lisbon, Portugal. ACM. Neary, M. O. and Cappello, P. (2005). Advanced eager scheduling for java-based adaptive parallel computing. Concurrency and Computation: Practice and Experience, 17(7-8):797–819. Newman, M. E. and Park, J. (2003). Why social networks are different from other types of networks. Physical Review E, 68(3):036122. Nieuwpoort, R. V. V., Wrzesińska, G., Jacobs, C. J. H., and Bal, H. E. (2010). Satin: A highlevel and efficient grid programming model. ACM Transactions on Programming Languages and Systems, 32(3):9:1–9:39. Odersky, M., Altherr, P., Cremet, V., Emir, B., Micheloud, S., Mihaylov, N., Schinz, M., Stenman, E., and Zenger, M. (2004). The Scala language specification. http://www. scala-lang.org/docu/files/ScalaReference.pdf. 202 of 206 BIBLIOGRAFÍA BIBLIOGRAFÍA Olson, M. A., Bostic, K., and Seltzer, M. (1999). Berkeley DB. In Proceedings of the FREENIX Track: 1999 USENIX Annual Technical Conference, pages 183–192. Orend, K. (2010). Analysis and classification of NoSQL databases and evaluation of their ability to replace an object-relational persistence layer. Master’s thesis, Technische Universität München. Page, L., Brin, S., Motwani, R., and Winograd, T. (1999). The PageRank citation ranking: Bringing order to the Web. Technical Report 1999-66, Stanford InfoLab. Papadimitriou, A., Symeonidis, P., and Manolopoulos, Y. (2011). Friendlink: Link prediction in social networks via bounded local path traversal. In Proceedings of the 2011 International Conference on Computational Aspects of Social Networks (CASoN), pages 66–71, Salamanca, Spain. Papadimitriou, A., Symeonidis, P., and Manolopoulos, Y. (2012). Scalable link prediction in social networks based on local graph characteristics. In Proceedings of the 9th International Conference on Information Technology: New Generations (ITNG), pages 738–743, Thessaloniki, Greece. Pritchett, S. (2008). BASE: An Acid alternative. ACM Queue, 6(3):48–55. Prud’Hommeaux, E. and Seaborne, A. (2008). SPARQL query language for RDF. W3C Recommendation. Rakesh, V., Singh, D., Vinzamuri, B., and Reddy, C. K. (2014). Personalized recommendation of Twitter lists using content and network information. In Proceedings of the 8th International AAAI Conference on Weblogs and Social Media (ICWSM 2014), Ann Arbor, MI, USA. Rausch, K., Ntoutsi, E., Stefanidis, K., and Kriegel, H.-P. (2014). Exploring subspace clustering for recommendations. In Proceedings of the 26th International Conference on Scientific and Statistical Database Management (SSDBM ’14), pages 42:1–42:4, Aalborg, Denmark. Ravasz, E., Somera, A. L., Mongru, D. A., Oltvai, Z. N., and Barabási, A.-L. (2002). Hierarchical organization of modularity in metabolic networks. Science, 297(5586):1551–1555. Resnick, P., Iacovou, N., Suchak, M., Bergstrom, P., and Riedl, J. (1994). GroupLens: An open architecture for collaborative filtering of Netnews. In Proceedings of the 1994 ACM Conference on Computer Supported Cooperative Work (CSCW ’94), pages 175–186, Chapel Hill, NC, USA. Ricci, F., Rokach, L., and Shapira, B. (2010). Recommender Systems Handbook, chapter Introduction to Recommender Systems Handbook, pages 1–35. Springer. Rodriguez, J. M., Mateos, C., and Zunino, A. (2014). Energy-efficient job stealing for CPUintensive processing in mobile devices. Computing, 96(2):1–31. Romero, D. M. and Kleinberg, J. M. (2010). The directed closure process in hybrid socialinformation networks, with an analysis of link formation on Twitter. In Proceedings of the 4th International Conference on Weblogs and Social Media (ICWSM 2010), Washington, DC, USA. BIBLIOGRAFÍA 203 of 206 BIBLIOGRAFÍA Rosinha, R. B., Geyer, C. F. R., and Vargas, P. K. (2009). WSPE: A peer-to-peer grid programming environment. Concurrency and Computation: Practice and Experience, 21(13):1709– 1724. Rowe, M., Stankovic, M., and Alani, H. (2012). Who will follow whom? exploiting semantics for link prediction in attention-information networks. In The Semantic Web - ISWC 2012, volume 7649 of LNCS, pages 476–491. Sakr, S., Elnikety, S., and He, Y. (2014). Hybrid query execution engine for large attributed graphs. Information Systems, 41:45–73. Salton, G. and McGill, M. J. (1983). Introduction to Modern Information Retrieval. McGrawHill. Schall, D. (2013). Who to follow recommendation in large-scale online development communities. Information and Software Technology, 56(12):1543–1555. Schall, D. (2015). Social Network-Based Recommender Systems. Springer. Schutt, T., Schintke, F., and Reinefeld, A. (2008). Scalaris: Reliable transactional p2p key/value store. In Proceedings of the 7th ACM SIGPLAN Workshop on ERLANG (ERLANG ’08), pages 41–48, Victoria, BC, Canada. Shao, B., Wang, H., and Li, Y. (2012). The Trinity Graph Engine. Technical Report MSR-TR2012-30, Microsoft Research. Shardanand, U. and Maes, P. (1995). Social information filtering: Algorithms for automating “Word of Mouth”. In Proceedings of the SIGCHI Conference on Human Factors in Computing Systems (CHI ’95), pages 210–217, Denver, CO, USA. Shvachko, K., Kuang, H., Radia, S., and Chansler, R. (2010). The Hadoop distributed file system. In Proceedings of the 26th IEEE Symposium on Mass Storage Systems and Technologies (MSST 2010), pages 1–10, Incline Village, NV, USA. Slee, M., Agarwal, A., and Kwiatkowski, M. (2007). Thrift: Scalable cross-language services implementation. Facebook White Paper, 5. Sørensen, T. (1948). A method of establishing groups of equal amplitude in plant sociology based on similarity of species and its application to analyses of the vegetation on danish commons. Kongelige Danske Videnskabernes Selskab, 5(4):1–34. Stonebraker, M. and Cattell, R. (2011). 10 rules for scalable performance in ’simple operation’ datastores. Communications of the ACM, 54(6):72–80. Strozzi, C. (1998). NoSQL relational database management system: Home page. http://www. strozzi.it/cgi-bin/CSA/tw7/I/en_US/nosql/Home-Page. Accessed: 05-07-2013. Sun, A. R., Cheng, J., and Zeng, D. D. (2009). A novel recommendation framework for microblogging based on information diffusion. In Proceedings of the 19th Annual Workshop on Information Technolgies & Systems (WITS’09). 204 of 206 BIBLIOGRAFÍA BIBLIOGRAFÍA Tang, J., Zhang, C., Cai, K., Zhang, L., and Su, Z. (2015). Sampling representative users from large social networks. In Proceedings of the 29th AAAI Conference on Artificial Intelligence, pages 304–310, Austin, TX, USA. Terracotta, I. et al. (2008). The Definitive Guide to Terracotta: Cluster the JVM for Spring, Hibernate and POJO Scalability: Cluster the JVM for Spring, Hibernate and POJO Scalability. Apress. Thusoo, A., Sen, J. S., Jain, N., Shao, Z., Chakka, P., Anthony, S., Liu, H., Wyckoff, P., and Murthy, R. (2009). Hive: A warehousing solution over a map-reduce framework. Proceedings of the VLDB Endowment, 2(2):1626–1629. Tommasel, A., Corbellini, A., Godoy, D., and Schiaffino, S. (2015). Exploring the role of personality traits in followee recommendation. Online Information Review, 39(6):812–830. Topcuoglu, H., Hariri, S., and you Wu, M. (2002). Performance-effective and low-complexity task scheduling for heterogeneous computing. IEEE Transactions on Parallel and Distributed Systems, 13(3):260–274. Tudorica, B. G. and Bucur, C. (2011). A comparison between several NoSQL databases with comments and notes. In Proceedings of the 10th Roedunet International Conference (RoEduNet 2011), pages 1–5. Valiant, L. G. (1990). A bridging model for parallel computation. Communications of the ACM, 33(8):103–111. Valverde-Rebaza, J. C. and de Andrade Lopes, A. (2013). Exploiting behaviors of communities of twitter users for link prediction. Social Network Analysis and Mining, 3(4):1063–1074. Vogels, W. (2009). Eventually consistent. Communications of the ACM, 52(1):40–44. Wan, S., Lan, Y., Guo, J., Fan, C., and Cheng, X. (2013). Informational friend recommendation in social media. In Proceedings of the 36th International ACM SIGIR Conference on Research and Development in Information Retrieval (SIGIR ’13), pages 1045–1048, Dublin, Ireland. Wang, P., Xu, B., Wu, Y., and Zhou, X. (2015). Link prediction in social networks: The stateof-the-art. Science China Information Sciences, 58(1):1–38. Wang, T., Chen, Y., Zhang, Z., Xu, T., Jin, L., Hui, P., Deng, B., and Li, X. (2011). Understanding graph sampling algorithms for social network analysis. In Proceedings of the 2011 31st International Conference on Distributed Computing Systems Workshops (ICDCSW ’11), pages 123–128, Minneapolis, MN, USA. IEEE. Wang, X., Ma, J., and Xu, M. (2014). Group recommendation for Flickr images by 4-order tensor decomposition. Journal of Computational Information Systems, 10(3):1315–1322. Weng, J., Lim, E.-P., Jiang, J., and He, Q. (2010). TwitterRank: finding topic-sensitive influential twitterers. In Proceedings of the 3rd ACM International Conference on Web Search and Data Mining (WSDM’10), pages 261–270, New York, NY, USA. BIBLIOGRAFÍA 205 of 206 BIBLIOGRAFÍA Xie, X. (2010). Potential friend recommendation in online social network. In Proceedings of the IEEE/ACM International Conference on Cyber, Physical and Social Computing (CPSCom) and Green Computing and Communications (GreenCom), pages 831–835, Hangzhou, China. Xin, R. S., Gonzalez, J. E., Franklin, M. J., and Stoica, I. (2013). GraphX: A resilient distributed graph system on Spark. In Proceedings of the 1st International Workshop on Graph Data Management Experiences and Systems (GRADES ’13), pages 2:1–2:6, New York, NY, USA. Yamaguchi, Y., Takahashi, T., Amagasa, T., and Kitagawa, H. (2010). TURank: Twitter user ranking based on user-tweet graph analysis. In Web Information Systems Engineering, volume 6488 of LNCS, pages 240–253. Springer, Hong Kong, China. Yin, D., Hong, L., and Davison, B. D. (2011). Structural link analysis and prediction in microblogs. In Proceedings of the 20th ACM International Conference on Information and Knowledge Management (CIKM ’11), pages 1163–1168, lasgow, Scotland, UK. ACM. Ying, J. J.-C., Lu, E. H.-C., and Tseng, V. S. (2012). Followee recommendation in asymmetrical location-based social networks. In Proceedings of the 2012 ACM Conference on Ubiquitous Computing (UbiComp ’12), pages 988–995, Pittsburgh, USA. Yu, W., Lin, X., and Zhang, W. (2014). Fast incremental SimRank on link-evolving graphs. In Proceedings of the IEEE 30th International Conference on Data Engineering (ICDE 2014), pages 304–315, Chicago, IL, USA. IEEE. Yu, Y. and Qiu, R. G. (2014). Followee recommendation in microblog using matrix factorization model with structural regularization. The Scientific World Journal, page Article ID 420841. Zaharia, M., Chowdhury, M., Das, T., Dave, A., Ma, J., McCauley, M., Franklin, M. J., Shenker, S., and Stoica, I. (2012). Resilient distributed datasets: A fault-tolerant abstraction for inmemory cluster computing. In Proceedings of the 9th USENIX conference on Networked Systems Design and Implementation (NSDI’12), pages 2–2, San Jose, CA, USA. USENIX Association. Zhang, B.-Y., Yang, G.-W., and Zheng, W.-M. (2006). Jcluster: An efficient java parallel environment on a large-scale heterogeneous cluster. Concurrency and Computation: Practice and Experience, 18(12):1541–1557. Zhao, G., Lee, M. L., Hsu, W., Chen, W., and Hu, H. (2013). Community-based user recommendation in uni-directional social networks. In Proceedings of the 22Nd ACM International Conference on Conference on Information and Knowledge Management (CIKM ’13), pages 189–198, San Francisco, CA, USA. Zhou, T., Lü, L., and Zhang, Y.-C. (2009). Predicting missing links via local information. The European Physical Journal B, 71(4):623–630. Zikopoulos, P. and Eaton, C. (2011). Understanding big data: Analytics for enterprise class Hadoop and streaming data. McGraw-Hill Osborne Media. 206 of 206 BIBLIOGRAFÍA