【问题标题】:Riak performance - unexpected resultsRiak 性能 - 意想不到的结果
【发布时间】:2011-08-25 20:32:36
【问题描述】:

在过去的几天里,我玩了一点 riak。初始设置比我想象的要容易。现在我有一个 3 节点集群,所有节点都在同一个虚拟机上运行以进行测试。

我承认,我的虚拟机的硬件设置降级了很多(1 CPU,512 MB RAM),但我仍然对 riak 的缓慢性能感到非常惊讶。

地图缩减

玩了一下 map reduce,我在一个存储桶中有大约 2000 个对象,每个对象的 json 大小约为 1k - 2k。我使用了这个地图功能:

function(value, keyData, arg) {
    var data = Riak.mapValuesJson(value)[0];

    if (data.displayname.indexOf("max") !== -1) return [data];
    return [];
}

仅执行返回其结果的 http 请求就花费了 2 秒多的时间,这还不包括我的客户端代码从 json 中反序列化结果所花费的时间。移除 3 个节点中的 2 个似乎略微将性能提高到略低于 2 秒,但这对我来说似乎仍然很慢。

这是意料之中的吗?对象的字节大小并没有那么大,一个桶中的 2000 个对象也没有那么多。

插入

批量插入大约 60.000 个与上述大小相同的对象花费了相当长的时间,实际上并没有真正起作用。

我在 riak 中插入对象的脚本在 40.000 左右死亡,并说它无法再连接到 riak 节点。在 riak 日志中,我发现了一条错误消息,表明该节点内存不足并死亡。

问题

这真的是我第一次尝试 riak,所以我肯定有可能搞砸了。

  • 我可以调整任何设置吗?
  • 硬件设置是否过于受限?
  • 也许我用于与 riak 交互的 PHP 客户端库是这里的限制因素?
  • 在同一台物理机器上运行所有节点是相当愚蠢的,但如果这是一个问题 - 我怎样才能更好地测试 riak 的性能
  • map reduce 真的那么慢吗?我在 riak 邮件列表中读到了 map reduce 对性能的影响,但是如果 Map Reduce 很慢,你应该如何对几乎实时的数据执行“查询”?我知道 riak 没有 redis 快。

如果有更多 riak 经验的人可以帮助我解决其中一些问题,那真的会对我有很大帮助。

【问题讨论】:

  • 你为什么不在riak邮件列表中询问?大多数 basho 员工都会帮助您解决问题。
  • 我知道这已经得到回答,但只是指出:“RAM 是最重要的因素之一——RAM 可用性直接影响你应该使用什么 Riak 后端(见下面的问题),也是必需的用于复杂的 MapReduce 查询。”来自:basho.com/top-five-questions-about-riak-2

标签: performance nosql riak


【解决方案1】:

这个答案有点晚了,但我想指出,Riak 的 mapreduce 实现主要设计用于处理链接,而不是整个存储桶。

Riak 的内部设计实际上已经针对整个存储桶进行了优化。这是因为桶不被认为是顺序表,而是分布在节点集群中的键空间。这意味着随机访问非常快——可能是 O(log n),但不要引用我的话——而串行访问非常、非常、非常慢。串行访问,Riak 当前的设计方式,必然意味着向所有节点询问他们的数据。

顺便说一句,Riak 术语中的“桶”并不像您想象的那样实现,令人困惑和失望。 Riak 所说的存储桶实际上只是一个命名空间。内部只有一个bucket,key以bucket名称为前缀存储。这意味着无论您的存储桶有多大或多小,枚举一个大小为 n 的存储桶中的键都将花费 m 时间,其中 m 是所有桶中键的总数。

这些限制是 Basho 的实现选择,不一定是设计缺陷。 Cassandra 实现了与 Riak 完全相同的分区模型,但支持跨大量键的高效顺序范围扫描和 mapreduce。 Cassandra 还实现了真正的存储桶。

【讨论】:

  • 能否详细说明 Cassandra 是如何实现真正的存储桶的?
  • 从 Riak 1.0 开始可以使用多个后端,如果您需要不同的存储引擎或不同的配置,这很有用。或者在这种情况下,如果您需要遍历存储桶的所有条目,而不会从其他存储桶中的条目中获得性能损失。对于多个后端,m 减少为同一后端所有存储桶中的键总数。
  • @CarloPires:在 Cassandra 中,单独的键空间(类似于 Riak 的存储桶)被单独存储和索引。
  • 我想知道为什么他们不能只保留一个单独的 buckets => 键映射,以便将 m 的值降低到大约 n我>。查阅密钥列表,然后使用该固定的密钥列表来获取记录。您可以通过其他一些数据存储(例如 Redis)单独执行此操作,但在 Riak 内部执行此操作似乎很常见。
【解决方案2】:

我现在有一个建议,因为一段时间过去了,Riak 已经出现了几个新版本。永远不要依赖完整的bucket map/reduce,这不是一个优化的操作,很有可能还有其他方法可以优化你的map/reduce,这样你就不必查看这么多数据来提取你需要的singlets。

现在在较新版本的 Riak 中提供的二级索引绝对是这方面的必经之路。在要查找的对象上放置一个索引(可能命名为“ismax_int”,值为 0 或 1)。您可以在几微秒内映射/减少具有数十万个键的二级索引,而完整的存储桶扫描需要几秒钟才能考虑。

【讨论】:

    【解决方案3】:

    我对 Riak 没有直接的经验,但与 Cassandra 有过一些合作,这很相似。

    首先,性能可能很大程度上取决于可用内核的数量和内存。这些系统通常是大量流水线和并发的,并且受益于许多内核。 4 个以上的内核和 4GB+ 的 RAM 将是一个很好的起点。

    其次,MapReduce 是为批处理而不是实时查询而设计的。

    Riak 和所有类似的 Key-Value 存储都是为高写入性能、高读取性能而设计的,用于简单的查找,根本不需要复杂的查询。

    仅作为比较,单个节点(6 核,6GB)上的 Cassandra 每秒可以执行 20,000 次单独插入。

    【讨论】:

    • "MapReduce MapReduce 是为批处理设计的,而不是实时查询。完全没有。" - 谢谢,这就是我想知道的:我使用 map reduce 是否错误,或者它只是我正在尝试做的错误工具。非常感谢您的见解!
    • 实际上 MapReduce 是为批处理而发明的,但它只是一个抽象的计算模型。 Riak 的实现专为实时查询而设计,但仅限于链接跟踪,而不是跨整个存储桶。
    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多