NoSQLBench釋出於2020年3月,它是第一個試圖在分散式系統效能測試上做到面面俱到的專業測試工具。同時,它旨在讓輕量級的和專業的使用者都可以使用。
什麼是NoSQLBench?
當今的開發人員希望創造效能可擴充套件的應用程式。這就要求使用在多地執行的分散式系統,無論是容器映象或是跨公共、私有或混合雲平臺執行的服務。然而,測試這些應用程式往往比想象的要難。
可擴充套件的系統的效能測試工具一直都很有限。NoSQLBench釋出於2020年3月,它是第一個試圖在分散式系統上做到面面俱到的專業測試工具。同時,它旨在讓輕量級的和專業的使用者都可以使用。
NoSQLBench致力於解決其他工具無法解決的測試難題。它允許使用者使用目標系統的原生查詢語言對訪問模式進行建模。它不假定所有NoSQL資料庫只是同一概念的不同版本。用NoSQLBench進行實際測試並不需要您是專業的程式設計師,也不需要您傳輸巨量資料來得到真實的測試資料或操作。
使用NoSQLBench配置了一個工作負載workload後,就可以開始測試了。如果需要更改訪問模式或操作中使用的資料,只需要更改配置,就可以再次測試。這個過程如此簡單,即使是任意大小的資料集也可如此操作。這樣使用者可以直觀的洞察到生產環境中同樣的工作負載會是什麼樣的效果。
NoSQLBench具有其他測試工具不具備的功能
- 基於模版的的過程式資料生成——使用函式輕鬆複製和貼上海量的虛擬資料集
- 確定性的工作負載的表現——每個週期cycle都是特定並可重複的
- 模組化協議支援——包括cql及其他
- 語句和資料的配置語言——操作和訪問模式的語言
- 內建指令碼——啟用自動機驅動的高階場景分析
- 基於週期cycle的操作和診斷——可以重試任何特定的週期以瞭解更多資訊
- docker-metrics監控介面——支援自動執行和配置基於docker的grafana功能棧,以實現豐富的監控介面
- 協調一致的顯示高保真的效能指標,支援coordinated omission,具有多種輸出格式和報告選項
這些功能每一個都有單獨的重要價值。當把它們合在一起時,他們將形成一個功能強大的工具包,使效能測試對每個人來說都變得更輕鬆。NoSQLBench使我們能夠專注於測試需求,而不用在測試工具上做出妥協。
這也意味著我們可以避免建立昂貴而複雜的一次性測試工具。在實踐中,這些一次性的工具通常有嚴重的缺陷。畢竟,構建各方面都考慮周全的測試工具並非易事。我們希望通過提供一種工具,它既可以簡化處理所有困難的部分而又不剝奪使用者的控制權。
效能測試工具需要一段時間才能在測試人員的工具箱中贏得一席之地。值得慶幸的是,無論是對於DataStax還是客戶,NoSQLBench都已證明自己是無價的工具。
核心概念
NoSQLBench的工作負載都被整合在一個YAML配置檔案中。工作負載主要基於語句(statements),而YAML格式強調出了這一點。您也可以通過在這些語句中新增繫結(bindings)來指定用於操作的資料。為了組織和選出起作用的語句,您可以新增標籤(tags)。語句還可以有針對特定語句的引數(params),比如是否將某一操作標記為冪等操作,或者是否使用預處理語句(prepared statement)等等。
Hello World
本教程是一個針對基礎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
這個版本中的新元素如下:
- 繫結部分沒有直接附加到insert-sample語句: 由於insert-sample語句模板中的名稱引用了全域性文件範圍中提供的繫結名稱,所以會使用它們。任何沒有引用的繫結都只是作為一個可選項存在,但並沒有被使用。如果沒有使用,它就不會被啟用。
- 引入了語句塊(statement blocks):這是組織語句的一種方式,以便您將它們打包進行配置和引用。第一個塊中的所有DDL語句都有一個語句引數prepared: false
- 使用語句標籤 (statement tags): 這允許我們選擇起作用的語句,我們將在下一節中演示。第一個塊中定義的所有語句都具有塊級配置,帶有標籤phase: schema。第二塊中的所有語句(僅一個)都有標籤 phase: main。
- 新增了一個新語句來實現讀取操作:實現randomish_cycle繫結(binding)的函式將生成一個介於0和當前操作週期之間的值。
- 為了演示的目的,新增了一些比率:按照上述比率,每5次操作中插入操作佔4次,讀取操作為第5次。為每個週期選擇的語句也是基於這個比率。
由於我們已經將不同型別的語句組織到測試工作流程的不同部分中,我們就可以分別呼叫它們了。
注意:在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
您可以在這個網址下載NoSQLBench的最新版本:https://github.com/nosqlbench/nosqlbench/releases
展望
NoSQLBench一直在改進。首先必須構建NoSQLBench的核心機制,而下一代的改進將集中於使使用者更容易使用NoSQLBench。我們期待著看到以下進步:
- 改進的文件
- 改進的內建案例
- 更多的驅動程式
- 指南的使用者介面
NoSQLBench允許您檢視在使用或不使用應用程式時資料庫的執行情況。它使得迭代資料模型、測量基線效能和計劃資料庫的規模成為可能。
我們希望讓所有人都能使用一套通用的概念和工具,不論你測試的是什麼NoSQL資料庫,都使得測試更加容易。為了實現這個目標,我們希望NoSQLBench所基於的工具集可以成為行業內NoSQL測試的事實標準。通過將NoSQLBench和CQL驅動程式作為開源釋出,我們已經邁出了實現這一願景的第一步。
測試愉快!