Table of Contents
环境
代码
结果 10万次
Memcache 10万次测试失败,报错内容如下
结论
回复内容:
Home Backend Development PHP Tutorial memcached - PHP缓存:Memcache 不如 直接File文件缓存吗

memcached - PHP缓存:Memcache 不如 直接File文件缓存吗

Jun 06, 2016 pm 08:29 PM
memcached php cache

使用本地的环境测试10万次和 100万次 缓存的读写,测试环境和结果如下。

环境

<code>Win7 x64 AMD7750双核 内存8G
Apache 2.4.9
PHP 5.5.12 ts vc11 
memcache 2.2.7 </code>
Copy after login
Copy after login

代码

<?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);
Copy after login
Copy after login

结果 1万次

<code>            花费时间           内存耗费
File        1.9 sec           250kb
Memcache    11 sec            250kb</code>
Copy after login
Copy after login

结果 10万次

<code>            花费时间    内存耗费
File        94s        251.18KB
Memcache    超时120s 报错 
</code>
Copy after login
Copy after login

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>
Copy after login
Copy after login

结论

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>
Copy after login
Copy after login

回复内容:

使用本地的环境测试10万次和 100万次 缓存的读写,测试环境和结果如下。

环境

<code>Win7 x64 AMD7750双核 内存8G
Apache 2.4.9
PHP 5.5.12 ts vc11 
memcache 2.2.7 </code>
Copy after login
Copy after login

代码

<?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);
Copy after login
Copy after login

结果 1万次

<code>            花费时间           内存耗费
File        1.9 sec           250kb
Memcache    11 sec            250kb</code>
Copy after login
Copy after login

结果 10万次

<code>            花费时间    内存耗费
File        94s        251.18KB
Memcache    超时120s 报错 
</code>
Copy after login
Copy after login

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>
Copy after login
Copy after login

结论

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>
Copy after login
Copy after login

错在你不该在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>
Copy after login

其次,操作系统会缓存本地文件到内存(就是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>
Copy after login

我们关注一下内存和磁盘的访问速度,上面是指随机访问,那么相差1000 000倍,但如果是顺序访问的话大约为 7倍

楼主应该好好看看设计模式,你的面试官没说错你。。。可能初级程序员都懂得缓存对象吧。。谁会每次循环都连接一次memcached?

如果用file存的话, 100w 请求,你去看下服务器的硬盘读写。服务器早挂掉了。

磁盘IO延迟和资源开销和文件系统开销也挺大得。

我只想问哈楼主是用什么测出PHP运行时间的?

事实证明 你就是1、2年的初级。 但是当时面试官否认掉你 没跟你讲明原因吗?

还有给你 也是给所有人一个忠心的建议,切忌不要太浮躁! 或是自我膨胀,以当前时间为节点来看,自己永远是井底之蛙,不经历一些事情有可能不会明白。

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

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

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

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

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

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

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

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,

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

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

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

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

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

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 PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

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.

See all articles