Riak:快速获得多件物品

问题描述 投票:3回答:2

假设我在PHP中有这个数组。

$ids = [
    246,
    8362,
    5241,
    2586,
    6548,
    9372,
    28504,
    14,
    5729
];

这些数组元素对应于存储桶“文章”中的项目,有时这个数组可能像1000个元素一样深。

目前,我正在循环遍历所有这些并将数据逐个拉出1。

$articles = [];
foreach($ids as $id)
{
    $articles[] = Riak::get("articles.$id");
}

当ID列表变得很长时,这比我想要花费的时间更长。

有没有更快的方法从Riak桶中提取物品清单?我已经环顾了一下,map-reduce很有用,但显然会导致比使用顺序GET请求保存更多的开销。

php riak
2个回答
2
投票

不幸的是,从Riak有效地获取大量记录是很困难的,因为它们遍布集群并且必须单独检索。一些客户端库最近获得了对客户端multi-get的支持,它允许使用多个连接并行获取对象,但我认为这还没有到达PHP客户端。

使用mapreduce执行此操作将减少对数据库的调用次数,但不会导致读取仲裁,因为它只查询覆盖的一组分区。然而,Mapreduce是一种相当广泛的查询数据的方式,并且不能像直接密钥访问那样扩展或执行。

如果这是您需要执行的常见操作,则可能表明您的数据模型过于规范化,并且您可能需要进行反规范化,以便更好地支持您的应用程序及其访问模式。

究竟如何做到这一点需要了解您的数据以及您的访问和查询模式。一种方式可以是基于例如基于例如已知且可预测的密钥将多个物品存储在单个对象中。固定范围的文章ID。这将使文章的检索效率更高,因为需要读取的对象要少得多,但在更新和插入时可能会花费更多的复杂性。

另一种选择是通过复制数据来去标准化。如果你是只需要文章中的一些信息,您就可以将这些数据存储在专门用于有效提供这些查询的单独对象中。

在Riak中通常更好地检索具有比您需要的更多信息的更大对象并在应用程序级别进行过滤,而不是尝试从数据库中获取所需的记录。


1
投票

基于https://github.com/basho/riak-php-client PHP示例:

/**
     * Retrieve JSON-encoded objects from Riak.
     * @param  array(int) $keys - List of the key.
     * @return RiakObjects
     */
    public function multiGet($keys) {
        if (!$keys || !count($keys))
            return array();
        $query = null;
        foreach ($keys as $key) {
            if ($query) {
                $query->add($this->getBucketName(), $key);
            } else {
                $query = $this->riak->add($this->getBucketName(), $key);
            }
        }
        $results = $query->map(('function(riakObject){return [{"key":riakObject.key, "document":riakObject.values}];}'))->run();
        if (!$results || !count($results)) {
            return array();
        }

        $objects = array();
        foreach ($results as $data) {
            if (isset($data->key) && isset($data->document[0]->data) && !empty($data->document[0]->data)) {
                $object = json_decode($data->document[0]->data, true);
                if ($object) {
                    $objects[$data->key] = $object;
                }
            }
        }
        return $objects;
    }
© www.soinside.com 2019 - 2024. All rights reserved.