日度归档:2012年4月18日

基于分析sql语句实现主动缓存

以前在上海的时候,做过一个用redis实现主动列表缓存的方案,但那时生产环境用的是1.0,所以那个列表缓存非常粗糙,只是满足需求而以,但运行得比较稳定,因此redis在实现上是可行的。

加上最近在看redis方面的资料,从头系统过了一遍redis,所以有了改进以前做的主动列表缓存的冲动,计划首先用在现在公司的一个新项目上,如果可行,就可以继续部署到老项目,改进性能。

要实现主动缓存,主要的问题在于以下几点

1. 怎么触发更新、删除、插入数据库时,同步更新redis里的数据

2. redis中数据的存储采用怎么的方式

3. 主动缓存中怎么排序和分类

4. redis意外停止服务的情况下,如果正常提供列表服务

5. 列表缓存应该工作在哪一层,dao ? service ?

6. redis中单个数据失效的情况下怎么剔除

7. 如果减少网络请求,尽量少的命令获取一个分布的数据

目前方案正在设想中,先写下些东西,做下记录,后面再逐步完善!

一,解决mysql数据改变时触发实时更新redis数据,并最少改动现有代码

所以想在加一层 cache 层,使用cache层可以在Controller和service二个层中相互调用。cache中的数据可以来源于dao也可以来源于service层

解决第一个问题,我的想法是,直接在sql执行时,获得sql语句分析sql , 决定是否更新redis中的数据。

二, 做要实现redis主动缓存的相关配置,配置如下

<?php

return array(
			// db_user 表做数据缓存
			'db_user' => array(
							// 定义分类的字段,用于生成多个id索引set
							'cate' => array('group_id', 'vip'),
							// 设定排序所要用到的字段,数字
							'sort' => array('sort', 'create_time', 'last_time', 'login_num'),
							'callback' => array(
												'get' => array('common::getUserService()', 'getOne'), //回调类与方法,用于更新单个数据
												//用于当redis数据丢失的情况从mysql中还原数据,需要用于反射来注入数据,有待完善
												'getlist' => array('common::getUserService()', 'getList'), 
											), 

						),
		);

主要的意义在配置中告诉程序怎么输出,如果redis失效的情况下,绕过redis缓存系统,直接按回调中的方法从mysql中输出数据。

redis怎么存储缓存数据:

1. 用一个或多个sets 存 id号索引数据。 比如配置中cate字段没有设置,就类型 listcache:db_user:ids

如果配置了cate字段 则出现一组 listcache:db_user:ids:cate:group_id:1 sets来分别存放对应的ID号

2. 另使用一个hash来存储内容,结构因sort配置而变
hset list:cache:db_user:content:id:1 sort 1
hset list:cache:db_user:content:id:1 create_time 122323123
hset list:cache:db_user:content:id:1 last_time 1223231223
hset list:cache:db_user:content:id:1 login_num 20
hset list:cache:db_user:content:id:1 data 用户数据的序列化数据
上面非data用于排序使用

最后获取列表使用 sort 命令
例 sort list:cache:ids BY list:cache:db_user:content:id:*->sort DESC LIMIT 0 10
上面命令用于获取排过序id号数据
也可以直接获取最终的data数据 sort list:cache:ids BY list:cache:db_user:content:id:*->sort GET list:cache:db_user:content:id:*->data DESC LIMIT 0 10

就写到这吧,写得比较混乱。以后再整理些图出来,比较直观!