|
1:mysql memcached UDF 其实就是通过libmemcached来使用memcache的一系列函数,通过这些函数,你能 对memcache进行get, set, cas, append, prepend, delete, increment, decrement objects操作,如果我们通过mysql trigger来使用这些函数,那么就能通过mysql更好的,更自动的管理memcache! 2:安装方法: 1)安装memcache 2)安装libmemcached shell> cd libmemcached-0.35
/ h% K; X; R2 D+ s( @+ q% l: yshell> ./configure --with-memcached=/usr/local/bin/memcached* w0 C! [& M& t5 e% v( W
shell> make && make install9 S Q0 n6 f% d1 c6 O: d
shell> echo "/usr/local/lib" >> /etc/ld.so.conf
, p$ E7 Y: o% D2 S! vshell> ldconfig 3)安装memcached_functions_mysql. s& n( F# }$ A) n0 W' U. g+ G
shell> tar zxvf memcached_functions_mysql-0.9.tar.gz
- B8 y5 X) t" Z* o1 E% Qshell> cd memcached_functions_mysql-0.9
2 c4 X7 n6 z7 X; [9 }+ |shell> ./configure --with-mysql=/usr/local/mysql51/bin/mysql_config --with-libmemcached =/usr/local/
9 d1 `4 c0 h" v% b$ F; v9 D) vshell> make && make install 4)拷贝lib文件到mysql的plugin下面- R9 W/ w) H2 ?$ e0 }" h7 X! d
shell> cp -R /usr/local/lib/libmemcached_functions_mysql.* /usr/local/mysql51/lib/mysql/plugin/ 5)添加memcache UDF 函数 在mysql里执行 source install_functions.sql 这样我们就可以使用mysql memcached UDF 了,我们可以通过下面语句查看是否已经正常安装 1)查看mysql.func,有很多函数 mysql> select * from mysql.func;1 m* f1 V& u) P0 W" V
+------------------------------+-----+---------------------------------+----------+
, b% e3 c, h1 i0 R4 C' A" c% q| name | ret | dl | type |3 z: u, k4 Z$ b$ v. }3 ]& l! v
+------------------------------+-----+---------------------------------+----------+. O1 O) e' G, J" X1 y2 F
| memc_add | 2 | libmemcached_functions_mysql.so | function |
3 r2 Q- Y! W8 }8 v- B" R| memc_add_by_key | 2 | libmemcached_functions_mysql.so | function |0 ^) M5 v5 C2 r) J$ A4 V" a3 i
| memc_servers_set | 2 | libmemcached_functions_mysql.so | function | 2)添加trigger,看是否向memcache里insert、update等 具体的语句,我们可以参照: 1)memcached_functions_mysql-0.9/sql 目录下的trigger_fun.sql " r3 e9 Z3 j- D4 v5 N+ ~
我们还必须注意以下几点: 1)mysql 编译时一定不要带'--with-mysqld-ldflags=-all-static' 这个参数,因为这样就限制了mysql 的动态安装功能了 2)使用时,要观察mysql.err日志,不知道是有意还是无意,udf更新memcache都会记录在err日志里,注意清理该日志,否则一下就爆满了 3)mysql 官网有这样一句话: The list of servers used by the memcached UDFs is not persistent over restarts of the MySQL server. If the MySQL server fails, then you must re-set the list of memcached servers. 所以,当我们重启mysql,我们必须通过select memc_servers_set('192.168.0.1:11211,192.168.0.2:11211');语句重新注册memcache服务器! 测试环境在Linux下进行,版本系统为CentOS5.
7 R8 |' {1 i+ L0 [8 R( c3 D' X以下为相关软件,包括其版本和下载地址: 5 W# }5 @& Q+ C! G$ P' y. S
mysql-5.1.30 下载
9 i6 I; h0 W4 p& n ]2 Wmemcached-1.2.6 下载* c8 M7 M" {+ J) v1 G( r" B" n
libevent-1.4.7-stable 下载9 U X& k l1 x( Y" Y+ I9 t. n
memcached_functions_mysql-1.1 下载1 k7 S9 L1 T& U8 k6 c x6 T E
libmemcached-0.26 下载 ! q, h; _ v/ V7 \9 H
% _% H2 F, O B! I. [+ G# D3 I编译安装MySQL,安装因个人细好而定,省略许多与测试无关的编译细节及参数。
- <span>[</span>root@localhost ~<span>]</span><span>#tar xzf mysql-5.1.30.tar_001.gz</span>
- <span>[</span>root@localhost ~<span>]</span><span>#cd mysql-5.1.30</span>
- <span>[</span>root@localhost ~<span>]</span><span>#./configure --prefix=/usr/local/mysql51</span>
- <span>[</span>root@localhost ~<span>]</span><span>#make</span>
- <span>[</span>root@localhost ~<span>]</span><span>#make install</span>
- <span>[</span>root@localhost ~<span>]</span><span>#./scripts/mysql_install_db --user=mysql --skip-name-resolve</span>
- <span>[</span>root@localhost ~<span>]</span><span>#/usr/local/mysql51/bin/mysqld_safe</span>
( w, s" b8 @* Q& L$ A
4 M* C% A$ o* H' E+ u3 ^2 e% w( B9 ?
7 E5 F+ W( M" G9 ~
省略列出安装memcached和libevent的相关命令,具体可按照实际情况安装,测试时我将libevent默认安装,memcached安装于/usr/local/memcached目录下。
+ H8 H! b9 I p/ \6 ]7 y启动memcached. - <span>/</span>usr<span>/</span>local<span>/</span>memcached<span>/</span>bin<span>/</span>memcached <span>-</span>d <span>-</span>m <span>50</span> <span>-</span>u root <span>-</span>p <span>11211</span> " n' d8 l8 |$ Y9 d+ o4 L
( j. Y' N( S1 u6 r
: I& q; K0 W& @# Q d& |" G/ N) F: ~
) x- a1 I3 s. ]+ z编译安装libmemcache. - <span>[</span>root@localhost ~<span>]</span><span>#tar xzf libmemcached-0.26.tar.gz</span>
- <span>[</span>root@localhost ~<span>]</span><span>#cd libmemcached-0.26</span>
- <span>[</span>root@localhost ~<span>]</span><span>#./configure --with-memcached=/usr/local/memcached/bin/memcached</span>
- <span>[</span>root@localhost ~<span>]</span><span># make && make install</span>
4 c- ]8 s6 X# h: E
1 ?$ H$ t( h/ z2 V4 \# b3 ]) d
1 E7 D: y$ S) g+ {2 j: T1 K5 Q$ s" r1 a. g/ V# G
编译安装Memcache UDFs for MySQL. - <span>[</span>root@localhost ~<span>]</span><span># tar xzf memcached_functions_mysql-1.1.tar.gz</span>
- <span>[</span>root@localhost ~<span>]</span><span># cd memcached_functions_mysql-1.1</span>
- <span>[</span>root@localhost ~<span>]</span><span># ./configure --with-mysql-config=/usr/local/mysql51/bin/mysql_config</span>
- <span>[</span>root@localhost ~<span>]</span><span># make && make install</span>
0 g5 k; A' U- y4 d4 }2 C6 } & f! y& H/ S8 t( P
+ M4 `) o1 G, D1 ^4 ^! c% ]. C4 x! H, `3 y
编译完成后将编译好的库文件复制到mysql的插件目录下,以便于加载使用。 - cp <span>/</span>usr<span>/</span>local<span>/</span>lib<span>/</span>libmemcached_functions_mysql<span>*</span> <span>/</span>usr<span>/</span>local<span>/</span>mysql51<span>/</span>lib<span>/</span>mysql<span>/</span>plugin<span>/</span> - [/ J5 _5 N3 ], L' B7 Z* V+ D# z) h
1 Z+ ^8 k) o# k3 R% N/ y8 Y) z
+ R8 s1 _) {- G
3 {. K) q1 T! ?进入memcached_functions_mysql的源码目录,在目录下有相关添加UDF的SQL文件用于初始化。 ' j3 N H/ ^: k! j6 i7 w
在mysql的shell中执行memcached_functions_mysql源码目录下的sql/install_functions.sql
/ D% ]% P7 B7 k8 c* a7 t* o7 L1 p或者运行memcached_functions_mysql源码目录下utils/install.pl这个perl脚本,把memcache function作为UDF加入mysql。
: v1 p3 w& J/ Z% ?. i8 l! N7 z[root@localhost ~]# mysql <sql/install_functions.sql 检查安装是否成功 ' E* R8 R' y0 w& q' {/ S: S( x3 L
mysql> select name,dl from mysql.func; % F! h" O, M, U5 i
5 E6 q) ] {9 q) B& D二. 测试用例设计情况: (1).新建两张表:urls和results,用来更新urls表里面的内容,让系统自动更新memcached的内容。results用来记录更新memcached失败的记录。0 }) w* n1 r5 Q7 S3 S/ h# j; z
sql语句如下:
, H3 T* v; ]9 X: m; g. j, ?use tests;
w9 B1 ^+ `; j# K4 Z, A* bdrop table if exists urls;
% {) T( d) j5 S& m O9 @( E6 I3 mCREATE TABLE `urls` (+ q! o: M/ O" I; _7 [9 i
`id` int(10) NOT NULL,. K' P3 x8 e/ ?0 d) ^
`url` varchar(255) NOT NULL DEFAULT '',
$ }: P7 U; ~) h7 |7 Z. r PRIMARY KEY (`id`)8 u- S& _" D8 T2 D9 B2 [ _
); drop table if exists results;
) a* B5 U! [/ j; RCREATE TABLE `results` (5 W: M+ W0 P ]3 ?0 }/ s8 r" x, t
`id` int(10) NOT NULL,$ R' F" D: q7 o. R
`result` varchar(255) NOT NULL DEFAULT 'error',
4 S* J5 O+ N0 ~. J* t# v `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
# e: C- Q, X+ O" r PRIMARY KEY (`id`)3 i$ X( F. M' M0 N9 n7 _! j1 B
); Z% [" h! X; ]& W5 w( t3 _
(2). 建立三个trigger. 当向urls表里面插入数据时,对memcached执行set操作,trigger如下:4 y& D; g; }0 f" M6 j9 B
DELIMITER //5 T/ X& E5 U* q% W
DROP TRIGGER IF EXISTS url_mem_insert;5 @1 L1 w4 c7 V
CREATE TRIGGER url_mem_insert
/ H& Y1 P* Z* a# q) cBEFORE INSERT ON urls2 {9 _) B% `4 i
FOR EACH ROW BEGIN4 L( d! t1 S. w3 g& y
set @mm = memc_set(NEW.id, NEW.url);8 g! C+ e, Q2 u& T
if @mm <> 0 then8 H3 [8 E) N; n1 w
insert into results(id) values(NEW.id);
! i! j* Y. Q- N: N {3 F end if; END //$ M' g& q* E8 w. z: m
DELIMITER ; " L1 n# ]- h7 N
当对urls表里面的数据进行更新时,对memcached执行replace操作,trigger如下: DELIMITER //
d }- _- T! vDROP TRIGGER IF EXISTS url_mem_update;
/ S B3 a0 ?2 zCREATE TRIGGER url_mem_update/ O8 c5 \7 ?6 o# N
BEFORE UPDATE ON urls
1 q4 y4 B, I' pFOR EACH ROW BEGIN! J" ~& Z: I3 J- V
set @mm = memc_replace(OLD.id,NEW.url);% _+ h; Y% E3 r3 y
if @mm <> 0 then3 b( M2 ~7 `# z
insert into results(id) values(OLD.id);1 P+ \5 J8 M9 W2 [" U; |
end if; END //
* v; ?; S' z6 J7 H5 ^2 [DELIMITER ; ( W0 s' j/ V, x8 G) ?+ _5 w; G
当对urls表里面的数据进行删除操作时,对memcached执行delete操作,trigger如下: DELIMITER //
' w9 V! Z# |! P6 L+ V$ a8 R+ lDROP TRIGGER IF EXISTS url_mem_delete;! A& ]/ T% q6 z- K# D1 v1 s
CREATE TRIGGER url_mem_delete
9 K+ b6 ?. d- ]7 |BEFORE DELETE ON urls" e0 y+ {+ t; B9 P& j3 \& j9 S
FOR EACH ROW BEGIN; R) d0 g3 Z& S, ~' ?
set @mm = memc_delete(OLD.ID);
. Y, l1 D; v" a if @mm <> 0 then p) e5 t. ^ z3 W, I
insert into results(id) values(OLD.id);, |: a. D% K0 |5 J
end if; END //
' M+ i7 y0 r/ _; eDELIMITER ; ; l1 a0 l( f7 ]
(3). 设置memcached相关参数 设置同时UDF操作的memcaced的机器IP和端口: mysql> SELECT memc_servers_set('192.168.3.184:11900');
L. G$ i+ [! w Q: I4 A+---------------------------------------+( N4 ^0 o: @- S- j4 S
| memc_servers_set('192.168.3.184:11900') |
* _ l! ~. J1 K& I$ J, J% X# ~6 n+---------------------------------------+
# o0 T' Y/ d+ E8 Z, U4 N" n| 0 |
' a& e/ M) W* G8 t' O0 c) M( O+---------------------------------------+
; G" |+ O& o" \1 N2 j) R: C1 row in set (0.00 sec) 1 K8 B( |3 H" r/ w( c! A. y! G3 ]
mysql> select memc_server_count();
7 u' z9 G6 s& D# t+---------------------+( a5 b# {, q, l' t: c9 z
| memc_server_count() |7 S- J- r" H" i0 o' m
+---------------------+- K" G8 |1 g `( R) m
| 1 |, n( S! V: s: L: p. e. ]9 N
+---------------------+8 _( M/ E. Y3 i$ V% Q
1 row in set (0.00 sec) : [: U# e7 V8 ^
在mysql命令行列出可以修改memcached参数的行为:
1 P! Z0 C: E3 S" fmysql> select memc_list_behaviors()/G
. R# e( C% V0 ?" O8 T( z! A0 p& D*************************** 1. row ***************************
- ?' s* l+ z! @5 N% Cmemc_list_behaviors():1 U7 B3 u* `- c6 Y% n
MEMCACHED SERVER BEHAVIORS
( E+ h, A3 E; ~MEMCACHED_BEHAVIOR_SUPPORT_CAS
5 N7 k8 l6 V; Y# K, [MEMCACHED_BEHAVIOR_NO_BLOCK/ L' [0 p9 t# \ h
MEMCACHED_BEHAVIOR_TCP_NODELAY
" M `* |9 |& i# D: [9 jMEMCACHED_BEHAVIOR_HASH
# l' ]% k- A" U& w1 Y G/ R7 V) EMEMCACHED_BEHAVIOR_CACHE_LOOKUPS7 h+ K' m6 U8 G; g+ d& t/ \$ D
MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE' B: K1 S! t2 U
MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE
! H/ g+ u8 ]6 L" T6 [! j9 Z/ d6 GMEMCACHED_BEHAVIOR_BUFFER_REQUESTS7 G: c% P; ~+ u/ p1 D
MEMCACHED_BEHAVIOR_KETAMA3 x- f/ G8 A0 Q( N7 Y
MEMCACHED_BEHAVIOR_POLL_TIMEOUT
" @ N: ~. x9 JMEMCACHED_BEHAVIOR_RETRY_TIMEOUT- m% G/ e1 z5 P+ Q
MEMCACHED_BEHAVIOR_DISTRIBUTION
" @! b, h, {( x4 n& CMEMCACHED_BEHAVIOR_BUFFER_REQUESTS0 A4 l; p% W3 @* N" |1 W5 U6 w
MEMCACHED_BEHAVIOR_USER_DATA. K1 g/ r. D. n! g0 g# E
MEMCACHED_BEHAVIOR_SORT_HOSTS
/ [# H( l2 }7 \( qMEMCACHED_BEHAVIOR_VERIFY_KEY4 t5 X2 [5 J, V' N
MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT
9 M6 U) h4 @& m" E1 I& ]MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
, d- e3 N+ ?" t) f- v- V* E) jMEMCACHED_BEHAVIOR_KETAMA_HASH% c3 `3 s* C: q1 x/ x, D l6 g
MEMCACHED_BEHAVIOR_BINARY_PROTOCOL; N Q6 R T5 G. L% M, J
MEMCACHED_BEHAVIOR_SND_TIMEOUT6 k' c+ w% e1 W" Q
MEMCACHED_BEHAVIOR_RCV_TIMEOUT
+ o+ `! W1 _6 C; G1 }, d% p5 IMEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
& i, B% A8 n6 Q; KMEMCACHED_BEHAVIOR_IO_MSG_WATERMARK4 H7 u. Z) Z; n6 \+ |: [
MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK 1 row in set (0.00 sec)
/ p+ F! S7 R+ E; ]4 v0 U设置MEMCACHED_BEHAVIOR_NO_BLOCK为打开状态,这样在memcached出现问题时(不能连接时)% C) s2 \8 Q7 w) ~
数据继续插入到mysql中,报错提示,如果不设置此值,如果memcached失败,mysql需要等到timeout% C. [0 \: H4 T" B0 T
才可以插入到表中。# v- v! s6 y. K" p, C1 J
mysql> select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1');
7 w1 T# L$ u' w% [+--------------------------------------------------------------+
1 T, Z8 L2 j. r# _ @! \: \| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1') |
, S/ s' U1 L# j/ l+--------------------------------------------------------------+8 z' r9 E# Z, f T- G
| 0 |. L% W; a( L- v: F: S3 j
+--------------------------------------------------------------+0 c* ~$ i& y X. C1 L! G0 d
1 row in set (0.00 sec)
- U2 `) C$ |6 ] A5 P+ @; dmysql> select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1');
/ |( u$ ~$ P: ~" _8 Y" J+-----------------------------------------------------------------+
9 r U0 I3 q5 i0 }" [| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1') |
& A4 ^ u* D; s4 M9 L" n2 M( |+-----------------------------------------------------------------+ F/ @* ]* Z7 R b& ~. w
| 0 |
! w8 j' e) b1 J9 @: |7 x) m- q- Z+-----------------------------------------------------------------+
( Y( W- A* b! m$ K& H; S1 row in set (0.00 sec)
+ c5 y9 Y& w: A. w8 d$ p( o! `
6 S3 L: U1 }* Z s& I" \/ V三. 简单的功能测试:
2 ` `( Q p* `5 v1 N8 \* w% M. _
1. 向表urls里面插入数据,然后查memcached是否也set进数据: mysql> insert into urls (id,url) values (1, 'http://www.sina.com.cn');# J+ N% r3 ]8 P2 g/ [, ]
Query OK, 1 row affected, 1 warning (0.00 sec) mysql> select memc_get('1');
7 S4 M9 G. k3 t( w! K5 D: Y: ~* V+------------------------+* j P* r- o0 m7 ?$ ^
| memc_get('1') |0 J* a' n4 o+ n! E9 ^( b$ m8 l
+------------------------+5 L0 O) I O- g# d
| http://www.sina.com.cn |
7 Y) O* l& Y6 {/ s5 n$ j+------------------------+, T# u( y g6 c: {% `) Y
1 row in set (0.00 sec)
( q2 Q3 @2 s! E! t* H1> telnet 192.168.3.184 119009 z: b3 K% [% @: T. N, W3 q
Trying 192.168.3.184...
* C, D/ F0 f3 y: PConnected to 192.168.3.184 (192.168.3.184).
" M+ c; A6 v% | E0 d OEscape character is '^]'.- [: N& i! J. {1 ]* N: `
get 1
" [$ j4 m! G% z! C7 F& Z2 v& ]VALUE 1 0 22
$ H0 o4 r9 `, s" Q6 Ghttp://www.sina.com.cn
- S% e% N3 S2 gEND* p, F2 H7 r' v- W2 [
2.更新表urls里面的数据,然后查询memcached里面是否也更新:: O `8 _/ x: F x% n! o
mysql> update test.urls set url='http://blog.sina.com.cn' where id=1;
( n7 P, A% O$ FQuery OK, 1 row affected, 1 warning (0.00 sec)
& f( }9 T+ r6 `) IRows matched: 1 Changed: 1 Warnings: 0 & \* N! f$ e! W- h$ y6 t' m
mysql> select memc_replace('1','http://blog.sina.com.cn'); + Y+ {* @; i- e' @& w
+---------------------------------------------+
- R) _# E/ `7 U7 U% m. R- B| memc_replace('1','http://blog.sina.com.cn') |
, p! \. y: B3 V+---------------------------------------------+* z0 H I0 t+ c3 G: Z
| 0 |: l% b3 w* G9 N) W
+---------------------------------------------+
! e6 f& y& {) p- D1 n1 row in set (0.00 sec) mysql> select memc_get('1'); 3 c" P. g* ^4 s" H
+-------------------------+
' L# U- ]: M) a# R0 m% }| memc_get('1') |( Y7 Y6 |& ^+ a; X
+-------------------------+
9 V$ W/ B8 D* u| http://blog.sina.com.cn |
s! @' }: K9 Z( B# G; f+-------------------------+1 ^: |8 L3 d% Z0 n, ~# r8 D
1 row in set (0.00 sec) . x& C- o5 K) d6 ?
1> telnet 192.168.3.184 11900
0 r" K- @ M% T1 f9 qTrying 192.168.3.184...
9 m6 O/ A( a& ]8 `Connected to 192.168.3.184 (192.168.3.184).& `8 R) x9 i8 U* B/ c: ?9 m
Escape character is '^]'.
3 X. v) ~/ i6 O; s$ i [get 1
, O4 \& `" o2 A1 SVALUE 1 0 23+ d3 A# x$ t% G& ^' w1 d6 d
http://blog.sina.com.cn
: J0 ]# L0 M* n+ K/ ?) @2 }END
6 F3 c7 e5 |4 J) a) Q3.删除表urls里面的数据,然后查memcached是否也删除:
& e! ?- f" m% Q4 n% E! \5 f+ }; Emysql> delete from test.urls where id=1;+ Q9 q; D! z/ t% Y5 z: ]
Query OK, 1 row affected, 1 warning (0.00 sec)
: A* X- j' p2 ^- g+ E- Q TRows matched: 1 Changed: 1 Warnings: 0
mysql> select memc_get('1');
: }8 J; G Z& _; o" M# D( B+---------------+
T& ?9 y+ S7 e0 C' U) X* k/ @| memc_get('1') |# t' z1 n9 w( W3 Z0 {, V
+---------------+
V4 Z/ _- Q$ ?3 k| NULL |1 D; g6 J4 o) Z+ T4 n
+---------------+
1 u4 V1 |, s# n3 M7 J# q1 row in set (0.00 sec)
3 ^) ]5 b7 i- t+ b$ @' {: ?" f7 W1> telnet 192.168.3.184 11900! C8 j0 f( }* O; b' \/ m4 H
Trying 192.168.3.184...: ]0 V' u! ~. o! _
Connected to 192.168.3.184 (192.168.3.184).
* l& _# k& v1 b8 zEscape character is '^]'.
& P0 a1 g8 n, ^" wget 19 w8 a! R/ M0 A, W# T
END 0 q5 [& m0 g# d3 U- V
& l$ |0 q( Y. r四. 利用php脚本insert, update,delete表urls里面的数据,进行测试。 每条记录的平均长度是:17K 单独向表urls里面插入10万条记录需要的时间为:75秒
- P6 o1 W4 B3 y! ?单独对表urls里面更新10万条记录需要的时间为:70秒2 L3 X/ d t; _$ {! u; o
单独对表urls里面删除10万条记录需要的时间为:105秒 同时进行30万数据的insert,update, delete操作需要时间为:241秒 上面操作都没有memcached失败情况:
. K+ X& ]$ V0 H0 rmysql> select * from results;
4 I% e- g! }# d$ [: g" LEmpty set (0.00 sec)
- |( i: S9 t' u2 @# H# @' \测试脚本如下:
插入脚本:. f) N$ N5 n2 [! q/ G( p- o7 h T3 H
0> more a.php
2 v. i; ]- O/ k/ l* ~ U<?php $conn = mysql_connect("192.168.1.61","test","test") or die(mysql_error()); mysql_select_db("test",$conn) or die(mysql_error()); //$sql = "show tables"; echo date("Y-m-d H:i:s");* S4 g& {4 J0 `+ Q
//mysql_query($sql) or die(mysql_error()); for ($i=1; $i<=100000; $i++) {9 u2 N( `; D6 n" L1 _% z# A; u
$sql="insert into urls (id,url) values ($i, 'http://$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i.com');";5 E% n% m# W5 A. V8 C$ r. B% z
mysql_query($sql) or die(mysql_error()); & b& h6 ^# h' y$ U" u0 P# _
} echo "/n";
( Q# `! L: @! A( a& x( necho date("Y-m-d H:i:s"); ?> 更新脚本:
( I- S2 @0 L* _6 o3 D4 a7 |& j/ ?: Z0> more b.php
* u0 q1 k: V' j4 O1 k& N/ Q f<?php $conn = mysql_connect("192.168.1.61","test","test") or die(mysql_error()); mysql_select_db("test",$conn) or die(mysql_error()); //$sql = "show tables"; echo date("Y-m-d H:i:s");
7 v1 `5 T0 F% n$ H% j* \, X//mysql_query($sql) or die(mysql_error()); for ($i=1; $i<=100000; $i++) {5 m, r* @( j7 F0 ?6 v
$sql="update test.urls set url='http://xxxx.$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i.com' where id=$i;";- `0 S1 U1 y/ M! i
mysql_query($sql) or die(mysql_error()); `' c8 R' k9 L% o- B! ?1 i0 @6 {
} echo "/n";
{ y+ w. O, x! w1 Fecho date("Y-m-d H:i:s"); ?> 删除脚本:* d! K* C; [6 A* }: Q4 S! F0 Y5 e
0> more c.php( r; m2 }: c# o! m
<?php $conn = mysql_connect("192.168.1.61","test","test") or die(mysql_error()); mysql_select_db("test",$conn) or die(mysql_error()); //$sql = "show tables"; echo date("Y-m-d H:i:s");
* i0 Q: B y$ l% h//mysql_query($sql) or die(mysql_error()); for ($i=1; $i<=100000; $i++) {
& v7 J5 F$ t3 m% K$sql="delete from test.urls where id=$i;";
$ @' h! @7 F1 Y. K# qmysql_query($sql) or die(mysql_error());
* J K+ m% l- E* y} echo "/n";
1 L# i6 I& B- y1 Pecho date("Y-m-d H:i:s"); ?> , }5 `- F3 Z$ m0 P3 F" M: O; H
7 ^0 X. _4 w' p8 b
五. 结论:+ a. ~. z: l9 K) x$ a6 G6 Q
测试依赖的环境比较多,可能数据会不准确。整体来看速度还不错。
) [- |- v! B6 H1 p0 d8 \适合项目应用相对比较小的场合。 优点:
0 r# L2 X0 R3 P/ i& \触发器中使用 UDFs 直接更新 Memcached 的内容,减轻了应用程序设计和编写的复杂性。 缺点:
6 |3 q# `1 C+ P& {, G1. 如果出现mysql服务重启,需要重新设置连接memcached关系(SELECT memc_servers_set('192.168.3.184:11900'))0 p# H F/ ]5 w! T( @$ _
2. 有可能存在bug问题,导致mysql的crash(测试时没遇到:)).
# a: R; g; Z4 i9 C7 ]真正的线上环境比这个复杂很多。我想到的需要考虑的问题:
8 ?9 m5 M0 i3 ^1 Z3 X1. 网络因素,mysql和memcached是否放在同一IDC,他们之间的网络性能是否很好。网络性能越好,速度肯定越快,如果使用本机的memcached能适当的减少网络开销。! B W+ ?; R+ ^1 w8 e# Z5 I
2. 插入的数据量,向mysql插入每条记录的size,以及向memcached里面更新的数据size大小。更新mysql,memcached的数据size越大,更新的速度越慢。" o4 Z+ U1 J. \( R- a
所以前期规划好,在memcached里面存那两列(key-value)是关键。
* v! t8 z0 Y3 I( d' _3. 延时问题需要考虑,mysql所在机器如果资源使用比较狠,会导致更新memcached慢(出现类似m/s的延时问题)。
) Y9 P7 k" M% i4. 考虑容灾问题,如果两者中有down出现时,需要考虑怎么恢复,当前的测试是这样考虑的:建一张错误表,如果在出现更新mc出现问题时,自动把更新错误的记录插到
0 M0 F: R9 u5 U, S一张表里面,通过查这张表,可以知道哪些数据在什么时间更新错误,如果应用于生产环境,需要考虑监控和出现问题时恢复工作(写好脚本完善这个工作)。4 H( q: g& |) k2 C8 c' K1 O6 q
5. mysql自身因素,例如执行的mysql语句效率,以及连接mysql的client程序(php)的连接开销等等。 3 \, h# W% J) q- ] z
|