memcached 服務端異常分析

memcached 服務端異常分析


客戶端連接memcached 幾種狀態:
1、正常
2、機器活着,進程不存在
3、進程在,但防火牆禁止了
4、進程在,已經死了,不能連接

各種狀態的表現


1、正常

  1. root@kickseed:/data/# telnet 172.19.103.15 11212

  2. Trying 172.19.103.15...

  3. Connected to 172.19.103.15.

  4. Escape character is '^]'.


複製代碼
2、機器活着,進程不存在:
  1. root@kickseed:/data/# telnet 172.19.103.15 11212

  2. Trying 172.19.103.15...

  3. telnet: Unable to connect to remote host: Connection refused

複製代碼
3、進程在,但防火牆禁止了.或者機器死機了
  1. root@kickseed:/data/# telnet 172.19.103.15 11212

  2. Trying 172.19.103.15...


複製代碼
4、進程還在,但已經死了,不能連接了
  1. root@kickseed:/data/# telnet 172.19.103.15 11212

  2. Trying 172.19.103.15...

複製代碼
3,4是一樣的,下面按一種情況測試



看看各種情況花的時間
正常情況下做addServer,set,get操作:
  1. addServer:spendtime is : 0.00025701522827148

  2. set:spendtime is : 0.00028610229492188

  3. get:spendtime is : 0.00026392936706543

  4. string(1) "1"


複製代碼
memcached機器能連接,但是memcached進程不在的情況
  1. addServer:spendtime is : 0.00055599212646484

  2. set:spendtime is : 0.0005800724029541

  3. get:spendtime is : 3.6954879760742E-5

  4. bool(false)  

複製代碼
各個時間比正常情況多一倍左右,也都能接受




分析一下"進程在,但是不能連接"的情況,這種最多(iptables封掉,模擬機器死機或進程還在但連接不上的情況)
  1. addServer:spendtime is : 4.0041761398315

  2. set:spendtime is : 8.0083198547363

  3. get:spendtime is : 4.6968460083008E-5

  4. bool(false)  


複製代碼
可以看出,addServer花了很長時間,set花了很長時間;get時間很短就返回了
說明addServer時也是會連接服務器,set get都會連接服務器




所以網絡連接問題或服務器死掉會導致502問題,單純memcached進程掛掉只會導致獲取不到數據




我是分割線=====================================================





返回值和超時時間分析

對方機器活着,進程不存在
  1. addServer:spendtime is : 0.00033211708068848

  2. bool(true)

  3. array ( 0 => array ( 'host' => '172.19.103.15', 'port' => 11212, 'weight' => 1, ), )

  4. set:spendtime is : 0.00057196617126465

  5. bool(false)

  6. get:spendtime is : 2.7894973754883E-5

  7. bool(false)

複製代碼
addServer成功,get和set都是失敗的,但不會超時失敗,不會導致業務502。


死機或進程還在但連接不上的情況,且不設置超時時間
  1. addServer: spendtime is : 4.0005769729614

  2. bool(true)

  3. array ( 0 => array ( 'host' => '172.19.103.15', 'port' => 11212, 'weight' => 1, ), )

  4. set: spendtime is : 8.0083749294281

  5. bool(false)

  6. get: spendtime is : 4.1007995605469E-5

  7. bool(false)

複製代碼
死機或進程還在但連接不上的情況,但設置了超時時間200毫秒
  1. $m->setOption(Memcached::OPT_CONNECT_TIMEOUT,200);

  2. $m->setOption(Memcached::OPT_RETRY_TIMEOUT,200);

  3. $m->setOption(Memcached::OPT_POLL_TIMEOUT,200);

複製代碼

  1. addServer: spendtime is : 0.20040106773376

  2. bool(true)

  3. array ( 0 => array ( 'host' => '172.19.103.15', 'port' => 11212, 'weight' => 1, ), )

  4. set: spendtime is : 0.40070199966431

  5. bool(false)

  6. get: spendtime is : 3.8862228393555E-5

  7. bool(false)


複製代碼

可以看出addServer都是成功的,set超時後返回false,get超時返回false

時間也分別是0.2 和 0.4 0.00038 。addServer和set時間基本等於超時時間和超時時間的2倍


默認超時時間
超時時間的默認值:
var_dump($m->getOption(Memcached::OPT_CONNECT_TIMEOUT));
var_dump($m->getOption(Memcached::OPT_RETRY_TIMEOUT));
var_dump($m->getOption(Memcached::OPT_SEND_TIMEOUT));
var_dump($m->getOption(Memcached::OPT_RECV_TIMEOUT));
var_dump($m->getOption(Memcached::OPT_RETRY_TIMEOUT));


result:
int(4000)
int(2)
int(0)
int(0)
int(5000)


而不是手冊上寫的(估計是版本問題,我測試的memcached extension版本是2.0.1):
1000
0
0
0
1000

實際觀察來看,OPT_CONNECT_TIMEOUT默認值不是手冊上寫的1000毫秒,而是4000毫秒。手冊有時也不可靠啊


阻塞模式和非阻塞模式


$m->setOption(Memcached::OPT_SEND_TIMEOUT,300);
$m->setOption(Memcached::OPT_RECV_TIMEOUT,300);

這兩個超時設置在阻塞模式下才有意義,我們只用非阻塞模式


結論:
1、進程死了會導致獲取不到數據,但不至於連接很長時間不返還
2、最壞的情況是機器死了。爲了防止機器掛掉的情況,一定要設置超時時間。
Memcached::OPT_CONNECT_TIMEOUT非常重要,有直接影響。OPT_RETRY_TIMEOUT和OPT_POLL_TIMEOUT還沒發現做什麼用。
3、看上面的spend time 可以看出,addServer等於OPT_CONNECT_TIMEOUT,set的時間等於OPT_CONNECT_TIMEOUT*2,get是非阻塞,所以可以忽略時間


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章