我做了一个小型基准测试,将 Couchbase(在 Win 中运行)与 Redis 和 MySql 进行比较(编辑:添加了 Aerospike 进行测试)
我们将 100 000 个 JSON“文档”插入到三个数据库/存储中:
- Redis(只是插入,没有别的)
- Couchbase(内存中的临时存储桶,JobId 上的 JSON 索引)
- MySql(简单表;Id(int),数据(MediumText),Id上的索引)
- Aerospike(内存存储)
JSON文件有67行,约1800字节。
INSERT:
- Couchbase:60-100 秒(编辑:似乎差别很大!)
- MySql:30秒
- Redis:8秒
- 气钉:71秒
读:
我们阅读了 1000 次,重复了 10 次并查看平均值。
- Couchbase:1000 次 GET 需要 600-700 毫秒(使用 KeyValue 操作,而不是查询 API。使用查询 API,这大约需要 1500 毫秒)
- MySql:1000 次 GET 需要 90-100 毫秒
- Redis:1000 次 GET 需要 50-60 毫秒
- Aerospike:1000 次 GET 需要 750 毫秒
结论:Couchbase 似乎最慢(INSERT 时间似乎变化很大),Aerospike 也很慢。这两者都使用内存存储(Couchbase => 临时存储桶,Aerospike => 存储引擎内存)。
问题:为什么 Couchbase 上的内存写入和读取速度如此之慢,甚至比使用普通 MySQL(在 SSD 上)还要慢?
CODE
注意:使用 Task.WhenAll 或等待每个调用并没有什么区别。
INSERT
沙发底座:
IBucket bucket = await cluster.BucketAsync("halo"); // <-- ephemeral
IScope scope = bucket.Scope("myScope");
var collection = scope.Collection("myCollection");
// EDIT: Added this to avoid measuring lazy loading:
JObject t = JObject.FromObject(_baseJsonObject);
t["JobId"] = 0;
t["CustomerName"] = $"{firstnames[rand.Next(0, firstnames.Count - 1)]} {lastnames[rand.Next(0, lastnames.Count - 1)]}";
await collection.InsertAsync("0", t);
await collection.RemoveAsync("0");
List<Task> inserTasks = new List<Task>();
sw.Start();
foreach (JObject temp in jsonObjects) // jsonObjects is pre-created so its not a factor in the test
{
inserTasks.Add(collection.InsertAsync(temp.GetValue("JobId").ToString(), temp));
}
await Task.WhenAll(inserTasks);
sw.Stop();
Console.WriteLine($"Adding {nbr} to Couchbase took {sw.ElapsedMilliseconds} ms");
Redis(使用 ServiceStack!)
sw.Restart();
using (var client = redisManager.GetClient())
{
foreach (JObject temp in jsonObjects)
{
client.Set($"jobId:{temp.GetValue("JobId")}", temp.ToString());
}
}
sw.Stop();
Console.WriteLine($"Adding {nbr} to Redis took {sw.ElapsedMilliseconds} ms");
sw.Reset();
Mysql:
MySql.Data.MySqlClient.MySqlConnection mySqlConnection = new MySql.Data.MySqlClient.MySqlConnection("Server=localhost;Database=test;port=3306;User Id=root;password=root;");
mySqlConnection.Open();
sw.Restart();
foreach (JObject temp in jsonObjects)
{
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand($"INSERT INTO test (id, data) VALUES ('{temp.GetValue("JobId")}', @data)", mySqlConnection);
cmd.Parameters.AddWithValue("@data", temp.ToString());
cmd.ExecuteNonQuery();
}
sw.Stop();
Console.WriteLine($"Adding {nbr} to MySql took {sw.ElapsedMilliseconds} ms");
sw.Reset();
READ
沙发底座:
IBucket bucket = await cluster.BucketAsync("halo");
IScope scope = bucket.Scope("myScope");
var collection = scope.Collection("myCollection");
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++)
{
string key = $"{r.Next(1, 100000)}";
var result = await collection.GetAsync(key);
}
sw.Stop();
Console.WriteLine($"Couchbase Q: {q}\t{sw.ElapsedMilliseconds}");
Redis:
Stopwatch sw = Stopwatch.StartNew();
using (var client = redisManager.GetClient())
{
for (int i = 0; i < nbr; i++)
{
client.Get<string>($"jobId:{r.Next(1, 100000)}");
}
}
sw.Stop();
Console.WriteLine($"Redis Q: {q}\t{sw.ElapsedMilliseconds}");
MySQL:
MySqlConnection mySqlConnection = new MySql.Data.MySqlClient.MySqlConnection("Server=localhost;Database=test;port=3306;User Id=root;password=root;");
mySqlConnection.Open();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < nbr; i++)
{
MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand($"SELECT data FROM test WHERE Id='{r.Next(1, 100000)}'", mySqlConnection);
using MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
}
}
sw.Stop();
Console.WriteLine($"MySql Q: {q} \t{sw.ElapsedMilliseconds} ms");
sw.Reset();
沙发底座设置:
and
和铲斗耐用性:
我只有 1 个节点(无集群),它位于我的计算机本地,运行 Ryzen 3900x 12 核、M.2 SSD、Win10、32 GB RAM。
如果您已经完成了这一步,这里有一个包含我的基准代码的 GitHub 存储库:https://github.com/tedekeroth/CouchbaseTests https://github.com/tedekeroth/CouchbaseTests