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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

[Drupal优化/SEO/环境] Drupal性能优化方案--自定义缓存之共享内存--Drupal教程

[复制链接]
发表于 4-20-2012 21:36 | 显示全部楼层 |阅读模式

对于高性能、高并发软件架构中一个重要的优化策略就是,能在内存中处理的决不能放到外存中。这里外存包括:网络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/ d7 L( f4 k$ B& F, f8 F
201: p4 I. I3 p$ b# |( b
202
( j: h" s! B" w) c7 I203
8 ]0 W$ Q# ~7 f5 W: T6 K8 ~- @204
4 C8 W, L( g7 @8 _7 w$ F0 x205: N8 x2 j, [5 A, a9 q$ Q
206
4 o6 Q( ?& B2 d% N5 A2 L207, S+ W2 m% }# q, e0 m& w
208# i* ^# T) y9 P  ^+ \$ K% f: L9 W
2096 O3 t0 X  z$ q$ c5 O1 f, V- ?9 j' \
210
2 Z6 Q% i8 U  R211  Q8 f, V4 @7 d6 i
212
9 [5 O( p8 X+ s+ g8 w# h213
, Z. p- V5 r: I  T214
7 g9 y+ R' ]  ?& @7 u& w2154 t3 O! f9 h; G' q% F
216
2 l  P; r9 O2 g) p8 t6 J3 w& O217% {3 z8 _9 `; z& E1 q, x. }: O
2181 J0 D4 G. H( J& u' }& l. e
2194 Z/ g8 K" u3 |2 f% x/ ]
2201 G4 ]  \- F2 f
221
( Z. D' S$ ]1 d222/ F5 y( I: o$ K9 L, d& k
223
& U2 U9 G' A* C+ n. X224
  ]0 A/ ?" d5 ~7 x; h  B225
( l+ \2 Q5 V0 R6 h! t& l* v226
  |" ?$ @7 C# R1 j2271 q1 b; c6 @5 `
228
, F$ {! h" L& g( D( J229& g" c$ ~) Z5 o2 ~
230; U' \  B* n- y- B; S6 T
231( y5 g/ T6 c" z
232; h2 ^- a4 g8 W  C$ s' l
2333 Q( B8 r8 O" m9 p4 Y+ I0 Q
234) q9 k. Z- h; q
2358 ^/ m; t+ d3 s/ e( N! z7 H+ q
236+ \( w; b& D" J/ K
237
; H" u8 l0 r; P4 A& V238
. w0 e: E0 W- m: p7 f239
) I' ^+ C6 e% W( |% ]" W8 q" h240
. w9 D7 u; d! F, f9 V! A2 m241
) z) w* m, R/ b- m7 F2427 z' J; L  g; D: n% o6 I. _
243
6 C4 }0 w1 Y* s6 Y244
0 a( \% \; t0 r5 z& I! ^: m245
- K; e7 B" h. t/ C# l( ~246
/ z* q% V0 X8 \  G- h4 l( V, o2470 E' f! Z$ ^9 U! c* B) s
248
2 d3 B& k, @4 m, w249
% \4 E5 L9 h4 ?4 {, g9 ^250
9 d% S1 |' {/ w0 [! z251
# L/ Y7 b. T- p# F# B7 h) T, e' c252- M- {* j4 Q" t* L" i9 ]) G
253
( i" C4 |$ z6 \  R- J3 r254
& q% G8 {5 C/ l# Y255
9 C9 m; z% q* N. _& }$ X256! O2 `0 O3 C7 c. d
257
, {, m3 G+ M( x: j- N) z" b: b258. y% i! _* V% u2 Q4 H0 M
259
4 r3 Q- G% r1 p7 P' P9 V2607 k% A6 b& q2 d# V# e
2618 A  ~* _5 J8 m5 z
262
% _7 o8 c5 i: `8 y3 ^" T263
( X8 Z8 t) z% t% x* E4 V264
+ Z: R" V4 _" O4 w( j0 w6 O7 U2 E265
. z! n! O. u6 A/ J! u266
  a6 c' J4 Y, B5 Q# C) M, z! d267( b7 ~' u  _( w6 B8 }, }- R9 l
268
( @' w7 e/ g2 ^269
1 G  Z; e( C  z) G% \" a270& _/ [6 Q7 C+ O% o# I0 ?
2713 v0 ], z5 |. y$ Q) ]
272* u% S+ ^( u3 @" ?+ G" a
2738 \( q4 f# m: d) x# F4 O
2740 @. l- u/ {5 W1 L4 R) A+ Z
275  e7 H" n! {, z  ~
276
$ w" @5 b) r# i  \! [! F! z4 k277' ]( \: U" V8 Z. Y) ~
278' \' c) L% K3 D* j- Z, c  i
279
4 x; _0 I% e! t7 o4 `/ Q" x$ J2 W280
3 }  t+ X3 {" ~9 V" I281- [# K. Z% {5 D% h$ j! I& [* q
282
$ C/ Y& d( V# r5 h. {1 U" _283
3 S4 d1 i9 r( I; _# j284
/ M/ {3 ^  p+ F# o5 n0 ^+ e7 O0 y; _5 Q2856 m# N. G# X; ?: U$ D; Z6 D
286
7 b5 _' B  t1 E5 Z  w2876 G4 S  p2 T' X  N4 Q0 u6 ]7 w1 a
288* {; r9 V3 T. h0 r/ C- T: I& K
2890 U8 f4 m" C& o/ d/ t
290; @+ h1 M: s7 F
291) x' }7 k& a$ T$ t% b  `/ K& m
292
# C5 u. R0 O0 L. F/ f5 }293
  f; l! u9 G, W294; |: R0 A3 b3 D& N# I1 M% c# B3 Q
295. F7 T% p( e. U4 P1 m( o0 J# I3 k$ e, U
296
2 e& I1 `0 `; `' O4 B1 b1 C297  H# H* F/ s) _2 @
298
2 D& E8 O/ a+ w. M/ m1 O  u4 X$ ]299
% I8 W' Y/ l$ z4 a( J300
3 Y) X. }0 L# z: Y: @! m  `301: Z6 N7 T: E* v& f: e5 w
302
; c$ X) u' n' q. Y303
& y# ]- B. W2 i% y0 M) B  X& D/ |
define('V_CACHE_FILE', 1);( ^+ |( F1 E2 _5 W! H+ b0 b
 
6 n0 x/ Q4 U# B$ @9 ~1 L  h/**
. U5 w7 X5 M" o8 Q  t8 ? *@important Create the cache folder to store the cache data firstly
. d0 d1 |/ c  t) J5 {! _8 K+ }2 L" u ! \. [! k) Z( J$ ?  f+ u
   #create memcache local cache folder
9 `- o; n9 Q* g  e$ ~   mkdir memcache ; sudo chown nginx:nginx memcache6 j) C) O( e* h: z6 e
 + G5 J) V2 o; V" g% q
 */
0 q5 l, d, p3 d: ufunction v_cache_file_dir() {
: l+ T: v; B9 l3 Z; R  $path = dirname($_SERVER['SCRIPT_FILENAME']);
/ x5 L3 S, N% U8 V. M% F6 t0 V$ d  _4 m  #$dir  = rtrim($path, '/') .'/'. trim(file_directory_temp(), '/') .'/memcache';/ m; ?0 @6 T/ [, j! R
  $dir  = rtrim($path, '/') .'/memcache';6 o( P( I4 P+ e8 I% {5 M
 
  }; [; x. @+ u4 |0 z  if($_GET['debug'] == 'test-cache') {: H9 i3 ~" V) S+ `) R2 }  i6 S4 n% m
    drupal_set_message($dir. '@DIR');$ f, v: i  u- Z' }( g. \, E/ K
  }+ B% n7 B- }9 x- T7 \3 g
  if(!is_dir($dir)) {! ?9 b; M- _5 o+ b$ V
    #mkdir($dir);4 i$ v( p* _0 P$ ?7 e+ O+ p+ R+ C
    throw new Exception('Create local directory for cache, ' .$dir);& P5 E( u" w" U/ L+ V4 I
  }
8 b; x2 ?, |( E5 B9 Q; a% k  return $dir;' _" V6 N# a- b6 m" t, C% t) i
}9 A8 }2 D* `# \4 `; x+ k6 ?5 H
 
/ T4 \1 I& ?! W6 E' Bfunction v_cache_file_set($key, $value) {
- _* I1 @; X* `" ?  $dir = v_cache_file_dir();
1 s, p) Z" E0 f7 f  t* F$ Y* Q  $file = "$key.ser";! f& l7 i, l" E8 o; ?% a. e
  if($_GET['debug'] == 'test-cache') {
+ F9 i0 Q9 o8 ^7 Y$ K; p7 u$ \; q    drupal_set_message($key. '@FILE_CACHE_SET');
) P1 m+ P3 t, B0 p% E8 n1 a  }6 p+ \- E8 J1 B- q2 Y. F
  file_put_contents($dir .'/'. $file, serialize($value));
1 Z7 M, i$ \7 `}
7 p; W. T/ U: S 4 m7 p. }0 t* e  F3 E
function v_cache_file_get($key) {
7 d0 f3 `. p! f) s% X1 x4 G  $dir = v_cache_file_dir();5 Y" w: @4 t( [$ x+ S- @/ P
 
; p! v3 ]  n" @: f- ~  $file = "$key.ser";# ]" E, H$ H4 w
  $file = $dir .'/'. $file;' u4 X, i, @+ c0 s2 B4 V8 L! g
  if(file_exists($file)) {
& Y3 h5 f4 P* Q+ p$ x% ?& d6 {% B     if($_GET['debug'] == 'test-cache') {( y! S9 V! D* {/ e8 _5 n* D4 C; ]
      drupal_set_message($key.'@FILE_CACHE_GET');' V2 Y3 ]' P0 ~7 k$ `5 J  q0 k
     }
1 M/ t6 u$ _) c    return unserialize(file_get_contents($file));+ |! @1 W) u' E# |! Z
  }1 J6 E4 y0 N# N
  else {$ ]6 a2 ~/ S& h' H+ u
    return false;
; L3 x  F- ?6 F2 s% C  }  }
4 e0 ?# \- ?  E2 ]5 W- l}
4 [) G( d+ [6 H. ~! J7 A' j 
+ D2 i  R- p. ?* ?+ \function v_cache_encode_key($key) {
# u  ]; a/ v! y1 P! b  $address = $_SERVER['SERVER_ADDR'];
. n4 \3 B6 l  V5 z* f  //$key     = str_ireplace(':', '-', $key);$ i. e+ m4 W$ r, r( b; E
  $key = "$key:$address";
" r) Y2 Y+ f1 \  return $key;
3 k+ u- X/ J4 ~: l}. X5 M* l; D4 j! ?1 ?
 0 {( i2 c. f3 s( Q
function v_cache_set($key, $value, $table = 'cache', $expire = CACHE_PERMANENT) {
, Q' P; z# ]7 B8 R! t- V- h  $key_mem = v_cache_encode_key($key);9 z: p+ y4 Y* l+ Q4 P$ J
  if (function_exists('apc_cache_info')) {0 z8 e! Z" G- N) b% Z! x$ `; X; m
    apc_store($key, $value, 60*60);//1 hour
- ^% L* Q  ^- j& P, ~0 y  M    cache_set($key_mem, time(), $table, $expire);6 g" v2 M, y; f! O% D- |! o
  }7 ]  B, G2 _" y2 M7 r& a/ o
  else if (V_CACHE_FILE) {  _4 ^+ U- A& H  S( I/ u0 D- s. H
    v_cache_file_set($key, $value);//1 hour
0 r. x0 T7 k5 S    cache_set($key_mem, time(), $table, $expire);
& I. m. Y) K) Q0 L% A8 p  }# A9 ~; J' @- H2 y  \
  else {9 [: [. I5 r& m9 [
    cache_set($key, $value, $table, $expire);
, _7 j" s8 X: \2 W5 s2 y  }
; |$ b$ `6 q" h$ q}2 a" ^$ x0 V0 y6 @0 L/ ^
 + q) f, ?' a) c2 O3 U9 [' d, a- Z
function v_cache_get($key, $table = 'cache') {
! S+ g; r5 W) |5 `* {  if (function_exists('apc_cache_info') || VIA_CACHE_FILE) {8 R# `* E3 e- S8 G& ~( x
    static $static;& B1 Y& @$ {0 w% ?0 y: J8 K3 `
    $ret = false;
  Y: a! N- d8 |5 B  if (isset($static[$key])) {. ?/ c9 [( y* B1 h7 a
    $ret = $static[$key];
! g2 r7 e! Y$ G  G5 B+ ^/ o' o  }
, M$ d# k3 H: J( ?( p  else {; I7 E4 p7 S# E
   $key_mem   = via_cache_encode_key($key);
, ~( v5 o) A3 Z, q   if(cache_get($key_mem, $table)) {
1 ~* `! ]$ H# d7 N     $cache_callback = function_exists('apc_cache_info') ? 'apc_fetch' : 'v_cache_file_get';
1 t3 y$ k3 w6 V& Q; G; Q+ B     $value = $cache_callback($key);/ r) O( o) R- p% G; Z/ k! _
     if($value) {
# s8 r, N( {  N) N; N, {/ Y       $cache = new stdClass;! ^1 j/ [( ~, {
       $cache->data = $value;
; k, M+ J4 P" e       $static[$key] = $cache;. u* s* w5 ?  E3 Y0 T$ M
       $ret = $cache;6 \. ~' f, O% V2 s
     }3 m& F- c' v2 Y. {
   }
0 a$ C8 `2 v. i  Z/ P+ Z  }
5 `, F1 p* K7 p- q/ T- E  return $ret;
: w. d) Q; p( p4 B }
6 w' j$ U3 k% [/ [7 P) T else {- h: J. j2 J5 Q2 ~# y
   return cache_get($key, $table);
) t* c+ P/ ~0 P2 P0 A3 _  }# q  @  U3 B2 t. L" ^3 n3 O; u) u/ d
}
2 h  {$ S- U% E! [ 
! C2 r+ Q9 B4 @6 Q0 B4 c4 ?) w& ofunction v_cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
; ?0 J4 O; L2 H0 j3 u' Z, y/ K0 o  if ($cid) {+ l9 z2 v% V2 K. `* q
    cache_clear_all($cid, 'cache', TRUE);0 u' y; g! \, u# J) D8 {0 F
    //apc_clear_cache('user');6 {: K% S8 U4 l. }7 w6 x
  }
, Z( C7 s4 u; ]0 x}

添加了上面到代码之后,我们需要修改一些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, 5-8-2025 05:22 , Processed in 0.272734 second(s), 27 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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