一旦工作,那就要努力的干,聪明的干,快速的干——用省下来的时间干自己喜欢干的事情。!

关于使用缓存出现问题的总结

php lampnick 1643℃ 0评论

原始需求:有一个功能是一个活动通过区域,楼栋,单元过滤房源,此时用到的缓存key采用活动ID,区域ID,楼栋ID,单元ID连接组成,类似$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId ;缓存的加载和删除在活动的发布和取消发布进行。

新需求:在以上功能的基础上,增加户型的过滤。

当做新需求时,采用的是key中增加一个户型ID进行过滤。此时key为:$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId . '-' . $houseTypeId;在活动发布和取消发布时,修改加载和清除缓存的功能。此时便出现了一个问题,由于户型在活动发布后还能修改,则会造成修改了户型,通过户型筛选时,发现筛选功能没有作用。

原因是这样的:

情景一:例如A1房间原来的户型是A户型,对应的key为$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId . '-' . 'AID';(原来这个key对应房间列表中有A1,A2房间),后来修改成了B户型,key为$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId . '-' . 'BID';(原来这个key对应房间列表中有B1,B2房间)。此时通过户型进行过滤,筛选A户型和B户型,由于缓存并没有修改,发现筛选出的房间列表并没有变化。

情景二:例如A1房间原来的户型是A户型,对应的key为$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId . '-' . 'AID';(原来这个key对应房间列表中有A1,A2房间),后来修改成了B户型,key为$key = $activityId . '-' . $areaId . '-' . $blockId . '-' . $unitId . '-' . 'BID';(原来缓存中没有这个户型对应的key)。此时通过户型进行过滤,筛选A户型没有作用,由于原来B户型key在缓存中不存在,则会从DB中进行加载,此时筛选B户型是正确的。

还有些情景也是有问题的。

解决方案一:在修改户型时,将此房间修改前的户型对应的key对应的缓存删除掉。将修改后的户型重新生成缓存。

解决方案二:由于区域,楼栋,单元下的数据不会有很多数据,所以不将户型ID加入到缓存中,进行户型筛选时,直接通过程序进行筛选。这样也不会有性能问题,而且能减少缓存的复杂度,尽可能避免出错。

在使用缓存的时候,一定要注意缓存的复杂度与性能的取舍。

另外Yii2中AR使用where()时建议使用andWhere()进行筛选,因为where()会过滤掉原来的过滤条件.

public function where($condition, $params = [])
{
    $this->where = $condition;
    $this->addParams($params);
    return $this;
}

public function andWhere($condition, $params = [])
{
    if ($this->where === null) {
        $this->where = $condition;
    } else {
        $this->where = ['and', $this->where, $condition];
    }
    $this->addParams($params);
    return $this;
}

转载请注明:MitNick » 关于使用缓存出现问题的总结

喜欢 (0)or分享 (0)
头像
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址