Reprinted: http://www.tuicool.com/articles/VJfEfyv
Memcache itself does not realize the cluster function. If you want to use Memcahce to realize the cluster, you need to use third-party software or design your own programming. Here we will use memagent proxy. Memagent is also called magent. You should pay attention to these two tools. For installation of Memcache and magent, please refer to the article. Installing Memcached Services on Linux Sum magent Compiler Installation and Common Errors
Overall framework
Direct picture above:
From the figure, we can see that there are two magent nodes, two memcached nodes. Each magent node proxies two memcached nodes respectively. The application side uses magent pool to call memcached for storage. The hardware structure is composed of two linux servers. Magent and memcached services are installed on each server and set to boot. The advantage of doing this is that no server downtime will affect magent pool access to memcache information, that is, to achieve high availability of memcached (HA), if both machines are down, it will only mean that your RP is too poor. Of course, you can also use three, four or more servers to improve HA.
Test HA
Background: Two servers in the local area network 172.18.117.71 (memcache port 11211, magent port 11210), 172.18.117.113 (memcache port 11211, magent port 11210), and two servers in the same LAN test machine, below is the test code:
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MainTest {
public static void main(String[] arg){
SockIOPool pool = SockIOPool.getInstance();
//magent connection pool
pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
pool.setSocketTO(3000);
pool.setNagle(false);
pool.setSocketConnectTO(0);
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient();
memCachedClient.set("becd0000", "Test example");
//System.out.println(memCachedClient.get("becd0000"));
//System.out.println(memCachedClient.flushAll());
}
}
Step 1: Put key as "becd0000" and value as "test example" into memcache through magent's pool
Step 2: Modify the magent connection pool to a single memcache connection with the following code
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MainTest {
public static void main(String[] arg){
SockIOPool pool = SockIOPool.getInstance();
//magent connection pool
pool.setServers(new String[] { "172.18.117.71:11211"});
pool.setSocketTO(3000);
pool.setNagle(false);
pool.setSocketConnectTO(0);
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient();
//memCachedClient.set("becd0000", "test examples");
System.out.println(memCachedClient.get("becd0000"));
//System.out.println(memCachedClient.flushAll());
}
}
You can see that accessing memcache alone can fetch the value you just stored.
Step 3: Modify
pool.setServers(new String[] { "172.18.117.71:11211"});
by
pool.setServers(new String[] { "172.18.117.113:11211"});
If you execute again, you can see the same result as Step 2, and you can get the values, which means that the values stored through the magent agent will be placed in two memcache s, respectively.
Step 4: Stop the memcached service on 172.18.117.113
Stop the memcached service command: kill "cat/tmp/memcached.pid"
Step 5: Get the value again through the magent agent, the code is as follows:
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MainTest {
public static void main(String[] arg){
SockIOPool pool = SockIOPool.getInstance();
//magent connection pool
pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
pool.setSocketTO(3000);
pool.setNagle(false);
pool.setSocketConnectTO(0);
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient();
//memCachedClient.set("becd0000", "test examples");
System.out.println(memCachedClient.get("becd0000"));
//System.out.println(memCachedClient.flushAll());
}
}
You can see that values are still available.
Step 6: Start the just stopped memcached service, and all information in memcached will be cleared after restart.
Step 7: Once again, the magent proxy pool is used to get the value of key as "becd0000". The code is as follows:
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MainTest {
public static void main(String[] arg){
SockIOPool pool = SockIOPool.getInstance();
//magent connection pool
pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
pool.setSocketTO(3000);
pool.setNagle(false);
pool.setSocketConnectTO(0);
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient();
//memCachedClient.set("becd0000", "test examples");
System.out.println(memCachedClient.get("becd0000"));
//System.out.println(memCachedClient.flushAll());
}
}
You can see that the value taken here is null.
Result analysis
The conclusion can be drawn from the above tests.
1. The value of the connection pool through the magent will exist on all memcached of the magent agent, respectively.
2. If there is a memcached downtime, the value can be retrieved by magent proxy.
3. If memcached is repaired and restarted, the value retrieved by magent proxy will be Null. This is because after memcached restart, the inner value disappears with the stop of memcache service (because it is in memory), but magent is allocated to a machine by hashing with key. After memcached restart, the value will be retrieved from this machine, and all the values retrieved will be empty.
Solution
1. After each memcache outage repair, a program can be written to copy all the information of other memcaches in the cluster to the memcache after the current downtime repair.
2. Write your own proxy. When the value from one memcached service is null, then go to other memcached to get the value.
Matters needing attention
Magent is called in the same way as memcached. Client can switch to magent mode without changing code.
Copyright is reserved. Please indicate the author and origin for reprinting.