本文介紹TairSearch、RediSearch資料寫入和搜尋效能的測試方法及測試結果。
TairSearch是Tair全自研的全文檢索搜尋資料結構,採用與Elasticsearch相似的查詢文法,可實現高效的全文檢索搜尋,更多資訊請參見Search。
測試說明
用戶端測試環境
測試環境資訊 | 說明 |
部署壓測工具的裝置 | Elastic Compute Service執行個體,規格為ecs.g7.8xlarge,詳情請參見執行個體規格類型系列。 |
地區和可用性區域 | 華東1(杭州),可用性區域K。 |
作業系統 | CentOS 7.9 64位。 |
資料庫測試環境
在同一台ECS執行個體上搭建Tair資料庫和Redis資料庫,執行個體資訊如下。
表 1. 自建Tair資料庫
測試環境資訊 | 說明 |
Tair版本 | 記憶體型(相容Redis 5.0),5.0.30。 |
IO Thread數 | 4 |
CPU | 為Tair執行個體綁定6個CPU,命令樣本: |
表 2. 自建Redis資料庫
測試環境資訊 | 說明 |
Redis版本 | 7.0.10。 |
RediSearch版本 | 2.6.6,開啟CONCURRENT_WRITE_MODE。 |
RedisJson版本 | 2.4.6。 |
IO Thread數 | 4 |
CPU | 為Redis執行個體綁定6個CPU,命令樣本: |
測試資料
中、英文測試資料樣本如下:
{
"id":"History_of_Pakistan",
"title":"History of Pakistan",
"url":"https://en.wikipedia.org/wiki/History_of_Pakistan",
"abstract":"The history of Pakistan for the period preceding the country's independence in 1947Pakistan was created as the Dominion of Pakistan on 14 August 1947 after the end of British rule in, and partition of British India. is shared with that of Afghanistan, India."
}
{
"id":"Wikipedia:哲學",
"title":"Wikipedia:哲學",
"url":"https://zh.wikipedia.org/wiki/%E5%93%B2%E5%AD%A6",
"abstract":"哲學()是研究普遍的、基本問題的學科,包括存在、知識、價值、理智、心靈、語言等領域。哲學與其他學科不同之處在於哲學有獨特之思考方式,例如批判的方式、通常是系統化的方法,並以理性論證為基礎。"
}
壓測工具
根據實際情況下載對應作業系統的二進位可執行檔(TairSearchBench.Darwin、TairSearchBench.Linux、TairSearchBench.Windows)。
以Linux為例,執行./TairSearchBench.Linux --help
可查看壓測工具的使用方法,用法如下:
Usage of ./TairSearchBench.linux:
-a string
The address(ip:port) of network to connect
# 執行個體串連地址。
-c int
Benchmark concurrency (default 30)
# 並發數,預設為30。
-d uint
Specify the number of seconds for the benchmark (default 30)
# 指定測試時間,到達時間後,測試終止,預設為30s。
-e string
The engine backend to run [tairsearch/redisearch]
# 指定運行引擎為TairSearch或RediSearch。
-f string
Input file to ingest data from (wikipedia abstracts)
# 執行資料檔案路徑。
-h string
Print usage (default "help")
# 顯示使用方法。
-j string
Specify the big json file to write
# 指定要寫入的Json檔案路徑。
-n uint
Specify the number of times to benchmark (default 100000)
# 指定總測試數,預設為100000。
-o int
Overwrite the doc (We will write the document with the same document id)
# 是否覆蓋寫,取值為1(開啟)或0(關閉,預設值)。
-p string
The password of redis to connect
# 執行個體的密碼。
-q string
Search query string to benchmark
# 指定壓測的查詢語句。
-s uint
Specify the compress threshold for tairsearch (default 10000000000)
# 指定TairSearch的文檔壓縮閾值,文檔超過該大小會進行壓縮,單位為位元組,預設為10000000000(10 kb)。
-t string
Specify the type of benchmark [write/search/readwrite]
# 指定測試類型為write、search或readwrite。
-z string
Specify the analyzer to use for query (default "standard")
# 指定查詢的分詞器,預設為standard。
測試時,提前分配20個CPU進行測試,命令樣本:taskset -c 10-30 ./TairSearchBench.linux
。
準備工作
建立Schema(索引),樣本如下。
TairSearch:
{ "settings": { "compress_doc": { "size": "使用者傳入的壓縮閾值", "enable": true } }, "mappings": { "properties": { "id": {"type": "keyword"}, "url": {"type": "keyword", "index": false}, "title": {"type": "text", "analyzer": "使用者傳入的analyzer"}, "abstract": {"type": "text", "analyzer": "使用者傳入的analyzer"}, "url_len": {"type": "integer"}, "abstract_len": {"type": "integer"}, "title_len": {"type": "integer"} } } }
RediSearch:
\\ SCHEMA $.id AS id TEXT $.url AS url TEXT NOINDEX $.title AS title TEXT $.abstract AS abstract TEXT $.abstract_len AS abstract_len NUMERIC $.url_len AS url_len NUMERIC $.title_len AS title_len NUMERIC \\ 如果是中文文檔,需要加上"LANGUAGE CHINESE"。
測試命令與測試結果
本次除混合讀寫以外的各項測試均為測試100萬次,例如寫入100萬個英文文檔、基於100萬個文檔查詢100萬次等。混合讀寫測試為測試60s。
寫入英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e tairsearch -f ./enwiki-latest-abstract.xml -c 20 -n 1000000 -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e redisearch -f ./enwiki-latest-abstract.xml -c 20 -n 1000000 -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) | 最終記憶體佔用(GB) |
TairSearch | 22615.15 | 0.874 | 1.735 | 1.39 |
RediSearch | 18295.10 | 1.092 | 2.352 | 1.67 |
寫入中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e tairsearch -f ./zhwiki-latest-abstract.xml -c 20 -n 1000000 -a 127.0.0.1:6379 -z jieba
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e redisearch -f ./zhwiki-latest-abstract.xml -c 20 -n 1000000 -a 127.0.0.1:6379 -z chinese
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) | 最終記憶體佔用(GB) |
TairSearch | 13980.41 | 1.427 | 3.275 | 1.87 |
RediSearch | 10924.40 | 1.830 | 3.857 | 1.83 |
TairSearch佔用更多記憶體的原因可能是:使用了Jieba分詞器,分出更細緻、更多的詞元(Token)。
覆蓋寫入英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e tairsearch -f ./enwiki-latest-abstract.xml -c 20 -n 1000000 -o 1 -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e redisearch -f ./enwiki-latest-abstract.xml -c 20 -n 1000000 -o 1 -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) | 最終記憶體佔用(GB) |
TairSearch | 9775.03 | 2.041 | 3.974 | 0.0002 |
RediSearch | 22239.67 | 0.898 | 1.38 | 0.165 |
TairSearch在覆蓋寫時是同步刪除,而RediSearch是標記刪除,標記刪除可能會造成記憶體存在垃圾(記憶體浪費)。
覆蓋寫入中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e tairsearch -f ./zhwiki-latest-abstract.xml -c 20 -n 1000000 -o 1 -a 127.0.0.1:6379 -z jieba
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t write -e redisearch -f ./zhwiki-latest-abstract.xml -c 20 -n 1000000 -o 1 -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) | 最終記憶體佔用(GB) |
TairSearch | 6194.15 | 3.206 | 6.456 | 0.025(含Jieba分詞器詞庫) |
RediSearch | 25096.18 | 0.796 | 1.338 | 0.671 |
TairSearch在覆蓋寫時是同步刪除,而RediSearch是標記刪除,標記刪除可能會造成記憶體存在垃圾(記憶體浪費)。
Term查詢英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"term":{"abstract":"hello"}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:hello" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 45501.13 | 0.437 | 0.563 |
RediSearch | 28513.87 | 0.700 | 0.833 |
Term查詢中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"term":{"abstract":"你好"}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:你好" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 40670.47 | 0.489 | 0.635 |
RediSearch | 24437.48 | 0.817 | 1.331 |
Match查詢英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"match":{"abstract":{"operator":"and","query":"chinese history"}}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:chinese history" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 24548.94 | 0.812 | 0.971 |
RediSearch | 2420.66 | 8.261 | 8.523 |
Match查詢中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 100000 -q '{"query":{"match":{"abstract":{"operator":"and","query":"中國的歷史"}}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 100000 -q "@abstract:中國的歷史" -a 127.0.0.1:6379 -analyzer jieba
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 6601.05 | 3.027 | 3.669 |
RediSearch | 889.37 | 22.486 | 22.985 |
Bool查詢英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 100000 -q '{"query":{"bool":{"must":[{"term":{"abstract":"war"}},{"term":{"abstract":"japanese"}},{"range":{"abstract_len":{"gt":500}}}],"must_not":{"term":{"abstract":"America"}},"should":[{"term":{"abstract":"chinese"}},{"term":{"abstract":"china"}}]}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 100000 -q "@abstract:(war japanese -America (chinese|china)) @abstract_len:[500 +inf]" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 4554.22 | 4.388 | 5.702 |
RediSearch | 1124.08 | 17.791 | 18.444 |
Bool查詢中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 100000 -q '{"query":{"bool":{"must":[{"term":{"abstract":"戰爭"}},{"term":{"abstract":"日本"}},{"range":{"abstract_len":{"gt":500}}}],"must_not":{"term":{"abstract":"美國"}},"should":[{"term":{"abstract":"中國"}},{"term":{"abstract":"亞洲"}}]}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:(日本 -美國 (中國|亞洲)) @abstract_len:[500 +inf]" -a 127.0.0.1:6379 -analyzer jieba
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 2619.00 | 7.623 | 18.42 |
RediSearch | 1199.76 | 16.669 | 17.064 |
Range查詢英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"range":{"abstract_len":{"lte":420, "gte":400}}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract_len:[400,420]" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 2840.02 | 7.038 | 8.599 |
RediSearch | 1307.02 | 15.300 | 16.817 |
Prefix查詢英文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"prefix":{"abstract":"happiness"}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:happiness*" -a 127.0.0.1:6379
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 36491.10 | 0.545 | 0.688 |
RediSearch | 25558.92 | 0.781 | 0.930 |
Prefix查詢中文資料
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e tairsearch -c 20 -n 1000000 -q '{"query":{"prefix":{"abstract":"開心"}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t search -e redisearch -c 20 -n 1000000 -q "@abstract:開心*" -a 127.0.0.1:6379 -z chinese
測試結果:
對比項 | QPS(次/秒) | Average Latency(毫秒) | 99th Percentile Latency(毫秒) |
TairSearch | 41308.71 | 0.481 | 0.638 |
RediSearch | 27457.86 | 0.727 | 1.234 |
混合讀寫測試(Write與Term查詢)
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t readwrite -e tairsearch -f ./enwiki-latest-abstract.xml -c 20 -d 60 -q '{"query":{"term":{"abstract":"hello"}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t readwrite -e redisearch -f ./enwiki-latest-abstract.xml -c 20 -d 60 -q "@abstract:hello" -a 127.0.0.1:6379
測試結果:
對比項 | 平均寫入QPS(次/秒) | 平均寫入Average Latency(毫秒) | 平均查詢QPS(次/秒) | 平均查詢Average Latency(毫秒) |
TairSearch | 14699.77 | 1.359 | 16224.03 | 1.232 |
RediSearch | 11386.75 | 1.755 | 11386.70 | 1.755 |
混合讀寫測試(Write與Bool查詢)
測試命令:
TairSearch:
taskset -c 10-30 ./TairSearchBench.linux -t readwrite -e tairsearch -f ./enwiki-latest-abstract.xml -c 20 -d 60 -q '{"query":{"bool":{"must":[{"term":{"abstract":"war"}},{"term":{"abstract":"japanese"}},{"range":{"abstract_len":{"gt":500}}}],"must_not":{"term":{"abstract":"America"}},"should":[{"term":{"abstract":"chinese"}},{"term":{"abstract":"china"}}]}}}' -a 127.0.0.1:6379
RediSearch:
taskset -c 10-30 ./TairSearchBench.linux -t readwrite -e redisearch -f ./enwiki-latest-abstract.xml -c 20 -d 60 -q "@abstract:(war japanese -America (chinese|china)) @abstract_len:[500 +inf]" -a 127.0.0.1:6379
測試結果:
對比項 | 平均寫入QPS(次/秒) | 平均寫入Average Latency(毫秒) | 平均查詢QPS(次/秒) | 平均查詢Average Latency(毫秒) |
TairSearch | 9589.18 | 2.085 | 10504.31 | 1.903 |
RediSearch | 5284.01 | 3.784 | 5283.96 | 3.784 |
總結
TairSearch通過內部精巧的倒排索引設計,充分利用多核並行計算的能力,實現了高吞吐、低延時的讀寫效能。同時,在保證不顯著降低讀寫效能的前提下,TairSearch儘可能地使用壓縮型資料結構,以降低記憶體消耗進而降低使用成本。