目录

一、缓存数据的目的

减轻数据库负载,减少cpu计算时间,提高数据请求速度,提升用户体验。 实现高并发、高可用的场景。

二、什么场景可能需要缓存数据

高频访问场景,频繁连接数据库,IO频繁读取处理慢,CPU计算时间长等场景

三、什么数据可能需要做缓存

结合可能需要缓存数据的场景,可以知道这些场景都有共同之处:

经常用到公用数据(区分不经常更新的数据和常更新的数据); 不论数据是通过静态文件、数据库、还是复杂计算得来,只要被高频请求,至于是否常更新,常更新有常更新的策略,不常更新也采用相应策略。

如:静态数据、缓存已经计算好的的数据、session数据、频繁访问的小文件、所有用户通用数据等

四、采用什么样的数据结构做缓存

在redis出现前,memcache是lamp环境下mysql的缓存黄金搭档, 由于业务复杂性的提高,缓存数据也越来越复杂,redis的在key-value的基础上增加了list、set、sort set、hash类型的数据存储方式, 比起memcache,redis数据结构更加丰富,redis还带有其他周边功能。

memcache采用的多线程方式,redis采用单线程方式,所以在key-value及数据量不是非常巨大的情况下,memcache的效率比redis高。

应用场景及数据结构

redis数据结构的多样性,让我们在存储数据上有了更多的选择,采用什么样的数据结构取决于要存储什么样的数据,用于什么地方:

比如配置数据,简单的key-value就可以解决;用户数据,可以使用hash结构;消息队列或timeline,可以使用list(链表)实现;

共同好友,可以用set求交集、差集、并集等操作实现相关数据存储;sort set可以用于排行榜、热门等列表数据展示。当然redis还提供了pub/sub发布与订阅服务。

五、缓存和数据库如何保证数据一致性

在高性能、高可用下,类似于时间换空间,如果要求强一致性,则可能耗费更多其他方面性能比如内存、cpu、IO等

一般在源数据修改时,将更新缓存操作放入事务中,否则回滚。 如果先更新源数据再更新缓存数据,在高并发情况下,可能会出现更新源数据时,缓存里的旧数据被读取; 如果先更新缓存数据再更新源数据,可以解决读取脏数据问题,但先更新缓存数据,可能涉及到和源数据有关的所有缓存数据更新,一来复杂度提高,二来容易导致数据一致性问题;

高并发高可用与数据一致性存在取舍关系,大部分业务不会强制要求数据一致性(1ms级别),而且ms级别的缓存数据与源数据不一致是可以接受的。

提供缓存热加载脚本,为服务器提供第一次所有缓存数据,或根据缓存数据校对数据库数据并更新缓存数据。

六、什么情况下更新或删除缓存

主动更新

源数据一旦删改,考虑删除对应缓存数据。是比较简单直接的方式。不考虑数据强一致性。 在第一次有用户访问时,再次缓存数据,之后通过缓存提供数据。

被动更新

缓存过期,再一次访问,重新加载源数据到缓存。

热缓存初始化

可能存在第一次都不想让用户访问数据库的数据,即需要热缓存或源数据有增删改后需要删除缓存数据,并重新添加缓存数据。不建议更新缓存数据操作,容易出现问题。

七、数据缓存过期时间

不同数据,应该是采用不同的缓存策略(缓存时间、不存在再缓存、已存在才缓存、有读取则重新设置缓存时间保证延续)

一般的数据默认缓存3天。

八、如何管理key

1、key的命名规则

数据名字:数据类型[:id]
如动态的可以是:user:hash:1321 ....
如静态的:app:sortset:hot   app:sortset:newest ....

2、统一配置key文件,注释说明

九、如何维护缓存数据

在service层,建立指定数据的set、get、del、setex

要求强一致性数据的,要求严谨的缓存数据读写:

php-redis使用01

对于普通的业务(不是指高并发的业务),不涉及ms级别上的资源或大额金钱交易精确性问题的,可以考虑

php-redis使用02