Exemplo n.º 1
0
 /**
  * 处理map reduce统计
  *
  * @return string
  */
 public function mrAction()
 {
     $cache = $this->cache();
     $this->_worker->addFunction("mapreduce", function (\GearmanJob $job) use($cache) {
         try {
             $job->handle();
             $params = unserialize($job->workload());
             $out = $params['out'];
             $this->_data->setCollection($params['dataCollection']);
             $this->_data->setReadPreference(\MongoClient::RP_SECONDARY_PREFERRED);
             $dataModel = $this->_data;
             $statisticInfo = $params['statisticInfo'];
             $query = $params['query'];
             $method = $params['method'];
             $rst = mapReduce($out, $dataModel, $statisticInfo, $query, $method);
             var_dump($rst);
             $cache->remove($out);
             if (is_array($rst) && isset($rst['ok']) && $rst['ok'] === 0) {
                 switch ($rst['code']) {
                     case 500:
                         $job->sendWarning('根据查询条件,未检测到有效的统计数据');
                         break;
                     case 501:
                         $job->sendWarning('MapReduce执行失败,原因:' . $rst['msg']);
                         break;
                     case 502:
                         $job->sendWarning('程序正在执行中,请勿频繁尝试');
                         break;
                     case 503:
                         $job->sendWarning('程序异常:' . $rst['msg']);
                         break;
                 }
                 $job->sendFail();
                 return false;
             }
             // sleep(30);//成功的操作等待30秒,用以确保复制集完成同步
             $job->sendComplete('Complete');
             return true;
         } catch (\Exception $e) {
             var_dump(exceptionMsg($e));
             $job->sendException(exceptionMsg($e));
         }
     });
     while ($this->_worker->work()) {
         if ($this->_worker->returnCode() != GEARMAN_SUCCESS) {
             echo "return_code: " . $this->_worker->returnCode() . "\n";
         }
     }
     return $this->response;
 }
Exemplo n.º 2
0
 /**
  * 逐一统计所有需要统计的脚本信息
  * 脚本执行方法: php index.php dashboard run
  *
  * @throws \Exception
  */
 public function runAction()
 {
     $logError = function ($statisticInfo, $rst) {
         $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => '', 'dashboardError' => is_string($rst) ? $rst : Json::encode($rst))));
     };
     $statistics = $this->_statistic->findAll(array('resultExpireTime' => array('$lte' => new \MongoDate())));
     if (empty($statistics)) {
         echo 'empty';
         return $this->response;
     }
     foreach ($statistics as $statisticInfo) {
         try {
             if (!empty($statisticInfo['dashboardOut'])) {
                 $oldDashboardOut = $this->collection($statisticInfo['dashboardOut'], DB_MAPREDUCE, DEFAULT_CLUSTER);
                 $oldDashboardOut->physicalDrop();
             }
             //检查是否存在映射关系
             $mapCollection = $this->_mapping->findOne(array('collection_id' => $statisticInfo['collection_id'], 'active' => true));
             if ($mapCollection != null) {
                 $dataModel = $this->collection($mapCollection['collection'], $mapCollection['database'], $mapCollection['cluster']);
             } else {
                 $dataModel = $this->collection(iCollectionName($statisticInfo['collection_id']));
             }
             $query = array();
             if (!empty($statisticInfo['dashboardQuery'])) {
                 $query['$and'][] = $statisticInfo['dashboardQuery'];
             }
             $query['$and'][] = array('__CREATE_TIME__' => array('$gte' => new \MongoDate(time() - $statisticInfo['statisticPeriod'])));
             $rst = mapReduce($dataModel, $statisticInfo, $query, 'reduce');
             if ($rst instanceof \MongoCollection) {
                 $outCollectionName = $rst->getName();
                 // 输出集合名称
                 $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => $outCollectionName, 'lastExecuteTime' => new \MongoDate(), 'resultExpireTime' => new \MongoDate(time() + $statisticInfo['interval']))));
             } else {
                 $logError($statisticInfo, $rst);
             }
         } catch (\Exception $e) {
             $logError($statisticInfo, $e->getMessage());
         }
     }
     echo 'OK';
     return $this->response;
 }
Exemplo n.º 3
0
 /**
  * 测试结果
  *
  * @return \Zend\Stdlib\ResponseInterface
  */
 public function testAction()
 {
     $statistic_id = $this->params()->fromQuery('statistic_id', null);
     $logError = function ($statisticInfo, $rst) {
         $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => '', 'dashboardError' => is_string($rst) ? $rst : Json::encode($rst))));
     };
     $statistics = $this->_statistic->findAll(array('_id' => myMongoId($statistic_id), 'isDashboard' => true));
     if (empty($statistics)) {
         echo 'empty';
         return $this->response;
     }
     foreach ($statistics as $statisticInfo) {
         try {
             if (!empty($statisticInfo['dashboardOut'])) {
                 $oldDashboardOut = $this->collection($statisticInfo['dashboardOut'], DB_MAPREDUCE, DEFAULT_CLUSTER);
                 $oldDashboardOut->physicalDrop();
             }
             // 检查是否存在映射关系
             $mapCollection = $this->_mapping->findOne(array('collection_id' => $statisticInfo['collection_id'], 'active' => true));
             if ($mapCollection != null) {
                 $dataModel = $this->collection()->secondary($mapCollection['collection'], $mapCollection['database'], $mapCollection['cluster']);
             } else {
                 $dataModel = $this->collection()->secondary(iCollectionName($statisticInfo['collection_id']));
             }
             $query = array();
             if (!empty($statisticInfo['dashboardQuery'])) {
                 $query['$and'][] = $statisticInfo['dashboardQuery'];
             }
             $query['$and'][] = array('__CREATE_TIME__' => array('$gte' => new \MongoDate(time() - $statisticInfo['statisticPeriod'])));
             $out = 'dashboard_' . $statisticInfo['_id']->__toString();
             $rst = mapReduce($out, $dataModel, $statisticInfo, $query, 'replace');
             if ($rst instanceof \MongoCollection) {
                 $outCollectionName = $rst->getName();
                 // 输出集合名称
                 $this->_statistic->update(array('_id' => $statisticInfo['_id']), array('$set' => array('dashboardOut' => $outCollectionName, 'lastExecuteTime' => new \MongoDate(), 'resultExpireTime' => new \MongoDate(time() + $statisticInfo['interval']))));
             } else {
                 $logError($statisticInfo, $rst);
             }
             // 替换统计结果中的数据为人可读数据开始
             if (isset($statisticInfo['xAxisType']) && $statisticInfo['xAxisType'] === 'value') {
                 $rshDatas = $this->dealRshData($statisticInfo['project_id'], $statisticInfo['collection_id'], $statisticInfo['xAxisField']);
                 if (!empty($rshDatas)) {
                     try {
                         $rstModel = $this->collection($out, DB_MAPREDUCE, DEFAULT_CLUSTER);
                         $rstModel->setNoAppendQuery(true);
                         $cursor = $rstModel->find(array());
                         while ($cursor->hasNext()) {
                             $row = $cursor->getNext();
                             $rstModel->physicalRemove(array('_id' => $row['_id']));
                             $_id = $row['_id'];
                             $rstModel->update(array('_id' => isset($rshDatas[$_id]) ? $rshDatas[$_id] : $_id), array('$set' => array('value' => $row['value'])), array('upsert' => true));
                         }
                     } catch (\Exception $e) {
                         var_dump($e);
                     }
                 }
             }
             // 替换统计结果中的数据为人可读数据结束
         } catch (\Exception $e) {
             $logError($statisticInfo, $e->getMessage());
         }
     }
     echo 'OK';
     return $this->response;
 }
Exemplo n.º 4
0
 /**
  * 对集合数据进行统计
  * 目前支持的统计类型:
  * 计数、唯一数、求和、均值、中位数、方差、标准差、最大值、最小值
  *
  * @author young
  * @name 对集合数据进行统计
  * @version 2014.01.29 young
  */
 public function statisticAction()
 {
     $action = $this->params()->fromQuery('action', null);
     $export = filter_var($this->params()->fromQuery('export', false));
     $statistic_id = $this->params()->fromQuery('__STATISTIC_ID__', null);
     if ($action !== 'statistic') {
         return $this->msg(false, '$action is not statistic');
     }
     if (empty($statistic_id)) {
         throw new \Exception('请选择统计方法');
     }
     $statisticInfo = $this->_statistic->findOne(array('_id' => myMongoId($statistic_id)));
     if ($statisticInfo == null) {
         throw new \Exception('统计方法不存在');
     }
     try {
         $query = array();
         $query = $this->searchCondition();
         $rst = mapReduce($this->_data, $statisticInfo, $query);
         if (is_array($rst) && isset($rst['ok']) && $rst['ok'] === 0) {
             switch ($rst['code']) {
                 case 500:
                     return $this->deny('根据查询条件,未检测到有效的统计数据');
                     break;
                 case 501:
                     return $this->deny('MapReduce执行失败,原因:' . $rst['msg']);
                     break;
                 case 502:
                     return $this->deny('程序正在执行中,请勿频繁尝试');
                     break;
                 case 503:
                     return $this->deny('程序异常:' . $rst['msg']);
                     break;
             }
         }
         if (!$rst instanceof \MongoCollection) {
             return $this->deny('$rst不是MongoCollection的子类实例');
             throw new \Exception('$rst不是MongoCollection的子类实例');
         }
         $outCollectionName = $rst->getName();
         // 输出集合名称
         if ($export) {
             $datas = $rst->findAll(array());
             $excel = array();
             $excel['title'] = array('键', '值');
             $excel['result'] = $datas;
             arrayToExcel($excel);
         } else {
             $limit = intval($statisticInfo['maxShowNumber']) > 0 ? intval($statisticInfo['maxShowNumber']) : 100;
             $datas = $rst->findAll(array(), array('value' => -1), 0, $limit);
             return $this->rst($datas, 0, true);
         }
     } catch (\Exception $e) {
         return $this->deny('程序异常:' . $e->getLine() . $e->getMessage());
     }
 }