使用redis模擬memcach多伺服器承載
如題分享一老外實現思路,拋開redis自身配置主從外模擬memcache中hash多伺服器承載
原文
作者思路不錯,大家可以借鑑
點選(此處)摺疊或開啟
-
php
-
/**
-
* Redisent, a Redis interface for the modest
-
* @author Justin Poliey
-
* @copyright 2009 Justin Poliey
-
* @license php The MIT License
-
* @package Redisent
-
*/
-
-
require \'redisent.php\';
-
-
/**
-
* A generalized Redisent interface for a cluster of Redis servers
-
*/
-
class RedisentCluster {
-
-
/**
-
* Collection of Redisent objects attached to Redis servers
-
* @var array
-
* @access private
-
*/
-
private $redisents;
-
-
/**
-
* Aliases of Redisent objects attached to Redis servers, used to route commands to specific servers
-
* @see RedisentCluster::to
-
* @var array
-
* @access private
-
*/
-
private $aliases;
-
-
/**
-
* Hash ring of Redis server nodes
-
* @var array
-
* @access private
-
*/
-
private $ring;
-
-
/**
-
* Individual nodes of pointers to Redis servers on the hash ring
-
* @var array
-
* @access private
-
*/
-
private $nodes;
-
-
/**
-
* Number of replicas of each node to make around the hash ring
-
* @var integer
-
* @access private
-
*/
-
private $replicas = 128;
-
-
/*** 特殊方法預設到特定連線
-
* The commands that are not subject to hashing
-
* @var array
-
* @access private
-
*/
-
private $dont_hash = array(
-
\'RANDOMKEY\', \'DBSIZE\',
-
\'SELECT\', \'MOVE\', \'FLUSHDB\', \'FLUSHALL\',
-
\'SAVE\', \'BGSAVE\', \'LASTSAVE\', \'SHUTDOWN\',
-
\'INFO\', \'MONITOR\', \'SLAVEOF\'
-
);
-
-
/**
-
* Creates a Redisent interface to a cluster of Redis servers
-
* @param array $servers The Redis servers in the cluster. Each server should be in the format array(\'host\' => hostname, \'port\' => port)
-
*/
-
function __construct($servers) {
-
$this->ring = array();
-
$this->aliases = array();
-
foreach ($servers as $alias => $server) {
-
$this->redisents[] = new Redisent($server[\'host\'], $server[\'port\']);
-
if (is_string($alias)) {
-
$this->aliases[$alias] = $this->redisents[count($this->redisents)-1];
-
}
-
for ($replica = 1; $replica <= $this->replicas; $replica++) {
-
$this->ring[crc32($server[\'host\'].\':\'.$server[\'port\'].\'-\'.$replica)] = $this->redisents[count($this->redisents)-1];
-
}
-
}
-
ksort($this->ring, SORT_NUMERIC);
-
$this->nodes = array_keys($this->ring);
-
}
-
-
/**
-
* Routes a command to a specific Redis server aliased by {$alias}.
-
* @param string $alias The alias of the Redis server
-
* @return Redisent The Redisent object attached to the Redis server
-
*/
-
function to($alias) {
-
if (isset($this->aliases[$alias])) {
-
return $this->aliases[$alias];
-
}
-
else {
-
throw new Exception(\"That Redisent alias does not exist\");
-
}
-
}
-
-
/* Execute a Redis command on the cluster */
-
function __call($name, $args) {
-
-
/* Pick a server node to send the command to */
-
$name = strtoupper($name);
-
if (!in_array($name, $this->dont_hash)) {
-
$node = $this->nextNode(crc32($args[0]));
-
$redisent = $this->ring[$node];
-
}
-
else {
-
$redisent = $this->redisents[0];
-
}
-
-
/* Execute the command on the server */
-
return call_user_func_array(array($redisent, $name), $args);
-
}
-
-
/*** 2分法查詢
-
* Routes to the proper server node
-
* @param integer $needle The hash value of the Redis command
-
* @return Redisent The Redisent object associated with the hash
-
*/
-
private function nextNode($needle) {
-
$haystack = $this->nodes;
-
while (count($haystack) > 2) {
-
$try = floor(count($haystack) / 2);
-
if ($haystack[$try] == $needle) {
-
return $needle;
-
}
-
if ($needle < $haystack[$try]) {
-
$haystack = array_slice($haystack, 0, $try + 1);
-
}
-
if ($needle > $haystack[$try]) {
-
$haystack = array_slice($haystack, $try + 1);
-
}
-
}
-
return $haystack[count($haystack)-1];
-
}
-
- }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26477398/viewspace-1258943/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PHP模擬多繼承的方式:traitsPHP繼承AI
- 使用Docker+Nginx模擬負載均衡DockerNginx負載
- 如何使用RunnerGo模擬使用者分流負載Go負載
- java 模擬器 多型Java多型
- Linux 中模擬多種系統負載的方法Linux負載
- 伺服器的大使用者量的承載方案伺服器
- NOIP模擬96(多校29)
- NOIP模擬92(多校25)
- NOIP模擬88(多校21)
- NOIP模擬83(多校16)
- NOIP模擬86(多校19)
- shell模擬“多執行緒”執行緒
- C++ 繼承、多型、虛擬函式C++繼承多型函式
- Go型別嵌入介紹和使用型別嵌入模擬實現“繼承”Go型別繼承
- Thinking in Java---多執行緒模擬:銀行出納員模擬+飯店模擬+汽車裝配工廠模擬ThinkingJava執行緒
- mysqlslap 負載模擬客戶端MySql負載客戶端
- Dymola — 多學科系統模擬平臺
- 「模擬賽」多校 A 層聯訓 16
- js使用yield模擬多執行緒的方法簡單介紹JS執行緒
- 模擬介面請求到web伺服器Web伺服器
- javascript模擬實現函式過載JavaScript函式
- 蒙特卡羅模擬技術 (轉載)
- Ubuntu18 上使用 docker 的 nginx 容器模擬負載均衡UbuntuDockerNginx負載
- 使用 node 模擬請求介面
- Openwrt使用Qemu模擬開發。
- 使用命名管道承載gRPCRPC
- 「模擬賽」多校 A 層衝刺 NOIP 24
- 前端坑多:使用js模擬按鍵輸入的踩坑記錄前端JS
- springboot+redis分散式鎖-模擬搶單Spring BootRedis分散式
- .NetCore+Redis模擬秒殺商品活動(分析)NetCoreRedis
- 多繼承繼承
- 模擬郵件伺服器,批量註冊利器伺服器
- 如何使網站伺服器承擔高負載網站伺服器負載
- 多繼承 與 多重繼承繼承
- Java:多執行緒模擬多站點售票過程薦Java執行緒
- 多伺服器使用Docker設定一主一從三哨兵redis(完整)伺服器DockerRedis
- [練手] 使用 Redis 模擬登陸使用者瀏覽商品頁面的 token 維護,足跡記錄,清理多餘記錄的實現Redis
- 模擬器多開玩遊戲有限制登入使用代理軟體解決!遊戲