繁体   English   中英

使用简单的map-reduce列出存储桶与bucket.get_keys()中的所有键?

[英]Using a simple map-reduce to list all keys in a bucket vs. bucket.get_keys()?

根据Riak的文档(使用Python绑定), get_keys()非常昂贵,不适合生产。 我的问题是一个非常简单的地图查询是否合适。 例如,仅通过以下功能使用map阶段:

function(v) { return [v.key]; }

这会比get_keys()更好吗? 为什么Riak不提供该实现而不是get_keys()的当前版本? 有什么更好的方法可以列出存储桶的密钥吗?

get_keys()函数在后端调用list_keys ,并且被认为是一项昂贵的操作,因为它执行了密钥空间的完整扫描。 根据您的Riak后端,这可能还包括对存储在磁盘上的数据进行全面扫描(InnoStore浮现在脑海)。 默认的存储后端(Bitcask)将所有密钥存储在内存中,因此性能不应该成为问题。

list_keys被认为很昂贵的另一个原因是因为它以前是一个阻塞操作,因为它涉及Basho开发人员所称的所有键的“折叠”。 list_keys现在使用存储桶的快照(而不是读取活动密钥空间),这也使它的重量减轻了。

通过升级到Riak 1.0,可以更轻松地进行此操作。 如果使用的是LevelDB后端,则可以在存储桶上启用二级索引,并使用$key索引(由Riak自动提供)来获取存储桶中所有键的列表。

至于为什么Riak没有提供更好的实现,例如:询问功能是什么。 在RDBMS中,获取表的所有主键涉及全表扫描。 在Riak中,要从存储桶中获取所有密钥,需要扫描每个节点中的所有数据,然后将密钥名称传送回原始节点,合并这些数据,然后将其发送给调用客户端。 由于Riak的分布是无序的,因此无论您如何切片,该操作都是昂贵的。 正如我上面概述的,有一些方法可以使它变得更好。

如果您正在使用eleveldb后端(由LevelDB库实现),则您的密钥按已排序的顺序存储,因此您可以执行以下操作:

def get_bucket_keys(riak_client, bucket_name, start='0', stop='Z'):
    for record_key in riak_client.index(bucket_name, '$key', start, stop).run():
        yield record_key

for key in get_bucket_keys(riak.RiakClient(), 'mybucket'):
    print key

使用eleveldb riak,仅扫描指定范围内的所有节点。 因此,如果以可以控制键范围的方式填充存储桶,则列表存储桶键可能会非常有效。

折衷方案是您不能为每个节点上处理的键数指定LIMIT。 因此,您需要控制需要列出密钥的存储桶的密钥。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM