couchbase基准显示非常慢的插入和获取(使用keyvalue操作);比持久化mysql数据慢

20jt8wwn  于 2021-06-09  发布在  Redis
关注(0)|答案(2)|浏览(426)

我做了一个小的基准测试来比较couchbase(在win中运行)与redis和mysql(编辑:添加了aerospeike进行测试)
我们正在将100000个json“文档”插入三个数据库/存储:
redis(只需插入,没有其他内容)
couchbase(内存中的临时存储桶,jobid上的json索引)
mysql(简单表;id(int)、数据(mediumtext)、id上的索引)
aerospike(内存存储)
json文件是67行,大约1800字节。
插入:
沙发床:60-100秒(编辑:似乎变化很大!)
mysql:30秒
redis:8秒
飞镖:71秒
阅读:我们阅读了1000次,我们做了10次,看看平均值。
couchbase:600-700毫秒用于1000个get(使用keyvalue操作,而不是查询api)。使用查询api,这大约需要1500毫秒)
mysql:90-100毫秒1000次
redis:50-60ms,1000次
aerospike:750ms,1000次
结论:couchbase似乎是最慢的(插入时间似乎变化很大),aerospeck也非常慢。这两个都使用内存存储(couchbase=>ephemeral bucket,aerospeike=>storage engine memory)。
问:为什么couchbase上的内存读写速度如此之慢,甚至比使用普通mysql(在ssd上)还要慢?

代码

注意:使用task.whenall或等待每个调用都没有区别。
插入
沙发床:

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();

阅读
沙发床:

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();

沙发床设置:




和铲斗耐久性:

我只有1个节点(没有集群),它在我的机器上是本地的,运行ryzen 3900x 12核,m.2 ssd,win10,32 gb ram。
如果您做到了这一点,下面是一个github回购,其中包含我的基准代码:https://github.com/tedekeroth/couchbasetests

x8goxv8g

x8goxv8g1#

我做了你的沙发床测试,把非沙发床的部分注解掉了。修复了从集合(mycollection)而不是jobcache中选择的查询,并删除了metrics选项。并在jobid上创建了一个索引。在上创建索引mybucket\u jobiddefault:mybucket.myscope.mycollection (jobid)它在19秒内插入100000个文档,kv平均获取146usec的文档,按jobid查询平均965usec。

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).

这是在MacBookPro上的7.0Build3739上,cbserver在本地运行。

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

我有一个用于javasdk的小型loaddriver应用程序,它使用kvapi。它有4个线程,平均响应时间为54微秒,吞吐量为73238个请求/秒。它使用localhost上cb服务器上的travel样本桶。git@github.com:mikereiche/loaddriver.git
运行:秒:10,线程:4,超时:40000us,阈值:8000us请求/秒:0(最大值),强制gc间隔:0ms计数:729873,请求/秒:72987,最大值:2796us平均值:54us,聚合rq/秒:73238
对于查询api,我得到了以下速度慢了18倍的结果。
运行:秒:10,线程:4,超时:40000us,阈值:8000us请求/秒:0(最大值),强制gc间隔:0ms计数:41378,请求/秒:4137,最大值:12032us平均值:965us,聚合rq/秒:4144

woobm2wo

woobm2wo2#

我必须亲自进行这样的比较才能做一个全面的调查,但有两件事很突出。
你的并行执行不是完全并行的。 async 方法同步运行到第一个等待,因此 InsertAsync/GetAsync 在添加任务时,第一个等待是按顺序运行的,而不是并行运行的。
couchbasenetclient在后台进行一些延迟连接设置,而您在timed部分要为此付出代价。取决于环境,包括ssl协商等,这可能是一个重要的初始延迟。
您可以通过使用 Task.Run 但您可能需要预先调整默认线程池大小。
您可以通过对bucket执行至少一个操作(包括 bucket.WaitUntilReadyAsync() )在定时部分之前。
60秒的插入仍然看起来不正常。您使用了多少个节点和什么耐久性设置?

相关问题