最近接触到了ssdb,个人感觉用起来跟redis是差不多的。暂时也没有过多的深究,反正连命令用起来都差不多。
目前使用的框架是yii
需求:
由于用户导出数据量过大,为了监控服务器内存的使用率,采用队列的形式去排队执行任务 。
配置什么的就不介绍了,贴一份代码而已。
当执行导出按钮的控制器操作:
//往队列里面添加一个记录
$uid = Yii::app()->user->id;
$createTime = Helper::zeqiiTime('u');
$filename = '订单统计报告';
Yii::app()->ssdb->_cache->qpush('export_csv',$uid.'|'.$createTime);
Yii::app()->ssdb->_cache->hset('export_csv',$uid.'|'.$createTime,json_encode(array(
'uid' => $uid,
'createTime' => Helper::zeqiiTime('l'),
'sql' => $sql,
'status' => 0,
'count' => $count,
'type' => 'order_export',
'filename' => $filename.''.date('YmdHis',time()) . '.csv'
)));
解释下上述代码中ssdb的使用:
往export_csv队列中添加一条数据,名字是export_csv,值是用uid和时间戳拼接的的一个字段,避免重复。
再ssdb中设置一个hashmap名字也叫export_csv,key的值就是当前队列中的值,便于取出来的时候使用。
第三个参数是一个json格式的数据,这里根据自己的业务逻辑去放任意数据。
然后这个数据就写到了export_csv队列和hashmap中,再服务器端搞个定时任务执行出队操作就可以了。
代码如下:
public function run( $args ){
if( Yii::app()->ssdb->_cache->qsize('export_csv')->data == 0 ){
exit;
}
$fp = fopen(dirname(__FILE__).'/../../../runtime/keys/'.md5('export_csv_running'), 'w+');
//非阻塞
if (!flock($fp, LOCK_EX | LOCK_NB)) {
exit;
}
try {
while ($hashMapKey = Yii::app()->ssdb->_cache->qfront('export_csv')->data) {
$content = Yii::app()->ssdb->_cache->hget('export_csv', $hashMapKey)->data;
if ($content) {
$data = json_decode($content, true);
$dir = Html::realStaticPath() . "files/export/" . date('Ymd', strtotime($data['createTime'])) . '/';
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
$filename = $dir . $data['filename'];
if (file_exists($filename)) {
continue;
}
//加个类型方便扩展其他数据的导出
switch ($data['type']) {
case 'order_export':
$this->orderExpoer($filename, $data);
break;
default:
break;
}
//更改当前任务的状态,为已完成
$data['status'] = 1;
Yii::app()->ssdb->_cache->hset('export_csv', $hashMapKey, json_encode($data));
}
//循环一次自动弹出一个
Yii::app()->ssdb->_cache->qpop('export_csv', 1);
}
flock($fp, LOCK_UN);
fclose($fp);
}catch (Exception $e){
Yii::log('Running exportCsv error:'.$e->getMessage(), 'error', 'info');
flock($fp, LOCK_UN);
fclose($fp);
}
}
解释下上述代码的逻辑:
先判断队列export_csv里的长度,如果是0就证明没有数据,直接退出。
然后再加一个文件锁的判断,因为有可能前面的任务还没执行完,后面的定时任务又开始执行这个脚本了。
在然后循环的取出数据,做自己想做的操作就可以了。