国外设计欣赏网站 - 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& |& a/ x7 r2 a' O6 B% n3 h5 n# F
201
3 a' X, i' [9 n' E9 T  K& V6 S202. }) B8 O" j) ^* u; c
203$ c/ U; w* Z; @7 \1 E) d* V- b3 k+ s6 B
204
# z" m  ~" k  |6 Y205
. q" q1 F% n5 O- f, r' L2 X1 R206; t1 L: s6 P# Q9 y3 I
207
" U1 D& J+ \. Y# ~8 L1 n  j" X208" k. u6 X: c9 b' E
209
% i. i" B! N' A8 Q2 ~+ _: t& D( I210$ v1 `8 q* l  v7 t' q" ^2 G
211
- @& z0 P" F$ a9 y, S212
' i, a1 [, r5 f1 f2 _8 g3 _213" d) S) d0 E& t% `" }
214: k; f' x$ h0 l1 P
2154 K% I6 L. {, F- K$ b2 E, B5 M
216% {1 H9 X8 S3 u, @& \
217& A* P3 X: ?' E/ X5 S; ]
218
! @- e& M5 k/ l7 T7 F219! P, @9 H( \* v- h
220
% n# M' H, T) Y- e! A# u221' n, W2 i; M) u  M$ S3 @) P; H2 V
222
: ?7 F/ f( C& h223
" `# m" K# m. G; m# {- s- G3 ?2240 U) c- R2 H0 \' R" F5 {
225
5 g7 }7 I  j  o  |! s226; ]5 ~) [$ F9 P& ^' u
227, M2 r! ~" u  G9 W9 v
228: ^8 @; V0 b" K# N1 c! q9 s
2290 @. n/ `( q& `7 w
230: n+ \' X5 v4 M! Q- z. _  s
231+ D; O* f% C$ I. L; \# [
232! b4 ^  t# p) b, r+ O: g! x5 D
233# m: g; K# e. C) W3 p, Y: b/ [
234
% v- I; H5 |* c0 a* u( z0 b235
5 @) @- \7 w& b236( P1 `# m/ e' U# c/ Y" }
237$ ~5 x8 X* V: n. A
238) _" W2 ?. F  s* j
239( Y7 H8 P( I% o/ v
2400 f& q, C  `: S0 P9 S% z- o1 Y! n
241( S# o6 u7 t% g: N% k6 y  g
242
" d4 R3 P7 K" x5 b243! g: B# v9 t' j* D$ R# k
244' W, g6 S& v8 Z) _( G, n
245
9 M) D- _0 l4 Z0 x( K246
, n& o' L+ D0 ~& ~247" n; |; [( ]- j' b
248
4 g, O: [# t3 s% i( \2491 a6 j, d8 H$ c+ P( [; o9 ~4 T; i
250' [/ D* _$ Q( r" b% q. f
251
1 b% ?, K4 g7 I4 v; {# S252+ E+ J$ M! L! _' P7 ]( [
253
+ Q( |9 u' y1 P4 K! Z& p254
5 J8 M8 o& A9 J2 l- U+ D255
" x5 q6 @" n* e! {  w  ~; y: C2 L- a/ R256
& h0 ?8 r6 E* R: y% {$ R257
1 K1 U8 a( K2 g8 a( j258
* K4 U5 ~7 E$ w0 H0 l' X259
- D9 q  m& O3 Z+ g7 Z" D" ~4 a" Q# x260+ E( @0 b6 e# t' `9 p7 T
261
1 e/ ~# g* ~7 S9 [) H7 C262
  b' g% F- {1 E+ N7 E  M263
2 f/ N8 B3 D. t+ |- a6 z264. M. C/ y& c. m3 @9 q0 Q) D
265+ d% B- i9 O& b6 ~: J% G1 _' x
2669 C' r) O2 R! v2 C" M
267
/ Q" w" E, o+ ?" }268
( j7 i7 f' @0 J: ~! ?/ z269$ G* F1 \% n6 d. F  b0 _
270
2 K. k) O% f4 i0 v/ n1 ?271  O# }; A1 ?1 i. O
272
) Q" i. _! \5 E+ n: T0 y2 e! b273
% c# A  m- z4 D7 F& _274: |7 H( ?9 v4 K' _# a; U
2759 C; d4 m  F+ n2 o
276
, h5 ]# C; r/ x2771 N0 k% X' g: i( i7 y! l: E
278
7 V* S1 H7 Z! I. [; X279
  N& \4 T' x2 j/ F280
7 q5 ^( f  q! i- R% Y/ D281
) ^! Y& N' g, J6 ?( j5 j9 I282# ~1 D  L2 z! i) c
283
- E. T' \, _3 s284
9 P3 K! {( l2 `- h" _6 |285; y! y% U7 Z: ]1 ?, }
286
1 \. O0 F5 z* j3 G7 ?. t+ _287/ y' B" k9 ?+ }0 i1 S4 @
2888 w; v% E4 M- [0 v4 K- X* B2 d
289
6 y; o0 S" P  F& R  a/ d' W290$ r" P+ j3 {1 E% Y2 S
291
  o1 V  u0 v! ?9 W- m0 ]292
0 o7 a! k% }/ a0 t- J293
; ]5 e' w% _) ?  j1 G& @) }294
! {, ?- h) {% \8 ~295; x6 d+ B6 y) a; w  _* @8 H$ S
296
4 D0 f6 O$ q, w+ q297
' [! e, z5 T3 ]298
8 b3 B% `5 |7 I3 X$ x6 k299
& r3 i, K3 |+ U$ t3 I! |300' ]& m1 l$ h& I( @
301
0 @# C2 x: Y- N9 x" B! s4 s302% `8 f3 c- c$ Z/ U+ \8 W
303( g* q" n" g8 t/ V, |4 C
define('V_CACHE_FILE', 1);
0 ^5 h+ s: y; K  B$ r 
2 R" Y& q* O. L) L* K# R/**) u3 [' Q& K: ]% b. {
 *@important Create the cache folder to store the cache data firstly
5 n$ M% D7 k2 e6 R; l/ W& r 
" M  ]" E7 z/ l- I+ q4 E   #create memcache local cache folder
/ T9 s! T- `( ?4 R" R3 k( o+ {3 @   mkdir memcache ; sudo chown nginx:nginx memcache
2 U( b- @" V# o; r, W3 `& E* D 
( ]. v% [( R% k5 U */
3 r, E6 |7 t* @4 ?0 `function v_cache_file_dir() {
% p! C! f- [$ ^9 Y) _% q! |  $path = dirname($_SERVER['SCRIPT_FILENAME']);7 Q2 b, P+ X; }8 ^  q! q
  #$dir  = rtrim($path, '/') .'/'. trim(file_directory_temp(), '/') .'/memcache';2 v' @0 T* Q7 y
  $dir  = rtrim($path, '/') .'/memcache';$ S/ o% t: }, \" A7 ]" t& W; I
 
) B+ ?2 x6 @) b  if($_GET['debug'] == 'test-cache') {2 [& Q& _" w# d5 p6 Z; E
    drupal_set_message($dir. '@DIR');: F6 j- M: @6 e& }! o/ @
  }
4 _& N4 F! S4 x% o+ _4 j6 v, Q) h  if(!is_dir($dir)) {
, n3 h" K- Z! ?9 @    #mkdir($dir);$ I, s& z& @/ Z& F  e9 s- k6 Y
    throw new Exception('Create local directory for cache, ' .$dir);2 U3 L1 ^2 F2 ^/ Q
  }
, E' d, B+ H* M! J( u  _& s( H3 b" j  return $dir;
- r  T# [/ }, Y6 q}
  B/ c, m- f" \) B " t9 b$ [8 B' Y
function v_cache_file_set($key, $value) {& {- @( W) Z4 L/ r$ N" Z$ t
  $dir = v_cache_file_dir();, c2 ^: P! q; @* O+ m. q; x- l
  $file = "$key.ser";$ a& Y2 p' g' h4 L* a6 C7 U9 k
  if($_GET['debug'] == 'test-cache') {
4 K7 D# _  i! \$ O    drupal_set_message($key. '@FILE_CACHE_SET');
. O0 N: ~* k; R8 G* o; b4 Y  }
8 I5 b3 R; j5 K4 L) T! B* E0 c  file_put_contents($dir .'/'. $file, serialize($value));
3 j4 c, B8 l* K+ x3 l0 f7 [}( O& I' D* i+ f) l  L# q
 
1 Q* R7 ?2 [9 n4 u4 g# h8 q( Bfunction v_cache_file_get($key) {
- v  e! D5 Q# s* ^8 Z0 W( S- Z  $dir = v_cache_file_dir();; `' z- R. }, Z4 S
 
, m, i8 ?0 r3 G8 W  $file = "$key.ser";% H( |3 f4 ^  q0 ^1 J, [
  $file = $dir .'/'. $file;
( S3 r( N" n- \# l% u/ z  if(file_exists($file)) {+ R; H1 ?) V# B; F
     if($_GET['debug'] == 'test-cache') {
- n$ S5 b# B* W+ b6 T) u4 O9 L) Q! G! ^      drupal_set_message($key.'@FILE_CACHE_GET');
' t- h3 w2 R1 b) I9 u  h8 D     }1 X- R( |* {, e4 j! G, b
    return unserialize(file_get_contents($file));; z8 E5 a( [) o" m7 w# d( J
  }4 \8 b6 w* {+ ?: m3 R! H
  else {& z9 n& ]  p. W, B: a" p' d
    return false;
! w- ^% s6 A5 `( }  }
. X, o; a( }/ ]: s4 r}( w, @- u+ G  c+ t/ p% h
 
, i& T: F5 O, |6 Jfunction v_cache_encode_key($key) {
: J" `: w. N0 F7 ?% P4 }  $address = $_SERVER['SERVER_ADDR'];
1 P0 b" f: m9 J4 V5 l0 W5 i  //$key     = str_ireplace(':', '-', $key);
* N: B! w8 J  \' g  $key = "$key:$address";
( K! m; M! p8 k5 X3 [  return $key;
$ C7 [7 S* h7 z/ j}( W9 H! v1 k2 L0 Q  ]& O' q$ X* j! B$ n
 
2 g0 V. ~2 E  @) qfunction v_cache_set($key, $value, $table = 'cache', $expire = CACHE_PERMANENT) {
* S8 A. r' I! m) h& W0 L  $key_mem = v_cache_encode_key($key);
, l% g0 Q+ B8 K# i) [' [  if (function_exists('apc_cache_info')) {+ v0 l8 G5 X: T# m, p# h! M9 X
    apc_store($key, $value, 60*60);//1 hour
! a2 ]1 d" L: {8 Z/ B- ^4 _    cache_set($key_mem, time(), $table, $expire);- e+ z$ P, N2 w3 x& S
  }
8 D- z! a" C/ b. Q) G! o# d  else if (V_CACHE_FILE) {4 S6 w  G6 Q* d5 G6 D" Q/ p
    v_cache_file_set($key, $value);//1 hour  h, G- Y- [) K8 t
    cache_set($key_mem, time(), $table, $expire);
( P7 r2 Q9 ~, k! I4 S+ @  }
4 I* o/ ^" r9 N0 f$ [8 {  else {
: ~/ r# `# u1 q6 X$ _    cache_set($key, $value, $table, $expire);9 x' y4 l; ]7 T% r+ E
  }. I; k5 n  w; H" B% k' K- m8 X
}3 o" x5 t5 c- C- p: u/ u
 
. N2 q8 S7 `! gfunction v_cache_get($key, $table = 'cache') {
8 k! N' c4 K+ }  if (function_exists('apc_cache_info') || VIA_CACHE_FILE) {
, z) n1 B, n+ y5 }, [3 M! W; r; @    static $static;
8 w. Z( Q, E4 z    $ret = false;
7 U% P9 |5 G* O4 i  if (isset($static[$key])) {* W9 ^! {+ U0 z; F; A, O' B
    $ret = $static[$key];9 g* @. A- t% J0 |9 O
  }# P' N+ c; ?: J6 T. M
  else {8 Z0 g! H+ j- I& E5 r& f# Y1 A
   $key_mem   = via_cache_encode_key($key);8 b+ D( {6 Z/ c$ w
   if(cache_get($key_mem, $table)) {: b2 N# M& |! O& {! p: y( j
     $cache_callback = function_exists('apc_cache_info') ? 'apc_fetch' : 'v_cache_file_get';8 z  S1 _8 f- g* G. y1 f
     $value = $cache_callback($key);: J2 L; H& L  G- y7 S" B
     if($value) {% X% Z; Y8 s) r( l, v  r
       $cache = new stdClass;  J- u  U% P# S0 ]+ v. E% G% j4 g/ @
       $cache->data = $value;
$ `# X0 x+ z- f/ {) J. b       $static[$key] = $cache;
% e0 K3 ]% h' c9 D7 {+ s/ s# J       $ret = $cache;3 A3 d( T* q( f$ b1 z
     }
$ n5 d  B7 }& R6 q, _1 `   }8 d9 u/ h) u$ E% i) W& Q' v. u
  }; ]) {( J, [. _2 L! k' @- k
  return $ret;! ?4 I$ o9 V7 C
 }0 r! l1 M. I1 x! M
 else {
. L9 i; V2 v' v3 \  z% K" z1 o   return cache_get($key, $table);
& N" q- S0 V3 M8 y  }
' w4 R. w- M) M& y5 L7 r$ V}
& L/ m; Z+ @' u9 W  _+ {2 ^ 6 Q, t# @; n  O9 a& h
function v_cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {" V) V+ H- q0 G8 d( Z
  if ($cid) {
7 |: r3 e/ R! I6 _    cache_clear_all($cid, 'cache', TRUE);
5 @  s, k0 n5 o+ a+ V2 r! X    //apc_clear_cache('user');! _# n" |2 H$ I" Z2 k
  }! ~# F& O6 r4 N
}

添加了上面到代码之后,我们需要修改一些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, 11-12-2025 10:49 , Processed in 0.247083 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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