NoSQLBench发布于 2020年 3月,它是第一个试图在分布式系统性能测试上做到面面俱到的专业测试工具。同时,它旨在让轻量级的和专业的用户都可以使用。
当今的开发人员希望创造性能可扩展的应用程序。这就要求使用在多地运行的分布式系统,无论是容器镜像或是跨公共、私有或混合云平台运行的服务。然而,测试这些应用程序往往比想象的要难。
可扩展的系统的性能测试工具一直都很有限。 NoSQLBench发布于 2020年 3月,它是第一个试图在分布式系统上做到面面俱到的专业测试工具。同时,它旨在让轻量级的和专业的用户都可以使用。
NoSQLBench致力于解决其他工具无法解决的测试难题。它允许用户使用目标系统的原生查询语言对访问模式进行建模。它不假定所有 NoSQL数据库只是同一概念的不同版本。用 NoSQLBench进行实际测试并不需要您是专业的程序员,也不需要您传输巨量数据来得到真实的测试数据或操作。
使用 NoSQLBench配置了一个工作负载 workload后,就可以开始测试了。如果需要更改访问模式或操作中使用的数据,只需要更改配置,就可以再次测试。这个过程如此简单,即使是任意大小的数据集也可如此操作。这样用户可以直观的洞察到生产环境中同样的工作负载会是什么样的效果。
这些功能每一个都有单独的重要价值。当把它们合在一起时,他们将形成一个功能强大的工具包,使性能测试对每个人来说都变得更轻松。 NoSQLBench使我们能够专注于测试需求,而不用在测试工具上做出妥协。
这也意味着我们可以避免创建昂贵而复杂的一次性测试工具。在实践中,这些一次性的工具通常有严重的缺陷。毕竟,构建各方面都考虑周全的测试工具并非易事。我们希望通过提供一种工具,它既可以简化处理所有困难的部分而又不剥夺使用者的控制权。
性能测试工具需要一段时间才能在测试人员的工具箱中赢得一席之地。值得庆幸的是,无论是对于 DataStax还是客户, NoSQLBench都已证明自己是无价的工具。
NoSQLBench的工作负载都被整合在一个 YAML配置文件中。工作负载主要基于语句 (statements),而 YAML格式强调出了这一点。您也可以通过在这些语句中添加绑定 (bindings)来指定用于操作的数据。为了组织和选出起作用的语句,您可以添加标签 (tags)。语句还可以有针对特定语句的参数 (params),比如是否将某一操作标记为幂等操作,或者是否使用预处理语句 (prepared statement)等等。
本教程是一个针对基础 NoSQLBench工作流程的高阶介绍。您可以将其作为进行任何级别测试的基本模板。如果您的测试需要更多具体的细节,您可以在此基础上进行增添。假设您想用 CQL向一个目标系统写入 10亿条记录,您将需要使用 cql驱动程序。
# hello-world-dml.yaml
statements:
- example: |
insert into hello.world (cycle,name,sample)
values ({cycle},{cyclename},{sample});
bindings:
cycle: Identity()
cyclename: NumberNameToString()
sample: Normal(100.0D, 10.0D)
既然我们有了开始,接下来我们怎么能知道它会做我们想做的事情呢 ?
您可以一步一步地预览语句可能呈现的样子。以下是 stdout驱动程序诠释此配置后生成的一些语句:
nb run driver=stdout yaml=hello-world-dml.yaml cycles=5
# output
Logging to logs/scenario_20200403_101645_863.log
insert into hello.world (cycle,name,sample)
values (0,zero,95.30390911280935);
insert into hello.world (cycle,name,sample)
values (1,one,104.73915634900615);
insert into hello.world (cycle,name,sample)
values (2,two,112.3236295086616);
insert into hello.world (cycle,name,sample)
values (3,three,111.38872920562173);
insert into hello.world (cycle,name,sample)
values (4,four,91.52878591168258);
好的,我们已经有一些可用的东西了 !您所看到的是使用 stdout驱动程序执行一个活动 (activity)的结果。这个驱动程序不使用任何传输协议,但是它可以将呈现出来的操作打印到控制台以供诊断。想要熟悉数据绑定,这是一种非常常见的方法。如果您针对 Apache Cassandra数据库运行工作负载的话,这也是一种快速检查工作负载将执行哪些操作的方法。为此,您所需要做的就是将 driver = stdout更改为 driver = cql并提供一个可以连接的主机。
这显示了在测试场景中拥有一组通用概念和配置原语的强大所在。虽然这并不意味着不同的系统能够奇迹般地使用彼此的语句形式和协议,但这确实意味着您可以用一种惯用的方式表达它们,并根据目标系统定制您的测试。 NoSQLBench高级驱动程序(如 cql)的工作是将语句模板调整为您正在使用的协议形式。对于严肃的测试来说,如果性能测试工具不允许您使用目标系统的原生语言来控制访问模式和访问操作,那么它一定是无用的。
输出中的每一行表明每个操作的周期数是特定的,这也是每个操作所使用数据的基础。
如果您将达到这种效果所花费的精力与其他任何测试工具进行比较,您就会明白我们为什么要努力构建这个工具包。继续阅读下去,您使用 NoSQLBench的原因会越来越多 !
那么,我们如何利用上面的简单语句,并把它转换成易得易用的工具呢?我们需要允许使用者建立一个完整的测试场景,包括 DDL。幸好这很容易做得到,因为在 NoSQLBench中没有什么语句形式是不能使用的。您只需创建语句来定义您的键空间 (keyspace)和模式 (schema):
下面是我们模式中的工作负载配置 :
# hello-world-ddl.yaml
statements:
- create-keyspace: |
create keyspace if not exists hello
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
params:
prepared: false
- create-table: |
create table if not exists hello.world (
cycle bigint,
name text,
sample double,
primary key(cycle)
);
params:
prepared: false
这里显示了两个没有绑定的语句 (DDL不需要绑定 ),以及一个被称为语句参数 (statement parameter)的新 YAML元素。 prepared: false 语句设置禁止自动使用预处理语句,因为您不能对 DDL执行此操作。
现在我们有两个语句块,只要我们将它们保存在单独的文件中就可以了。然而,我们还可以做得更好。 NoSQLBench YAML格式已经被改进,以支持不同类型的测试结构,包括块、标签和默认值。它仍然是 YAML,但是 NoSQLBench知道如有效地将这些层组合在一起:
# hello-world.yaml
bindings:
cycle: Identity()
cyclename: NumberNameToString()
sample: Normal(100.0D, 10.0D)
randomish_cycle: HashRangeScaled()
blocks:
- tags:
phase: schema
params:
prepared: false
statements:
- create-keyspace: |
create keyspace if not exists hello
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
- create-table: |
create table if not exists hello.world (
cycle bigint,
name text,
sample double,
primary key(cycle)
);
- tags:
phase: main
statements:
- insert-sample: |
insert into hello.world (cycle,name,sample)
values ({cycle},{cyclename},{sample});
ratio: 4
- read-sample: |
select * from hello.world where cycle={randomish_cycle}
ratio: 1
这个版本中的新元素如下:
由于我们已经将不同类型的语句组织到测试工作流程的不同部分中,我们就可以分别调用它们了。
注意:在 YAML文件中,正确的缩进是很重要的。第一次使用 YAML的用户经常会纠结这个问题。确保使用空格键而不是 tab键,并将所有子元素缩进到比父元素靠后的位置。如果您从未使用过 YAML,那么在构建更高级的场景之前先熟悉一下 YAML为好。我们推荐 Eric Goebelbecker的《 YAML Tutorial: Everything You Need to Get Started in Minutes》一文。
本节要求您拥有一个 CQL系统用来连接。如果您还没有,您可以用下面的指令启动 DSE实例 :
docker run -e DS_LICENSE=accept --name my-dse -p 9042:9042 -d
datastax/dse-server:6.7.7
我们来创建模式。
nb run driver=cql yaml=hello-world tags=phase:schema host=host
# output
Logging to logs/scenario_20200205_013213_767.log
注意,这里没有命令行输出。这是因为 NoSQLBench假定除非您指定,您不希望被细节所困扰。如果您确实想查看详细信息,则可以添加一个 -v 来将命令行日志记录级别从警告 WARNING级别提高到信息 INFO级别,或者添加 -vv 来提高到 DEBUG调试级别。
我们现在还可以执行一些 DML操作:
nb run driver=cql yaml=hello-world tags=phase:main host=host cycles=1M
# output
01:53:23.719 [scenarios:001] WARN i.e.activityimpl.SimpleActivity - For testing at
scale, it is highly recommended that you set threads to a value higher than the
default of 1. hint: you can use threads=auto for reasonable default, or consult the
topic on threads with `help threads` for more information.
^C (I hit control-C to interrupt it.)
NoSQLBench 提醒我们增加线程。很好。 让我们顺便再加一个参数,把grafana 的图表功能也用起来。这个参数得益于NoSQLBench 内部通过Docker 容器集成的Prometheus, Grafana 和Graphite Exporter 环境。
nb run driver=cql yaml=hello-world tags=phase:main host=host cycles=1B threads=20x
--docker-metrics
# output
Logging to logs/scenario_20200205_015849_242.log
# every minute you'll see a progress indicator
hello-world: 0.36%/Running (details: min=0 cycle=3589475 max=1000000000)
hello-world: 0.67%/Running (details: min=0 cycle=6734460 max=1000000000)
hello-world: 0.98%/Running (details: min=0 cycle=9777225 max=1000000000)
对于 -docker-metrics,在测试场景开始之前,一个 docker应用栈会在本地生成,并且所有指标都已预先配置好以便自动进入该应用栈。我们刚开始关注到这个特别的功能就已经能感受到它的有用之处了。
下面是它呈现的样子 :
如果需要,您还可以用其他格式获得您的结果。如果您查看了 nb help 的输出,您会看到各种报告指标的方法,包括 graphite、 HDR logs、 CSV等等。
如果您希望每个人只需要一个命令就能够运行您的工作负载,包括模式设置和主阶段,您可以这样做。 NoSQLBench新添加的一个名为 named scenario的特性允许您以如下形式将命令嵌入到 workload YAML中 :
# add this to hello-world.yaml
scenarios:
default:
ddl: run driver=cql tags==phase:schema threads==1 cycles==2
dml: run driver=cql tags==phase:main threads=auto cycles=1M
有了这个,你可以运行如下命令来从头到尾运行测试 :
nb hello-world host=host
最终的结果是使用了命名场景中的两个模板化命令,只要它们没有被 “ ==”锁定,命令行上的任何选项都会覆盖它们。当然,您仍然可以使用 -docker-metrics 和其他选项。您还可以使用 default之外的名称来编写不同的命名场景,并将它们作为工作负载 yaml文件以外的第二个选择器进行传递。这是一个相对较新的特性,但它已经用于将一系列常见工作负载集成到 NoSQLBench中。
您可以在这里访问NoSQLBench 文档: http://docs.nosqlbench.io/ .
您还可以使用 docserver模式访问作为工具组成部分的 NoSQLBench文档。有了这个工具附带的文档,您永远不会纳闷这些文档是否属于您使用的版本。这种模式也是 UI功能在 NoSQLBench中的应用。
您可以使用 docker命令启动 docserver模式,如下所示 :
docker run --rm -a STDOUT --net=host --name nb-docs nosqlbench/nosqlbench docserver http://0.0.0.0:12345/
# output
Started documentation server at http://0.0.0.0:12345/# or
nb docserver
# output
Started documentation server at http://localhost:12345/
然后,您可以在启动它的系统上的一个网络连通的地址看到它。
要完全掌控 NoSQLBench场景,需要了解一些活动参数 (比如线程 )。强烈建议新用户在指南中阅读基本的活动参数。
您可以在这个网址下载NoSQLBench 的最新版本: https://github.com/nosqlbench/nosqlbench/releases
NoSQLBench一直在改进。首先必须构建 NoSQLBench的核心机制,而下一代的改进将集中于使用户更容易使用 NoSQLBench。我们期待着看到以下进步 :
NoSQLBench允许您查看在使用或不使用应用程序时数据库的执行情况。它使得迭代数据模型、测量基线性能和计划数据库的规模成为可能。
我们希望让所有人都能使用一套通用的概念和工具,不论你测试的是什么 NoSQL数据库,都使得测试更加容易。为了实现这个目标,我们希望 NoSQLBench所基于的工具集可以成为行业内 NoSQL测试的事实标准。通过将 NoSQLBench和 CQL驱动程序作为开源发布,我们已经迈出了实现这一愿景的第一步。
测试愉快!