Couchbase 基准测试显示 INSERT 和 GET 非常慢(使用 KeyValue 操作);比持久化 MySQL 数据慢

2024-01-01

我做了一个小型基准测试,将 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


我拿了你的 CouchbaseTests,注释掉了非 Couchbase 的部分。修复了从集合 ( myCollection ) 而不是作业缓存中选择的查询,并删除了 Metrics 选项。并在JobId上创建了索引。 在默认值:myBucket.myScope.myCollection (JobId) 上创建索引 mybucket_JobId 它在 19 秒内插入 100,000 个文档,kv 获取文档平均需要 146 usec,通过 JobId 查询平均需要 965 usec。

Couchbase Q: 0 187
Couchbase Q: 1 176
Couchbase Q: 2 143
Couchbase Q: 3 147
Couchbase Q: 4 140
Couchbase Q: 5 138
Couchbase Q: 6 136
Couchbase Q: 7 139
Couchbase Q: 8 125
Couchbase Q: 9 129
average et: 146 ms per 1000 -> 146 usec / request

Couchbase Q: 0 1155
Couchbase Q: 1 1086
Couchbase Q: 2 1004
Couchbase Q: 3 901
Couchbase Q: 4 920
Couchbase Q: 5 929
Couchbase Q: 6 912
Couchbase Q: 7 911
Couchbase Q: 8 911
Couchbase Q: 9 927
average et: 965 ms per 1000 -> 965 usec / request. (coincidentally exactly the same as with the java api).

这是在 Mac Book Pro 上的 7.0 build 3739 上,cbserver 在本地运行。

#################################################### ####################

我有一个使用 kv api 的 java sdk 小型 LoadDriver 应用程序。使用 4 个线程时,平均响应时间为 54 微秒,吞吐量为 73238 个请求/秒。它使用本地主机上的 cb 服务器上的 Travel-sample 存储桶。[电子邮件受保护] /cdn-cgi/l/email-protection:mikereiche/loaddriver.git

运行:秒:10,线程:4,超时:40000us,阈值:8000us 请求/秒:0(最大),强制GC间隔:0ms 计数:729873,每秒请求数:72987,最大值:2796us 平均:54us,聚合 rq/s:73238

对于查询 API,我得到以下结果,速度慢了 18 倍。

运行:秒:10,线程:4,超时:40000us,阈值:8000us 请求/秒:0(最大),强制GC间隔:0ms 计数:41378,每秒请求数:4137,最大值:12032us 平均:965us,聚合 rq/s:4144

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Couchbase 基准测试显示 INSERT 和 GET 非常慢(使用 KeyValue 操作);比持久化 MySQL 数据慢 的相关文章

随机推荐