NoSQL(Memcache)
一、大型项目优化概述
1、PHP项目执行流程
【简单理解】
读取源码 -》 词法分析 -》 创建opcode -》 执行opcode 重复创建会增加额外的内存和CPU开销
【解决方案】
安装ZendOptimizer或APC2.0等可以加速PHP代码访问,主要用于缓存opcode而不是每次重复编译减少CPU和内存开销(php5.5+后不需要安装第三方软件,直接开启PHP配置文件中Opcache即可。
http://www.cnblogs.com/HD/p/4554455.html
2、大型项目优化的方向
1)代码优化
开启opcode缓存
重模型,轻控制器(减少冗余、保证项目完整运行 -> 单元测试)
能用单引号不用双引号,推荐PHP代码统一小驼峰,MySQL推荐下划线命名法
2)数据库优化
架构:读写分离、主从复制
设计:三范式、存储引擎、字段类型
功能:索引、缓存、分区
缓存优化
减少对数据库的操作,将数据保存到文件中或者内存(memcache)中>内存 > 文件(TP的S方法和F方法) > 数据库
架构优化
负载均衡、集群(动静分离)、读写分离、主从复制、sphinx站内搜索、内存缓存(memcache和redis) 、CDN加速
二、了解Memcache
1、什么是Memcache
Memcache是一个高性能分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态 Web 应用的速度、提高可扩展性。
集群:多个服务器实现同一个业务
分布式:多个服务器使用不同的的业务
简单概括:就是一软数据库软件,将数据保存到内存中。
将数据保存到内存中,如果电脑关机后数据丢失
2、与mysql比较
- 都是C/S架构(client/server)
- MySQL将数据保存在磁盘文件中,Memcache保存在内存中
- MySQL保存数据必须先创建数据库、再创建表最后才可以插入数据,Memcache直
接插入键值对形式数据,如:数组[键=>值,键=>值],js对象{键:值,键:值}。
键key 值value
字串(唯一) 字符串,整数,浮点数,布尔,数组,对象,NULL,二进制数据(图片,视频,音频)
三、安装与配置Memcached(C/S结构)
1、服务器端软件安装(win)
查看memcached.exe相关参数(常用参数说明)
- -l localhost 服务器ip地址
- -p port 端口
- -d install/uninstall/start 服务管理
- -m memory 内存大小,默认64M
1)安装memcache(绿色版:直接解压即可)
脚下留心:不能有中文或者空格
3)安装memcached服务
命令:memcached -d install
脚下留心:必须使用管理员身份运行
4)启用memcached服务
命令:memcached -d start
复杂:memcached -l 127.0.0.1 -p 11211 -d start -m 64
说明:处-d外其他参数必须,不写则默认
5)检查是否安装成功
说明:通过netstat -ano查看端口11211是否存在
2、客户端软件的安装(Telnet服务连接)
1)通过电脑的telnet服务
测试系统中是否安装了Telnet服务
如果弹出以下界面,代表安装了Telnet服务,否则代表电脑中没有安装此服务
【默认情况下,Win7/Win8/Win10都是没有安装Telnet的,安装步骤如下】
第一步:打开控制面板,找到程序和功能
第二步:打开和关闭Windows功能
第三步:找到Telnet服务进行安装
z
安装完成后,使用Telnet连接Memcached服务器
回车,如下图所示,代表连接成功:
2)通过putty第三方工具telnet协议
操作Memcached
http://www.runoob.com/memcached/memcached-tutorial.html
增/改键(set)
- 基本语法:set 键 是否压缩 缓存时间/s 字符长度
- 说 明:
- 键 – 不能超过250个字符
- 是否压缩 – 1-是,0-否(默认) 注:以空间换时间,以时间换空间
- 缓存时间 – 0-理论永久,最大不超过30天(存满了,重启服务)
- 字符长度 – 先声明回车后输入内容
获取键值(get)
- 基本语法:get 键
添加键数据(add)
- 基本语法:add 键 是否压缩 时间 长度
- 说 明:只能添加不能修改
修改键数据(replace)
- 基本语法:replace 键 是否压缩 时间 长度
- 说 明:只能修改不能添加
删除键(delete)
- 基本语法:delete 键
删除所有键(flush_all)
- 基本语法:flush_all
递增(incr)
- 基本语法:incr 键 数字
- 说 明:返回增加后的值,键必须存在(注:后期用过php操作必须提前存在)
递减(decr)
- 基本语法:decr 键 数字
- 说 明:返回减少后的值
查看当前Memcached运行状态(stats)
pid: memcache服务器进程ID
uptime:服务器已运行秒数
time:服务器当前Unix时间戳
version:memcache版本
pointer_size:操作系统指针大小
rusage_user:进程累计用户时间
rusage_system:进程累计系统时间
curr_connections:当前连接数量
total_connections:Memcached运行以来连接总数
connection_structures:Memcached分配的连接结构数量
cmd_get:get命令请求次数
cmd_set:set命令请求次数
cmd_flush:flush命令请求次数
get_hits:get命令命中次数
get_misses:get命令未命中次数
delete_misses:delete命令未命中次数
delete_hits:delete命令命中次数
incr_misses:incr命令未命中次数
incr_hits:incr命令命中次数
decr_misses:decr命令未命中次数
decr_hits:decr命令命中次数
cas_misses:cas命令未命中次数
cas_hits:cas命令命中次数
cas_badval:使用擦拭次数
auth_cmds:认证命令处理的次数
auth_errors:认证失败数目
bytes_read:读取总字节数
bytes_written:发送总字节数
limit_maxbytes:分配的内存总大小(字节)
accepting_conns:服务器是否达到过最大连接(0/1)
listen_disabled_num:失效的监听数
threads:当前线程数
conn_yields:连接操作主动放弃数目
bytes:当前存储占用的字节数
curr_items:当前存储的数据总数
total_items:启动以来存储的数据总数
evictions:LRU释放的对象数目
reclaimed:已过期的数据条目来存储新数据的数目
五、PHP操作Memcached
1、开启php的php_memcache.dll扩展
- 步骤2:查看php相关信息选择对应的扩展库文件
- 步骤3:将扩展文件移动到对应PHP版本的ext目录下
- 步骤4:修改php的配置文件(php.ini)
- 步骤5:重启apache
2、操作
■ 语法
创建对象:$mem = new Memcachd;
连接服务:$mem->connect(服务器ip地址,端口);
关闭连接:$mem->close();
添加数据:$mem->set(键,值 [,是否压缩,缓存时间]) 注:默认理论永久
读取数据:$mem->get(键);
增加:$mem->incr(键,$num=1);
减少:$mem->decr(键,$num=1);
1)创建memcache对象
2)添加和获取数据
<?php
//1.创建memcachd对象
$mem = new Memcache;
//2.连接服务
$mem->connect(‘127.0.0.1’, 11211);
//3.设置数据
$mem->set(‘laotie’, ‘mei mao baobing’);
//4.获取
echo $mem->get(‘laotie’);
die;
六、探究Memcache能存储的数据类型
回顾PHP中的八种数据类型
PHP
基本类型:整型、浮点型、字符型、布尔型
复合类型:数组、对象
特殊类型:资源、null
JS
基本类型:数字型(整型、浮点型)、字符型、布尔型
复合类型:数组、对象
特殊类型:undefined、null
2、使用PHP存储标量类型
数据:整型(8)、浮点型(8.88)、字符串型(php0225)、布尔型(true)
验证:
<?php
//1.创建memcache对象
$mem = new memcache;
//2.连接服务
$mem->connect(‘localhost’, 11211);
//3.设置服务
$rs = $mem->set(‘int1’, 8);
var_dump($rs);
$rs = $mem->set(‘int2’, 8.88);
var_dump($rs);
$rs = $mem->set(‘int3’, ‘php12’);
var_dump($rs);
$rs = $mem->set(‘int4’, true);
var_dump($rs);
echo ‘<hr />’;
$rs = $mem->get(‘int1’);
var_dump($rs);
$rs = $mem->get(‘int2’);
var_dump($rs);
$rs = $mem->get(‘int3’);
var_dump($rs);
$rs = $mem->get(‘int4’);
var_dump($rs);
die;
3、使用PHP存储复合类型
- 数组:array(‘name’=>zhangsan,’age’=>18)
- 对象:class test { public $name = 123} $obj = new test()
- 验证:
<?php
//1.创建memcache对象
$mem = new memcache;
//2.连接服务
$mem->connect(‘localhost’, 11211);
//3.设置服务
$data1 = array(‘name’=>’zhangsan’,’age’=>18);
class test { public $name = 123;}
$data2 = new test();
$rs = $mem->set(‘arr1’, $data1);
var_dump($rs);
$rs = $mem->set(‘obj2’, $data2);
var_dump($rs);
echo ‘<hr />’;
$rs = $mem->get(‘arr1’);
var_dump($rs);
echo ‘<br />’;
$rs = $mem->get(‘obj2’);
var_dump($rs);
die;
4、使用PHP存储特殊类型
<?php
//1.创建memcache对象
$mem = new memcache;
//2.连接服务
$mem->connect(‘localhost’, 11211);
//3.设置服务
$data = fopen(‘xxxx’, ‘a+’);
$rs = $mem->set(‘source’, $data);
var_dump($rs);
$rs = $mem->set(‘null1’, null);
var_dump($rs);
echo ‘<hr />’;
$rs = $mem->get(‘source’);
var_dump($rs);
echo ‘<br />’;
$rs = $mem->get(‘null1’);
var_dump($rs);
die;
七、Memcache的相关算法【★★★】
1、惰性过期机制(lazy expiration)
- 说明:memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,
检查记录是否过期。这种技术被称为惰性过期。
- 好处:memcached不会在过期监视上耗费CPU时间 。
- 注意:memcached最大存储时间为30天
- 验证:
#关闭服务
memcached -d stop
#启动服务
memcached -d start
#查看状态
stats
#设置一个键
set php1 0 10 1
#10s内,再查看状态
stats
#10s后,再查看状态
#get后查看状态
2、最近最少使用算法(LRU:Least Recently Used)
答:缓存空间已满,采用LRU策略,删除旧的缓存项(最近最少使用算法)
LRU:Least Recently USE。
八、Memcache常见问题
1、单个key键名的最大长度是多少?
答:最大不能超过250个字符
2、每个item选项其最大可以存储多少M的数据
答:每个item最大只能存储1M的数据
3、最大存储时间(30天)
<?php
//1.创建memcache对象
$mem = new Memcache;
//2.连接服务
$mem->connect(‘127.0.0.1’, 11211);
//3.设置数据
$rs = $mem->set(‘time1’, 111, 0, 3600 * 24 * 30 -1); //30天-1s
var_dump($rs);
$rs = $mem->set(‘time2’, 222, 0, 3600 * 24 * 30); //30天
var_dump($rs);
$rs = $mem->set(‘time3’, 333, 0, 3600 * 24 * 30 +1); //30天+1s
var_dump($rs);
echo ‘<hr />’;
//4.获取数据
$rs = $mem->get(‘time1’);
var_dump($rs);
$rs = $mem->get(‘time2’);
var_dump($rs);
$rs = $mem->get(‘time3’);
var_dump($rs);
die;
memcached的cache机制是怎样的?
惰性过期机制:当过期之后不会删除,而是当get时候在删除
最近最少使用:内存存满之后,删除最近最少使用
6、memcache里面适合存储哪些数据
- 明确使用场景:数据缓存
- 适合存储哪些数据:
访问比较频繁的数据,安全性差的数据,丢失无所谓的数据。
数据更新,比较频繁的数据,比如用户的在线状态。
数据的单个键值不能太大,不要超过1Mb数据。
文件缓存案例
//获取缓存中的数据
$data = file_get_contents(唯一标识);
if (!$data) {
$data = 连接数据库获取的数据;
file_put_contents(唯一标识,$data);
}
$this->assign(‘data’, $data);
九、分布式Memcache服务器
1)分布式服务器原理
2)使用PHP实现分布式Memcache
<?php
//1.创建memcache对象
$mem = new Memcache;
//2.通过addServer方法添加到memcache连接池
$mem->addServer(‘127.0.0.1’, 11211);
$mem->addServer(‘192.168.72.53’, 11211);
$mem->addServer(‘192.168.72.38’, 11211);
//3.向连接池中保存数据
$mem->set(‘userinfo’, [‘name’ => ‘瑶瑶’, ‘age’ => 18]);
$mem->set(‘orderinfo’, [‘id’ => 18, ‘price’ => 1]);
$mem->set(‘address’, 123);
$data = $mem->get(‘userinfo’);
var_dump($data);
echo ‘<hr />’;
$data = $mem->get(‘orderinfo’);
var_dump($data);
echo ‘<hr />’;
$data = $mem->get(‘address’);
var_dump($data);
echo ‘<hr />’;
die;
十、Session入Memcache缓存
方法1:修改php配置文件,永久(php.ini)
=================================================================
<?php
session_start();
$_SESSION[‘yaoyiyao’] = ‘别闹’;
$_SESSION[‘huangyihuang’] = ‘哈哈’;
$_SESSION[‘douyidou’] = ‘嘿咻’;
echo ‘<hr />’;
echo session_id();
echo ‘<br />’;
print_r($_SESSION);
die;
方法2,临时,在php中使用 ini_set函数
<?php
//1.更改session存储方式
ini_set(‘session.save_handler’, ‘memcache’);
//2.存储路径(说明:分布式则逗号隔开)
ini_set(‘session.save_path’, ‘tcp://127.0.0.1:11211,tcp://192.168.72.68:11211’);
session_start();
$_SESSION[‘yaoyiyao’] = ‘别aaaaa闹’;
$_SESSION[‘huangyihuang’] = ‘哈aaaa哈’;
$_SESSION[‘douyidou’] = ‘嘿aa咻’;
echo ‘<hr />’;
echo session_id();
echo ‘<br />’;
print_r($_SESSION);
die;
总结
什么是memcache:基于内存数据库(注:重启后数据丢失)
相关参数
-l 服务ip地址(localhost)
-p 端口(port)
-d 服务管理(start/stop/install/uninstall)
-m 内存大小(memory)
memcache命令
memcache的set:set 键 是否压缩 时间 长度(1-压缩,0-不压缩,时间:0-理论永久,最大不超过30天)
memcache的get:get 键
php操作memcache(http://pecl.php.net/package/memcache)
创建对象:$mem = new Memcache;
连接服务:$mem->connect(服务器ip地址,端口号)
关闭服务:$mem->close()
设置数据:$mem->set(键,值,[是否压缩,压缩时间])
获取数据:$mem->get(键)
递增:$mem->incr(键,值)
递减:$mem->decr(键,值)
算法,
惰性过期机制:不过监控是否过期,而是get后检测
最近最少使用算法:内存占满了就删除最近最少使用的
分布式:多台服务器实现不同的业务
分布式:$mem->addServer(服务器ip地址,端口)
session入库
ini_set(‘session.save_handler);
ini_set(‘session.save_path’, ‘tcp://服务器ip地址:端口,tcp://服务器ip地址:端口’)