memcached - PHP缓存:Memcache 不如 直接File文件缓存吗
使用本地的环境测试10万次和 100万次 缓存的读写,测试环境和结果如下。
环境
<code>Win7 x64 AMD7750双核 内存8G Apache 2.4.9 PHP 5.5.12 ts vc11 memcache 2.2.7 </code>
代码
<?php function convert($size) { $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb'); return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; } function cacheFile($key) { $dir = 'cache'; if (!is_dir($dir) && !mkdir($dir)) { throw new Exception(" can't make dir $dir"); } $filepath = $dir . DIRECTORY_SEPARATOR . sprintf('%x', crc32($key)); if (!(file_exists($filepath) && ($data = file_get_contents($filepath)) && !empty($data))) { $data = date('Y-m-d H:i:s'); file_put_contents($filepath, $data); } return $data; } function cacheMem($key) { $mem = new Memcache(); $mem->connect('127.0.0.1', 11211); $data = $mem->get($key); if (empty($data)) { $data = date('Y-m-d H:i:s'); $mem->set($key, $data); } return $data; } $t1 = microtime(true); $i = 0; $limit = 1000 * 100; //10 万次 $data = null; while ($i < $limit) { // $data = cacheFile($i); $data = cacheMem($i); $i++; } $timeUse = microtime(true) - $t1; $arr = [ 'cost' => sprintf('%.7fs', $timeUse), 'mem' => convert(memory_get_usage()) ]; var_dump($arr);
结果 1万次
<code> 花费时间 内存耗费 File 1.9 sec 250kb Memcache 11 sec 250kb</code>
结果 10万次
<code> 花费时间 内存耗费 File 94s 251.18KB Memcache 超时120s 报错 </code>
Memcache 10万次测试失败,报错内容如下
<code>Warning: Memcache::connect(): in D:\localhost\speed.php on line 37 Warning: Memcache::get(): No servers added to memcache connection in D:\localhost\speed.php Warning: Memcache::set(): No servers added to memcache connection in D:\localhost\speed.php on line 41 Fatal error: Maximum execution time of 120 seconds exceeded in D:\localhost\speed.php on line 38</code>
结论
memcache
用来做缓存却还没有 直接File文件缓存快,之所以做这个测试,是因为面试的时候我回答自己并没有使用这个memcache 来做缓存,直接使用File文件缓存,结果直接被技术官认定为是初级程序员
。但我通过这样的测试,虽然是在win下面,可为什么Memcahe性能还不如File ?
还是说我测试的方式存在错误?
2015-8-21 20:52:17
改进后,真的速度快了N倍! 10万毫无压力。17.18 sec
265KB内存
<code>function cacheMem($key) { static $mem = null; if ($mem === null) { $mem = new Memcache(); $mem->connect('127.0.0.1', 11211); } $data = $mem->get($key); if (empty($data)) { $data = date('Y-m-d H:i:s'); $mem->set($key, $data); } return $data; } </code>
回复内容:
使用本地的环境测试10万次和 100万次 缓存的读写,测试环境和结果如下。
环境
<code>Win7 x64 AMD7750双核 内存8G Apache 2.4.9 PHP 5.5.12 ts vc11 memcache 2.2.7 </code>
代码
<?php function convert($size) { $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb'); return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; } function cacheFile($key) { $dir = 'cache'; if (!is_dir($dir) && !mkdir($dir)) { throw new Exception(" can't make dir $dir"); } $filepath = $dir . DIRECTORY_SEPARATOR . sprintf('%x', crc32($key)); if (!(file_exists($filepath) && ($data = file_get_contents($filepath)) && !empty($data))) { $data = date('Y-m-d H:i:s'); file_put_contents($filepath, $data); } return $data; } function cacheMem($key) { $mem = new Memcache(); $mem->connect('127.0.0.1', 11211); $data = $mem->get($key); if (empty($data)) { $data = date('Y-m-d H:i:s'); $mem->set($key, $data); } return $data; } $t1 = microtime(true); $i = 0; $limit = 1000 * 100; //10 万次 $data = null; while ($i < $limit) { // $data = cacheFile($i); $data = cacheMem($i); $i++; } $timeUse = microtime(true) - $t1; $arr = [ 'cost' => sprintf('%.7fs', $timeUse), 'mem' => convert(memory_get_usage()) ]; var_dump($arr);
结果 1万次
<code> 花费时间 内存耗费 File 1.9 sec 250kb Memcache 11 sec 250kb</code>
结果 10万次
<code> 花费时间 内存耗费 File 94s 251.18KB Memcache 超时120s 报错 </code>
Memcache 10万次测试失败,报错内容如下
<code>Warning: Memcache::connect(): in D:\localhost\speed.php on line 37 Warning: Memcache::get(): No servers added to memcache connection in D:\localhost\speed.php Warning: Memcache::set(): No servers added to memcache connection in D:\localhost\speed.php on line 41 Fatal error: Maximum execution time of 120 seconds exceeded in D:\localhost\speed.php on line 38</code>
结论
memcache
用来做缓存却还没有 直接File文件缓存快,之所以做这个测试,是因为面试的时候我回答自己并没有使用这个memcache 来做缓存,直接使用File文件缓存,结果直接被技术官认定为是初级程序员
。但我通过这样的测试,虽然是在win下面,可为什么Memcahe性能还不如File ?
还是说我测试的方式存在错误?
2015-8-21 20:52:17
改进后,真的速度快了N倍! 10万毫无压力。17.18 sec
265KB内存
<code>function cacheMem($key) { static $mem = null; if ($mem === null) { $mem = new Memcache(); $mem->connect('127.0.0.1', 11211); } $data = $mem->get($key); if (empty($data)) { $data = date('Y-m-d H:i:s'); $mem->set($key, $data); } return $data; } </code>
错在你不该在while里写connect...哪有每次都去连接的?
首先,建立一个到Memcached的TCP连接的开销肯定要比打开一个本地文件大,而在你的cli测试中,反复建立了上万次连接,而在Web上(比如PHP-FPM,MOD_PHP),可以使用到Memcached的持久连接,也就是一个PHP-FPM工作进程保持一个Memcached的长连接,用于处理多个不同的请求:
http://php.net/manual/zh/memcached.construct.php
<code><?php $mc = new Memcached('story_pool');</code>
其次,操作系统会缓存本地文件到内存(就是Linux上的buffers/cache),读性能肯定是不错的,但是频繁的写性能肯定没有Memcached好,因为Memcached读写操作都保证在内存中完成。
另外,Memcached能实现分布式(由客户端实现,比如PHP的PECL扩展memcached),这个也是本地文件缓存不具备的优势。Memcached的分布式体现在将不同的键保存到不同的服务器上。
http://php.net/manual/zh/memcached.addserver.php
注意:PHP有两个针对Memcached的PECL扩展,一个叫做memcache,一个叫做memcached:
http://php.net/manual/zh/intro.memcache.php
http://php.net/manual/zh/intro.memcached.php
其中基于libmemcached的扩展memcached实现了分布式,而memcache则没有实现。
上面说的对,你的测试方法是错误的,因为memcache已经达到最大连接数了,所以报错
不过我想知道你用的是什么磁盘,SSD or FIO or SAS,IOPS是多少;说明一下,memcache中key最大值为250B,value最大值为1M,一般情况下value大于1M,也就是超过memcache中page的大小时候,memcache也就无能为力了,不过你可以通过更改源代码来实现或者换redis(value最大值512M)
其实也不必测试,memcache数据全部放在内存中,然而内存和磁盘不是一个级别,我们可以分析一下:
1纳秒等于10亿分之一秒,= 10 ^ -9 秒
<code>Numbers Everyone Should Know L1 cache reference 读取CPU的一级缓存 0.5 ns Branch mispredict(转移、分支预测) 5 ns L2 cache reference 读取CPU的二级缓存 7 ns Mutex lock/unlock 互斥锁\解锁 100 ns Main memory reference 读取内存数据 100 ns Compress 1K bytes with Zippy 1k字节压缩 10,000 ns Send 2K bytes over 1 Gbps network 在1Gbps的网络上发送2k字节 20,000 ns Read 1 MB sequentially from memory 从内存顺序读取1MB 250,000 ns Round trip within same datacenter 从一个数据中心往返一次,ping一下500,000 ns Disk seek 磁盘搜索 10,000,000 ns Read 1 MB sequentially from network 从网络上顺序读取1兆的数据 10,000,000 ns Read 1 MB sequentially from disk 从磁盘里面读出1MB 30,000,000 ns Send packet CA->Netherlands->CA 一个包的一次远程访问 150,000,000 ns</code>
我们关注一下内存和磁盘的访问速度,上面是指随机访问,那么相差1000 000倍,但如果是顺序访问的话大约为 7倍
楼主应该好好看看设计模式,你的面试官没说错你。。。可能初级程序员都懂得缓存对象吧。。谁会每次循环都连接一次memcached?
如果用file存的话, 100w 请求,你去看下服务器的硬盘读写。服务器早挂掉了。
磁盘IO延迟和资源开销和文件系统开销也挺大得。
我只想问哈楼主是用什么测出PHP运行时间的?
事实证明 你就是1、2年的初级。 但是当时面试官否认掉你 没跟你讲明原因吗?
还有给你 也是给所有人一个忠心的建议,切忌不要太浮躁! 或是自我膨胀,以当前时间为节点来看,自己永远是井底之蛙,不经历一些事情有可能不会明白。

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
