本文介绍TairSearch、RediSearch数据写入和搜索性能的测试方法及测试结果。
TairSearch是Tair全自研的全文搜索数据结构,采用与Elasticsearch相似的查询语法,可实现高效的全文搜索,更多信息请参见Search。
测试说明
客户端测试环境
测试环境信息 | 说明 |
部署压测工具的设备 | |
地域和可用区 | 华东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尽可能地使用压缩型数据结构,以降低内存消耗进而降低使用成本。