Board logo

标题: 关于mysql与memcache应用 [打印本页]

作者: fangzhen    时间: 2011-1-20 09:10     标题: 关于mysql与memcache应用

Memcached 简介 Memcached 是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。 Memcached 可以将数据库负载大幅度降低,更好的分配资源,提供更快速的访问。

通常情况下,只有首次访问的时候会访问数据库获得数据,并放入 Memcached 中,之后的访问就会直接从 Memcached 中获得数据,这对于以查询为主,更新为辅的应用系统,访问数据库的频率会有很明显的下降,甚至配置很低的数据库都可以轻松完成。
Memcached 中保存的数据只存储在 Memcached 服务器的内存中,因此重起 Memcached 服务或者重起操作系统都会导致缓存的数据消失。可以设置缓存的数据的过期时间,超过时间的缓存数据会优先从缓存中删除。此外当缓存的内容到达指定的容量大小时,就会按照 LRU 算法自动删除不使用的缓存数据。这个指定的容量大小默认值是 64M ,可以通过 -m 参数进行调整。同时也可以通过 -M 参数控制 Memcached ,在空间容量不足时,也不使用 LRU 算法删除部分缓存,而是返回错误提示。
可以使用一台或者多台 Memcached 来提供缓存的服务,如果使用多台,那么多台之间可以通过分布式算法把数据放到不同的服务器上,以此来减轻某一台服务器的访问压力,并且当其中一台出现故障的时候,其他的服务器仍然是可用的,增强了系统得可用性。分布式是 Memcached 的最大的特点。但是这个分布式的算法,并不是 Memcached 来提供的,数据应该放到那个缓存服务器以及查询时应该从哪个缓存服务器获得都是客户端程序来控制的。同时,客户端程序还需要考虑增加或者减少 Memcached 服务器时如何重新部署已有的数据、更新数据库时如何更新 Memcached 内容等等。
4.3.2   Memcached 安装和服务的启动
Memcached 的安装很简单,从网上下载最新的包解压后安装即可,需要注意的是,需要事先安装 libevent 。下面是 libevent 和 Memcached 的安装步骤:
cd libevent-1.3e
configure
make
make install
cd memcached-1.2.6
configure
make
make install
Memcached 的下载地址: http://danga.com/memcached/download.bml
Libevent 的下载地址: http://www.monkey.org/~provos/libevent/
安装完成以后,就可以在服务器上启动 memcached 服务:
memcached -d -m 128 -l 192.168.0.3 -p 11211 -u memcached
主要参数解释:
-d :以守护程序( daemon )方式运行 Memcached ;
-m :设置 Memcached 可以使用的内存大小,默认为 64M ,单位为 M ;
-l :设置监听的 IP 地址;
-p :设置监听的端口,默认为 11211 ;
-u :指定用户,如果当前为 root 的话,需要使用此参数指定用户。
其他参数请参见 Memcached 的帮助信息。
使用 Memcached 的 stats 的命令可以获得很多 Memcached 的统计信息。执行这个命令的方法很多,使用 telnet 最为简单:
-bash-3.00$ telnet localhost 11211
Trying 127.0.0.1…
Connected to localhost.localdomain (127.0.0.1).
Escape character is ‘^]’.
stats
STAT pid 27936
STAT uptime 7842
STAT time 1220478114
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 0.000000
STAT rusage_system 0.011998
STAT curr_items 6
STAT total_items 10
STAT bytes 356
STAT curr_connections 2
STAT total_connections 29
STAT connection_structures 3
STAT cmd_get 16
STAT cmd_set 10
STAT get_hits 10
STAT get_misses 6
STAT evictions 0
STAT bytes_read 632
STAT bytes_written 418
STAT limit_maxbytes 67108864
STAT threads 1
END
stats detail dump
PREFIX id get 5 hit 5 set 1 del 0
END
stats items
STAT items:1:number 6
STAT items:1:age 5601
STAT items:1:evicted 0
STAT items:1:outofmemory 0
END
4.3.3   MySQL memcached UDFs

UDFs 是 User Defined Functions 的缩写,指 Mysql 的用户定义函数,应用可以通过使用这些函数从 Mysql5.0 以上版本的数据库中访问 Memcached 写入或者获得数据。此外,从 Mysql5.1 开始支持触发器,这样就可以在触发器中使用 UDFs 直接更新 Memcached 的内容,减轻了应用程序设计和编写的复杂性。下面我们简要介绍 UDFs 的安装和使用:
UDFs 的安装,需要在数据库服务器上安装两个包,分别是 libmemcached 和 memcached_functions_mysql ,都可以从 http://download.tangent.org/ 下载。
Libmemcached 包的安装比较简单,只要从网上下载最新的包解压后安装即可:
cd libmemcached-0.22
configure
make
make install
memcached_functions_mysql 安装的时候需要指定 Mysql 服务的路径,其他并没有什么特别的地方:
cd memcached_functions_mysql-0.4
./configure ?with-mysql=/home/mysql/bin/mysql_config
make
make install
安装完成之后,需要将 libmemcached_functions_mysql 的库文件拷贝到 mysql/lib 目录下的 plugin 目录中。
cp /usr/local/lib/libmemcached_functions_mysql* /home/mysql/lib/plugin/.
首次使用的时候,需要使用 CREATE FUNCTION 来初始化用户定义函数。有两种方法可以初始化所有提供的用户定义函数,一个是执行 memcached_functions_mysql-0.4/sql 目录下的 install_functions.sql ;另一个是执行 memcached_functions_mysql-0.4/utils/install.pl 。
创建好函数之后,就可以使用这些函数进行 Memcached 的操作,首先需要定义 Memcached 服务器,假设我们测试的环境配置了两个 Memcached 服务器( 192.168.0.1 和 192.168.0.2 ),都使用默认端口 11211 :
mysql> SELECT memc_servers_set(’192.168.0.1:11211,192.168.0.2:11211′);
配置完成后,就可以进行数据的写入和读取的操作了,下面我们创建了一个临时表用来介绍通过触发器更新 Memcached 的简要步骤:
创建测试表:
mysql> create table test3 (
-> id int(3) not null,
-> name varchar(64) not null default ”,
-> primary key (id)
-> );
Query OK, 0 rows affected (0.17 sec)
给自增变量赋初值:
mysql> select memc_set(’id:sequence’, 0);
+?????????-+
| memc_set(’id:sequence’, 0) |
+?????????-+
| 0 |
+?????????-+
1 row in set (0.00 sec)
mysql>
在测试表上创建 insert 触发器:
mysql> DELIMITER |
mysql>
mysql> DROP TRIGGER IF EXISTS test3_insert;
-> CREATE TRIGGER test3_insert
-> BEFORE INSERT ON test3
-> FOR EACH ROW BEGIN
-> SET NEW.id= memc_increment(’id:sequence’);
-> SET @mm= memc_set(concat(’id:’,NEW.id), NEW.name);
-> END |
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> DELIMITER ;
mysql>
插入记录:
mysql> insert into test3 (name) values (’memcached’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test3 (name) values (’test’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test3 (name) values (’mysql’);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test3;
+?-+????+
| id | name |
+?-+????+
| 1 | memcached |
| 2 | test |
| 3 | mysql |
+?-+????+
3 rows in set (0.00 sec)
访问 Memcached 可以得到已经通过触发器写入缓存的记录:
mysql> select memc_get(’id:1′);
+??????+
| memc_get(’id:1′) |
+??????+
| memcached |
+??????+
1 row in set (0.00 sec)
mysql> select memc_get(’id:2′);
+??????+
| memc_get(’id:2′) |
+??????+
| test |
+??????+
1 row in set (0.00 sec)
mysql> select memc_get(’id:3′);
+??????+
| memc_get(’id:3′) |
+??????+
| mysql |
+??????+
1 row in set (0.00 sec)
4.4  使用复制分流查询操作
MySQL 的主从复制可以有效地分流更新操作和查询操作。具体的实现是一个主服务器承担更新操作,而多台从服务器承担查询操作,主从之间通过复制实现数据的同步。
多台从服务器的结构既可以确保数据库的可用性,又可以通过在从服务器上创建不同的索引来满足应用不同查询的需要。
大多数情况下,从数据库分担的查询压力并不需要访问主数据库拥有的全部表,对于这种情况,可以通过在主服务器上搭建一个虚拟的从服务器,将需要复制到从服务器的表设置成 BlackHole 引擎,然后定义 replicate-do-table 参数只复制这些表,这样就过滤出需要复制的 BINLOG ,减少了传输 BINLOG 的带宽。因为搭建的虚拟从服务器只起到过滤 BINLOG 的作用,并没有实际记录任何数据 ,所以对主数据库服务器的性能影响也非常得有限。通过 BlackHole 引擎实现的主从复制可以在满足查询要求的前提下,有效的减轻 BINLOG 的网络传输。
通过复制来分流查询是减少主数据库负载的一个常用方法,但是这种办法也存在一些问题,最主要的问题是当主数据库上更新频繁或者网络出现问题的时候,主从之间的数据可能存在比较大的延迟更新,从而造成查询结果和主数据库上有所差异。因此应用在设计的时候需要有所考虑,尽量将允许部分差异的查询安排访问从数据库,对准确性要求高的查询仍然需要从主数据库获取。
4.5  历史数据的处理

对于一个以插入和更新为主的应用,在设计阶段就要考虑到未来的数据量,并因此决定关键表中是否需要对历史数据的存放进行特别的考虑。通常在应用上线之初,数据量都会相对较小,系统运行的效率也会非常好。但是随着时间的推移,应用的推广使用,数据量就可能会有质的飞跃。如果没有在设计阶段有准备,那么后续处理起来会相对比较困难。
通常我们会建议对表的内容进行分析,对表的数据进行横向或者纵向的拆分。例如对于保存日志数据的表,将一个月的数据放在一个小表中,一个月以上的历史数据放在另一个大表中,通过相应的机制定期将数据从小表移动到大表中。通常,用户对于一个月以上的日志的查询需求通常都会线性的下降,而小表由于数据量小,对应的索引也会比较小,可以更轻松的进行扫描和缓存,访问的效率会因此有明显的改善。
4.6     使用分布式架构
分布式的数据库架构适合大数据量、负载高的情况,它具有良好的扩展性和高可用性。通过在多台服务器之间分布数据,可以实现在多台服务器之间的负载平均,提高了访问的执行效率。具体实现的时候,可以使用MySQL的CLUSTER功能或者通过用户自己编写的程序来实现全局事务。需要注意的是当前分布式事务只支持InnoDB存储引擎,因此如果自己编写程序来实现分布式架构数据库的话,那么就必须采用InnoDB存储引擎。




欢迎光临 PHP开发笔记 (http://phpvi.com/) Powered by Discuz! 6.1.0