背景
最近公司用户量上来了,因此,对考勤打卡的瓶颈也就越发明显。每到打卡高峰期,公司APP就打开很慢,甚至服务开挂。针对这些问题,检查服务器发现,原来是考勤接口并发上来不停请求数据库导致的CPU剧增。因此,升级了服务器,提升了配置,但是还是不能抗住压力。因此,自己百度发现redis是个好东西,可以做缓存数据库,缓解mysql压力。因此,写下这篇文章。
主要运用
- 1.redis:hset,del,hKeys...
- 2.定时任务
- 3.注意:设计时,是以每天为单位,异步同步redis缓存数据到mysql。
代码模块
redis = app('redis.connection');
}
private function _getEnable()
{
$conf = $this->config;
return $conf['enable'];
}
/**
* 查询key
* @param $key
* @return mixed
*/
public function keys($key){
return $this->redis->keys($key);
}
/**
* 设置位图
* @param $key
* @param $offset
* @param bool $value
* @param int $time
*/
public function setBit($key, $offset,$value,$time=0)
{
$result = $this->redis->setbit($key,$offset,$value);
if($time>0){
$this->redis->expire($key,$time);
}
return $result;
}
/**
* 获取位图
* @param $key
* @param $offset
* @return mixed
*/
public function getBit($key,$offset)
{
return $this->redis->getBit($key,$offset);
}
/**
* 统计位图
* @param $key
* @return mixed
*/
public function bitCount($key)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitCount($key);
}
/**
* 位图操作
* @param $operation
* @param $reKey
* @param array ...$key
* @return mixed
*/
public function bitOp($operation,$reKey,...$key)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitOp($operation,$reKey,$key);
}
/**
* 计算在某段位图中 1或0第一次出现的位置
* @param $key
* @param $bit 1/0
* @param $start
* @param null $end
* @return mixed
*/
public function bitPos($key,$bit,$start,$end=null)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitPos($key,$bit,$start,$end);
}
/**
* 删除位图
* @param $key
* @return mixed
*/
public function del($key)
{
return $this->redis->del($key);
}
/**
* 写入
* @param $key
* @param $hashKey
* @param $value
* @return bool
*/
public function hSet($key, $hashKey, $value )
{
return $this->redis->hset($key,$hashKey,$value);
}
/**
* 批量获取
* @param $key
* @return bool
*/
public function hGetAll($key)
{
return $this->redis->hGetAll($key);
}
/**
* @param $key
* @param $hashKey
* @return bool
*/
public function hExists($key,$hashKey)
{
return $this->redis->hExists($key,$hashKey);
}
/**
* @param $key
* @return bool
*/
public function hKeys($key)
{
return $this->redis->hKeys($key);
}
/**
* @param $key
* @return bool
*/
public function hLen($key)
{
return $this->redis->hLen($key);
}
/**
* 管道技术批量入库
* @param $key
* @param $value
*/
public function setPipe($key,$value)
{
$this->redis->multi();
$this->redis->set('sign_'.$key,$value);
$this->redis->get('sign_'.$key);
$replies=$this->redis->exec();
print_r($replies);
}
}
1/0
}
}
hSet($key,$hashKey,$value);
if(!$res){
return false;
}
}catch (\Exception $e){
return ['msg'=>$e->getMessage(),'code'=> $e->getCode()];
}
}
}
$e->getMessage(),'status'=>false];
}
}
$end = microtime(true);
echo '耗时'.round($end-$start,3)."秒
";
echo '内存(Now memory_get_usage): ' . memory_get_usage() . "
";
return true;
}
}
keys('sign_'. $day .':*');
$sign_key = 'sign_'.$day;
$keys = $signLogModel->hGetAll($sign_key);
$today = date('Y-m-d',time()) .' ';
foreach ($keys as $key){
//公司|用户uuid|打卡时间|打卡类型
$userArr = explode('|',$key);
//获取用户信息 公司id,用户id,签到时间,签到类型
$data[] = [
'company_id'=> $userArr[0],
'uuid'=> $userArr[1],
'sign_time'=> $today . $userArr[2],
'sign_type'=> $userArr[3],
];
}
// var_dump($data);die;
try{
$is_success = false;
if($data){
//数据入库
$insert_res = OrderSpikeModel::insert($data);
//入库成功后,删除入库数据
if($insert_res){
$isExist = $signLogModel->hLen($sign_key);
if($isExist > 0){
$is_success = $signLogModel->del($sign_key);
}
}
}
return $is_success;
}catch (\Exception $e){
return ['msg'=> '操作入库失败,error:'. $e->getMessage(),'code'=> $e->getCode(),'status'=>false];
}
}
}
注:定时同步redis数据到mysql数据库。这里同步数据时,可以采用队列异步同步到msyql,根据自己喜欢而定。
总结
高并发下缓存数据库不为是一个很好的抗压工具,建议多使用,切勿滥用!