`
windytwang
  • 浏览: 49947 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Django下统一的cache接口

阅读更多

 

需求:

用Django做一款网页游戏的后端,用memcached减少数据库的压力

1,  尽量保持统一的使用cache的接口

2,  在没有Cache的情况下也能正常工作

3,  尽量增加cache的命中率

 

Cache的工作原理:

1,对于指定不重复key,且只会返回唯一结果的查询:

         Cache.set( key, value ),可以通过切面编程,对所有的savedelete操作加上post hook.自动的在savedelete后,执行相应的set操作

         Cache.get( key ) 提供统一的接口 getFromCache( ModelName, id )

         其中key由查询条件拼出

         比如对于league_id=3, item_number=0这样的查询生成key

item_number_0_league_id_3.

 

2,对于返回的不是唯一结果

         两种办法:

1,  查询得到id,然后通过idcache找到没有在cache中的东西,然后找出没有在cache中的东西,最后拼出整个事物。(需要测试看提升的性能为多少)(在一般的数据库上测试下来结果是用了这种方法,反而比没用 cache要慢上10倍,应该是频繁的使用memcached降低了性能)

2,  通过查询条件拼出key,然后查询是否有无在Cache中,如果没有在cache中,则查询,放到cache. 这里比较麻烦的是,如何对于key不只是id的如何将cache置为无效。比如查询items = Item.objects.filter( league_id=3, item_number = 0 ).在什么时侯将itemscache设为无效呢?

设想的是这样来做:

1)  在定义Model时,会定义好一些查询条件,像上面的情况,就会定义league_id_item_number.初始化时,会有一个cacheManager记录下,每个Model对应的查询条件。

2)  save,delete后,加入post hook,会自动调用一个updateCache方法,该方法会通过cacheManagerModel下所有定义查询条件的key进行更新

3)  进行条件查询的方法都有所记录,可以以此为根据来定义Model里的查询条件。

举上面的列子

1)       定义Item类,定义好一个查询条件为(league_id,item_number)。cacheManager[Item] = [ [item_number,league_id] ](查询条件会进行排列,增加cache命中率)

2)       第一次访问Item.objects.filter( league_id=2,item_number=3)会在keyitem_filter下找有无Item_item_number_2_league_id_3,没找到,取出数据,更新key,value.并将item_filter下加入当前key.

3)       第二次访问item.objects.filter( league_id=2,item_number=3),item_filter下找到数据,并直接访问key= Item_item_number_2_league_id_3,返回结果

4)       更新item表项,item_filter表项置为空

 

需要注意的是cache机制可能会引致多线程的问题。

上面很多地方用到了AOP(切面编程),减少了一些重复代码。有兴趣的话,可以去找一找AOP的文章来看。

4
2
分享到:
评论
2 楼 jianpx 2010-08-17  
可以 用 python 的decorator, too~
1 楼 snowolf 2010-07-28  
用切面 这个想法很不错!!!

相关推荐

Global site tag (gtag.js) - Google Analytics