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 数据慢 的相关文章

  • 如何以最少的查询次数获取帖子列表和关联标签

    我的表格结构如下 标签 更多的是一个类别 id 标签名称 描述 slug POSTS ID 标题 网址 邮戳 id idPost idTag USERS ID 用户名 userSlug VOTES id idPost idUser 每个帖子
  • MySQL 存储过程将值分配给 select 语句中的多个变量

    这是我的存储过程 我在为声明的变量赋值时遇到问题 当我执行它时 插入和更新命令工作正常 但声明变量的值保持为 0 但我在数据库中有一些价值 我怎样才能正确地做到这一点 BEGIN DECLARE PaidFee INT DEFAULT 0
  • 比较表中的行以了解字段之间的差异

    我有一个包含 20 多列的表 客户端 其中大部分是历史数据 就像是 id clientID field1 field2 etc updateDate 如果我的数据如下所示 10 12 A A 2009 03 01 11 12 A B 200
  • 为什么 MySQL 创建带有 _seq 后缀的表?

    我创建了一个 InnoDB 表 名为foo在 MySQL 中 一旦我对表执行插入操作 我就会看到另一个表foo seq被建造 如果我删除自动生成的表 它会在下一次插入后出现 是什么原因造成的 听起来像是正在创建一个序列 您是否有自动生成的主
  • 无法启动 MySQL 服务器 - 控制进程退出并出现错误代码

    我的 mysql 服务器停止后无法启动 命令使用 sudo etc init d mysql restart Error 重新启动 mysql 通过 systemctl mysql serviceJob for mysql service
  • Python:如何使用生成器来避免 sql 内存问题

    我有以下方法来访问 mysql 数据库 并且查询在服务器中执行 我无权更改有关增加内存的任何内容 我对生成器很陌生 并开始阅读更多有关它的内容 并认为我可以将其转换为使用生成器 def getUNames self globalUserQu
  • PHP 绑定“bigint”数据类型(MySQLi 准备好的语句)

    studentId 57004542323382 companyOfferId 7 sql INSERT INTO studentPlacement companyOfferId studentId VALUES if stmt db gt
  • Python 中的计时代码块,无需将其放入函数中

    我想对一段代码进行计时 而不是将其放入单独的函数中 例如 def myfunc some code here t1 time time block of code to time here t2 time time print Code t
  • 当sql连接中存在两个同名列时,如何从一个表列中获取值

    当我连接两个具有相同名称列的表时 我目前面临着尝试获取值的问题 例如 table1 date和table2 date 每个表中的日期不同 我将如何获取 日期 本例中的表1 我目前正在跑步 while row mysqliquery gt f
  • 截断 Mysql 表 Cron 作业?

    我在如何使用 cron 作业截断 Mysql 表时遇到了一些麻烦 无论我尝试什么 我似乎都无法让数据库清除表格 感谢您的帮助 mysql uderp example pexample hlocalhost Dexample e TRUNCA
  • MySQL Connector/C++ 库链接错误问题

    PROBLEM 好吧 我一直在尝试遵循 MySQL Forge Wiki 和其他一些网站上的示例代码 这些网站提供了有关如何获得简单数据库连接的教程 但由于某种原因 我的项目总是因链接错误而失败 我可以我自己不明白为什么或如何解决它 我仍在
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • 免费 PHP 登录库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 vitess 仅对特定表进行分片

    我创建了一个包含三个表的未分片键空间 现在我想对前两个表的键空间进行分片 但不想对第三个表进行分片 如何才能做到这一点 Vitess 文档不包含任何与此相关的信息或示例 请帮忙 Thanks vitess 中的垂直分片与水平分片类似 您应该
  • Mysql 将 int 转换为 MAC

    我有一些数据可以转换 其中有 2 列 其中一列有 IP 它包含整数值 我在 mysql 查询中使用了以下函数 是否有一个函数可以用来转换我的 mac 列 其中包含整数和数据类型是bigint to MAC地址 SELECT INET NTO
  • Flask-login:无法理解它是如何工作的

    我试图理解如何Flask Login https flask login readthedocs org en latest works 我在他们的文档中看到他们使用预先填充的用户列表 我想使用数据库存储的用户列表 但是 我不明白其中的一些
  • 如何将ElasticSearch与MySQL集成?

    在我的一个项目中 我计划将 ElasticSearch 与 MySQL 结合使用 我已经成功安装ElasticSearch 我可以单独管理ES中的索引 但我不知道如何用 MySQL 实现同样的功能 我读过一些文件 但我有点困惑 没有明确的想
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s

随机推荐