[英]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.