云测评-RedisGraph 1.0的基准测试

导读:这篇文章来自RedisGraph团队,RedisGraph是一个Redis内嵌高性能内存图数据库。翻译由云测评君公众号完成。本文介绍了RedisGraph v1.0正式版本的一些实现特性、以及使用基准测试工具TigerGraph对RedisGraph进行测试的过程和结果。

本文由磊哥测评翻译整理完成,全文约2800字,阅读需20分钟。

今天我们很高兴地宣布:RedisGraph v1.0正式版本上线了。 RedisGraph是Redis Labs开发的Redis模块,用于向Redis添加图数据库功能。我们在六个月前以预览/测试模式发布了RedisGraph,感谢我们在第一个GA版本上一起工作时从社区和客户那里得到的所有反馈和建议。

与现有的图数据库实现不同,RedisGraph将连接数据表示为邻接矩阵,而不是每个数据点的邻接列表。通过将数据表示为稀疏矩阵并利用GraphBLAS(用于稀疏矩阵运算的高度优化库)的强大功能,RedisGraph提供了一种快速有效的方式来存储,管理和处理图形。事实上,我们的初步基准已经发现RedisGraph比现有的图形数据库快6到600倍!下面,我将分享我们如何对RedisGraph v1.0进行基准测试,但如果您想了解有关我们如何使用稀疏矩阵的更多信息,请查看以下链接:

RedisGraph中并发请求

在进入我们的基准测试之前,读者应该知道Redis是一个默认的单线程进程。在RedisGraph 1.0中,我们没有发布在多个分片上分割图形的功能,因为在单个分片中包含所有数据允许我们执行更快的查询,同时避免多个分片之间的网络开销。 RedisGraph绑定到Redis的单个线程以支持所有传入的查询,并包括一个线程池,该线程池在模块的加载时间内采用可配置数量的线程来处理更高的吞吐量。每个图形查询都由Redis主线程接收,但是在线程池的一个线程中计算。这允许读取扩展并轻松处理大吞吐量。在任何给定时刻,每个查询仅在一个线程中运行。

这与其他图形数据库的实现方式不同,后者通常在机器的所有可用内核上执行每个查询。 我们相信我们的方法更适合实际使用的情况,其中并发操作下的高吞吐量和低延迟比一次处理单个序列化请求更重要。

虽然RedisGraph可以同时执行多个读取查询,但是必须以完全隔离的方式执行以任何方式修改图形的写入查询(例如,引入新节点或创建关系以及更新属性)。 RedisGraph通过使用读/写(R / W)锁来强制执行写/读分离,以便多个读取器可以获取锁或仅获取单个写入器。 只要编写器正在执行,没有人可以获得锁定,只要有读者执行,没有编写者可以获得锁定。

RedisGraph的基准测试

通过上面的部分我想我们已经讲清楚了RedisGraph的一些重要背景,这也为接下来的测试奠定了基础。现在让我们了解最新基准测试的细节。在图数据库的领域有很多测试工具可供使用,最全面的是LDBC graphalytics,但是,对于这个版本,我们选择了TigerGraph在2018年9月发布的更简单的基准测试。这个版本评估了TigerGraph,Neo4J,Amazon Neptune,JanusGraph和ArangoDB等领先的图形数据库,并公布了平均执行时间和所有平台上所有查询的总体运行时间。 TigerGraph基准涵盖以下内容:

  • 数据加载时间
  • 加载数据的存储大小
  • 查询k-hop邻居计数的响应时间
  • 查询弱连接组件和页面排名的响应时间

TigerGraph基准测试表明了TigerGraph比其他图形数据库快约2-8000倍,因此我们决定挑战这个(记录完备的)实验并使用完全相同的设置比较RedisGraph。由于TigerGraph比较了所有其他图形数据库,我们直接使用其基准测试发布的结果,不再重复这些测试。

鉴于RedisGraph是v1.0并且我们计划在未来版本中添加更多功能和功能,对于我们当前的基准测试,我们决定主要关注k-hop邻居计数查询。当然,我们将在不久的将来发布其他查询的结果。

测试配置

硬件配置:

数据集配置:

测试使用版本:

  • RedisGraph 1.0.0 GA
  • TigerGraph Developer Edition 2.1.4

K-hop邻域计数查询算法

k-hop邻域查询算法是一种本地类型的图查询算法。 它计算从单个起始节点在特定深度处连接的节点数,并且这些节点都距离起始节点K跳。

计算方法如下:

MATCH (n:Node)-[*$k]->(m) where n.id=$root return count(m)

这里,$ root是我们开始探索图的种子节点的ID,$ k表示我们计算邻域的深度。 为了加快执行速度,我们在根节点ID上使用了索引。

测试结果

虽然我们遵循与TigerGraph完全相同的基准,但我们惊讶地发现他们只比较了一个请求查询响应时间。基准测试未能在并发并行负载下测试吞吐量和延迟,这几乎代表了任何实时的现实场景。正如我之前提到的,RedisGraph是从头开始构建的,具有极高的并行性,每个查询都由一个线程处理,利用GraphBLAS库处理矩阵运算和线性代数。 RedisGraph可以以接近线性的方式添加线程和扩展吞吐量。

为了测试这些并发操作的效果,我们向TigerGraph基准测试添加了并行请求。尽管RedisGraph只使用一个核,而其他图形数据库使用多达32个核,但它比任何其他图形数据库实现更快(有时甚至更快)的响应时间(TigerGraph除外,单个请求k-hop)查询Twitter数据集上的测试)。

单一请求基准

单个请求基准测试基于300个种子用于一跳和两跳查询,以及10个种子用于三跳和六跳查询。这些种子在所有图形数据库上顺序执行。结果每一行的时间(毫秒)表示对于给定数据集不同数据库的所有种子的平均响应时间。每个数据集的行“标准化”表示归一化为RedisGraph的平均响应时间。

值得注意的是,TigerGraph对单跳和双跳查询应用了三分钟的超时,对所有数据库的所有请求应用了三跳和六跳查询2.5小时(有关有多少请求计时的详细信息,请参阅TigerGraphs的基准报告为每个数据库输出)。如果对给定数据集和给定数据库的所有请求超时,我们将结果标记为“N / A”。当存在平均时间时,这仅适用于成功执行的请求(种子),这意味着查询没有超时或内存不足。这有时会导致结果出现偏差,因为某些数据库无法响应更难的查询,从而导致更好的平均单个请求时间并给出对数据库性能的错误印象。在所有已经执行的测试中,RedisGraph从未超时或内存不足。

下面是测试的详细结果:

关于并行请求基准测试

对于并行请求测试,我们只比较了RedisGraph和TigerGraph。 此设置包括在同一测试计算机上运行的22个客户端线程,总共生成300个请求。 下面的结果显示了每个图形数据库在每个深度(一、二、三和六跳)处理所有组合请求所花费的时间(以毫秒为单位)。

对于TigerGraph,我们通过将每个深度的单个请求的平均响应时间乘以300来推断结果。 我们相信这是最好的情况,因为TigerGraph已经完全消耗了单个请求的所有32个内核。 下一次,我们将使用TigerGraph在22个客户端的相同负载下重复这些测试,并且我们预计(考虑到并行的原理和执行并行请求所产生的开销)我们的结果会更好。

结论

我们为v1.0 GA版本的这些初步基准测试结果感到非常自豪。 RedisGraph是在两年前由Roi Lipman(我们自己的图数据库专家)在Redis Labs的黑客马拉松中开始的项目。最初,该模块使用了hexastore实现,但随着时间的推移,我们在稀疏矩阵方法和GraphBlas的使用方面看到了更多的潜力。我们现在已经对此决定进行了正式验证,RedisGraph已经成熟为一个可靠的图形数据库,在大型数据集(twitter)的现有图形解决方案的加载速度下,性能提高了6到60倍,在普通数据集上的速度提高了20到65倍。

最重要的是,RedisGraph在单个请求响应时间上优于Neo4j,Neptune,JanusGraph和ArangoDB,速度提高了36到15,000倍。与使用仅使用单个核心的RedisGraph相比,使用所有32个核心来处理单个请求的TigerGraph,我们实现了单个请求响应时间快2倍和0.8倍。同样重要的是要注意,我们的查询都没有超时大数据集,也没有产生内存溢出等异常。

在进行这些测试的时候,我们的工程师重新审视了RedisGraph的架构,并发现了一些可以改进性能的点。除此之外,接下来我们还将推出这些新特性:

  • 组合查询或大结果集的性能改进
  • GraphBLAS的新版本(甚至更快版本)
  • 更多Cypher子句/功能,以支持更多样化的查询
  • 图形可视化软件的集成
  • 支持LDBC基准测试

谢谢大家!

——————RedisGraph团队

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

caffe源码分析-cmake 工程构建

本文主要说明下,caffe源码分析过程中的cmake(结合IDE CLion)工程构建问题。在分析caffe源码的过程中,我没有仅仅只是看代码,而是:

13010
来自专栏用户2442861的专栏

caffe源码分析-DataLayer

DataLayer作为caffe训练时的数据层(以多线程的方式读取数据加速solver的训练过程),继承自BaseDataLayer/BasePrefetchi...

19230
来自专栏用户2442861的专栏

caffe源码分析-inner_product_layer

本文主要分析caffe inner_product_layer源码,主要内容如下:

11610
来自专栏用户2442861的专栏

caffe源码分析-ReLULayer

激活函数如:ReLu,Sigmoid等layer相对较为简单,所以在分析InnerProductLayer前,我们先看下激活函数层。

11010
来自专栏用户2442861的专栏

caffe源码分析-SyncedMemory

本文主要分析caffe中Blob内存管理类SyncedMemory,主要内容包括:

10820
来自专栏用户2442861的专栏

caffe源码分析-BlockingQueue

BlockingQueue线程安全的队列, 作为caffe训练时数据同步的重要数据结构,本文做简要分析。

11130
来自专栏用户2442861的专栏

c++ mnist转化为opecv Mat

本文主要介绍如何使用C++将mnist 数据集转化为Opencv Mat,问题来源主要代码以及运行示例如下:

10820
来自专栏用户2442861的专栏

caffe源码分析-DataTransformer

下面仅仅给出将Datum类型转化为caffe的Blob, cv::Mat的转化同理.

13430
来自专栏用户2442861的专栏

caffe源码分析-DataReader

DataReader作为DataLayer的数据成员变量,以多线程的方式从数据库(如lmdb, hdf5)读取数据:

10220
来自专栏用户2442861的专栏

caffe源码分析-InternalThread

InternalThread封装自boost::thread的线程,主要用于多线程的数据获取(可以理解为solver前向传播的同时,后台线程继续获取下一个bat...

14550

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励