6

我已经使用过 MongoDB、CouchDB、Redis、Tokyo Cabinet 和其他 NoSQL 数据库。最近我偶然发现了 Riak,我觉得它很有趣。为了开始使用它,我决定编写一个小型 Twitter 克隆,即 NoSQL World 中的“hello world”。要获得一个完全可用的克隆,有必要按时间顺序对推文进行排序。在阅读了 Riak 文档后,我发现 Map-Reduce 是完成这项工作的正确工具。在我的开发环境中它工作得很好,但是在生产环境中,有数百个并行查询的性能如何?是否有其他可能更快的数据排序方法,或者是否可以以有序的形式存储数据(如 Cassandra)?

我想我已经找到了解决这个问题的另一种方法——一个简单的链表。因此,一种可能的实现可能是,每个用户都有他/她自己的“时间线存储桶”,其中存储了指向推文数据本身的链接(推文单独存储在“推文”存储桶中)。如您所知,这个时间线桶必须包含一个名为“first”的键,它链接到最新的时间线对象并且是列表的起点。要在时间线中插入一条新推文,只需在时间线桶中插入一个新项目,将此新项目的“下一个”链接设置为“第一个”项目,然后将新项目设置为“第一个”。

简而言之:像在链表中一样插入一个项目......

与 Twitter 一样,个人时间线仅包含向用户显示的 20 条推文。要接收最后 20 条推文,只需 2 次查询。为了加快速度,第一个查询使用 Riak 的链接遍历功能来获取最新的 20 个对象,标记为“下一个”。最后,第二个也是最后一个查询使用第一个查询计算的键来接收推文本身(使用 map/reduce)。

要删除您刚刚取消关注的用户的推文,我会使用 Riak 1.0 的二级索引功能来接收相关的时间线对象/推文。

4

2 回答 2

2

如果不重新编写 Riak 核心的部分,就不可能在 Riak 中以有序的形式存储数据。数据大致按桶 + 键的顺序存储。实际顺序取决于您用于 Riak 的后端存储机制。

Riak 1.0 也有一些可能对您有所帮助的功能。对二级索引的支持以及对 Map Reduce 操作的改进——特别是它们在高并发场景中的表现要好得多。

Alexander Siculars 写了一篇关于与 Riak 进行分页的文章。它很好地概述了这个问题。Yammer 还广泛使用了 Riak,他们的两位工程师在 Yammer 上组织了一个关于 Riak的演示。它没有涉及很多实现细节,但您可以了解很多关于他们如何设计解决方案的信息。

结合二级索引查询和 Map Reduce 可以非常轻松地解决您的问题。

于 2011-10-01T13:09:40.703 回答
0

正如 Jeremiah 所说,不可能按排序顺序存储数据,但您仍然可以通过使用二级索引和 map/reduce 使其返回排序结果。如上所述,问题在于您无法以排序方式有效地限制查询。

这是一个示例,使用范围查询列出所有键,然后使用 *riak_kv_mapreduce*: 中的内置函数对它们进行排序:

{ok, Pid} = riakc_pb_socket:start_link("127.0.0.1", 8087),
riakc_pb_socket:mapred(Pid                                               
    , {index, colonel_riak:bucket(context), <<"$key">>, <<0>>, <<255>>}       
    , [{reduce, {modfun, riak_kv_mapreduce, reduce_sort}, none, true}])

您可以lists在 erlang 中使用模块中的函数或使用本机 javascript 排序函数。lists:reverse/1在erlang中可以通过order by来实现。

于 2012-10-09T09:17:51.153 回答