简单地说,我们现在是Redis
今天,我们很高兴地宣布RedisGraph 1.0版正式发布。RedisGraph是Redis开发的一个Redis模块,为Redis添加图形数据库功能。我们在6个月前发布了RedisGraph的预览/测试模式,非常感谢我们在开发第一个GA版本时从社区和客户那里收到的所有很棒的反馈和建议。
与现有的图形数据库实现不同,RedisGraph将连接的数据表示为邻接矩阵而不是邻接表每个数据点。通过将数据表示为稀疏矩阵并利用GraphBLAS(一个高度优化的稀疏矩阵操作库),RedisGraph提供了一种快速和有效的方式来存储、管理和处理图。事实上,我们最初的基准测试已经发现,RedisGraph比现有图表数据库快6到600倍!下面,我将分享我们如何对RedisGraph v1.0进行基准测试,但如果你想了解更多关于我们如何使用稀疏矩阵的信息,请同时查看以下链接:
在开始我们的基准测试之前,我应该指出Redis默认是一个单线程进程。在RedisGraph 1.0中,我们没有在多个分片上发布分区图的功能,因为将所有数据都放在一个分片中可以让我们执行更快的查询,同时避免分片之间的网络开销。RedisGraph绑定到Redis的单个线程,以支持所有传入的查询,并包括一个线程池,在模块加载时需要一个可配置的线程数量,以处理更高的吞吐量。每个图查询都由主Redis线程接收,但在线程池中的一个线程中计算。这使得读取可以扩展并轻松处理大吞吐量。在任何给定的时刻,每个查询只在一个线程中运行。
这与其他图形数据库实现不同,后者通常在机器的所有可用核心上执行每个查询。我们相信我们的方法更适合实时的真实世界用例,在这种情况下,并发操作下的高吞吐量和低延迟比一次处理单个序列化请求更重要。
虽然RedisGraph可以同时执行多个读取查询,但以任何方式修改图形(例如引入新节点或创建关系和更新属性)的写入查询必须完全隔离执行。RedisGraph通过使用读/写(R/W)锁来强制执行写/读分离,以便多个读卡器都可以获得锁,或者只有一个读卡器。只要有一个编写器在执行,就没有人能获得锁;只要有一个读卡器在执行,就没有编写器能获得锁。
既然我们已经有了重要的背景知识,现在让我们开始了解最新基准测试的细节。在图形数据库空间中,有多种基准测试工具可用。最全面的一个是LDBC graphalytics,但是,对于这个版本,我们选择了由TigerGraph在2018年9月.它评估了TigerGraph、Neo4J、Amazon Neptune、JanusGraph和ArangoDB等领先的图形数据库,并发布了所有平台上所有查询的平均执行时间和总体运行时间。TigerGraph基准测试包括以下内容:
TigerGraph基准测试报告TigerGraph的速度是任何其他图形数据库的2-8000倍,因此我们决定对此提出挑战(证据确凿的)实验和比较RedisGraph使用完全相同的设置。由于TigerGraph比较了所有其他图形数据库,所以我们使用了基准测试发布的结果,而不是重复这些测试。
考虑到RedisGraph是1.0版,我们计划在未来的版本中添加更多的特性和功能,对于当前的基准,我们决定主要关注k-hop邻居计数查询。当然,我们将在不久的将来发布来自其他查询的结果。
云实例类型 | 个vCPU | 成员(GiB) | 网络 | 固态硬盘 |
---|---|---|---|---|
AWS r4.8xlarge | 32 | 244 | 10吉比特 | EBS-Only |
的名字 | 描述和来源 | 顶点 | 边缘 |
---|---|---|---|
graph500 | 综合Kronecker图 http://graph500.org |
2.4米 | 64米 |
推特 | Twitter用户跟随者有向图http://an.kaist.ac.kr/traces/WWW2010.html | 41.6米 | 1.47 B |
k-hop邻域查询是一种局部类型的图查询。它统计单个起始节点(种子)在某个深度连接到的节点数,并且只统计距离k-hop的节点数。
以下是密码:
匹配(n:Node)-[*$k]->(m)Where n.id=$root return count(m)
这里,$root是我们开始探索图形的种子节点的ID,$k表示我们计算邻居的深度。为了加快执行速度,我们在根节点ID上使用了索引。
尽管我们遵循与TigerGraph完全相同的基准,但我们惊讶地发现,它们只比较了单个请求查询响应时间。基准测试未能测试并发并行负载下的吞吐量和延迟,而这几乎代表了所有实时的真实场景。正如我前面提到的,RedisGraph是为了极高的并行性而从头构建的,每个查询都由单个线程处理,该线程利用GraphBLAS库处理线性代数的矩阵操作。RedisGraph可以以接近线性的方式添加线程和扩展吞吐量。
为了测试这些并发操作的效果,我们将并行请求添加到TigerGraph基准测试中。尽管RedisGraph仅使用一个内核,而其他图形数据库最多使用32个内核,但它的响应时间比任何其他图形数据库都要快(有时甚至要快得多)(除了Twitter数据集上的单请求k-hop查询测试中的TigerGraph)。
单个请求基准测试基于300个种子用于一跳和两跳查询,基于10个种子用于三跳和六跳查询。这些种子将在所有图形数据库上顺序执行。行' time (msec) '表示给定数据集的每个数据库的所有种子的平均响应时间。每个数据集的行“标准化”表示这些标准化到RedisGraph的平均响应时间。
需要注意的是,TigerGraph对所有数据库上的所有请求应用了三分钟的一跳和两跳查询超时,以及2.5小时的三跳和六跳查询超时(请参阅TigerGraphs基准的报告有关每个数据库有多少请求超时的详细信息)。如果对给定数据集和数据库的所有请求超时,我们将结果标记为' N/ a '。当给出平均时间时,这只适用于成功执行的请求(种子),这意味着查询没有超时或产生内存溢出异常。这有时会影响结果,因为某些数据库无法响应较困难的查询,导致更好的平均单个请求时间,并给数据库的性能带来错误的印象。在所有测试中,RedisGraph从未超时或生成内存溢出异常。
数据集 | 测量 | 再描记器 | TigerGraph | Neo4j | 海王星 | JanusGraph | ArangoDB |
---|---|---|---|---|---|---|---|
graph500 | 时间(毫秒) | 0.39 | 6.3 | 21.0 | 13.5 | 27.2 | 91.9 |
正常化 | 1 | 16.2 | 53.8 | 34.6 | 69.7 | 235.6 | |
推特 | 时间(毫秒) | 0.8 | 24.1 | 205.0 | 289.2 | 394.8 | 达到1674 |
正常化 | 1 | 30.1 | 256.3 | 361.5 | 493.5 | 2093年。4 |
数据集 | 测量 | 再描记器 | TigerGraph | Neo4j | Neptune1 | JanusGraph | ArangoDB2 |
---|---|---|---|---|---|---|---|
graph500 | 时间(毫秒) | 30.7 | 71 | 4180 .0 | 8250 .0 | 24050 .0 | 16650 .0 |
正常化 | 1 | 2.3 | 136.2 | 268.7 | 783.4 | 542.3 | |
推特 | 时间(毫秒) | 503 | 460.0 | 18340 .0 | 27400 .0 | 27780 .0 | 28980 .0 |
正常化 | 1 | 0.9 | 36.5 | 54.5 | 55.2 | 57.6 |
数据集 | 测量 | 再描记器 | TigerGraph | Neo4j | Neptune1 | JanusGraph | ArangoDB * 2 |
graph500 | 时间(毫秒) | 229 | 410 | 51,380.0 | 2270 .0 | 1846710 .0 | 3461340 .0 |
正常化 | 1 | 1.8 | 224.4 | 9.9 | 8064年。2 | 15115 .0 | |
推特 | 时间(毫秒) | 9301 | 6730 | 298,000.0 | 38700 .0 | 4324000 .0 | 3901600 .0 |
正常化 | 1 | 0.7 | 32.0 | 4.2 | 464.9 | 419.5 |
数据集 | 测量 | 再描记器 | TigerGraph | Neo4j | Neptune1 | JanusGraph | ArangoDB2 |
---|---|---|---|---|---|---|---|
graph500 | 时间(毫秒) | 1614 | 1780 | 1,312,700.0 | N/A | N/A | N/A |
正常化 | 1 | 1.1 | 813.3 | N/A | N/A | N/A | |
推特 | 时间(毫秒) | 78730 | 63000 | N/A | N/A | N/A | N/A |
正常化 | 1 | 0.8 | N/A | N/A | N/A | N/A |
对于并行请求测试,我们只比较了RedisGraph和TigerGraph。这个设置包括在同一台测试机器上运行的22个客户端线程,总共生成300个请求。下面的结果显示了每个图形数据库在每个深度(1、2、3和6跳)下回答所有请求所需的时间(以msec为单位)。
对于TigerGraph,我们通过将每个深度的单个请求时间的平均响应时间乘以300来推断结果。我们认为这是最好的情况,因为TigerGraph已经为单个请求完全消耗了所有32个内核。下一次,我们将在22个客户机的相同负载下使用TigerGraph重复这些测试,我们期望(考虑到并行规则以及执行并行请求所产生的开销),我们的结果会更好。
单 | 两跳 | Three-hop | Six-hop | ||||||
---|---|---|---|---|---|---|---|---|---|
数据集 | 测量 | RediGraph | 老虎 | 再描记器 | 老虎 | 再描记器 | 老虎 | 再描记器 | 老虎 |
graph500 | 时间(毫秒) | 29 | 1,890 | 772 | 21000年 | 5554年 | 123,000 | 24388年 | 534000年 |
正常化 | 1 | 65.2 | 1 | 27.2 | 1 | 22.1 | 1 | 21.9 | |
推特 | 时间(毫秒) | 117 | 7,200 | 12923年 | 138,000 | 286018年 | 2019000年 | 3117964年 | 18900000年 |
正常化 | 1 | 61.5 | 1 | 10.7 | 1 | 7.1 | 1 | 6.1 |
对于我们的v1.0 GA发行版的这些初步基准测试结果,我们感到非常自豪。RedisGraph是两年前由Roi Lipman(我们自己的图形专家)在Redis的一次黑客马拉松中创立的。最初,该模块使用了一个六存储实现,但随着时间的推移,我们看到稀疏矩阵方法和GraphBlas的使用更有潜力。我们现在已经对这个决定进行了正式的验证,并且RedisGraph已经成熟成为了一个坚实的图形数据库,它在负载下的性能提高比现有的大型数据集(twitter)快6到60倍,在普通数据集(graph500)上快20到65倍。
最重要的是,RedisGraph在单个请求响应时间上比Neo4j、Neptune、JanusGraph和ArangoDB要快36到15000倍。与TigerGraph相比,我们实现了2倍和0.8倍的单请求响应时间,TigerGraph使用所有32个核来处理单个请求,而RedisGraph只使用单个核。同样需要注意的是,我们的查询没有在大数据集中超时,也没有产生内存溢出异常。
在这些测试中,我们的工程师还分析了RedisGraph,并发现了一些可以使我们的性能更好的低挂果实。除此之外,我们即将发布的路线图包括:
图形快乐!
RedisGraph团队
2019年1月17日
在我们发布了这些RedisGraph基准测试结果后,TigerGraph的同事们给出了一些想法。虽然我们很高兴听到竞争对手的观点,但我们想谈谈他们对虚假新闻的指控。点击这里阅读我们的基准更新博客。