RedisGraph的整体架构

The architecture of RedisGraph

本文关注RedisGraph的整体架构,分别从图存储模型、索引、并发控制、和执行计划四个方面简要阐述。下图为RedisGraph的整体架构图。

1 图存储模型

了解一个图数据库的架构,最重要的就是其图存储模型,即其中的图数据是怎么组织和存储的。

首先,在一个图数据库中,必不可少的数据是:节点的属性(node attribute)以及节点之间的关系(edge)。比如说,图数据库中有两个节点node1{name: 小明}、node1{name: 小红},两者存在朋友关系,那么,就需要存储node1和node2的name属性,以及node1和node2之间的朋友关系。除此之外,RedisGraph还支持存储节点之间的关系的属性(edge attribute),比如,存储node1和node2朋友关系的建立时间。

在RedisGraph中,node attribute和edge attribute存储在Block数组中,而节点之间的关系使用邻接矩阵进行存储。值得注意的是,node的数量与邻接矩阵的维数是一致的。每一个节点都有一个node_id(≥ 0),节点属性存储在Block数组node_id偏移地址(nodes[node_id])处,节点的下一跳信息存储在邻接矩阵(adjacency)的第node_id行。显而易见,这样做的目的是,快速索引节点属性和下一跳信息。

对于节点间关系的存储,RedisGraph不仅仅使用了邻接矩阵。为了方便快速查询,还是用了label矩阵(labels)和relation矩阵(relations)。为了适应类型化节点,每个标签分配一个额外的矩阵,即label矩阵。每个类型的关系都有自己的专用矩阵,即relation矩阵。

2 索引

RedisGraph中并没有索引的代码实现,其使用RediSearch搜索引擎来构造索引,并且,RedisGraph仅仅支持哈希索引。RedisGraph中的索引分为两种:exact match index和full-text index。本文只关注exact match index。

  • 为什么要建立索引?

    我们来看一个cypher查询:

    GRAPH.QUERY DEMO_GRAPH "MATCH (n:作品)-[]-(m:角色) where m.name='郭靖' return n.name"
    

    这个查询仅仅涉及name=‘郭靖’,如果没有在角色: name上建立索引,RedisGraph只能是扫描一遍Block数组,进行字符串匹配,来找出name='郭靖’的节点。显然,这效率低下。

  • 索引的key和value是什么?

    以一个在节点属性上建立索引的cypher为例进行分析:

    GRAPH.QUERY DEMO_GRAPH "CREATE INDEX ON :角色(name)"
    

    RedisGraph在执行这个请求后,就会在角色的name属性上建立索引。

    索引的key是name属性;value是node_id。通过node_id,就可以在Block数组中查询节点属性,在矩阵中查询下一跳信息。

    同样,如果在关系的属性上建立索引,那么,索引的key是属性;value是edge_id。

3 并发控制

RedisGraph内创建有两个线程池,分别是读线程池(_readers_thpool)和写线程池(_writers_thpool),分别用于处理读写请求。当接收到query时,redisgraph会为其分配读写线程,若线程池满,则放入等待队列中。

RedisGraph内创建有两个线程池,分别是读线程池和写线程池,分别用于处理读写请求。当接收到query时,RedisGraph会为其分配读写线程,若线程池满,则放入等待队列中。需要注意的是,写线程池中的线程数为1,即,RedisGraph中不会出现write-write冲突。

在并发控制过程中,Redisgraph的封锁粒度为Graph。

4 执行计划

RedisGraph使用Cypher查询语言,并为其构建了解析器。与一般的关系数据库类似,RedisGraph也需要进行词法分析、语法分析、语义分析等流程,从而生成执行计划。

RedisGraph会将查询操作转换为相应的矩阵操作,获取查询结果。当一个搜索模式 (N0)-[A]->(N1)-[B]->(N2)<-[A]-(N3) 被用作查询的一部分时,RedisGraph将其转换为一组矩阵乘法。对于给定的示例,一种可能的表达式是:A * B * Transpose(A)。

### RedisGraph 安装配置与使用教程 #### 1. 下载并编译 RedisRedisGraph 模块 为了使用 RedisGraph 功能,需要先获取最新版的 Redis 并编译安装。如果希望集成 RedisGraph 支持,则还需要单独下载对应的模块源码。 对于 Redis 的安装可以参考官方文档或其他资源,在此不再赘述。针对 RedisGraph 部分,可以从 GitHub 上克隆仓库: ```bash git clone https://github.com/RedisGraph/RedisGraph.git cd RedisGraph/ make ``` 上述命令会自动拉取依赖项并且完成整个构建流程[^1]。 #### 2. 启动带有 RedisGraph 加载选项的服务端实例 当成功编译好之后,可以通过指定 `--loadmodule` 参数来加载 RedisGraph 插件文件路径的方式启动 Redis 实例: ```bash redis-server --loadmodule /path/to/module/src/redisgraph.so ``` 这里 `/path/to/module/src/redisgraph.so` 应替换为实际存放已编译好的 so 文件的位置。 #### 3. 创建图数据库对象以及执行 Cypher 查询语句 一旦服务正常运行起来以后就可以通过客户端连接到该节点并对其中存储的数据结构进行操作了。比如创建一个新的图形数据集可以用如下方式实现: ```python import redis from redis.commands.graph import Graph r = redis.Redis(host='localhost', port=6379) # 初始化名为 'social' 的新图表谱 graph = Graph('social', r) query = """ CREATE (a {name:'Alice'}), (b {name:'Bob'}), (c {name:'Charlie'}), (a)-[:KNOWS]->(b), (a)-[:KNOWS]->(c) """ result_set = graph.query(query) print(result_set.result_set) ``` 以上 Python 脚本展示了如何利用 PyPI 中提供的库接口快速建立简单的社交网络模型,并向其内部添加几个顶点及其之间的边关系。 #### 4. 执行查询和遍历图中的元素 有了之前定义的基础之上还可以进一步尝试更复杂的模式匹配表达式来进行检索工作。例如查找所有由 Alice 认识的人的名字列表可写作: ```cypher MATCH (alice{name:'Alice'})-[:KNOWS]->(friend) RETURN friend.name AS name; ``` 这段 Cypher 代码片段将会返回一个包含两个字符串 `"Bob"` 和 `"Charlie"` 的集合作为结果输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值