zoukankan      html  css  js  c++  java
  • Cassandra社区是怎么测试4.0的

    点击查看活动录像,获取更多技术细节。

    Cassandra 4.0的目标就是成为史上最稳定的版本。为了达到这个目的,我们需要用很多方法和工具进行测试。我今天主要为大家介绍一下Cassandra 4.0的测试思路。不同的公司用不同的方法,希望我的介绍能给大家带来一些启发。 

    我先简单介绍一下自己。我其实早在2006年就开始参与开源软件的开发,一直致力于以开源的方式、以工程师驱动的方式来开发软件。我在2010年至2013年曾领导过VMWare北京的研发团队,所以我对国内的工程师很有感情,特别愿意和大家沟通,向大家介绍我们最新的方法,希望为大家提供帮助和借鉴。 

    我在2014年加入了DataStax,并带领我们的后端工程师团队在Cassandra的基础上整合了Apache Spark、Apache Solr和ThinkerPop等技术,开发出了一个多模式的大数据平台DSE (DataStax Enterprise),可以提供搜索和分析功能,并利用Graph搭建图数据库。 

    不过今天我的重点不在DSE,而是在于Cassandra的测试。 


    Cassandra数据库准确性测试架构


    我今天介绍大致是围绕PPT中的这张图进行的。 

    对于数据库来讲,最最重要的就是准确性——你不希望你的数据在存储的过程中被修改或丢失。所以,数据的准确性是4.0版本中最关注的地方。 

    简单来讲,在通常情况下,在测试时会有一个运行着Cassandra集群的生产环境。在这里,我们的核心方式是利用开源的Cassandra-diff工具来测试源集群和目标集群里面的数据。

    首先,测试架构中包括了夜照恢复,这个功能能够把想要测试的某个数据点在生产环境中恢复到测试环境中的源集群和目标集群。 

    第二,如果不希望别人知道schema的情况,我们有一个匿名化的工具帮助隐藏schema,这样其他做测试的人就看不出来可能包含的敏感的信息,比如客户数据等。 

    第三步就是将不同的数据加载到源集群或目标集群。在加载过程中我们会使用到一些工具,主要包括NoSQLBench和fqltool。fqltool是一个full query log,会存储所有通过CQL interface的query,之后可以再进行回放。在后面我会再具体介绍这两种工具。 

    在Cassandra-diff运行中,有时数据量会非常大,这里我们就用到了Spark。以Spark集群的形式,我们将Cassandra程序运行在Spark Workers上,然后再由Spark Workers运行Cassandra-diff来确保源集群和目标集群中的数据是准确的。 

    在实际应用时,夜照恢复可能是可选项,如果只是测试则完全不必要。匿名化Schema则取决于是否有生产环境,也不一定绝对需要。所以整个测试架构中的核心就是数据加载和Cassandra-diff。 

    整个测试环境可以运行在一般的服务器环境之下,也可以运行在Kubernetes集群中。我们现在正在努力实现这些工具的自动化,将他们放到Kubernetes集群中,使得所有社区成员都可以使用。
    接下来,我会就其中几个重要的工具进行介绍。 


    匿名化schema


    其实匿名化schema的概念非常简单。在PPT中,源schema的keyspace的名字是cassandradiff,匿名化后变为ks_0,使得测试人员完全无法辨认原来的keyspace名字。除此之外,包括数据库的名字、表的名字等等都被匿名化了。这样一来,我们就可以放心地将数据导出并用来测试。 

    --- 

    加载数据

    NoSQLBench


    加载数据主要用到两种工具,其中一个是NoSQLBench。 

    NoSQLBench本来是一个用来做性能测试的工具,我们用它来加载数据的原因是它是决定性的(deterministic),即当开发人员配置好相关的配置文件,NoSQLBench能确保多次生成的数据是一致的,方便测试比较。另外一个使用NoSQLBench的原因是它可以基于匿名schema随机生成数据。 

    在这里,我们给出一个简单的NoSQLBench的例子。 

    在PPT中,我们看到的是一个NoSQLBench配置文件。这里面包括bindings,可以定义匿名化schema中不同字段的属性。 

    在下面的blocks中也分为不同的步骤(phase),比如这个例子中的第一步phase: schema是根据schema创建表;第二步phase: main主要是用来加载数据,在这其中我们可以定义需要插入的数据量。 

    点击此处了解更多关于NoSQLBench的详细信息。
     

    FQL - Replay Testing


    第二种加载数据的方式是FQL(Full Query Log,所有查询日志)。 

    FQL是Cassandra 4.0中的新功能,它会记录所有从CQL interface输入的命令。通常情况下,FQL是用来做调试和性能测试的。而4.0中的另一个亮点功能审核日志Audit log就是基于FQL开发的。FQL只会记录成功的命令,不成功的命令不会被记录。另外,FQL的运行对于集群性能的影响非常小,主要是因为FQL使用了非常简单且性能很好的BinLog格式和高性能的Chronicle Queue。 

    点击此处了解更多关于Audit Log的信息。

    在PPT中展示的是一些简单的FQL命令。想要启用FQL,有两种方式。 

    一是使用nodetool enablefullquerylog。由于这些nodetool命令都是local的,所以你需要在local的每一个node上都启用FQL,它才会记录本地的CQL命令并支持回放。在nodetool enablefullquerylog后面定义的路径存储了所有被记录的CQL命令。进到这个路径地址,可以看到,不管记录了多少命令,这里都有两个体积差不多的文件,你记录更多就会有更多文件。这就是一个基于Chronicle Queue的存储格式。 

    第二种启用FQL的方式是在cassandra.yaml文件的full_query_logging_options中有相关的参数,可以用于配置路径、存储方式等等。我在这里做一个最简单的介绍。在测试中,所谓的“加载数据”其实就是一个回放。也就是说,在生产环境中启动了FQL,记录了所有CQL命令。如果这时出现问题,我们就需要查看一下问题出在哪里。 

    在以前,出现问题时我们需要模拟用户的使用过程,但是想要快速有效地复制之前的情况是一件很难的事情,因为每个运行环境和每个客户的使用方法都有不同。而FQL相当于做了一个完整的记录,当我们再遇到问题,就可以用replay功能来进行诊断和修复。在4.0版本中,我们就可以使用fqltool这一工具来操作FQL。当我们使用replay功能时,我们可以指定想要replay的数据库或表,得到的结果会被存储到指定的路径、集群或者节点。

    PPT中的例子就是在processing,回放存储的命令。有时候因为目标节点上没有所需的表,所以可能会出现错误。在PPT中我们还能看到有多少query以及完成了多少的query。 

    fqltool dump这个命令可以让我们看到记录的query,这里面包括非常详细的信息,比如query开始的时间、使用的协议的版本、timestamp时间戳、执行花费的时间以及query本身是什么。无论是SELECT、INSERT还是其它query,所有的命令都有详细记录。 


    Cassandra-diff


    我们通过NoSQLBench或是FQL将数据加载到两个不同集群里面之后,有可能这两个集群的Cassandra版本不同,也可能配置不同。在Cassandra的yaml文件中有很多配置,我们曾经做过调研,如果将yaml文件中不同的配置进行排列组合,大约能得到超过十亿种组合。 

    而Cassandra-diff则可以帮助比较两个版本或配置不同的集群所得到的结果是否相同。 

    使用Cassandra-diff的主要目的是确保数据库的准确性,然后在数据库不准确时查找出现的问题。具体实现方法是将整个集群的token切分,然后将不同的部分分配给不同的spark worker,进而比较每个token的数据。 

    Cassandra-diff是一个开源的程序,有兴趣的朋友可以自行了解更多相关信息。 

    这里我们举一个Cassandra-diff的例子。

    正如前面提到的,Cassandra-diff是用Spark来submit。Spark是一个分布式的计算框架,能够将程序放到多台机器上同时运行,从而节省性能。 

    在这个例子的命令行中,我们可以看到一个配置文件,它主要是给Cassandra-diff使用的。在这个文件中,我们可以定义keyspace是什么、想要比较的table是什么、splits是多少、buckets是多少等等与Spark相关的配置。后面的部分与集群相关,包括目标集群、源集群和metadata。 

    Metadata根据Cassandra运行的不同阶段,可以把我们希望存的数据存到目标集群中,出现问题时可以在此寻找错误原因。 

    左边下面的框里是运行时的情况,我们可以看到有很多token range,每一个token range中的数据都被取出来进行比较。比较后会给出状态信息,并反馈是否两个集群中所有的partition都是一致的。如果一致就皆大欢喜,如果不一致可能就需要找到问题所在。 


    Property based testing (PBT)


    在Cassandra 4.0中,我们采用了一个新的写测试用例的方式。 

    在这之前,大家熟悉的是单元测试(unit test or example based test)——假设我们需要测试加法功能是否正确运行,我们可能以1+3为例进行测试,从结果是否为4判断功能是否正确运行。 

    但是PBT与单元测试不同,PBT考虑的是问题本质的属性,通过对属性的深入理解提出到达解集的不同路径,从而进行验证。这个概念可能比较难理解,我们先讲一下PBT的步骤,后面还会给出例子,帮助大家理解。 

    PBT将一个测试分为三步:

    1. 输入策略:无需手写一条条数据数据,只需定制输入策略,PBT框架会自动根据策略生成足够大的、随机的、包含所有情况的测试数据集
    2. 结果检查:结果检查是需要费心考虑的,因为无法预知测试集的输入也就无法预先写好测试集的输出。所以PBT要求对逻辑需求有深入的理解,并精心构造不同的解题路径来对结果进行验证。
    3. 错误收敛:因为PBT会自动生成大量输入参数,自然会产生众多结果。为了使开发人员更方便地找到具有典型意义的异常数据,PBT框架会自动对错误集进行收敛,生成尽可能小的异常参数集合。 

    在这里举一个简单的例子来帮助理解:加法的属性。属性一:比如我们需要求得a、b之和,无论是a+b还是b+a,其结果应该是相同的;属性二:a+1+1与a+2应该得到相同的结果;属性三:a+0和a应该是一样的。 

    所以说,我们要的是像这样的属性而非具体的例子。 

    在数据库的测试中来讲,我们可以再举一个例子:如果硬盘出现故障,就会发生数据损害。数据损害就是一个属性,可以利用checksum来诊断数据损害。也就是说,数据受损后的checksum与受损前是不同的。 

    总的来说,PBT可以帮助我们更好、更多地发现问题,并且由于PBT产生的数据是随机的,所以也能更广泛地覆盖测试的范围。 


    结尾

    以上就是今天我想和大家分享的Cassandra 4.0中使用到的测试方法,希望这些新的方法对大家有借鉴意义。 

    但是作为一个开源产品,要是想测试到所有情况,光靠少量程序员测试是很难达到的。因为虽然我们可以测试每一行程序,但是不能测试每个用户的使用情景。这就是为什么我们希望大家能够参与到社区和项目当中。

    PPT中列出了一些可以参与到社区和项目的方式和渠道,比如回答用户的问题、参与测试、review代码、提交补丁、参与开发新功能等等。这些会让你对产品有更深入的了解,也会帮你在社区中建立自己的个人品牌。 

    Go fast, go alone; go far, go together. (单打独斗也许会走得更快,但团队作战才能走得更远。)希望大家能够积极为社区贡献力量。 

    非常高兴今天有机会和大家分享这些,谢谢大家。

  • 相关阅读:
    SQL COUNT() 语法
    SQL AVG 函数
    Android开发
    IIf 函数
    励志
    王者归来
    Java基础知识总结(绝对经典)
    LeetCode算法题-Third Maximum Number(Java实现-四种解法)
    LeetCode算法题-Fizz Buzz(Java实现)
    LeetCode算法题-Longest Palindrome(五种解法)
  • 原文地址:https://www.cnblogs.com/datastax/p/13566574.html
Copyright © 2011-2022 走看看