php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73673 Memcached を持続的接続で行っているのにも関わらず、接続が?
Submitted: 2016-12-07 09:30 UTC Modified: 2021-06-09 11:55 UTC
From: yoogawa at gungho dot jp Assigned: cmb (profile)
Status: Closed Package: memcached (PECL)
PHP Version: 5.6.28 OS:
Private report: No CVE-ID: None
 [2016-12-07 09:30 UTC] yoogawa at gungho dot jp
Description:
------------
---
From manual page: http://www.php.net/memcached.getserverlist
---
Memcached new する際に持続的接続で接続先を登録を行っているのにも関わらず hostname と port no が登録されて無い case が存在している様です。

Test script:
---------------
<?php

$hostname = 'localhost';
$hostname2 = 'localhost';

$port = 11211;
$port2 = 11212;

if(isset($argv[1])){
    $value = $argv[1];
}
elseif(isset($_GET['value'])){
    $value = $_GET['value'];
}

if(!isset($value)){
    exit;
}

echo $value . PHP_EOL;

class Cache{
    private $id;
    private $obj;

    function __construct($id){
        $this->id = $id;
        $this->obj = new Memcached($id);
    }

    public function connect($host, $port){
        $servers = $this->obj->getServerList();

        var_dump($servers);
        echo PHP_EOL;

        if(count($servers)){
            foreach($servers as $server){
                if($server['host'] == $host && $server['port'] == $port){
                    return true;
                }
            }
        }

        $this->obj->addServer($host , $port);
        //$this->obj->setOption(Memcached::OPT_SERVER_FAILURE_LIMIT, 3);

        return true;
    }

    public function set($key, $value){
        return $this->obj->set($key, $value);
    }

    public function get($key){
        return $this->obj->get($key);
    }

    public function getResultCode(){
        return $this->obj->getResultCode();
    }

    public function resetServerList(){
        $ret = $this->obj->resetServerList();
        var_dump($this->obj->getServerList());
        echo PHP_EOL;

        return $ret;
    }
}

$memcached_stop_command = <<<EOT
sudo service memcached stop 2>&1
EOT;

$memcached_start_command = <<<EOT
sudo service memcached start 2>&1
EOT;

$httpd_restart_command = <<<EOT
sudo service httpd restart
EOT;

$connection_count_command = <<<EOT
netstat -an | awk '{print $5,$6}' | grep '11211' | wc -l 2>&1
EOT;

if('connection_init' == $value){
    `$httpd_restart_command`;
    #実行は出来ているが使い勝手が悪いな。
}
elseif('pool_init' == $value){
    echo 'from connection count : ' . `$connection_count_command`;

    $tmp = new Cache('pool');
    $tmp->resetServerList();
    unset($tmp);

    echo 'connection count : ' . `$connection_count_command`;
}
elseif('1_connect_set' == $value){
    echo '登録' . PHP_EOL;
    echo 'from connection count : ' . `$connection_count_command`;

    $cache = new Cache('pool');
    $cache->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($cache->set('pool_key' . $v, 100 * $v));

        echo 'result : ';
        var_dump($cache->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}
elseif('2_connect_get' == $value){
    echo 'connect を増やして参照先確認' . PHP_EOL;
    echo 'from connection count : ' . `$connection_count_command`;

    $cache = new Cache('pool');
    $cache->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;
    $cache->connect($hostname2, $port2);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($cache->get('pool_key' . $v));

        echo 'result : ' . PHP_EOL;
        var_dump($cache->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}
elseif('2_connect_set' == $value){
    echo 'connect を増やして参照先の確認(更新)' . PHP_EOL;
    echo 'from connection count : ' . `$connection_count_command`;

    $connect = new Cache('pool');
    $connect->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;
    $connect->connect($hostname2, $port2);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($connect->set('pool_key' . $v, $v));

        echo 'result : ' . PHP_EOL;
        var_dump($connect->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}
elseif('1_connect_get' == $value){
    echo '取得' . PHP_EOL;
    echo 'from connection count : ' . `$connection_count_command`;

    $get = new Cache('pool');
    $get->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($get->get('pool_key' . $v));

        echo 'result : ' . PHP_EOL;
        var_dump($get->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}
elseif('init_1_connect_get' == $value){
    echo 'from connection count : ' . `$connection_count_command`;

    $tmp = new Cache('pool');
    $tmp->resetServerList();
    unset($tmp);

    echo 'connect 再構築して取得' . PHP_EOL;

    $get = new Cache('pool');
    $get->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($get->get('pool_key' . $v));

        echo 'result : ' . PHP_EOL;
        var_dump($get->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}
elseif('init_1_connect_set' == $value){
    echo 'from connection count : ' . `$connection_count_command`;

    $tmp = new Cache('pool');
    $tmp->resetServerList();
    unset($tmp);

    echo 'connect 再構築して更新' . PHP_EOL;

    $update2 = new Cache('pool');
    $update2->connect($hostname, $port);
    echo 'connected connection count : ' . `$connection_count_command`;

    foreach(range(1, 5) as $v){
        var_dump($update2->set('pool_key' . $v, 100 * $v));

        echo 'result : ' . PHP_EOL;
        var_dump($update2->getResultCode());
    }

    echo 'to connection count : ' . `$connection_count_command`;
}

Expected result:
----------------
http://localhost/memcached_persistent_connection_test.php?value=1_connect_set

1度目の結果

1_connect_set 登録 from connection count : 0
array (size=0)
  empty
connected connection count : 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
to connection count : 1

2度目の結果
1_connect_set 登録 from connection count : 1
array (size=0)
  empty
connected connection count : 1
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
to connection count : 2

3度目の結果
1_connect_set 登録 from connection count : 3
array (size=1)
  0 => 
    array (size=2)
      'host' => string 'localhost' (length=9)
      'port' => int 11211
connected connection count : 3
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
boolean true
result :
int 0
to connection count : 3




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-06-09 11:55 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2021-06-09 11:55 UTC] cmb@php.net
The memcached bug tracker is now on Github[1].  If this is still
an issue with the current memcached version, please report there.

[1] <https://github.com/php-memcached-dev/php-memcached/issues>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 03:01:28 2024 UTC