国外设计欣赏网站 - DOOOOR.com

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索
打印 上一主题 下一主题

[Drupal优化/SEO/环境] Drupal教程:自定义缓存之共享内存

[复制链接]
跳转到指定楼层
楼主
发表于 2-7-2012 02:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

对于高性能、高并发软件架构中一个重要的优化策略就是,能在内存中处理的决不能放到外存中。这里外存包括:网络I/O,DB,硬盘。
对于一个Drupal站点,我们都要使用到缓存,前文《drupal性能优化经验贴》中也谈到,必须使用cache。
一般情况下,我们使用memcache,大型站点,使用分布式memcache,并且memcache常常和Application不在同一台服务器上面。这就会带来一个问题,内部网络IO。对于小站点可能没有什么问题,但是对于一个大型站点,这个问题很严重。
因为Drupal的某些缓存比较大,比如theme-registry, content-type-info, locale翻译信息,对于一个较复杂的站点,这几个缓存加起来至少1M以上,大到3-5M。如果一个request需要3M的缓存,那么1000request需要3G的流量,这样即便是内网的IO,也会造成很大的瓶颈。(笔者曾经就遇到这样的问题,所以这里就是对这个问题的解决方案的分享)。

如何解决呢,就是将某些缓存,再缓存到本机,这样就会省去网络IO,降低了网络瓶颈。
缓存到本机,我们可以使用本机文件缓存,比如缓存到tmp下面。但是按照我们的原则: 能在内存中处理的决不能放到外存中,我们可以把这缓存放到内存中(前提是硬件服务器内存比较大,现在一般较好的服务器可以达到8G,以至于20,30G,这样内存完全可以拿出1G去缓存这些内容)。

为了方便,我们可以写一个接口函数,去封装缓存动作,可以缓存到APC(内存共享)、文件。这里我们重点选择文件夹,因为文件夹正常是缓存在磁盘上,但是我们可以把这个文件夹挂载到内存上。如果内存不够可以取消内存挂载,这样操作起来比较灵活,也不需要修改任何代码。

200
' e! |- a  J/ n+ B8 h4 M201! ?6 X6 r, e  S2 M
202/ |9 k* d' |8 P$ S
2032 m% `, ]- w' s" Z2 J& q
204! k" R: i6 N4 V
205
) H# a* u; M. n" ~" Z5 x206% b% f* q9 k9 b
207
! M1 [, U0 C) H- B" O. V208
& r4 i( u  W, V. g2095 U# ~" c. {8 t% d/ a: u! n
210
, h2 H/ M& Q9 R$ t4 Y  a9 |4 x( }* m; Q211
0 |6 O. x7 k" z; [# _) v: W0 b212
) p3 ?6 R' R; E213
. A- A* D) O* O, m/ m5 H1 v6 t' N214
& Y7 `. Z: h  f) L" X8 j3 s- {215
1 N  u. O- k1 x, S  i6 a216! W: O6 x7 T/ c) k5 [, I: s
2176 D- I! L7 k' L$ c6 ?3 A
218
" O, W& f( [, \3 m) u% t3 {219
1 A% q. Y. |1 ]* ?: A2201 _8 j& E1 z) n
221  V% a  q' R+ r: j3 a  f' a  q
222
8 I3 y2 W0 v% ]/ I* Y3 L223
3 B/ {) v; r' X7 p7 ^& }, G224
& U2 [" ^! L1 n& z2256 `9 O$ _1 X# |+ k- y
2269 a: ^$ W- z  s. f( w9 g9 v$ D
227
3 A  L0 ?+ G' Y3 H* ^) ^  s228$ \; K6 D3 k" [2 z. G
229
6 p8 T$ v/ P- R230
* ]; C3 {. [* A) t1 g5 A231
, k/ y( k& q8 F232  _9 X; f$ h! B* O3 [( E* ^
233
+ k# ^7 s/ h% K2 S234
) w% N5 V5 V$ `! y7 K7 l: w235. \, s+ m2 ?* C
236
! w* Q  O0 [# o: z237! f' H" b4 P) V, m# y1 c( D! c
2381 k: j) g# ?; u' o2 S$ s
239
# |( M- E6 A3 d* F3 `240
" h$ r0 S& ]: Q4 o241
/ \! k& R# K, u7 X, n: @/ a242
/ S5 O3 s* K2 V* Y$ T+ f* x243/ @- J0 a" \& Y$ w3 s8 S. A
244
/ O8 Z, [7 T- j' D( a; Q245
8 D/ T. U% |6 g% M246
" P" ]: n5 ~4 C+ K) y; H" d247
  V  W9 F6 b0 @# T& @6 ^) v248
6 l- \6 G1 E1 q1 |2 v249
/ u% @/ K5 m" x( b250
: I! x4 R! H+ ~) \- P9 q9 L: Y5 Y251
' m6 e3 g: T( S, e252
6 N* a; n- u' F% O253
1 }9 `2 _9 s& m4 R% r) O254
/ q7 g7 x! q6 ?255- R7 l# B: w5 Z1 \% h; V
256
( _% I7 H. i' q8 t, J+ h3 x257
& M1 ?' ~) w& N; c$ B$ `258
- a0 Z  y7 J/ I8 f( ^& d259. k  Q; G' l4 R" q2 v+ o3 @
260: }% a2 _  v# x, |! }' y+ ?- I
261+ T( `# K, q, \
262+ ]+ |6 ~  J6 u" c/ U' ^
263
& q# h3 ]+ C. `7 |4 r) D264& S: C" G- u" P
265) K7 N, k# C. z  S
2663 W9 \  x6 @2 ?: h" Z
267" q3 v2 [7 Q- O9 z* t+ d! H' R: ]) \" _
2682 H- {, q* F' d# z8 u# S, T- X8 Y
269
# M0 x6 T, |; W& H0 j1 I270
0 }/ W, V3 f4 y$ \) c. T- e; V271
4 U* P. I- q  Q$ C272
& _( a) r2 s* d) T( r273
# d: E; X+ W& G& P+ e' y  A274( R; Q. ~5 B* n) h" B2 H
275
4 o- X6 `& l: ~" A. q276$ |" ~* D3 ^. ~( n. _
2772 g* W5 ]1 Y0 k
278
# c, o0 h  K( d9 \! {279
/ @6 J0 t+ |5 b7 o' U- {* P280+ Z# m1 Q2 t. i0 F* V
281
, j2 g! z6 X' A5 w8 U282
2 L/ ^9 s$ a( m: _+ O283! [5 b8 g  J: o# d
284
$ s5 A' o; ~9 P  |3 M: Q# v2850 c5 y& ~0 S! l, g  F
286
! B: q3 n; ~# v287
: F5 i: Y0 y% t288
6 f6 i2 G- ^0 J, D2890 E1 s. F( ]6 D: X" h
290
) m: Q1 r& o7 o. \. i7 x291
/ {% H6 o8 e) w0 I  c7 T" T( _292
- y5 s7 D. }( V9 f293
% z! M) C9 V6 X+ C# N294
3 e5 f1 e, w+ W" V9 b1 ?# I) s7 g295
; f: Z+ g  ]5 Y  l5 I0 r296( o; U2 \6 y4 s" j% u+ c9 n
297
, }4 B- Z" \8 i298! l0 n% g* o1 e8 U! w$ s: X4 B- x
299
( t& k. O5 ~( J0 Q300$ D- L' o* n% T+ v' m1 n* G+ D! M
3018 N& C  [- s% r) \+ e" j* k% F8 v7 `
302
& Y) h. Z2 u7 \* d! T) u1 d+ M303- z, R2 e2 c7 D/ e, I; ?# P, u
define('V_CACHE_FILE', 1);
6 O1 N4 C1 l) U   [5 l7 z; Q. i& c+ j! O" ?* b
/**; D  |; ?. \3 O5 `5 ~0 y1 j
 *@important Create the cache folder to store the cache data firstly1 m1 M% |5 y9 @6 C4 F
 4 w/ ~7 p! a8 m, z4 i; h8 w' I
   #create memcache local cache folder
4 U: E/ @' r/ A" |   mkdir memcache ; sudo chown nginx:nginx memcache
( `& Y7 ~( X& I6 x2 }! G1 j2 K- B . b- I  B8 B9 _) Q+ N
 */' i2 ~& S. r$ p
function v_cache_file_dir() {
1 v: b, d  q5 }6 g: v3 G  $path = dirname($_SERVER['SCRIPT_FILENAME']);
* n& P- k. s/ r& ^" N  #$dir  = rtrim($path, '/') .'/'. trim(file_directory_temp(), '/') .'/memcache';
# Q& x$ y) S3 \0 `  $dir  = rtrim($path, '/') .'/memcache';
5 S2 y4 ^% t3 j 
) C3 _6 i) f" G1 K3 [( q  if($_GET['debug'] == 'test-cache') {* [6 q% ?5 v; W, h- |' m7 z: v9 f
    drupal_set_message($dir. '@DIR');
1 f3 }/ g' V% L* l4 l* ?  }
: ~% ?) }: D9 \. H& x  if(!is_dir($dir)) {
& ~! N3 t3 D" E# z  U' J4 W    #mkdir($dir);, O4 I; `2 L9 J) r+ B0 c4 w5 Y1 b
    throw new Exception('Create local directory for cache, ' .$dir);
! b5 Q6 F# ^8 e# {* R  N/ F: c$ I  }( X6 f# L# {! i: R
  return $dir;
" E& W0 Z" x1 W: T- c' B( n}
2 b; D7 w# ]$ ~0 p8 I0 _3 V4 ^ 
' }$ N" q4 w$ K6 rfunction v_cache_file_set($key, $value) {
2 d; `* w' K. f$ V  $dir = v_cache_file_dir();
7 E. Y0 ~2 M  m: D1 W" \/ F4 `6 n' t% c  $file = "$key.ser";
# g* {* j8 r. T4 X/ v  if($_GET['debug'] == 'test-cache') {
& c" ?) s7 H  n2 g5 n, u    drupal_set_message($key. '@FILE_CACHE_SET');
6 r2 B9 x! m; f# c3 M  }
6 s) C. e3 r4 g1 e  file_put_contents($dir .'/'. $file, serialize($value));6 K2 s4 i0 B7 F, K8 X) X  N, I
}
) \! f9 F. V# i 
; }% l: Q% V. s* W, ~" Y1 dfunction v_cache_file_get($key) {/ _5 }/ I5 M  C5 T' s
  $dir = v_cache_file_dir();2 m8 b0 g% K8 }' ]
 7 ?- H! ^( r! K
  $file = "$key.ser";8 r- G8 d6 ~+ F& \
  $file = $dir .'/'. $file;
) T. z5 N& f0 c  if(file_exists($file)) {6 d! z4 c  _6 S
     if($_GET['debug'] == 'test-cache') {
: l" {- H+ q# D5 X9 u0 C# B% ~      drupal_set_message($key.'@FILE_CACHE_GET');% V' m( s6 C1 V1 l0 z+ K8 [
     }
) j" W7 G* G7 P6 N    return unserialize(file_get_contents($file));9 l, \+ [  X& k
  }
6 g+ O: C6 M6 n# ~% v$ ]  else {  j9 L# w8 q& [
    return false;+ {1 \" m& E# C6 z9 a9 [4 r* M
  }6 D# g* T3 R) m2 k- x- e
}
  o! q0 N! s$ m  w3 }4 y$ e/ R 
/ W) ~3 [5 B' M) @' t4 B: Ffunction v_cache_encode_key($key) {8 R/ v! {/ S" [! }3 x
  $address = $_SERVER['SERVER_ADDR'];" W' g4 C9 b* N! @  y# y
  //$key     = str_ireplace(':', '-', $key);# k' s& ]# @( _6 }6 L2 E
  $key = "$key:$address";
1 ~2 R' a4 v! q9 m) F! t) g  return $key;, Y/ _3 |( C7 }4 R: v# n/ t
}9 H8 c' ^6 T" u! ]( B% F& o
 
: e* B2 E4 l" C7 w# cfunction v_cache_set($key, $value, $table = 'cache', $expire = CACHE_PERMANENT) {; U3 u9 L& Z" j" ?. J7 X
  $key_mem = v_cache_encode_key($key);$ ]9 K2 _; @- m: D' h
  if (function_exists('apc_cache_info')) {2 n7 M& `( g. I1 ]* a5 @% N
    apc_store($key, $value, 60*60);//1 hour
# f. o# d4 q* ~) w    cache_set($key_mem, time(), $table, $expire);0 \! N/ f$ t4 g; w& \
  }9 |) l. S% b6 C& g/ a% n
  else if (V_CACHE_FILE) {' ~; ]/ y! \$ d
    v_cache_file_set($key, $value);//1 hour
% T$ l3 F: g8 F. g    cache_set($key_mem, time(), $table, $expire);
) |9 H! y: {( U; Q2 M  }* @+ d6 c5 Q4 ^" `! W( ^- z
  else {  }% r1 a0 C( I# E5 e
    cache_set($key, $value, $table, $expire);& P9 ]6 w3 D( L# _: e- ]
  }
& I! `' P' K' I' `6 p0 I( T' i}' T+ S6 }- Y( U; k- |! Q1 _
 
; V0 g4 J, l* \1 P* qfunction v_cache_get($key, $table = 'cache') {
/ D3 L) |% {4 L# y  if (function_exists('apc_cache_info') || VIA_CACHE_FILE) {% n8 @* ]7 q0 O6 G* W6 n- F0 O+ F' Z
    static $static;
2 x) h; V8 C! ?8 {! G+ @2 D: |! C    $ret = false;
6 j6 i6 I3 x0 M9 k/ L) q+ W  if (isset($static[$key])) {# w7 ?2 X  N- ~
    $ret = $static[$key];, x3 d/ [% a7 |+ q
  }
2 ?7 m$ c5 O, E. Y  else {
( J) Y! r7 t2 d& s& e1 ?, y9 d   $key_mem   = via_cache_encode_key($key);
& d. I# w( [/ i6 N& Q1 B   if(cache_get($key_mem, $table)) {
6 N2 A5 z' m% d4 k' m: V5 D' N: z3 D     $cache_callback = function_exists('apc_cache_info') ? 'apc_fetch' : 'v_cache_file_get';
: f. ?  m; d1 `' A     $value = $cache_callback($key);
( N0 G0 f; c" @: y1 K- [7 h     if($value) {
! o) D' p6 Y3 |/ [5 W( m. _       $cache = new stdClass;& M! i5 m( i; E6 l1 B
       $cache->data = $value;2 g/ H, A' H4 G6 a
       $static[$key] = $cache;
" D5 Z# @, `2 T$ \4 R1 r/ S2 i/ x       $ret = $cache;
5 ^/ H+ w/ j9 w1 G     }- E7 z# p! i+ g& x7 E& X! o; p
   }
$ b  ~, l" k0 N( z4 L& I5 L3 Y, f  }8 {8 E5 A6 ?3 L% ~6 Q
  return $ret;
% G. @! c6 G5 J1 ], C0 L3 I) g2 ] }0 V: \. y- m) S( I& }9 @
 else {: S- @0 m* R! `8 N& S% L. V% M
   return cache_get($key, $table);
5 O' R% g- h5 I" D  }- C( h) O) l# `- H; b3 r
}+ B8 \# _, Z- p) N0 k  |# v  u
 
8 Z& J  r9 s9 M) N( }& r& O# x+ k8 Efunction v_cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
; Y3 n! V& O# {9 t0 A  if ($cid) {
: x  Z- X  b0 p6 z! e8 T" h    cache_clear_all($cid, 'cache', TRUE);. t% b. @- J& [5 ]
    //apc_clear_cache('user');
6 `7 k! [+ Z! a, U- k' b0 F  }# ~6 i. V3 x! _9 n. N( o
}

添加了上面到代码之后,我们需要修改一些drupal核心code,去调用我们自己定义的cache方法,重点关注下面几个cache:

  • common.inc 里面的shema,函数: drupal_get_schema里面调用的cache方法。
  • theme.inc 里面的theme-registry,函数:_theme_save_registry。
  • locale.module里面的locale函数,修改里面的cache方法。
  • content.module里面的content-type-info, 函数:_content_type_info。

因为以上信息缓存一次,修改机会比较小,所以缓存到本机是比较理想的做法。
还有一个需要注意的,上面的缓存虽然存到的本机,但是cache的key还是存到了drupal正常的cache里面,所以当清除drupal的cache之后,这些key消失,通过这样的方法,可以实现对cache清除的操作控制。

当然,除了修改缓存的操作,还需要一个清除缓存的操作,我们可以通过实现相关hook来操作。
这个修改是需要修改drupal核心代码的,所以请谨慎使用。

Drupal自定义cache操作流程


声明: 本站所有文章欢迎转载,所有文章未说明,均属于原创,转载均请注明出处。 
本文有效链接: http://www.drupal001.com/2011/10/drupal-custom-cache-tips/ 
版权所有: Drupal与高性能网站架构 http://www.drupal001.com



|2011-2026-版权声明|平台(网站)公约|DOOOOR 设计网 ( 吉ICP备2022003869号 )

GMT+8, 3-19-2025 17:47 , Processed in 0.654027 second(s), 108 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表