1. 程式人生 > 實用技巧 >比較Apache Cassandra的壓力測試工具

比較Apache Cassandra的壓力測試工具

對Apache Cassandra進行基準測試和壓力測試是操作人員和開發人員都定期進行的重要演習。

測試的方法五花八門,從“看看我的程式碼比其他人的程式碼好多少”,到“我需要什麼條件才能執行這個?”, 以及“這將為我節省多少錢?”,以及我的最愛——“當我的叢集被壓測壓死了時,會是什麼樣?”。

知道您想實現的目標以及如何解釋測試的結果,這些都是巨大挑戰的一部分。我們希望通過介紹以下這些可用的工具,會使您的工作變得容易一些。


這篇文章將研究並比較以下三種壓測工具:

  • cassandra-stress

  • tlp-stress

  • nosqlbench

藉助這三個工具,我們將介紹一些基本用例:

  1. 生成負載

  2. 使用真實叢集

  3. 迭代和執行緒數

  4. 可觀察性

  5. 批處理大小和重寫操作

  6. 預定義的工作負載

  7. 自定義的工作負載

  8. 客戶端併發競爭和伺服器飽和

這些用例中所使用的工具的版本是:對於cassandra-stress是3.11.6,對於tlp-stress是4.0.0,對於nosqlbench是3.12.77。

01生成負載

有時,您想要做的只是生成一些負載或資料。如果我們只是想看到一個Cassandra節點在正常執行某個任務,這種測試方法非常有用。我們可能只需要提高CPU負載或在磁碟上生成一些commitlog、memtables或sstables。

每個工具都會為這些測試生成稍微不同的負載配置:

$ cassandra-stress write

在初始的50k寫入預熱之後,執行超過一百萬次的寫入,從四個執行緒開始,迭代多次並增加客戶端中使用的執行緒數。

$ tlp-stress run BasicTimeSeries -i 1M

精確地以9:1的讀寫比例執行一百萬個的請求。

$ nb cql-iot write_cl=LOCAL_ONE

在預熱階段執行1千萬次寫入,然後以9:1的讀寫比例進行1千萬次請求。

這些測試全部使用Java驅動程式和一致性級別LOCAL_ONE,來向一個本機(localhost)上的Cassandra節點執行寫操作。

不過它們在資料模型上還是有所不同——Cassandra-stress使用簡單的鍵值表,而tlp-stress和nosqlbench則使用時間序列的資料模型。

02使用真實叢集

這一部分與以上生成任何負載或資料的操作基本相同,不過現在您有一個具體的目標叢集來進行測試。

$ cassandra-stress write -node cassandra1
$ tlp-stress run BasicTimeSeries --host cassandra1
$ nb cql-iot host=cassandra1

注意:使用這些壓力工具中的任何一個時,您都無需指定多個主機。這些是傳遞給Java驅動程式的聯絡人主機(contact host),與編寫的應用程式不同。

在編寫的應用程式中,為了在部署和啟動過程中的可靠性,您需要指定多個聯絡人主機。而在呼叫壓力工具時,您一般會只會需要指定單個聯絡人主機來啟動和執行。

03迭代和執行緒數

下面展示了在不同的壓測工具中,如何指定迭代數和執行緒數。

$ cassandra-stress write n=100000 -rate threads=16
$ tlp-stress run BasicTimeSeries -n 100k -t 16
$ nb cql-iot write_cl=LOCAL_ONE main-cycles=100k threads=16

04可觀測性

即使是有設計合理的工作負載,對於基準測試來說結果遠不止是吞吐量那麼簡單。我們想看看隨著時間的推移,叢集究竟如何運作,這也許包括從流量峰值到Cassandra可能執行的許多後臺操作。仔細研究Cassandra的效能將有助於長遠規劃一個健康而穩定的叢集,這個時間將超出我們可以做基準測試的時間範圍。

1)cassandra-stress

$ cassandra-stress write -graph file=example-benchmark.html title=example revision=benchmark-0

有關此的更多資訊,請閱讀這篇有關cassandra-Stress和Graphs的部落格文章。

2)nosqlbench

$ nb cql-iot write_cl=LOCAL_ONE --docker-metrics

然後在瀏覽器中開啟

http://localhost:3000

請注意,這僅適用於Linux,並且要求Docker在主機上執行。

有關更多資訊,請參見nosqlb官方文件

3)tlp-stress

注意:tlp-stress沒有類似的觀察性功能,但會在埠9501上匯出Prometheus指標。

cassandra-stress提供的開箱即用的圖表生成功能相當不錯。對於任何慎重嚴肅的基準測試,您都會希望將Cassandra的指標視覺化並深入瞭解壓測工具的表現,而不僅停留在效能數字上。

05批處理大小和重寫操作

下面的呼叫非常有意思,因為很多Cassandra-stress的使用者為之感到痛苦。在Cassandra中,unlogged batch是不正常的且不被建議使用的,除非用於位於同一分割槽中的幾小組資料行(10-20行)。

在預設情況下,cassandra-stress會將所有分割槽的寫入都放進同一個的批處理中,這會導致不佳且不切實際的結果。要讓cassandra-stress不使用批處理是不可能的,要讓cassandra-stress使用只包含單個插入的批處理也相當麻煩。

更多資訊請參見此JIRA裡的討論——CASSANDRA-11105

在已釋出的Cassandra基準測試中,我們不經常看到重寫(overwrite)和刪除,因為這些不太容易發生。通常來說這是有道理的,因為像鍵值和時間序列之類的工作負載不太可能會重寫資料模型。

但是,目前有很多資料模型確實需要重寫和刪除,這也是為什麼我們想要做一下這方面的基準測試。

1)cassandra-stress

首先,請下載batch_too_large.yaml
(https://issues.apache.org/jira/secure/attachment/12785737/batch_too_large.yaml)

$ cassandra-stress user profile=batch_too_large.yaml ops\(insert=1\) -insert visits=FIXED\(10M\)

2)tlp-stress

在預設情況下,tlp-stress不會像cassandra-stress一樣執行unlogged batch。如果需要unlogged batch,則需要編寫自己的工作負載,請參閱下文“自定義工作負載”的部分。

tlp-stress確實使刪除非常容易,因其以類似於讀取率引數的方式處理刪除動作。下面的命令列將使10%的操作刪除以前寫入的資料。

$ tlp-stress run KeyValue --deletes 0.1

tlp-stress的重寫方式與cassandra-stress相似。它將在100個分割槽(partition)上寫入10萬次操作。如果沒有聚類鍵,則每個分割槽上的重寫量大約為1k。

$ tlp-stress run KeyValue -p 100 -n 100k

3)nosqlbench

通過提供比迭代計數小的分割槽數,nosqlbench可以以與cassandra-stress和tlp-stress相同的方式處理重寫。nosqlbench當前不提供任何刪除操作或unlogged batch的示例。

使用自定義工作負載可以實現logged batch,刪除操作和unlogged batch可能也可以用自定義工作負載實現。

06預定義的工作負載

1)Cassandra-stress

cassandra-stress沒有內建的工作負載。如下一節所示,您需要指定user的模式並提供自己的配置。

2)tlp-stress

tlp-stress具有最廣泛的工作負載型別。這些工作負載已在TLP中用於論證某些功能的實際侷限性,併為推薦最佳生產方案提供了的實踐方法。

$ tlp-stress list 
Available Workloads:
AllowFiltering
BasicTimeSeries
CountersWide
KeyValue
LWT
Locking
Maps
MaterializedViews
RandomPartitionAccess
Sets
UdtTimeSeries
$ tlp
-stress run CountersWide

3)nosqlbench

nosqlbench從其預定義的yaml工作負載檔案中給出工作負載。在這些工作負載中,它列出了所使用的不同階段,這些階段可以組合在一起。這些讓我們一窺工作負載可以被定義得多麼複雜和細緻。nosqlbench還列出了非基於cql驅動程式的sequences工作負載。

$ nb --list-workloads
    from: cql-keyvalue.yaml
from: cql-iot.yaml
from: cql-iot-dse.yaml
from: cql-tabular.yaml
from: sequences.yaml

$ nb cql
-tabular

07自定義工作負載

作為生產環境可行性計劃或容量規劃工作的一部分的基準測試,幾乎總是需要自定義的工作負載。

1)cassandra-stress

關於cassandra-stress,Zipkin專案中有一個例子。掃描二維碼訪問GitHub上的程式碼檔案。

https://github.com/openzipkin/zipkin/tree/master/zipkin-storage/cassandra/src/test/resources

cassandra-stress不能一次對多個表進行基準測試,因此每個表都有單獨的工作負載yaml檔案,而且它們必須單獨地被呼叫。

這裡我們看到cassandra-stress不支援Zipkin的原始模式(schema),特別是使用者自定義資料型別(UDT)和集合(collection),因此上面連結中的資料夾還包含一些cql檔案,來建立我們可以用做壓力測試的模式(schema)。

建立zipkin測試的模式

cqlsh -f zipkin2-test-schema.cql

用些資料填充該模式,並適當調整

$ cassandra-stress  user profile=span-stress.yaml ops\(insert=1\) no-warmup duration=1m  -rate threads=4 throttle=50/s

現在對讀寫混合工作負載進行基準測試,然後再適當調整

$ cassandra-stress  user profile=span-stress.yaml ops\(insert=1,by_trace=1,by_trace_ts_id=1,by_annotation=1\)  duration=1m  -rate threads=4 throttle=50/s

從上面可以看出,在cassandra-stress裡建立自定義工作負載一直是一項艱鉅困難的工作。但是tlp-stress和nosqlbench在這方面有所改進,因它們使用了其它的方式。

2)nosqlbench

nosqlbench通過yaml檔案提供所有工作負載的配置。對於新手來說,理清這些檔案的頭緒無疑有些令人畏縮,但是,利用好已有的文件,並先直接使用或微調預定義的工作負載來進行練習,掌握這些的概念的機會就很大了。

3)tlp-stress

另一方面,tlp-stress專注於用程式碼編寫工作負載。tlp-stress是用Kotlin編寫的,因此,如果您喜歡Kotlin,您會發現編寫工作負載是快捷而直觀的。

這裡有一些現成的工作負載,大概一掃您就會發現它們很容易編寫。

https://github.com/thelastpickle/tlp-stress/tree/master/src/main/kotlin/com/thelastpickle/tlpstress/profiles

08客戶端併發競爭和伺服器飽和

哪個基準測試工具更快?這可能聽起來像是一個奇怪的問題,但卻帶來了一些實際的擔憂。不僅要選擇執行客戶端的硬體或需要多少客戶端,還要在獲得的毫無意義的結果時意識到問題。對於基準測試來說,瞭解要生成的負載和所需測量的指標與工作負載本身是同樣重要的。

避免伺服器飽和是很重要的。任何將吞吐量提高到極限的基準測試都是沒有意義的。

現實世界中的(且非常之簡化的)一個對比來自於聯機分析處理(OLAP)叢集。這些叢集就像是與Apache Spark配對的那些叢集,在沒有適當閾值的spark-cassandra-connector上,其吞吐量出現了類似於溜溜球上下跳動的效果——當叢集飽和時,吞吐量會被卡住,然後又重新開始接受寫入。

長時間且可持續進行的高吞吐量可以通過適當的調優和對吞吐量閾值的設定來實現。而測試負載下響應速度(RUL)基準時,才是我們該限制吞吐量並觀察響應速度的時候。

這些問題也擴充套件到了客戶壓力工具中。不像能自行在達到預定的吞吐量閾值時對負載進行阻隔或降低的伺服器,客戶端的操作吞吐量是需要限制或提前計劃的。

這種差異很重要,但對其進行解釋超出了本文章的範圍。

對於那些有興趣的人,建議閱讀這篇的文章——《在Cassandra Stress中解決Coordinated Omission》

1)cassandra-stress

$ cassandra-stress write -rate threads=4 fixed=50/s

2)nosqlbench

nosqlbench本身沒有排程程式,但是可以通過非同步請求和非固定的執行緒數來減少Coordinated Omission。

有關nosqlbench計時術語的更多資訊,請參見此處

$ nb cql-iot cyclerate=50 async=256 threads=auto

很少有生產叢集能表現出這樣恆定的吞吐量,因此基準測試時不穩定的突然輸出是一件很有必要的事情。目前只有nosqlbench能在程序內執行此操作。

$ nb cql-iot cyclerate=50,1.5 async=256 threads=auto

這指定了每秒50次操作的速率閾值,突發輸出最高可達50%。

有關突發(Burst)的更多資訊,請參見此處

3)tlp-stress

tlp-stress不能處理Coordinated Omission。其--rate引數依賴於Google的RateLimiter且限制了吞吐量,但它沒有排程程式。

09關於文件

通過瀏覽以上三種工具的文件,您會很容易看到nosqlbench提供了更多的功能。雖然tlp-stress還缺失在如何實現自定義工作負載方面(或tlp-stress所指的profile)的資訊,但是tlp-stress文件優雅簡潔,對於初學者而言易於使用。

10總結

cassandra-stress只對於很小一部分的基於Cassandra的應用程式而言是高階工具。它的使用者體驗很笨拙,使用者通常需要理解一些奇奇怪怪的程式碼才能使其發揮預期的作用。

tlp-stress是為替代cassandra-stress而編寫的。除了不處理Coordinated Omission之外,它在各方面都達到了這一目標:易用的文件、豐富的命令列使用者介面,以及易於理解和改進的程式碼。

nosqlbench更進了一步,旨在替代雅虎雲服務基準測試(YCSB, 即Yahoo! Cloud Serving Benchmark)。它就像一個高階使用者的工具,而且它優越的特性和能力使其當之無愧。我們期待在NoSQL世界中,看到越來越多的可以用來測試許多不同技術的工作負載。