波克城市 x NebulaGraph|高效数据血缘系统在游戏领域的构建实战

news2024/11/19 13:32:43

关于波克城市和作者‍‍

波克城市,一家专注于研发精品休闲游戏的全球化公司,连续七年入选中国互联网综合实力百强,2023 年位列 17 位。波克城市旗下拥有《捕鱼达人》《猫咪公寓2》等精品休闲游戏,全球注册用户超 5 亿,月活 6000 万,其中 70% 来源于海外,产品发行范围覆盖全球 200 多个国家和地区。

作者潘长江,波克大数据团队成员,自 2022 年起专注于图数据分析,其在风控和数据血缘管理等关键业务场景的应用实践,有效推动了业务的显著增长和效率提升。

图片

一、业务背景

随着公司的持续发展和扩张,所涉及的项目日益增多,相应的数据积累也在持续上升。在这一过程中,数据表及其需要计算的数据指标数量也在急剧增加,数据结构变得愈加复杂和杂乱。

为了应对这一挑战,建立一个有效的数据血缘系统显得尤为必要。数据血缘系统能够追踪数据的来源、流向以及其间的变化过程,这对于维护数据质量、确保数据的可追溯性和透明性至关重要。通过构建数据血缘系统,我们能够实现对数据流转全过程的监控和管理,从而提高数据治理的效率和精确度。

  • 数据血缘系统的建设有助于清晰地识别数据之间的依赖关系和影响范围。在数据出现问题时,可以快速定位问题源头,有效减少错误诊断和修复的时间,保证业务的连续性和数据的准确性。

  • 数据血缘分析为数据管理提供了透明度,使得数据的利用更加合规,尤其是在遵守日益严格的数据保护法规(如 GDPR 或 CCPA)的背景下。

  • 数据血缘系统通过详细记录数据的每一次处理和传输,增强了数据安全性,让我们能够对潜在的数据泄露和非授权访问进行有效预防。通过这种方式,数据血缘系统不仅提升了数据的可用性和可靠性,也增强了企业对数据资产的掌控能力,从而支撑了数据驱动决策的实施,提升了企业的竞争力。

二、技术选型

在深入的技术选型过程中,我们主要对比了两款领先的图数据库:Neo4j 和 NebulaGraph。两者都采用属性图数据模型,允许我们存储丰富的实体属性和关系信息。这种模型特别适合用于表现和查询复杂的数据关系,这是数据血缘追踪所必需的。

Neo4j 作为一款老牌图数据库,提供了强大的社区支持和成熟的技术生态,其查询语言 Cypher 也被广泛认可和使用。然而,Neo4j 在大规模数据处理和分布式扩展性方面存在一定的局限性。尽管最新的版本有所改进,但在面对极大规模数据时,其性能可能会受到影响。

相比之下,NebulaGraph 作为一款新兴的开源的分布式图数据库,展现出了在大规模数据集上的卓越性能。NebulaGraph 采用 shared-nothing 架构,提供了在线水平扩缩容的能力,这使得它在处理千亿节点和万亿条边的超大规模图时仍能保持低延迟的查询响应。

此外,NebulaGraph 的兼容性设计,如支持 openCypher 查询语言,使得在这方面的学习成本大大降低。

在综合考虑了性能、后续的扩展性、易用性以及成本效益之后,我们得出结论:NebulaGraph 更适合我们当前及未来的业务需求。

NebulaGraph 不仅在技术层面满足了我们对大规模图数据处理的需要,而且在成本控制和团队技能转移方面也显示出了明显的优势。

因此,我们选择 NebulaGraph 作为构建数据血缘系统的理想图数据库解决方案。

三、踩坑总结

Part.01 环境搭建阶段

问题:搭完环境尝试执行 insert 语句时报错:Error: Storage Error: RPC failure, probably timeout.

检查集群中各节点的状态,未发现任何异常

图片

图片

在每个节点上分别查看 NebulaGraph 的运行状态,发现有两个节点的服务没有正常启动。

图片

图片

进一步查看报错的执行日志,发现是接口被占用了,但 netstat 命令查看 占用接口的进程就是 Nebula。

图片

解决方案:

手动终止进程,再重启 Nebula 服务,数据可以正常写入,并且各个节点状态正常。

因为我这个 Nebula 环境是卸载后重装的,推测是在卸载之前,原来的进程没有杀干净,导致占用了接口,新安装的无法正常启动。

NebulaGraph 一定要每个节点逐个关闭并卸载。

Part.02数据写入阶段

问题1:VID问题

在 NebulaGraph 中,点的唯一标识 VID,支持两种数据类型,分别是定长字符串 FIXED_STRING()和 INT64。其中整数 VID 通常比字符串类型更高效,因为整数的处理速度更快,占用空间更少。在本数据血缘项目中,由于是表级别的数据血缘,所以是库名+表名 唯一确定一张表,很明显这是字符串类型。

在测试环境下,由于预装了 Spark 环境,所以考虑借助 NebulaGraph 提供的 Spark 连接器完成数据写入。对于 VID 问题,由于希望实现幂等写入,因此不考虑雪花 ID 等实现方案,而是考虑借助 Java 中自带的 hashCode() 方法生成 VID。

图片

上述方案在测试环境中能行得通,但是在正式环境下却无法实现,正式环境下并没有预装的 Spark 环境,因而在正式环境下,考虑使用 Python 连接器,拼接 insert 语句,批量将数据写入图库。最开始考虑与 Spark 环境下相同的方案生成 VID,但经测试发现,Python 中的生成 Hash ID 的方法多次执行,生成的 Hash ID 不一样(Python 3.3及以上版本引入了 hash 随机化机制)。

解决方案

考虑仿照 Java 中 hashCode 的生成方式在 Python 中实现类似功能:

def hashCode(value):
    h = 0
    for c in value:
        h = (31 * h + ord(c)) & 0xFFFFFFFF
    return h if h < 0x80000000 else h - 0x100000000

但执行上述代码发现,在 Python 中并没有类似 Java 中的截断机制,以上面生成的 ID 作为 VID 写入图库中时,会出现超出数据范围的错误。
最终,在正式环境下,将 VID 类型修改为定长字符串 FIXED_STRING(128),以 库名+表名的拼接作为 VID。

图片

问题2:SQL拼接问题

使用拼接 insert 语句的方式进行数据写入时,最为关键的一环就是 SQL 语句的生成。在本系统中表的生成 SQL 将作为节点属性存入图库中,由于 SQL 中本身就会有一些特殊符号,如, " ’ \ / $ 等等,这些特殊结构在 insert 语句的拼接过程中需要格外注意【PS:NebulaGraph 以后要是能多加一个 text 类型就好了,可以忽略字符串中本身存在的一些特殊格式,防止出现一些意外的错误】

图片

并且一些空值也要注意,Python 中的空值用 None 表示而在 NebulaGraph 则使用 NULL 表示,如果不进行转换,对于字符串类型的字段还是可以正常写入的,但是对于数字类型的则会报错。

图片

一些特殊格式如 datetime 类型,不能以字符串格式直接写入,需要在写入时增加手动转换操作。

图片

Part.03数据查询阶段

问题:后端反应图库查询速度慢

解决方案:增加针对常用查询字段的联合索引+优化查询语句,把多条查询压缩为一条查询。

最有效的优化方案:增加针对常用查询字段的联合索引,增加之后查询速度提高了100多倍。

CREATE TAG INDEX IF NOT EXISTS database_index_0 on table_node(database_name(15), table_name(20));REBUILD TAG INDEX database_index_0;

图片

速度提升非常明显。

优化 nGQL 的写法,将多次查询优化为一条,如查询当前节点、当前节点的上游以及当前节点的下游,原来的三个查询可以压缩为一条查询,有效提高查询速度。

MATCH
  // 查询指定节点及其属性
  (n:table_node{database_name:"byhls_ods",table_name:"app_login_log"}) AS target_node,

  // 查询该节点的所有上游节点(边的起始点)
  (upstream:table_node)-[:has_consanguinity]->(n) AS upstream_nodes,

  // 查询该节点的所有下游节点(边的终点)
  (n)-[:has_consanguinity]->(downstream:table_node) AS downstream_nodes

RETURN
  target_node.database_name AS database_name,
  target_node.table_name AS table_name,
  COLLECT(DISTINCT upstream) AS upstream_nodes,
  COLLECT(DISTINCT downstream) AS downstream_nodes

四、总结反思

目前项目处在起步阶段,很多功能还没有加,后续考虑应用 NebulaGraph 中自带的图计算功能,增加最优路径检索,核心度计算等功能,充分挖掘 NebulaGraph 的潜力。

如果你觉得 NebulaGraph能帮到你,或者你只是单纯支持开源精神,可以在 GitHub 上为 NebulaGraph 点个 Star!每一个 Star 都是对我们的支持和鼓励✨

https://github.com/vesoft-inc/nebula

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2132639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AB 1756-L62 与 AB 5069 通过串口通信

PLC AB L62 控制器 插槽2 Path, RS232=2, 3 PLC Compactlogix 5069-SERIAL 配置

【提示词】浅谈GPT等大模型中的Prompt

Prompt是人工智能&#xff08;AI&#xff09;提示词&#xff0c;是一种利用自然语言来指导或激发人工智能模型完成特定任务的方法。在AI语境中&#xff0c;Prompt是一种自然语言输入&#xff0c;通常指的是向模型提出的一个请求或问题&#xff0c;这个请求或问题的形式和内容会…

【QT】系统-上

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;事件QWidget中常见的事件 &#x1f449;&#x1f3fb;处理鼠标事件&#xff1a;leaveEvent和enterEvent&#x1f449;&a…

epoll接口使用 -- 非阻塞式网络io(仅读事件)

目录 epoll接口使用 思路 注意点 代码 封装epoll接口 epoll.sever.hpp 运行结果 epoll接口使用 接口epoll原理介绍 -- epoll接口介绍,epoll模型介绍原理,接口和模型的关系,epoll优点(和select/poll进行对比)-CSDN博客 思路 我们可以先将系统提供的epoll简单封装一下…

Java 入门指南:Java 并发编程模式 —— 生产者-消费者模式

文章目录 生产者-消费者问题解决方案 生产者-消费者模式模式的核心问题基本原理生产者消费者 优点实现方式使用阻塞队列示例代码 使用 wait/notify 机制wait()notify()notifyAll()示例代码 使用 Exchanger示例代码 应用场景总结 生产者-消费者问题 生产者消费者问题是一个经典…

Java项目: 基于SpringBoot+mybatis+maven旅游管理系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven旅游管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

【SqlServer】SQL Server Management Studio (SSMS) 下载、安装、配置使用及卸载——保姆级教程

超详细的 SQL Server Management Studio (SSMS) 下载、安装、连接数据库配置及卸载教程 SQL Server Management Studio (SSMS) 是微软提供的图形化管理工具&#xff0c;主要用于连接、管理和开发 SQL Server 数据库。以下是详细的 SSMS 下载、安装、连接数据库以及卸载的完整教…

CLIP:Learning Transferable Visual Models From Natural Language Supervision

论文:https://arxiv.org/abs/2103.00020 代码:https://github.com/openai/CLIP 官博:https://openai.com/index/clip/ 复现:https://github.com/mlfoundations/open_clip 基础知识 InfoNCE loss

S7-1500T分布式同步功能

1. 功能描述工控人加入PLC工业自动化精英社群 在一些实际应用中&#xff0c;会需要很多轴进行同步运行&#xff0c;如印刷机、纸尿裤生产线等。由于一个 PLC 的运动控制资源有限&#xff0c;控制轴的数量也是有限的&#xff0c;就会需要多个 PLC 间协调实现轴工艺对象的跨CPU的…

使用Cerbot---Let’s Encrypt生成免费的ssl证书,并设置自动更新证书

安装Certbot客户端 yum install certbot 获取证书 certbot certonly --webroot -w /var/www/demo.com -d demo.com 按照步骤 输入邮箱 同意条例 成功申请证书 修改对应的nginx的conf文件 server {listen 80;listen [::]:80;server_name demo.com;# 将 HTTP 请求重定向到 H…

分布式事务学习笔记(一)分布式事务问题、CAP定理、BASE理论、Seata

文章目录 1 分布式事务问题1.1 本地事务1.2 分布式事务1.3 创建分布式事务演示案例 2 理论基础2.1 CAP定理2.2 BASE理论2.3 解决分布式事务的思路2.4 Seata 1 分布式事务问题 1.1 本地事务 本地事务&#xff0c;也就是传统的单机事务&#xff0c;它必须要满足以下四个原则&am…

RabbitMQ延迟消息——DelayExchange插件

什么是死信以及死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff1a; 1. 消费者使用basic.reject或 basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false 2. 消息是一个过期消息&#xff0c;超时无人消费 3. 要投递的队列消…

【JavaSE】--方法的使用

文章目录 1. 方法概念及使用1.1 什么是方法1.2 方法定义1.3 方法调用的执行过程1.4 实参和形参的关系&#xff08;重要&#xff09;1.5 没有返回值的方法 2. 方法重载2.1 方法重载概念2.2 方法签名 3. 递归3.1 递归的概念3.2 递归执行过程分析3.3 递归练习 1. 方法概念及使用 1…

解码3D数字人及AIGC产品,如何赋能医美行业全场景业务增长

9月13日&#xff0c;第六届“医美小小聚”暨医美信息与服务创新发展大会在热烈的氛围中拉开帷幕。此次盛会汇聚了医美行业的顶尖精英与前瞻者&#xff0c;他们围绕“聚焦营销&#xff0c;合规增长&#xff0c;融合共创”的主题&#xff0c;深入剖析了行业的新趋势、新机遇与新挑…

SpringBoot开发——整合SSL证书启用HTTPS协议

文章目录 1、https协议2、SpringBoot项目启用HTTPS协议过程2.1 创建SpringBoot项目2.2 准备SSL证书2.3SpringBoot设置2.4启动项目 1、https协议 网站使用的协议包括&#xff1a;http协议和https协议。http协议就是网址以http://开头的&#xff0c;https协议就是网址以https://…

http连接github远程仓库密码问题解决办法

目录 一、问题&#xff1a;使用http连接失败 二、解决办法&#xff1a;使用个人访问令牌。 1、生成访问令牌&#xff1a; 步骤 1: 登录 GitHub 步骤 2: 进入设置页面 步骤 3: 生成新的访问令牌 步骤 4: 配置访问令牌 步骤 5: 复制令牌 2. 使用访问令牌 一、问题&#…

从卷积的物理意义出发的第二种卷积计算方法

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;电子信息前沿技术丛书&#xff09;》P78 第一&#xff0c;从物理意义理解卷积&#xff0c;为什么要卷&#xff0c;为什么要积。全名卷积和&#xff0c;先卷&#xff0c;再积&#xff0c;后和。 第二&#xff0c;这种方式计算节…

类加载机制和双亲委派

打印一个类加载器的示例。 import java.net.URL; import sun.misc.Launcher;public class TestJDKClassLoader {public static void main(String[] args) {System.out.println(String.class.getClassLoader());System.out.println(com.sun.crypto.provider.DESKeyFactory.clas…

Mysql 搭建主从复制

Docker Mysql 镜像启动命令(主库) docker run --name mysql-master -ti -d --privileged"true" -p 3306:3306 alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/mysql_optimized:20240221-8.0.32-2.3.0 mysql_keentune.sh 修改临时密码 如果您…

OpenCV 4.10 windows 上编译并上传conan

目录 一. 上传opencv 预编译包 二. 自己手动写一个测试包并上传 三. 自己写一个app, 引用包 一. 上传opencv 预编译包 1. 下载Opencv, 并用cmake 打开 打开工程之后&#xff0c;编译&#xff0c;install&#xff0c; 目录如下 2. 准备conan 包 把Debug 和 Release 分开放 3…