最近下了班有空時都會繼續專研 MongoDB 分析資料的部分,一開始完全都用 Aggregation ,實在是有一些實測的效能比 MapReduce 好很多,但對於一些較複雜的計算方式,一直用 Aggregation 反而會卡住或是增加資料結構的複雜度 Orz 總之,開始正式去寫一些簡單的 MongoDB MapReduce 程式。
把玩的過程中,發現先前設計的 Sparse Matrix 結構,在計算矩陣相乘時,花了不少步驟並且效果變成永遠只能有一隻 Mapper 在進行 Orz 完全不能平行處理,因此開始研究一下如何用 MapReduce 進行矩陣運算。
網路上資源果然豐富,找到一篇:Programming Puzzle: Multiply Matrixes with MongoDB,概念解釋得很清楚。簡言之,當矩陣相乘時,以 A x B = C 為例,在組成 C 矩陣內的元素過程中,會採用 A 跟 B 矩陣內的部分元素相乘,那麼試著找個關係式子,讓這些元素最後在 Reducer 裡撞在一起,撞在一起時再相乘即可。
原來如此簡單的想法就可以讓 MapReduce 架構處理矩陣相乘了!有興趣可以再參考一下:changyy/node-mongodb-matrix-multiplication。
2014年12月29日 星期一
2014年12月28日 星期日
MongoDB 開發筆記 - 在 MapReduce 進行 debug 的一些心得
有點久沒寫 blog 了!最近有空時就是把玩 MongoDB 或是嘗試送一些 patch ,所以反而就少寫一些筆記,因為都改成用 Code 啦 :P
最近玩 Mongodb MapReduce 時,碰到幾個問題跟需求:
最近玩 Mongodb MapReduce 時,碰到幾個問題跟需求:
- 碰到 mongod Out of memory
- 想要在 Mapper 跟 Reducer 輸出一些 console 訊息
其中 out of memory 的部分,經過 trace 後發現是內部 Mapper 實作的架構採用 C++ Map Structure 紀錄結果,累計處理完一百筆資料會輸出,但如果單一個筆 input 會產生極大數量的結果時,就會出現 out of memory,已經送了個鳥鳥的 patch 出去,就看 MongoDB Reviewer 決定如何 :P 畢竟這種現象也可以歸屬在使用者資料設計問題,為何讓一筆 input 產生巨量資料 XD
至於現況怎樣解套?若碰到 mongod crash 問題,先試試把 jsMode 打開吧!因為 jsMode = true 時,將採用 v8 engine 處理 mapper function,並且資料是直接輸出到 temp collection 的,可避開 out of memory 問題。
對於前期開發時,想在 Mapper 跟 Reducer 印出一些訊息時,此時不能直接用 console.log(obj),要改用 print(JSON.stringify(obj)) ,並且去翻一下
/var/log/mongodb/mongod.log 吧!
標籤:
mapper,
mongod,
mongodb,
out of memory,
reducer
2014年11月25日 星期二
iOS 開發筆記 - UIWebview loadData 以及 local resource 配置
很久以前把玩過 PhoneGap 後,就很久沒使用 UIWebview 來當作主要 UI。這次嘗試使用 Web UI 當作操作介面,於是乎就碰到使用 jQuery 的問題 XD 偷懶的解法就是用 remote resource,更佳的解法是用 local file。
使用方式:
其中的 baseURL 只要填寫正確,在 index.html 裡頭就可以用相對路徑存取 local file 了。
例如:
使用方式:
// 記得要 Added folders 要採用 Create folder references
// web-resource/index.html
// web-resource/jquery.min.js
//
NSString *localWebPagePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"web-resource"];
[self.webview loadData:[NSData dataWithContentsOfFile:localWebPagePath] MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL URLWithString:localWebPagePath]];
其中的 baseURL 只要填寫正確,在 index.html 裡頭就可以用相對路徑存取 local file 了。
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="jquery.min.js"></script>
</head>
<body>
...
</body>
</html>
[PHP] CodeIgniter 與 Facebook PHP SDK v4 整合筆記 @ Ubuntu 14.04
整個流程並主要是把 Facebook PHP sdk v4 source code 下載到 ci_proj/application/libraries 中,接著撰寫一隻 ci library: facebook.php 來橋接一下,就差不多可以收工了。在此謹驗證收到的 facebook token 是否有效,其他部分並不實作:
建立 Facebook 相關 config:
編輯橋接的 library 用法:
使用方式:
$ cd /path/ci_proj/application/libraries
$ git clone https://github.com/facebook/facebook-php-sdk-v4.git
$ ln -s facebook-php-sdk-v4 facebook
建立 Facebook 相關 config:
$ vim /path/ci_proj/application/config/facebook.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
$config['facebook']['api_id'] = 'FACEBOOK APP ID';
$config['facebook']['app_secret'] = 'FACEBOOK APP SECRET KEY';
編輯橋接的 library 用法:
$ vim /path/ci_proj/application/libraries/facebook.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once APPPATH . 'libraries/facebook/autoload.php';
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
class Facebook {
var $ci;
var $helper;
var $session;
var $permissions;
public function __construct() {
$this->ci =& get_instance();
$this->ci->load->config('facebook');
$this->permissions = $this->ci->config->item('permissions', 'facebook');
FacebookSession::setDefaultApplication( $this->ci->config->item('api_id', 'facebook'), $this->ci->config->item('app_secret', 'facebook') );
}
public function token_validation($token) {
try {
$this->session = new FacebookSession( $token );
if ( $this->session->validate() )
return true;
} catch ( Exception $e ) {
}
$this->session = null;
return false;
}
public function get_user($token = NULL) {
if ( $this->session || (!empty($token) && $this->token_validation($token)) ) {
$request = ( new FacebookRequest( $this->session, 'GET', '/me' ) )->execute();
$user = $request->getGraphObject()->asArray();
return $user;
}
return false;
}
}
使用方式:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Test extends CI_Controller {
public function index()
{
$this->load->config('facebook');
$this->load->library('facebook');
$output = array(
'reqeusts' => $_REQUEST,
'app_id' => $this->config->item('api_id', 'facebook'),
'user_id' => $this->facebook->get_user($_REQUEST['token'])
);
$this->output->set_content_type('application/json')->set_output(json_encode($output));
}
}
[PHP] 使用 CodeIgniter 和 codeigniter-restserver 建立 RESTful API 以及測試方式 @ Ubuntu 14.04
環境資訊:
接著,透過 github.com/chriskacerguis/codeigniter-restserver 擴充 CodeIgniter:
接著,請確認 application/config/rest.php 設定:
之後,就可以撰寫簡單的 RESTful API 啦:
測試方式:
取得清單(GET)
新增資料(POST)
更新資料(PUT)
刪除資料(DELETE)
也可以用 wget --method GET/POST/PUT/DELETE 等進行測試。
至於 RESTful 常見的 HTTP STATUS CODE,可以參考 Using HTTP Methods for RESTful Services
例如:
取得清單成功回應 200 OK,失敗則為 404 NOT FOUND;新增資料成功 200 OK 或是 201 LOCATION 到新增項目的 URI,失敗為 404 NOT FOUND;更新資料成功為 200 OK,失敗為 404 NOT FOUND;刪除資料成功為 200 OK,失敗為 404 NOT FOUND。
接著,是設計每個 GET, POST, PUT, DELETE API 細節,可以分別使用 $this->get('param')、$this->post('param')、$this->put('param') 和 $this->delete('param') 取得對應資料,而回應時,需要的 HTTP Status Code 可以使用:
若要 debug 的話,大概可以用:
搭配 curl -i -X GET|POST|PUT|DELETE -d 'key=value' 方式進行,除了可以看到 HTTP Response code 外,也能看到 get, post, put, delete 各種參數資訊:
- Ubuntu 14.04 64 Bit (lsb_release -a)
- PHP 5.5.9 (php -v)
- CodeIgniter 2.2.0 (echo CI_VERSION)
接著,透過 github.com/chriskacerguis/codeigniter-restserver 擴充 CodeIgniter:
$ wget https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/application/config/rest.php -O /path/ci_proj/application/config/rest.php
$ wget https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/application/libraries/Format.php -O /path/ci_proj/application/libraries/Format.php
$ wget https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/application/libraries/REST_Controller.php -O /path/ci_proj/application/libraries/REST_Controller.php
接著,請確認 application/config/rest.php 設定:
$config[rest_default_format] = 'json'; // 預設為 xml
之後,就可以撰寫簡單的 RESTful API 啦:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require(APPPATH.'/libraries/REST_Controller.php');
class Item extends REST_Controller {
public function index_get() {
$this->list_get();
}
public function index_post() {
$this->add_post();
}
public function index_put() {
$this->update_put();
}
public function index_delete() {
$this->delete_delte();
}
public function list_get() {
echo "list";
}
public function add_post() {
echo "create";
}
public function update_put() {
echo "put";
}
public function remove_delete() {
echo "remove";
}
}
測試方式:
取得清單(GET)
$ curl -X GET http://localhost/ci_proj/item/list
$ curl -X GET http://localhost/ci_proj/item/
新增資料(POST)
$ curl -X POST http://localhost/ci_proj/item/add
$ curl -X POST http://localhost/ci_proj/item/
更新資料(PUT)
$ curl -X PUT http://localhost/ci_proj/item/update
$ curl -X PUT http://localhost/ci_proj/item/
刪除資料(DELETE)
$ curl -X DELETE http://localhost/ci_proj/item/delete
$ curl -X DELETE http://localhost/ci_proj/item/
也可以用 wget --method GET/POST/PUT/DELETE 等進行測試。
至於 RESTful 常見的 HTTP STATUS CODE,可以參考 Using HTTP Methods for RESTful Services
例如:
取得清單成功回應 200 OK,失敗則為 404 NOT FOUND;新增資料成功 200 OK 或是 201 LOCATION 到新增項目的 URI,失敗為 404 NOT FOUND;更新資料成功為 200 OK,失敗為 404 NOT FOUND;刪除資料成功為 200 OK,失敗為 404 NOT FOUND。
接著,是設計每個 GET, POST, PUT, DELETE API 細節,可以分別使用 $this->get('param')、$this->post('param')、$this->put('param') 和 $this->delete('param') 取得對應資料,而回應時,需要的 HTTP Status Code 可以使用:
$this->response( array('status' => true), 200);
$this->response( array('status' => false, 'error' => 'error message'), 400);
$this->response( array('status' => false, 'error' => 'error message'), 404);
若要 debug 的話,大概可以用:
$this->response( array('status' => true, 'get' => $this->get(), 'post' => $this->post(), 'put' => $this->put(), 'delete' => $this->delete() ), 200);
搭配 curl -i -X GET|POST|PUT|DELETE -d 'key=value' 方式進行,除了可以看到 HTTP Response code 外,也能看到 get, post, put, delete 各種參數資訊:
$ curl -i -X DELETE -d "haha=hehe" CGI
HTTP/1.1 200 OK
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.5
Content-Length: 68
Content-Type: application/json; charset=utf-8
{"status":true,"get":[],"post":[],"put":[],"delete":{"haha":"hehe"}}
訂閱:
文章 (Atom)