php の memcache ライブラリのフェイルオーバー実装についてソースを読んでみた

概要

php の memcache のライブラリでは フェイルオーバーを実現している.これを把握する必要があったのでソースを読んでみた.

超ざっくりな説明

memcache.hash_strategy で設定されたアルゴリズム(standard または consistent) により分散させる. どのサーバに割り当てるかは memcache.hash_function で設定されたハッシュ関数(crc32 または fnv)を用いて計算されたハッシュを対象サーバ分で剰余とってインデックス得て決定. 接続できなかったり addServer() 時に使わない設定にした場合はハッシュを再度計算して決定することを memcache.max_failover_attempts 回(デフォルトは 20 )接続できるまで行う.

ソース取得

$ curl -O http://pecl.php.net/get/memcache-2.2.7.tgz

該当部分

 66 mmc_t *mmc_standard_find_server(void *s, const char *key, int key_len TSRMLS_DC) /* {{{ */
 67 {
 68     mmc_standard_state_t *state = s;
 69     mmc_t *mmc;
 70 
 71     if (state->num_servers > 1) {
 72         unsigned int hash = mmc_hash(state, key, key_len), i;
 73         mmc = state->buckets[hash % state->num_buckets];
 74 
 75         /* perform failover if needed */
 76         for (i=0; !mmc_open(mmc, 0, NULL, NULL TSRMLS_CC) && MEMCACHE_G(allow_failover) && i<MEMCACHE_G(max_failover_attempts); i++) {
 77             char *next_key = emalloc(key_len + MAX_LENGTH_OF_LONG + 1);
 78             int next_len = sprintf(next_key, "%d%s", i+1, key);
 79             MMC_DEBUG(("mmc_standard_find_server: failed to connect to server '%s:%d' status %d, trying next", mmc->host, mmc->port, mmc->status));
 80 
 81             hash += mmc_hash(state, next_key, next_len);
 82             mmc = state->buckets[hash % state->num_buckets];
 83 
 84             efree(next_key);
 85         }
 86     }
 87     else {
 88         mmc = state->buckets[0];
 89         mmc_open(mmc, 0, NULL, NULL TSRMLS_CC);
 90     }
 91 
 92     return mmc->status != MMC_STATUS_FAILED ? mmc : NULL;
 93 }
 94 /* }}} */

参考文献

いろいろ自分で頑張って読んでたけど下記ページ見つけたので詳細はこっちに投げる。

The PHP Memcached server interaction distributed implementation source code analysis - Php - php javascript html

http://www.phpjavascripthtml.com/1426767/

(2017/06/14 追記:いまみたらドメイン失効してた…)