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
(2017/06/14 追記:いまみたらドメイン失効してた…)