Memcached客户端可以设多个memcached服务器,它是如何把数据分发到各个服务器上,而使各个服务器负载平衡的呢?
可以看看.net版中的客户端中的源码,就可以知道 先看代码:
获取Socket连接代码
1 /// <summary>
2 /// Returns appropriate SockIO object given
3 /// string cache key and optional hashcode.
4 ///
5 /// Trys to get SockIO from pool. Fails over
6 /// to additional pools in event of server failure.
7 /// </summary>
8 /// <param name="key">hashcode for cache key</param>
9 /// <param name="hashCode">if not null, then the int hashcode to use</param>
10 /// <returns>SockIO obj connected to server</returns>
11 public SockIO GetSock(string key, object hashCode)
12 {
13 string hashCodeString = "<null>";
14 if(hashCode != null)
15 hashCodeString = hashCode.ToString();
16
17 if(Log.IsDebugEnabled)
18 {
19 Log.Debug(GetLocalizedString("cache socket pick").Replace("$$Key$$", key).Replace("$$HashCode$$", hashCodeString));
20 }
21
22 if (key == null || key.Length == 0)
23 {
24 if(Log.IsDebugEnabled)
25 {
26 Log.Debug(GetLocalizedString("null key"));
27 }
28 return null;
29 }
30
31 if(!_initialized)
32 {
33 if(Log.IsErrorEnabled)
34 {
35 Log.Error(GetLocalizedString("get socket from uninitialized pool"));
36 }
37 return null;
38 }
39
40 // if no servers return null
41 if(_buckets.Count == 0)
42 return null;
43
44 // if only one server, return it
45 if(_buckets.Count == 1)
46 return GetConnection((string)_buckets[0]);
47
48 int tries = 0;
49
50 // generate hashcode
51 int hv;
52 if(hashCode != null)
53 {
54 hv = (int)hashCode;
55 }
56 else
57 {
58
59 // NATIVE_HASH = 0
60 // OLD_COMPAT_HASH = 1
61 // NEW_COMPAT_HASH = 2
62 switch(_hashingAlgorithm)
63 {
64 case HashingAlgorithm.Native:
65 hv = key.GetHashCode();
66 break;
67
68 case HashingAlgorithm.OldCompatibleHash:
69 hv = OriginalHashingAlgorithm(key);
70 break;
71
72 case HashingAlgorithm.NewCompatibleHash:
73 hv = NewHashingAlgorithm(key);
74 break;
75
76 default:
77 // use the native hash as a default
78 hv = key.GetHashCode();
79 _hashingAlgorithm = HashingAlgorithm.Native;
80 break;
81 }
82 }
83
84 // keep trying different servers until we find one
85 while(tries++ <= _buckets.Count)
86 {
87 // get bucket using hashcode
88 // get one from factory
89 int bucket = hv % _buckets.Count;
90 if(bucket < 0)
91 bucket += _buckets.Count;
92
93 SockIO sock = GetConnection((string)_buckets[bucket]);
94
95 if(Log.IsDebugEnabled)
96 {
97 Log.Debug(GetLocalizedString("cache choose").Replace("$$Bucket$$", _buckets[bucket].ToString()).Replace("$$Key$$", key));
98 }
99
100 if(sock != null)
101 return sock;
102
103 // if we do not want to failover, then bail here
104 if(!_failover)
105 return null;
106
107 // if we failed to get a socket from this server
108 // then we try again by adding an incrementer to the
109 // current key and then rehashing
110 switch(_hashingAlgorithm)
111 {
112 case HashingAlgorithm.Native:
113 hv += ((string)("" + tries + key)).GetHashCode();
114 break;
115
116 case HashingAlgorithm.OldCompatibleHash:
117 hv += OriginalHashingAlgorithm("" + tries + key);
118 break;
119
120 case HashingAlgorithm.NewCompatibleHash:
121 hv += NewHashingAlgorithm("" + tries + key);
122 break;
123
124 default:
125 // use the native hash as a default
126 hv += ((string)("" + tries + key)).GetHashCode();
127 _hashingAlgorithm = HashingAlgorithm.Native;
128 break;
129 }
130 }
131
132 return null;
133 }
134