代码之家  ›  专栏  ›  技术社区  ›  tinybluerobot

Riak:快速获取多个项目

  •  3
  • tinybluerobot  · 技术社区  · 12 年前

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

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

    这些数组元素对应于桶“articles”中的项目,有时这个数组可能有1000个元素深。

    目前,我正在循环浏览所有这些文件,并逐一取出数据。

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

    当id列表变得很长时,这比我想花的时间还要多。

    有没有更快的方法从Riak桶中提取物品列表?我已经仔细研究了一下,map reduce是有用的,但显然会导致比顺序GET请求节省的开销更多的开销。

    2 回复  |  直到 8 年前
        1
  •  2
  •   Christian Dahlqvist    12 年前

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

    使用mapreduce可以减少对数据库的调用次数,但不会导致定额读取,因为它只查询覆盖的一组分区。然而,Mapreduce是一种相当广泛的查询数据的方法,其规模和性能不如直接键访问。

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

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

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

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

        2
  •  1
  •   Pentium10    12 年前

    基于 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;
        }
    
    推荐文章