我们这版迭代大幅度使用了redis来缓存数据。
但是我们业务在不停迭代,这样我们就需要添加进更多需要缓存的东西,但是我们取数据的时候,每次都期望不改代码,直接取到所有需要缓存的数据。一开始我们是每次变更redis数据结构,都要运维手工删除redis里面所有的相关的key,但是这样运维很烦,后来我们想到了用版本来控制redis数据的方式来解决这个问题。具体有两种方式。1.在数据结构中添加版本号,取数据的时候,判断取到的数据是否是最新的版本,如果不是从新取一次数据。这种方式,需要在代码中添加相关的逻辑,但是也不复杂。2.在redis的前缀中添加版本号,取数据的时候,啥也不用管,直接取就好了,不用改任何逻辑,原来版本的数据不用管,超时后,他就被redis清除了。我们采用的是第二种方法。
我们在缓存用户的基础数据的时候采用的是集中式缓存,即查询多张表汇总后将数据缓存到一个key下面,这个也有个问题,就是我变更了一个value,就得把数据全部清除了,对于每次查询更新缓存来说,数据库压力比较大,我们接下来要在代码中抽象出数据服务器。对于我们这种规模的应用来说,还不需要将数据服务单独拆成一个个微服务,事务一致性的成本比较高,但是可以抽象出数据服务层来,采用他来管理不同存储的一致性。在数据服务层之上,抽象出web服务层,来调用数据服务层。
在使用redis过程中,我们还发现遇到redis缓存和数据库不一致的问题,一开始大家没有找到真正原因,怀疑是redis删除数据后,在事物没有提交的时候,其他线程又取了一次数据导致缓存和数据库不一致。因此采用了redis删除2次的方式,就是在删除redis数据的时候,先删一次,将删除的key放入延迟队列中,2秒后再删除一次。后来发现还是有数据不一致的问题,这样才确认一定是我们代码的问题,最终找到了真正的原因。